Nov 2026 · Grasphouse · Nablaframe technical report

Nablaframe: Beating the Null Isn’t Enough

Three cheap checks on what an interpretability result means, from a small GPT trained on tasks with planted variables and measured beside random-weights twins.

Authorapolloh0
PublishedNovember 15, 2026
Scale1–4 layers, width 32–128
StatusHeadlines: feasibility
Code and recordsapolloh0/nablaframe
Contents

Abstract #

Nablaframe is a small GPT-2-style transformer whose training run replays bit for bit, and each of its explanatory views carries a badge of what a gate measured for it. Its tools are held, gate by gate, to tasks with planted variables: induction, an in-context two-hop lookup and modular addition. Each trained model is measured beside a random-weights twin. Everything here is toy scale, with one to four layers, residual widths of 32 to 128, and no claim about large models.

Beyond the gates, we re-measured three findings on five or six training seeds per task, against bars written before the new seeds were measured. These results are tagged feasibility: they were measured outside the gates.

  1. A causal meter with a null control still reads structure into random weights. Swap a set of dictionary latents after one block, and the matching set one block later at the same position follows on every twin: 35% to 56% of the time, 20 to 35 points above a null of random latents. That is below the 80% the gates ask of an edge, but a test that asks only "above the null?" accepts it. The residual stream passes the edit along. With the block between them frozen, the swap still follows 30% to 51% of the time, and that is the test that exposes it. Try it in Figure 4 →
  2. Whether weak neuron activations can be removed depends on the model. Zeroing each neuron's activations below its 75th percentile costs induction at most 0.013 nats. It costs modular addition 2.1 to 2.5 nats: less than a random removal of the same activation mass, yet it still changes 66% to 75% of the predictions. On four of five two-hop seeds it costs more than the random removal. Each order holds against all 20 random draws on every seed. Figures 5 and 6 →
  3. At one site, how well units are named doesn't predict how well they steer. At induction's second MLP, single neurons name 78% to 86% of the copied token's values, yet swapping the 16 best-named neurons moves no prediction on any seed. Sixteen transcoder latents name fewer values and move 98% to 100%. The site is one the model barely needs, so this compares two bases as steering handles, not as accounts of what the model uses. Figure 7 →

Four other bars failed, and the failures are reported. Two-hop's replacement of a working earlier route held as written on one seed of five, and its neuron account on none. A sparse edit steering past its whole component's own output cleared its bar on three seeds where four were needed. Tuned neurons out-steering a sparse autoencoder on modular addition held on no seed.

Back to contents

Contributions #

  1. An instrument and its judged record. Models are trained the ordinary way on tasks whose variables are planted in the data. Each judged name and edge is reported beside a null and a random-weights twin, training replays bit for bit, and a gate rules on each phase before the next begins. Bars are fixed before a gate runs and rulings go in an append-only decision log. The parts exist elsewhere: ground truth by construction (Tracr, InterpBench), benchmarks of methods (MIB, SAEBench), hypothesis tests by resampling (causal scrubbing) and random-model baselines (Adebayo et al.; Heap et al.). What we add is the combination. We found no system with all of them, which is a search result. The ground truth is the task's variables, not a known circuit. Where a model holds them is found by patching.
  2. A twin baseline for a causal meter (feasibility, five two-hop seeds; seed 0 recorded in G6.3). At one position, a swap meter reads a residual carry as an edge. A null of random latents doesn't catch it; a twin and a frozen-block pass do. Two remedies are measured.
  3. A random removal matched on mass, beside the weak-activation ablation (feasibility, three tasks, five or six seeds each). The two removals rank differently by task, and on two-hop by seed. So a small loss from removing weak activations is a fact about one model.
  4. Naming and steering measured on the same units at the same budget (feasibility, five induction seeds). Under the per-neuron threshold the neuron-reading literature uses, neurons name more values than transcoder latents on every seed, and 8 or 16 of them steer nothing. Three qualifications belong to the result. All 256 neurons together steer as well as the MLP's own output, the MLP is one the model barely needs, and under the latents' own rule (active above zero) the neurons' naming collapses on seed 0, the only seed where that was measured.
  5. The bars and their outcomes, failures included (Figure 1).

