Triptych
Home
Pt. 1: The Map and the Landscape
Pt. 2: Distributional Surface Theory
2.1: The Helmholtz Machine2.2: Othello2.3: DST
Cover NoteGrokking & FourierAt the Frontier: Opus 4.6MazesChess-GPTCode Type ErrorsGolden Gate Gemma
2.5: Sparks and Parrots2.6: The Undiscovered Country2.7: How to Carve a Soul in 90 Seconds
Pt. 3: Beethoven and the Bitter Lesson
Contact
© Triptych 2026

Grokking & Fourier

Github repo ↗

In the introduction I described the empirical work done in DST at 'experiments'. The air quotes are not a false modesty, they are a description of an odd feature of all this work. It is itself an example of completely separating two things: a human conceptual thesis and an AI systems functional capacity to build and stress test it.

This capacity to build and stress test, as anyone who knows these AI systems well, is variable. Given clear direction and goals they can produce incredibly high quality work. But the reality is that if the person directing it does not have the hard skills to audit that work, there is a serious gap. All the work in this program contains this.

Since transparency about this is important, I thought it worth also explaining in more detail the process itself. Whatever the outcome of the work, it might itself be a useful stimulus for new approaches or a roadmap for what not to do.

Before walking through the methodology and some notes on the research discussed, I'd like to point out something for non-technical people working in academic disciplines. The advent of coding harnesses like Claude Code and Codex means that the bridge between a conceptual idea and the technical work to explore it is getting shorter and shorter. Large data analysis, the building of bespoke tools, or even the training and fine tuning of AI models is becomes more and more possible. Previously this would have demanded development resources that were either unaffordable or inaccessible.

I have been lucky in that my day job has exposed me to technical approaches, languages and processes that mean they are not inherently intimidating. This small bridge, learning the basics of programming and a general sense of system architectures is not uncrossable. With a little time investment, or external training, getting to a place where you feel comfortable messing around (with the appropriate caveats to your own understanding) is easily possible. These tools will only get better, so that barrier of accessibility should drop further and further and now is, I think, a great time to dive in and enjoy using them. There is something amazing about this technical-alchemical process, of magicking something into being, however amateur.

The wrong way round

Part of the oddity of having access to these tools, as a person with a background in the arts rather than the sciences, is that it exposes an asymmetrical approach to idea generation. So much modern science is done by collecting data and inferring patterns, and it is data itself that drives hypothesisation. In one sense this is obviously preferable: that data itself is extant and you work to try to understand its underlying patterns.

This is the opposite of how the DST work was done. Failing to instantiate a layer of structural understanding led me to wonder why the instantiation failed. I had spent time reading about conceptual blending theory and trying to apply its ideas to metaphor creation specifically. So the experiments are generated out of theory of what was missing rather than from data. The tests were done to stress test a theory before the data existed. This isn't really how most modern science is done.

This approach also compounds a specific danger when working with AI tools to help tighten testing criteria or write code. The directional bias of the predictions shapes the code itself. There are loops of adversarial auditing that can be done (and were) but this is where the missing piece of deep technical expertise really hurts. I hand over the explosives with an apologetic shrug about how they might have been wired.

'Experimental Process'

After the failed experiment the first thing to do was try to understand world models better, a learning phase. This began by researching the original papers themselves and trying to understand what the techniques were being used, how they worked, and some of the basic maths. In many cases the technique itself was interpretable (what it did) but the specific mathematics behind the technique remained unintelligible (how it was done).

So instead of trying to get all the way through the maths, which would have made doing all the experiments impossible, I built out a framework of tools that were then used across the different tested domains.

Almost all the work in DST, and all the experiments, were done in very short 1–2 day sprints. This tended to be on the weekend or sometimes over a few evenings. Occasionally, when model training was involved, it could be set up and left to run. By necessity this cut short the deep learning time.

The process was something like this for each domain

Conceptual framework (the dissociation between structural understanding and surface navigation) → specification of behaviours / features that would dissociate these two → specification of testing in a loop with Claude Code (Opus 4.6) against the defined conceptual framework and tools → generation of tests / training scripts → run locally or on RunPod → analysis with Claude Code + human intervention feedback → cycle.

At the end of each experiment a set of audit loops were set up adversarially. Creating a prompt that was designed to try and find fundamental problems in the code, approach or methodology. Sometimes these uncovered core issues that then necessitated either a rerun or a new analysis of the existing data.

This posed its own problem, which I list here more for interest than anything else. Since LLMs are so suggestible this can function in either direction. A hyper aggressive audit would often flag minor syntactic issues in the code which on further inspection were non material. The register, either in the positive framing, or the negative, is often what drives what we find.

Pinching the shoulders of giants

