Mechanistic interpretability
Open the model up, read what it's thinking layer by layer, and run controlled experiments to find which parts actually cause an answer.
Start here (no maths needed)
Mechanistic interpretability is detective work inside an AI. You switch small parts of it on and off to find out which parts make it give a certain answer.
Think of it like this
Imagine a long line of people passing a note down a row, each one adding a few words. At the end, someone reads out "Paris". Which person added the important bit? You can peek at the note after each person (that's the "logit lens"). Or you can run the game twice, once about the Eiffel Tower and once about the Colosseum, then swap one person's words from the first game into the second. If the answer flips to "Paris", that person mattered (that's "activation patching").
How it works
- Pick a behaviour, like finishing "The Eiffel Tower is in the city of" with "Paris".
- Make a near-identical prompt that gives a different answer, like the Colosseum and "Rome".
- Record everything the model computes inside on the first prompt.
- Run the second prompt, but paste in one recorded piece from the first. Measure how far the answer moves back towards "Paris".
- Do this for every piece. The pieces that move the answer most are part of the "circuit".
Why robots care
Robot brains built from language and vision models can do the wrong thing for hidden reasons. A grasping model might be looking at the table's colour instead of the cup. The same switch-and-measure tricks can show what the model is really paying attention to before you trust it near people.
Try it
- With a friend, build a sentence one word each, five rounds. Then replay it but swap just one person's word. Which swaps change the meaning a lot, and which barely matter?
- In the demo further down, press Corrupted: Colosseum, then drag the Patch component slider. Watch which single part brings back "Paris", and notice that no single part brings it all the way back except the whole subject state.
Words to know
- Residual stream
- The running "note" each layer reads from and adds to.
- Logit lens
- Reading the model's best guess early, from a middle layer.
- Activation patching
- Pasting a part's output from one run into another to test if it matters.
- Attention head
- A small unit that moves information between words.
- Circuit
- The small set of parts that work together to produce one behaviour.
Going deeper: everything below is the full version, with some maths. On a first read, skim the headings and the "Why it matters for robotics" box, and come back for the rest later.
1. What this stage covers
TL;DR
Interpretability tools let you test hypotheses about how a trained transformer computes something. The logit lens reads intermediate predictions. Activation patching gives causal evidence by swapping activations between a clean and a corrupted run. Circuit discovery scales patching up to find the subgraph responsible for a behaviour. The post's project, "find the exact attention head for the Eiffel Tower fact", needs one correction: the classic study of this exact example (ROME) found factual recall concentrated in mid-layer MLPs at the last subject token, with attention later moving the answer to the final position. Facts are spread over several components, not stored in one head.
- Learn: activation patching, the logit lens, circuit discovery, and the tooling (TransformerLens, Baukit) that makes hooking into a model easy.
- Practice: localise a factual recall such as the Eiffel Tower → Paris, and patch activations to change the output. On this page you do it in GPT-2 small on a laptop, with a patching heatmap over layers and token positions.
- Why (the post's claim): you can't fix hallucinations or bias without knowing which circuit produces them. That's partly true and partly overstated. See the reality check.
2. Concepts, explained
The residual stream and the logit lens
In a decoder transformer, each layer reads the residual stream and adds its output back to it. The final layer norm and unembedding turn the last residual vector into logits. The logit lens (nostalgebraist, 2020, LessWrong post) applies that same final step to the residual stream after every layer, to see what the model "would say" if it stopped there:
h_0 = embed(x) + pos
h_l = h_{l-1} + attn_l(h_{l-1}) + mlp_l(…) # each block adds to the stream
lens_l = W_U · LN_final(h_l) # logits "as of" layer l
It's cheap and often revealing in GPT-2: the right answer climbs the ranking over the later layers. It's also biased, because middle layers weren't trained to be read by the final unembedding. The tuned lens (Belrose et al., 2023) learns a small affine map per layer to fix this. Treat the logit lens as a quick look, not a proof. It's correlational: it shows what's present, not what's used.
Activation patching (causal tracing)
Patching is an intervention. You need two inputs that differ in one controlled way, a metric, and a list of components to test:
clean: "The Eiffel Tower is located in the city of" → Paris
corrupted: same template, different subject → Rome (say)
metric: LD = logit(Paris) − logit(Rome) at the last position
for each component c (layer × position, or head):
run corrupted, but replace c's activation with its clean value
recovered(c) = (LD_patched − LD_corr) / (LD_clean − LD_corr)
This direction (clean into corrupted) asks "is this component sufficient to restore the behaviour?". The reverse (corrupted into clean, sometimes called noising) asks "is it necessary?". The two can disagree when information is stored redundantly. ROME's causal tracing (Meng, Bau, Andonian & Belinkov, 2022) used a variant: it corrupts the subject's token embeddings with Gaussian noise rather than swapping subjects, then restores one hidden state at a time. Practical details that change results: the choice of metric (logit difference is more stable than probability), whether the two prompts tokenise to the same length, and whether you patch a single position or all of them.
What ROME found, and the correction to the post
The post frames the project as finding "the exact attention head" for "The Eiffel Tower is in…". The paper that studied exactly this kind of fact found something different. Meng et al. traced factual predictions in GPT-2 XL and found a distinct set of steps in middle-layer feed-forward (MLP) modules while the model processes the last token of the subject ("Tower"). They then edited one MLP weight matrix with a rank-one update (ROME) to rewrite a fact, and showed the edit generalised to paraphrases without spilling onto unrelated subjects.
Follow-up work filled in the picture. Geva, Bastings, Filippova & Globerson (2023) found a three-step flow: early MLPs enrich the last-subject-token representation with many attributes, the relation ("is located in") is moved to the final position, and then attention heads at the final position extract the attribute from the enriched subject. So heads do matter, but as readers and movers spread over several layers, not as a single head that "contains" the fact. A good project result is a map with an MLP hot spot at the subject and an attention hot spot at the end, not one glowing head.
One more caution. Hase, Bansal, Kim & Ghandeharioun (2023) found that where causal tracing localises a fact doesn't predict which layer is best to edit. Localisation and control are separate questions.
Circuits and circuit discovery
A circuit is a subgraph of the model (heads, MLPs and the edges between them) that implements one behaviour. The framing comes from Anthropic's "A Mathematical Framework for Transformer Circuits" (Elhage et al., 2021), which treats each attention head as reading from and writing to the residual stream independently.
The landmark manual study is the IOI circuit (Wang, Variengien, Conmy, Shlegeris & Steinhardt, 2022). In "When Mary and John went to the store, John gave a drink to", GPT-2 small predicts "Mary". They explained it with 26 attention heads in 7 classes, found with causal interventions, and checked the explanation for faithfulness, completeness and minimality. Even then they reported gaps.
ACDC (Conmy, Mavor-Parker, Lynch, Heimersheim & Garriga-Alonso, 2023) automates the search: it prunes edges of the computational graph whose removal barely changes the metric. On GPT-2 small's greater-than task it kept 68 of 32,000 edges and recovered all 5 component types that manual work had found. Path patching and attribution patching (a gradient-based linear approximation of patching) are cheaper ways to rank components before confirming with real patches.
circuit ⊂ graph(model)
faithful: running only the circuit (rest ablated) ≈ full model on the task
minimal: removing any node hurts the metric
Tools: TransformerLens and Baukit
TransformerLens (Neel Nanda and contributors) reimplements GPT-style models with a named hook at every activation: blocks.5.hook_mlp_out, blocks.9.attn.hook_z and so on. run_with_cache stores them all, and run_with_hooks lets you edit any of them during a forward pass. That makes patching a few lines. Baukit (David Bau's lab, the ROME authors) wraps an ordinary PyTorch model and lets you trace or edit any named module's output. It's lighter and works on models TransformerLens doesn't support. Under the hood both use the forward hooks you met in stage 01. For larger models, nnsight follows the same idea. The newer direction of the field, sparse autoencoders that split activations into interpretable features, is covered in the Transformer Circuits Thread linked below.
3. The practice project
(a) Laptop version: patch a fact in GPT-2 small
pip install transformer_lens. Loadgpt2(124M parameters, runs on CPU).- Check the model knows the fact first. Print the top 5 next tokens for your prompt. If " Paris" isn't top-1, try a rephrase, a different fact, or
gpt2-medium/gpt2-xlon Colab. Patching a fact the model doesn't know measures noise. - Pick a corrupted subject with the same number of tokens (check with
m.to_str_tokens) and a single-token answer. - Logit lens: for each layer, project the last-position residual through
ln_finaland the unembedding. Record the rank of " Paris". - Patching heatmaps: for
resid_pre,mlp_outandattn_out, patch each (layer, position) from clean into corrupted and record the recovered fraction. Then patch individual heads (hook_z) at the final position. - Repeat on 20–50 facts (city, language, company), averaged. One prompt is an anecdote.
from transformer_lens import HookedTransformer, utils
import torch
m = HookedTransformer.from_pretrained("gpt2")
clean = m.to_tokens("The Eiffel Tower is located in the city of")
corr = m.to_tokens("The Colosseum is located in the city of") # check lengths match
assert clean.shape == corr.shape, m.to_str_tokens(corr)
P, R = m.to_single_token(" Paris"), m.to_single_token(" Rome")
ld = lambda lg: (lg[0, -1, P] - lg[0, -1, R]).item()
lg_c, cache = m.run_with_cache(clean)
base_c, base_x = ld(lg_c), ld(m(corr))
def patch(act, hook, pos):
act[:, pos] = cache[hook.name][:, pos]
return act
L, T = m.cfg.n_layers, clean.shape[1]
heat = torch.zeros(L, T)
for l in range(L):
for p in range(T):
h = (utils.get_act_name("mlp_out", l), lambda a, hook, p=p: patch(a, hook, p))
heat[l, p] = (ld(m.run_with_hooks(corr, fwd_hooks=[h])) - base_x) / (base_c - base_x)
# logit lens at the last position
for l in range(L):
r = cache["resid_post", l][:, -1:]
print(l, m.to_string(m.unembed(m.ln_final(r))[0, -1].argmax()))
What to measure: the recovered-fraction heatmap for MLP, attention and residual; the layer where " Paris" first reaches top-1 in the lens; the top 5 heads at the final position. What to look for, based on ROME and Geva et al. rather than a run I can vouch for in GPT-2 small: a band of MLP effect around the subject's last token in early-to-middle layers, and attention effect at the final position in later layers. If your map differs, report it. That's a finding.
"Change the behaviour": patching from a corrupted run already flips the answer in that run. To make a persistent change, add a steering vector (for example, mean activation difference between Paris and Rome prompts at the hot layer) or try a ROME edit with the authors' code. Then test on paraphrases and unrelated facts so you can see side effects.
(b) Full version from the post
The same experiment on a 1–8B model (Pythia, Gemma 2 2B or Llama-class), over a few hundred facts, with head-level patching, path patching between the key heads, and an edit or steering intervention evaluated for generalisation and specificity. A 2B model fits a free Colab T4 in half precision. An 8B model with caching of all activations needs a 24–48 GB GPU, about $0.50–2 per hour rented; head-level sweeps over hundreds of prompts take a few GPU-hours. Use attribution patching to shortlist components so you don't run every patch.
(c) Pitfalls
- Token misalignment. Different-length subjects shift every position. Match lengths or use ROME-style noise on the subject embeddings.
- Bad metric. Probabilities saturate. Use logit difference and normalise to the clean/corrupted range.
- One prompt. Average over many, and look at the variance.
- Sufficiency isn't necessity. A head that restores the answer when patched in may not be needed when knocked out, because of backup heads (the IOI paper found such backup name movers).
- Logit lens over-reading. Early-layer lens output is unreliable. Use the tuned lens if you need to compare layers.
- Calling it "the" circuit. Report what fraction of the effect your components explain.
Interactive: logit lens and patching in a toy model
A hand-built 6-layer toy, not a real model. Subject MLPs (layers 1–3) write a city into the subject token. Attention at layers 4–5 copies it to the last token. Left: logit lens at the last token, one row per layer, darker = more probable. Right: how much of the clean answer each single patch recovers (clean → corrupted). The highlighted bar is your current patch.
4. Reality check
The claim: you can't fix hallucinations or bias without knowing which circuit generates them.
- True in spirit: understanding mechanisms gives you tools that behaviour-only testing can't: you can check whether a model uses a feature you didn't intend, and find directions to steer or ablate.
- Overstated as a requirement: almost every hallucination and bias fix used in practice today is behavioural: better data, preference training (stage 05), retrieval, abstention training and evals (stage 10). None needed a circuit diagram.
- "Exact head" is the wrong frame. Facts are spread over mid-layer MLPs at the subject and several later attention heads. Behaviours like hallucination are spread wider still.
- Localisation ≠ control. Hase et al. (2023) showed the traced location doesn't predict the best layer to edit. Knowing where isn't the same as knowing how to fix it.
- Scale is open. Full circuits exist for narrow tasks in small models (IOI, greater-than). Explaining a frontier model's behaviour end to end is still a research problem.
Still worth learning: patching and the lens are the debugger of model internals, and the habit of forming a hypothesis and testing it with an intervention transfers to everything else on this roadmap.
5. In this course
- 30u30 Day 13 · The Transformer and Day 14 · Annotated Transformer: the attention heads, MLPs and residual stream you'll be hooking into.
- 30u30 Day 01 · RNN Effectiveness: the early "interpretable neuron" result (cells tracking quotes and line position), the ancestor of this field.
- Stage 01: PyTorch hooks and autograd, the mechanics behind TransformerLens and Baukit.
- Module 02 · TensorTonic: lists an Interpretability project track for practice.
- Module 07 · Preference alignment: the behavioural route to fixing model behaviour, for contrast.
6. Why it matters for robotics
- The tools transfer to VLAs. A vision-language-action model is a transformer, so the same hooks, lens and patching apply. You can patch image tokens between a "cup on left" and "cup on right" scene and see where the action decision forms.
- Catching shortcuts. Patching or ablating visual tokens can show whether a policy keys on the object or on a background cue that won't hold in a new lab. That's a cheap check before deployment.
- Weak link today. Most robot debugging still happens with ablations, saliency maps and held-out evaluation, not circuit analysis. Mechanistic work on robot policies is early, so treat this stage as useful background, not a core robotics skill.
- Steering is risky on hardware. Editing activations in a model that drives motors needs the same safety testing as any new policy.
7. Self-check
What does the logit lens compute, and why can it mislead?
It applies the final layer norm and unembedding to an intermediate residual stream. Middle layers weren't trained to be read that way, so the representation can be in a different basis. The lens shows what's decodable, not what's causally used. The tuned lens adds a learned per-layer map to reduce the bias.
Patching a component from clean into corrupted recovers 90% of the logit difference. Is it necessary for the behaviour?
Not necessarily. That shows sufficiency. To test necessity, patch corrupted into clean or ablate it, and check whether backup components take over.
Where did ROME localise factual recall, and what did it edit?
In middle-layer MLP (feed-forward) modules while processing the last subject token. It edited one MLP weight matrix with a rank-one update.
Why would a single attention head rarely be "the" location of a fact?
Facts are enriched into the subject representation by MLPs. Attention heads at the final position read and move that information, and several heads across layers share the job. Geva et al. (2023) describe this enrich-then-extract flow.
Why use logit difference rather than probability as the patching metric?
Probability saturates near 0 and 1, so big internal changes can look small. Logit difference is roughly linear in the residual stream and compares the right answer to a specific alternative.
What does ACDC automate?
Finding the circuit: it iteratively removes edges of the computational graph whose removal barely changes the task metric, leaving a small subgraph.
8. Courses & content
| Resource | Type | Use it for |
|---|---|---|
| ARENA · Transformer interpretability chapter | Course (free materials) | Hands-on exercises: logit lens, attribution, activation patching, circuits |
| ARENA 3.0 materials (GitHub) | Exercises (free) | The notebooks themselves |
| Neel Nanda · Getting started in mechanistic interpretability | Guide | Reading list and learning path |
| TransformerLens docs | Library + docs | Hooking and patching activations |
| Transformer Circuits Thread | Research publications | The primary research on circuits and features |
Start with ARENA's transformer interpretability chapter: it walks you through the logit lens, patching and the IOI circuit in TransformerLens, which is exactly this stage's project.
9. Papers & docs
- Meng, Bau, Andonian & Belinkov (2022). Locating and Editing Factual Associations in GPT (ROME). Project page: rome.baulab.info
- Geva, Bastings, Filippova & Globerson (2023). Dissecting Recall of Factual Associations in Auto-Regressive Language Models
- Hase, Bansal, Kim & Ghandeharioun (2023). Does Localization Inform Editing?
- Wang, Variengien, Conmy, Shlegeris & Steinhardt (2022). Interpretability in the Wild: a Circuit for Indirect Object Identification in GPT-2 small
- Conmy, Mavor-Parker, Lynch, Heimersheim & Garriga-Alonso (2023). Towards Automated Circuit Discovery for Mechanistic Interpretability (ACDC)
- Belrose et al. (2023). Eliciting Latent Predictions from Transformers with the Tuned Lens
- nostalgebraist (2020). interpreting GPT: the logit lens
- Elhage et al. (2021). A Mathematical Framework for Transformer Circuits
- Docs: TransformerLens · Baukit