Figure 1. Eight of twelve pre-registered bars held; the four that failed are reported below

Each row is a bar written before the new seeds were measured. Each mark is one seed. Column 0 is the discovery seed, on which every finding was first seen.

● holds on this seed ✕ fails on this seed ◆ separated, opposite sign ○ nothing to label (counted as passing, vacuously)
Seed counts on the new seeds alone, leaving out seed 0: twin baseline 4 of 4; weak against random 4 of 4 (induction), 5 of 5 (modular addition), 3 of 4 (two-hop); naming without steering 4 of 4; over-steering 2 of 4; modular addition's steering 0 of 5; learned twice 0 of 4; neuron re-use 0 of 4. Source: step3-results.json and ablate_r_draws.json.

Back to contents

The instrument #

Nablaframe is built in phases, and each phase ends at a human gate that rules on scripted measurements before the next phase starts. Phases 0 to 7 are complete (D61, 2026-11-07).

Phases and the dates their gates were ruled (docs/charter.md, docs/decisions.md). Phase 8, the self-learning ledger, is next.

How it's built #

The zoo #

Three tasks with planted variables, and a reference run on real text. All models have four heads per layer and dense GPT-2-style blocks.

ModelTaskLayersResidualMLPVocabStepsAccuracy, seed 0
InductionPeriodic windows; copy the token that followed the current one last time264256644,000100.0% at mechanism positions (G4.1)
Two-hopSix facts a → b, then a query a ⇒; answer c, where b → c41285125120,00099.6% held out (G4.1)
Modular additiona + b mod 113, trained on 30% of pairs13212811410,000100.0% held out (G7.1)
Reference runTinyStories, word-level tokenizer412,208No planted variables; recorded only (D44)

Two-hop carries most of this report. Its intermediate b is never in the query, so the model must compute it. Figure 2 shows a window and the sites the results read.

Figure 2. Illustration: a two-hop window, and where the meters look

Hover an entity to follow its chain. Choose an overlay to see the sites the results use.

Overlay

Controls beside the numbers #

Figure 3. Illustration: a null and a twin answer different questions

A null asks whether this set is special among sets, inside one model. A twin asks whether this model is special among models: the same recipe run on weights that learned nothing. Result 1 is a case where the first passes and only the second catches the problem. Schematic.

What the tags mean #

The judged record #

Every row is seed 0's specimen. The gates judge tools against one specimen's planted variables. On two-hop they don't say how the task is solved in general: Result 1 and Bars that failed show other seeds holding b elsewhere.

GateWhat it judgesTrained, seed 0BarTwin
G4.2Induction patch after block 0 and after block 1followed 100.0% and 0.0%at least 90%; at most 10%best head's attention to targets 4.8%
G4.3Two-hop patch control, answer unchangedat least 99.6% at every site and blockat least 95%
G5.2, G5.3Dictionary reconstruction, FVUat most 2.4% and 3.2%at most 10%9.4% to 17.0%
G6.2Names: named as planted, steering follows, nullat least 81.2%, at least 92.6%, at most 1.0%at least 70%, 80%; at most 5%named 0.0%, follows at most 2.1%
G6.3Edges: follows, null, through the residual aloneat least 91.6%, at most 3.3%, at most 3.1%at least 80%; at most 10%, 10%excess over the null at most 0.0%
G6.5Envelope of two-hop's b nameholds from step 6,000 to 20,000, from the probe's first readingstarts within 1 checkpoint
G7.4Crystallizations: KL from the model, mean ablation, wrong functionsat most 0.024 nats; at least 4.141; at least 4.429wrong functions within 0.002 nats of the right one
G7.4Modular addition's write as a function of the sumholds from step 1,100; held-out accuracy reaches 0.9 at 1,700

The last row repeats a known order: Nanda et al. (2023) saw modular addition's circuit form before test accuracy moved.

The seed round re-measures three single-seed findings on new training seeds, each with its own twin and dictionaries. Seeds, inclusion, intervals and definitions are in Appendix A.

Back to contents