A general reticence to share this work comes directly out of its inception and production. To make the statements made in DST, which is to suppose there may be an alternative explanation for work done with a rigour that the person making those statements cannot match, is just cringemaking.

More than that though is something secondary. The domains (Othello and Fourier for example) directly relate to some of the people and research that over the course of the reading I've come to admire most. Neel Nanda, quoted in the Helmholtz essay, is my favourite Mechanistic Interpretability researcher. Not only has he made libraries available which in turn made this work possible (however accurate or inaccurate) he also has constantly fought to do the work trying to make these systems safe. Some of the work done by him, and the other people whose models are examined in these essays is breathtakingly elegant and well designed.

I do not believe that a computationalist view of cognition is definitively wrong, or that it may not provide a correct model for cognition; my views are different, as outlined in these essays, but obviously not definitive. I don't think either that DST is in any way confirmation of what the world models found inside these systems are or aren't doing, but it does offer a different explanation. I hope only that if any of the researchers who did this work read this they may find something in the morass that is directly valuable for how they think about investigating the systems they work on.

In 2022, Alethea Power and her collaborators were working on training small transformers to do maths. As training progressed something interesting happened: as a model learned modular arithmetic, memorising the training data, seemed to plateau in its improvement, and then, later in training suddenly jumped to being able to generalise. Task accuracy would go from near zero to near perfect in a few thousands 'steps' of training. What they observed is called 'grokking' and has given its name to different AI products and models.

The problem they trained the model on was (a + b) mod 113. Modular arithmetic is like doing maths on a clock face. On a 12-hour clock, 10 + 4 is not 14; it's 2 o'clock. Mod 113 is the same idea, but imagine it on a much larger clockface: add two numbers, and if the result goes past 113, wrap back to the start.

A year later Neel Nanda and his team did some investigations into what was going on in the model. Inside, they found what looked like an algorithm: a Fourier circuit, computing modular addition through trigonometric identities. The model seemed to have learned, or constructed, in a precise and inspectable way, what modular arithmetic was.

This became one of the most cited results in mechanistic interpretability: a simple system, opened up, revealing an algorithm of the sort a mathematician would write.

With DST we can look at these results again; and, as with Othello, not refute any of the research done, but try to offer another perspective.

A note on setup before we begin. When the first version of this battery returned results this strong, the first question was whether we were testing Nanda's architecture or our own. We weren't, quite: three small things had drifted. No causal attention mask, ReLU instead of GELU, biases in the MLP layers. So we re-ran the whole battery on a faithful rebuild: causal mask, GELU, no MLP bias. Every finding below replicates across both versions. The numbers quoted are from the second faithful rerun.

The grokking moment

The model memorises, then, much later, generalises.

0%25%50%75%100%ACCURACYgrok0K5K10K15K20KTRAINING STEPS →Training accuracyTest accuracy
Indicative trajectory · V2 causal-mask models · mod 113 · train/test split 30%/70%

Two Readings

The structural reading of models trained on this problem says: the model has discovered modular addition, expressed as a Fourier circuit. The DST reading says: the model has learned a (mod 113, addition) shaped surface that happens to express itself in trigonometric features, because trigonometric features are an efficient encoding of cyclic data. If the goal of compressing the data into the ideal map involves finding features that corroborate what we think of as the most efficient, this seems, in principle, like a good thing for the model to do.

If the structural reading is correct, the model's representations perhaps could generalise across moduli, across operations, across seeds. If the distributional reading is correct, each circuit should be specific: to the operation, to the modulus, to the seed.

So we trained six models (I know, always training models). Three on (a + b) mod 113, differing only in their random seed. Two on (a + b) mod 127. One on (a × b) mod 113.

Private Frequencies

We start, as with Othello, with the probes. A probe is a small classifier trained to read a model's internal activations and predict something we care about; here, the inputs a and b. If a probe succeeds, the information is geometrically present in the model's representations.

Self-probes work almost perfectly. Every model can read its own state with 99.9% accuracy: the geometry is there.

But cross-probes, a probe trained on Seed A and then applied to Seed B, perform at 0.90%. Chance is 0.88%.

Private frequencies

Each model reads itself. None reads any other.

Probe applied to ↓
Probe trained on →
Seed 0
Seed 1
Seed 2
99.80%
0.08%
1.27%
0.94%
100.00%
0.81%
0.38%
1.93%
100.00%
Seed 0
Seed 1
Seed 2
99.93%
self-probing (diagonal)
0.90%
cross-probing (off-diagonal)
0.88%
random chance

Control-verified: an untrained network of the same architecture decodes (a+b) mod 113 at 0.0% against a 0.9% chance floor, so the privacy here is a fact about learned circuits, not about the input.

