1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""
Distance-based Toroidal Logit Processor.
This is the PUBLISHED, distance-based logit bias (DOI: 10.5281/zenodo.18516477).
Uses token_id % N^2 mapping to the Tonnetz torus, NOT spectral resonance.
Compatible with HuggingFace `transformers` LogitsProcessor interface.
"""
"""Distance-based toroidal logit processor for HuggingFace generate().
Maps token IDs onto an N x N torus via token_id % N^2, then biases
logits toward tokens that are topologically close to recent context.
This is the published "free sample" — it works, it's in the paper,
and it reduces the *drift rate* by ~40% on synthetic sequences (a training-dynamics
metric). NOTE (2026-07-05): this does NOT translate to out-of-sample hallucination
reduction — a controlled replication found the inference-time bias null (McNemar p=0.22).
Args:
grid_size: Side length N of the torus (default 12, giving 144 positions).
radius: Locality radius for full-strength bias.
alpha: Exponential decay rate beyond radius.
context_window: How many recent tokens to consider for bias.
top_k: Clip bias to top-k candidates (300 for OpenAI API compat).
bias_strength: Scaling factor for the bias signal.
Example:
>>> from transformers import AutoModelForCausalLM, AutoTokenizer
>>> model = AutoModelForCausalLM.from_pretrained("gpt2")
>>> tokenizer = AutoTokenizer.from_pretrained("gpt2")
>>> processor = ToroidalLogitProcessor(grid_size=12)
>>> inputs = tokenizer("The quantum", return_tensors="pt")
>>> outputs = model.generate(**inputs, logits_processor=[processor], max_new_tokens=50)
"""
=
=
=
=
=
=
=
= *
"""Apply distance-based toroidal bias to logit scores.
Args:
input_ids: (batch_size, seq_len) token IDs generated so far.
scores: (batch_size, vocab_size) raw logit scores for next token.
Returns:
Biased scores with same shape.
"""
, =
# Get recent context token positions on the torus
=
return
= # (batch, context_len)
# Map recent tokens to torus positions
= # (batch, context_len)
# Compute bias for each batch element
=
# Accumulate distance-based bias from each context token
=
+= 1.0
# For each torus position, compute weighted average distance to context
# Then map back to vocab via token_id % N^2
=
=
# This context position contributes bias to nearby positions
=
+= *
+= * *
# Normalize
/=
# Map torus bias to vocab: each token gets bias of its torus position
= %
=
# Zero-center the bias (so it doesn't shift overall magnitude)
-=
=
return +