1A null is not a twin #

On all five two-hop twins, a swap meter clears its null where little is computed: the carry of b from block 1 to block 2 follows 35.2% to 56.1% of the time, against a null of 15.2% to 20.9%. A null asks whether this set is special among sets; a twin asks whether this model is special among models. For this causal meter, the two questions come apart.

Figure 4. Swap b's latents, and watch what the residual stream carries

Position 25 (⇒) of a two-hop window. Pick a model, a seed and an edge, then freeze the block in between.

Model
Seed
Edge
Block between
The meter: after the upstream set for value v is swapped for another value's, the share of instances where the downstream set for the matching value outweighs the original's (D50). Null: four random active latents swapped instead. Frozen: the block between the two sites patched back to the unintervened pass at that position. 512 instances per bar; feasibility, except seed 0 trained and twin, which match G6.3.

What was measured. Two-hop's b has a set of latents in the SAE after block 1 and another in the SAE after block 2, both at ⇒. Swapping the first set to another value's makes the second set follow. On the twins the excess over the null is 20 to 35 points. That is below the 80% the gates ask of an edge, so the gates' own bar would not pass it. A test that asks only whether the meter beats its null does pass it. With block 2's attention and MLP frozen, the twin's carry still follows 29.7% to 51.4% of the time, so block 2 computes little of it: the residual stream passes the swapped set on.

The trained models, and the other twin checks #

SeedTrained carry: follows (null)Trained carry, frozenTrained hop: follows (null)Twin's hop over its nullTwin's names follow, mostTranscoder names token(p) at block 0: trained, twin
0 (discovery)98.8% (0.2%)94.5%91.6% (3.3%)−2.5 points2.1%6%, 43%
195.7% (2.9%)94.5%15.6% (4.5%)−0.42.8%8%, 51%
22.9% (17.2%)3.5%0.4% (0.4%)+0.42.7%16%, 47%
388.7% (5.7%)97.9%32.8% (13.5%)+1.02.2%59%, 33%
445.1% (21.5%)61.3%0.4% (2.5%)−2.72.0%22%, 55%

Two remedies, each measured once. Label an edge at one position by its rate with the blocks between frozen, as Phase 6 does ("carried" against "computed"). Or judge only edges that cross positions, or that stop following when frozen. On the twins, the one such edge measured, the hop, stays within 3 points of its null. Either check costs one forward pass with the blocks frozen, or one randomly initialized copy of the model, and needs no ground truth.

What it doesn't show. That carries are as large in deeper models, or under another normalization or initialization. The twins are five draws of one initialization scheme at one architecture, and how much a random residual stream carries depends on how close its blocks are to the identity.

Back to contents

2Weak activations need a random control matched on mass #

On modular addition, removing each neuron's weakest activations costs 2.07 to 2.51 nats on every seed: less than a random removal of the same mass (4.07 to 4.66), and still enough to change 66% to 75% of predictions. Without the random removal beside it, the first number reads as weak activations mattering. With it, they matter less than an average activation of the same mass, and the model is broken either way.

The design copies AMX07's replication of "Neural Networks Are Already Clean", run on a 4-layer TinyStories model. It zeroes each neuron's activations below its 75th percentile of magnitude, beside a removal of the strongest activations matched on activation mass. Its random removal is matched on count: it drops 75% of activations, strong ones included, and costs +2.389 against +0.037 for the weak removal. The replication's own review asks for a random removal matched on mass. That removal, with 20 draws per seed, is what we added. Figure 5 shows the difference between the controls on one neuron.

Figure 5. Illustration, synthetic data: four ways to remove activations from one neuron

Each dot is one activation; its area is its magnitude. Hollow dots are zeroed. Move the threshold, switch the removal, draw again.

Removal
75th pct.