Real data · Linear probes on post-MLP activations · V2 causal-mask models · Chance = 1/113

To check this with a second instrument we use CKA, or Centred Kernel Alignment. CKA is a measure of how similarly two neural networks structure their internal representations; it returns a number between 0 and 1, where 1 means the models arrange information in essentially the same geometry and 0 means there is no shared structure to find. Across our three seeds, CKA is 0.0008. A third measure, Procrustes distance, returns 1.394: essentially √2, which is the theoretical maximum for representations of this kind, the point at which two geometries are as misaligned as they can possibly be. The representations are not rotated versions of each other; they look as separate as they can get.

When we look directly at the Fourier circuits each model has built we can see this even more clearly. Seed 0 uses dominant frequencies {110, 3, 48, 65, 75}. Seed 1 uses {112, 1, 24, 89, 59}. Seed 2 uses {81, 32, 20, 93, 111}. The overlap across any pair of seeds is zero.

Dominant frequencies

Three models, three different sets of frequencies.

Seed 05 dominantSeed 15 dominantSeed 25 dominant11034865751121248959813220931110285684112FOURIER FREQUENCY (0 - 112)
0
frequencies shared across all three seeds
0
frequencies shared between any pair
113
frequencies available
Real data · Top 5 dominant frequencies by embedding power spectrum · V2 causal-mask models · mod 113

Three models, trained on identical data with identical hyperparameters, all reaching 100% accuracy through Fourier circuits, share not a single dominant frequency. The circuit is absolutely real, but the specific frequencies it uses are arbitrary.

There is a reasonable objection here: perhaps the 'different' frequencies are secretly the same information in a different form. Fourier features come in conjugate pairs (frequency k and frequency p - k together carry the same cyclic content), so in principle two seeds could be using the same underlying features under different labels. But even after pairing the conjugates, the overlap across seeds is still zero. The encodings seem private.

There is a further objection: three seeds is a very small sample. With only three sets of five frequencies drawn from 113 candidates, zero pairwise overlap has about a 47% probability under pure random selection. So the n=3 result is suggestive, not decisive. To tighten the question, we trained thirty more seeds and compared the observed overlap against a Monte Carlo null in which each seed picks five frequencies uniformly at random.

Thirty seeds

Thirty independently trained models. No frequency is preferred.

seed 1000seed 1009seed 1019seed 10290285684112FOURIER FREQUENCY (0 - 112)30 SEEDS
30 / 30
seeds grokked
5
max seeds picking any single frequency
113
frequencies available
Comparison against uniform-random null (Monte Carlo, n = 20,000)
StatisticObservedNull mean95% CIP-value
Mean pairwise overlap0.220.22[0.18, 0.27]
0.49
P(obs ≤ null)
Fraction of pairs with zero overlap86.2%79.2%[75.2%, 82.8%]
< 0.0001
P(obs ≥ null)
Max times any single frequency appears across seeds54.9[4, 7]
0.69
P(obs ≥ null)

With thirty seeds the story is more precise than with three. No frequency is preferred; the most any single frequency appears across seeds is five. Pairs with zero shared frequencies occur at 86.2%, modestly above the random-null's 79.2% (p < 0.0001). The circuit is real, and the specific frequencies each seed settles on are essentially arbitrary.

Real data · 30 seeds (1000-1029), all grokked to ≥ 99% test accuracy · top-5 frequencies by embedding power spectrum · V2 causal-mask model · RTX 3090

Three things show up in the larger sample. The mean pairwise overlap is 0.22 shared frequencies per pair, which matches the random-null mean (0.22) exactly. No frequency is preferred across seeds: the most any single frequency appears is five out of thirty seeds, which is what the random null predicts. The fraction of pairs with zero overlap is 86.2%, modestly above the null's 79.2% (p < 0.0001) - a real but small dispersion effect.

Taken together: the circuit is real, and the specific frequencies each seed settles on are essentially arbitrary. Most pairs share nothing not because the model is avoiding shared representations, but because random selection of five things from 113 naturally produces mostly-disjoint small subsets. The strong form of the claim - that seeds build "entirely different" encodings - was overstated at n=3. The weaker form - that no particular frequencies are structurally preferred, and the specific Fourier basis each model lands on is arbitrary - holds cleanly at n=30.

(Just for fun, here is the graph at n=300)

Three hundred seeds

Three hundred independently trained models. No frequency is preferred at scale.