Illustration with synthetic activations (one neuron, 200 heavy-tailed magnitudes). The masks follow the experiment's rules: weak zeroes magnitudes below the neuron's percentile; strongest zeroes the top fraction whose mass matches weak's; random, same mass, zeroes each activation with probability equal to weak's mass share; random, same count (the replication's control) zeroes the same share of activations as weak, strong ones included.

The result on real models, every included seed, all MLPs together:

Task (seeds)WeakRandom, same massStrongest, same massPredictions changed by weak
Induction (5)+0.001 to +0.013 nats+0.05 to +0.34+1.04 to +2.91at most 0.3%
Modular addition (6)+2.07 to +2.51+4.07 to +4.66+5.99 to +6.7665.9% to 75.2%
Two-hop (5)+0.76 to +3.20+0.13 to +2.37+0.98 to +11.9913.9% to 78.7%

Random ranges are the first draw on each seed, as first measured. Figure 6 shows all twenty draws.

Figure 6. Weak removal against twenty random removals of the same mass, every seed

Loss change at the task's positions, nats, log scale. Hover any mark.

Show
weak (below the 75th percentile) random, same mass (20 draws) strongest, same mass
On every seed of every task, weak lies outside the range of all 20 draws and the bootstrap interval for weak minus random excludes zero (the rule fixed in ablate_r.py before the draws ran). With one sign: induction 5 of 5 below random, modular addition 6 of 6 below, two-hop 4 of 5 above; two-hop seed 4 is separated the other way. Source: step3/results/ablate_r_draws.json; feasibility.

Twenty random draws per seed. The random draws vary little: their range on any seed is at most 0.32 nats (two-hop seed 3), against weak-minus-random gaps of 0.06 to 2.23 nats. On new seeds alone the counts are 4 of 4, 5 of 5 and 3 of 4.

Mass matching. The random removal's mass is within 0.02 of the weak removal's on every seed but two-hop seed 2 (0.04, with random removing more, which works against the finding). The strongest removal's mass is off by up to 0.08.

What this bears on. A small loss from a weak removal needs a random removal of the same mass beside it before it says anything about weak activations. This isn't a test of the essay, whose evidence comes from image classifiers and large language models. On a medium ConvNeXt, removing the weakest 75% of activations moves accuracy from 72% to 71%, and the essay concludes that almost all weak activations can be ablated "for almost no cost". On our modular-addition and two-hop models that doesn't hold; they are one- and four-layer models on algorithmic tasks, outside what the essay studied. Our result says nothing about large models. Goodfire's technical companion, Neurons as an Interpretable Basis (Tigges et al., 2026-11-10), zeroes the weakest 92.2% of routed neuron activations in Qwen3.6-35B-A3B, and its loss rises from 1.886 to 1.940. At a matched count of 87.5%, its random removal costs +2.328 where keeping the strongest costs +0.066. Both random controls with numbers, AMX07's and Goodfire's, are matched on count. A mass-matched random control was tried before on a small sorting classifier, without reported numbers (Gadeev, 2026-10-22). Added here: the mass-matched control with numbers, across seeds, on tasks with planted variables, with the order changing by task.

What it doesn't show. What in each model makes the difference. Two-hop's seeds, whose patchable state sits at different depths, differ among themselves.

Back to contents

3At one site, names don't predict steering #

At induction's block 1, neurons name 78% to 86% of the copied token's values, yet swapping the 8 or 16 best-named neurons moves 0.0% of predictions on every seed. Sixteen transcoder latents, which name 58% to 77% of values, move 98.4% to 100%.

Figure 7. Steering as more units are swapped, neurons against transcoder latents

Swap the top-k units for two values to the other value's mean, and count predictions that follow. The dashed line is the donor patch: the MLP's own output from a row holding the other value.

Site
Seed
Model
neurons transcoder latents donor patch (ceiling) nulls, random units
Top-k is ranked by F1 for each value. "All" swaps every unit. 512 instances per point; source step3/results/measure_a.json; feasibility. Block 0 reads the current token at every position; block 1 reads the copied token at mechanism positions.

Over-steering: seen on four seeds, below its bar #

Switch Figure 7 to block 0. The other direction, a sparse edit that steers more than its whole component can, failed its pre-registered bar (3 of 5 seeds; 4 needed). It is reported as an observation.

Seed16 latents steerDonor patch64 latentsReconstruction of the donor rowEvery latent to its meanEvery neuron to its meanEdited output's norm pct., 16 latents
0 (discovery)71.1%11.9%13.7%11.1%10.9%10.2%59th
222.7%10.2%6.1%10.2%4.9%4.7%57th
333.4%11.7%2.5%12.9%2.3%2.1%58th
571.7%8.8%10.0%9.4%6.2%5.7%62nd
73.5%2.9%2.7%2.7%2.1%2.1%64th

Induction's block 0, token(p) at every position, 512 instances per seed. Nulls follow 0.0%.

Back to contents

4Bars that failed #

Two candidates failed outright, and one finding turned out to describe one run. Each is reported because the failure changes what the single-seed result meant.

One run is one specimen: two-hop's formation #

On seed 0, two-hop answers 74.3% of held-out windows at step 5,000 while a probe for b at ⇒ reads 0.366 and the query patch moves 1.2% of answers. By step 6,000 the probe reads 0.981, G6.5's patch at position 25 moves 78.5% and the name's envelope begins (G6.5: the envelope is judged, the rows are recorded). The earlier route is seen and not explained (H6). Figure 8 uses G4.3's query patch, which moves positions 24 and 25 together; that is a different patch, and it reads 71.9% at step 6,000 (feasibility; G4.3's report gives only the final 85.2%).

As written before the seeds were measured, the test looked for the same order of events after block 2. It holds on seed 0 only. Scrub through training to see where each seed's patchable state appears.

Figure 8. Where a patch can swap the answer, through training, seed by seed

G4.3's query patch after each block, beside held-out accuracy and a linear probe for b at ⇒. Drag the step, or press play.

Seed
held-out accuracy probe for b at ⇒, best block swap after block 0 after block 1 after block 2 after block 3
Accuracy on 2,048 held-out windows. Seed 0: every 1,000 steps plus the replay's 100-step checkpoints from 5,000 to 6,000; seeds 1 to 4: every 200 steps. Source: step3-results.json, claim C; feasibility.

The data show a patchable state at different depths on different seeds. They don't show different algorithms. On seeds 2 and 4 b may sit at the query's a (position 24) rather than at ⇒, or be held non-linearly; neither was measured. A probe for b at position 24, and G4.3's patch split into its two positions, would test the first of these.

A hypothesis for the next round, with its bar fixed now. Read after the fact at whichever block ends with the largest swap, four of five seeds answer 71% to 79% of held-out windows before any swap appears, then swap at least 75%. That reading was chosen after seeing the data, so it is a hypothesis, not a result. The bar for testing it: on at least 8 of 10 new seeds, held-out accuracy of at least 60% at a checkpoint where the query patch swaps at most 10% after every block, followed later by a swap of at least 75% after some block.

The neuron account failed too. On seed 0, 63% of the neurons that take up the new route already had a name, but 83% of all neurons at that block are named, so re-use is below the base rate (notebook finding 36). What holds on every induction seed is narrower: a named neuron rarely takes an unrelated name. Across induction's formation at most one does, where a shuffled null gives 5 to 42. Over the same window 14 to 97 named neurons lose their name.

Sparse dictionaries and distributed codes #

The candidate that sparse dictionaries miss modular addition's distributed code fails on every seed. With about 30 latents, G7.2's SAE steers the sum 60.5% to 77.5%, against 13.7% to 45.1% for the frequency-tuned neurons. G7.2's 0.9% (recorded) is a four-latent result. The two edits sit at different sites: the SAE rewrites the residual stream after block 0, which also carries attention's write, and on 4 of 6 seeds it goes past all 128 neurons together (35.9% to 87.9%). So the comparison doesn't rank the bases either way.

Back to contents

Discussion #

The three results suggest three cheap checks on what an interpretability result means. Each costs one extra model or one extra pass. None needs more ground truth than the result it checks, so each could in principle run on a larger model. We haven't tried.

CheckCostsCatches, here
Run the causal meter on a random-weights twin, or with the blocks between frozenone initialized copy, or one forward passa carry read as an edge, 20 to 35 points above its null on every twin
Put a random removal of the same mass beside any ablation of "unimportant" activationsone more removala small or large loss that is a fact about one model, not about weak activations
Bound a sparse edit by the component's own output for the other value (the donor patch), and measure whether the model needs the siteone patch and one ablationa sparse edit steering past the donor patch (4 of 5 seeds, below its bar), and steering at a site the model barely uses