0510152025SEEDS PICKINGuniform-random expectation ≈ 13.30285684112FOURIER FREQUENCY (0 - 112)
300 / 300
seeds grokked
23
max seeds picking any single frequency
1,500
total frequency picks
Comparison against uniform-random null (Monte Carlo, n = 2,000)
StatisticObservedNull mean95% CIP-value
Mean pairwise overlap0.2240.223[0.219, 0.228]
0.59
P(obs ≤ null)
Fraction of pairs with zero overlap85.4%79.2%[78.8%, 79.6%]
< 0.001
P(obs ≥ null)
Max times any single frequency appears2323.4[21, 27]
0.65
P(obs ≥ null)

With three hundred seeds the picture is the same as with thirty. The zero-overlap fraction is still modestly elevated above the random null (85.4% vs 79.2%), but the mean pairwise overlap and the maximum single-frequency count both sit at what uniform random selection would produce. The Fourier circuits are real and they are seed-specific; the specific frequencies each model settles on are essentially arbitrary.

Real data · 300 grokked mod-113 seeds, top-5 dominant Fourier frequencies each · 1,500 total picks across 113 available frequencies

One further check protects everything above. Across the programme we ran the same control on every cross-probe result: take an untrained network of the identical architecture and probe it identically. In the board game domains that control was deflating, a network that had learned nothing read the board nearly as well as the trained ones, because the board comes with the input. Here it is the opposite. An untrained network decodes (a+b) mod 113 at exactly 0.0%, below even the 0.9% chance floor. The decodability of modular addition is created entirely by training, so the privacy these probes report is real and control-verified: the seeds built genuinely different learned circuits, not one input signal viewed from different angles.

The Arithmetic Overlap

Even if seeds diverge, perhaps a model that has learned modular addition of some kind should be able to minimally transfer to a different modulus. The rule is the same, but the wrap point differs.

We tested the mod 113 model on (a + b) mod 127. The raw accuracy was 40.4%. This looked, at first at least, like a real transfer.

But since your solo researcher is neither an AI researcher nor a mathematician, there was a confound. For any pair where a + b is less than 113, the answer is identical under both moduli: the wrap point is irrelevant because the sum doesn't reach it. The number of in-vocabulary pairs where this happens is 6,441 out of 16,129, or 39.9%. That is not roughly the observed accuracy; it is the observed accuracy. The 'transfer' had precisely the magnitude you would expect if it were arithmetic overlap and nothing else.

So in a second analysis we restrict the test to the 6,328 pairs where the two moduli give different answers.

The mod 113 model's accuracy on the mod 127 task: 0.00%. Not a single pair. The model produced (a + b) mod 113 with 99.56% accuracy and the mod 127 answer never. This seems to be the signature of having specifically learned (a + b) mod 113.

We tightened the test once more. Of the 6,328 pairs, we kept only the 4,851 where the mod 127 answer sits inside the model's output range, so the model could in principle produce it. Same result: 0.00%. Not one pair.

The same test from addition to multiplication: 0.88%. Exact chance. Multiplication to addition: 0.86%.

Clean, But Fragile

Maybe the circuit itself is real even if it doesn't transfer. We can try to test this directly. Activation patching is a technique for probing internal computation: we run the model on an input, reach into its internal state, and swap out the part that represents one of the numbers. If we swap b for b + 1, and what the model is doing really is addition, then its output should shift by exactly one.

That's what happens. The output shifts by one, cleanly, with 100% reliability. We also looked at the probability the model assigns to a near-miss, an answer off by one in either direction. It is zero, to six decimal places.

Embedding noise

Small distortions of the input break the circuit.

Gaussian noise applied to the input embeddings, as a fraction of the embedding's typical norm.

0%25%50%75%100%ACCURACY99.6%99.5%82.0%38.5%cleanσ = 0.001%σ = 0.015%σ = 0.0510%σ = 0.10NOISE LEVEL (FRACTION OF EMBEDDING NORM) →
Real data · Gaussian noise applied to input embeddings · V2 causal-mask model · seed 0

A genuine arithmetic algorithm should be insensitive to a small distortion in its inputs; the rule 'add the two numbers, mod 113' doesn't care if a is represented slightly imprecisely. But it seems that perhaps the Fourier circuit isn't an arithmetic algorithm. Instead, it looks more like a precisely tuned distributional pattern, depending on exact relationships between exact frequencies.

Distort the inputs and the pattern degrades. It seems the cleanness of the circuit and its fragility are not in tension; they are the same property seen from two angles.

Maps, Again

The Fourier circuits are real in the sense that they are discoverable and compute. In their own way they are a beautiful demonstration of the extraordinary power of statistical compression to find the most efficient encoding and decoding of a problem. Another demonstration of why we should not take transformer based models lightly. But they don't show the characteristic qualities of an algorithm, a learned operation that can be transferred.

The grokking experiments are, for me, beautiful maps drawn in trigonometry.

At the Frontier: Opus 4.6 →