For a safety reader the pitch is evidence hygiene, not a claim about large models. A twin run for a causal meter, a random removal matched on mass, and a ceiling for a steering result are each easy to leave out. On these toy models, leaving each one out would have misled on at least some seeds.

What a single run supports. Of the single-seed findings we started from, two-hop's learned-twice story and its neuron re-use account didn't survive new seeds as written. The judged two-hop results stand, but they describe seed 0's specimen. On the other seeds the patchable state sits at a different depth, or a probe at ⇒ doesn't read b. The gates were built to judge tools against one specimen's planted variables, and that is all they judge.

What stays open. Two-hop's earlier route (H6), the cause of the over-steering at induction's block 0, and why four of nine induction seeds are slow.

Back to contents

Using Nablaframe #

There are two ways to use this work. The three checks need nothing from Nablaframe, and Nablaframe itself is a place to test a method where the answer is known.

The three checks, on your own model #

  1. A twin run. Initialize a second copy of the model with the same configuration and a seed no trained run uses, and never train it. Train any dictionaries on it the way they were trained on the real model. Run the same meter and the same null on both, and report the twin's excess over its null beside the trained model's. For an edge between two sites at one position, also rerun it with the blocks between them patched back to the unintervened pass.
  2. A random removal matched on mass. Measure the share of activation mass, the sum of magnitudes, that the removal takes. Then zero each activation at random with that probability, so the random removal takes the same mass in expectation. Draw it at least 20 times, and report where the removal sits against all the draws.
  3. A donor-patch ceiling. Replace the component's output with its own output from an input where the variable holds the other value. That is the most an edit inside the component should move, so a sparse edit that moves more is doing something the component doesn't. Mean-ablate the component as well, to see whether the model needs the site at all.

Nablaframe itself #

Quickstart #

You need Python 3.12 or later, uv and a CPU. The tests run on macOS or Linux. The gate scripts, the last line among them, run on macOS only.

git clone https://github.com/apolloh0/nablaframe
cd nablaframe
UV_PROJECT_ENVIRONMENT=.venv-jax uv sync --extra jax
UV_PROJECT_ENVIRONMENT=.venv-jax uv run --extra jax pytest -q
UV_PROJECT_ENVIRONMENT=.venv-jax uv run --extra jax python gates/phase4/g41_zoo_training.py --only induction

The tests, 387 of them, took about 13 minutes on a 2-core Linux machine. The last line trains the induction model for 4,000 steps, retrains it from step 0 and checks that the two final state hashes are identical; both trainings together took just under 2 minutes on an M-series Mac.

What it isn't. Nablaframe isn't a library for interpreting arbitrary pretrained models, and it works at toy scale on a CPU.

Back to contents

Back to contents

Limits #

Back to contents

What resources would buy #

In the order the results suggest:

  1. Compute for the architecture dial and wider models. The twin baseline and the weak-activation control are cheap tests whose answers may change with depth, normalization and initialization. The charter's dial (LayerNorm-free or element-wise norm, weight-sparse, bilinear MLP) is the first place to look.
  2. More seeds, with dictionaries per seed and per checkpoint. Two-hop's seeds disagree about where b lives. Ten or more seeds with a probe at every position would turn that into a distribution, and test the formation hypothesis against the bar fixed above.
  3. API credits for the weights-only reader. The harness is built and self-tested with its scoring bars fixed and hashed (SHA-256 e8906dc2…); it hasn't run.
  4. Phase 8's ledger. Leave-a-batch-out replay over the 1,000 steps where seed 0's second route forms. Attribution by deterministic replay is known (MAGIC; Mechanistic Data Attribution); here it would be applied to a mechanism with a judged envelope.

To take up any of these, or to report a result that doesn't reproduce, open an issue on the repository.

Back to contents

Appendix A. Methods for the seed round #

The three results re-measure single-seed findings (notebook findings 18, 33 and 35) on new training seeds, with each seed's own twin and dictionaries.

Definitions #

Departures from the plan, made during measurement #

Seed 0 reproduces the reports where they overlap: G4.3's final swap 85.2% and accuracy 99.6%; G6.3's carry 98.8% (null 0.2%, frozen 94.5%) and its twin's 56.1% (null 20.9%); G6.2's twin names.

Evidence and reproducibility #

Gate results: reports/phase4/ to reports/phase7/ in the Nablaframe repository, lockfile 9c2155edb31c, Apple M2 Max, JAX on CPU. Decisions D1 to D61 are in docs/decisions.md, and notebook findings 1 to 37 in docs/notebook.md. The seed round is in the evidence release: step3-results.json, step3-tables.md and step3/results/ablate_r_draws.json, with the scripts that produced them in step3/ (sweep_c.py, measure_a.py, measure_b.py, ablate_r.py, train_dicts.py, assemble.py). Every figure on this page draws from those files' values.

The code is under Apache-2.0. The docs, the reports, the evidence release's results and this report are under CC BY 4.0.

Back to contents

References #

  1. Adebayo et al. Sanity Checks for Saliency Maps. NeurIPS 2018.
  2. AMX07. Are Neural Networks Already Clean? A small replication. README at commit 715c62b.
  3. Arad, Mueller, Belinkov. SAEs Are Good for Steering, If You Select the Right Features. EMNLP 2025.
  4. Arora, Wu, Steinhardt, Schwettmann. Language Model Circuits Are Sparse in the Neuron Basis. ICML 2026.
  5. Cammarata. Neural Networks Are Already Clean. Goodfire, 2026-10-15.
  6. Chan et al. Causal Scrubbing. Redwood Research, 2022.
  7. Che, Li. Does the Model Use the Feature? Separating Steering from Mechanism in LLMs. 2026.
  8. Comparing Sparsified MLPs and Transcoders: Many Transcoder Features Are Neurons in Disguise. NeurIPS 2026.
  9. Evidence Press. Are Neural Networks Already Clean?
  10. Gadeev. Post on Habr, 2026-10-22 (a mass-matched random control on a sorting classifier).
  11. Guo et al. How Do LLMs Perform Two-Hop Reasoning in Context?
  12. Gupta, Arcuschin, Kwa, Garriga-Alonso. InterpBench. NeurIPS 2024.
  13. Heap, Lawson, Farnik, Aitchison. Automated Interpretability Metrics Do Not Distinguish Trained and Random Transformers (v2).
  14. Ilyas, Engstrom. MAGIC: Near-Optimal Data Attribution for Deep Learning.
  15. Karvonen et al. SAEBench. ICML 2025.
  16. Lindner et al. Tracr: Compiled Transformers as a Laboratory for Interpretability. NeurIPS 2023.
  17. Makelov, Lange, Geiger, Nanda. Is This the Subspace You Are Looking For? ICLR 2024.
  18. Mechanistic Data Attribution.
  19. Mueller et al. MIB: A Mechanistic Interpretability Benchmark. ICML 2025.
  20. Nanda et al. Progress Measures for Grokking via Mechanistic Interpretability. 2023.
  21. Automatically Interpreting Attribution Graphs via Probe Prompting.
  22. Tigges, Kowal, McGrath, Lewis, Cammarata. Neurons as an Interpretable Basis. Goodfire, 2026-11-10.
  23. Wang, Yue, Su, Sun. Grokked Transformers Are Implicit Reasoners. NeurIPS 2024.
  24. Wu et al. AxBench. ICML 2025.
  25. Xu, Wang, Wang. Tracking the Feature Dynamics in LLM Training.
  26. Yavuz. Are Causal Neuron Circuits Unique and Transferable? 2026.
  27. Ye et al. How Do Transformers Learn Implicit Reasoning?

Back to contents


Published November 15, 2026. Toy scale throughout; the three headline results are tagged feasibility. Figures are drawn in the page from the measured values, except Figures 2, 3 and 5, which are illustrations and say so in their titles. Part of Grasphouse.

Text and figures: CC BY 4.0. Code: Apache-2.0.