Interactive demos

Activation patching on GPT-2 small

Measured on GPT-2 small

Survey: §7.1 Circuit Discovery Methods

Where does GPT-2 small work out who receives the drink? We run a clean prompt and a corrupted prompt whose answer differs. Then we copy one internal activation at a time from the clean run into the corrupted run and measure how much of the correct behaviour comes back.

clean When Mary and John went to the store, John gave a drink to → Mary
corrupted When Mary and John went to the store, Mary gave a drink to → John
32prompt pairs
3.60clean logit diff
-3.60corrupted logit diff
0.985r(activation, attribution)
Fraction of logit difference recovered by patching resid_pre at each layer and position0:<|endoftext|>1:When2:·Mary3:·and4:·John5:·went6:·to7:·the8:·store9:,10:·John11:·gave12:·a13:·drink14:·toL0L1L2L3L4L5L6L7L8L9L10L11L0, 0:<|endoftext|>: 0.0%L0, 1:When: 0.0%L0, 2:·Mary: 0.0%L0, 3:·and: 0.0%L0, 4:·John: 0.0%L0, 5:·went: 0.0%L0, 6:·to: 0.0%L0, 7:·the: 0.0%L0, 8:·store: 0.0%L0, 9:,: 0.0%L0, 10:·John: 100.0%L0, 11:·gave: 0.0%L0, 12:·a: 0.0%L0, 13:·drink: 0.0%L0, 14:·to: 0.0%L1, 0:<|endoftext|>: 0.0%L1, 1:When: 0.0%L1, 2:·Mary: 0.0%L1, 3:·and: 0.0%L1, 4:·John: 0.0%L1, 5:·went: 0.0%L1, 6:·to: 0.0%L1, 7:·the: 0.0%L1, 8:·store: 0.0%L1, 9:,: 0.0%L1, 10:·John: 100.1%L1, 11:·gave: 0.0%L1, 12:·a: 0.0%L1, 13:·drink: -0.1%L1, 14:·to: -0.0%L2, 0:<|endoftext|>: 0.0%L2, 1:When: 0.0%L2, 2:·Mary: 0.0%L2, 3:·and: 0.0%L2, 4:·John: 0.0%L2, 5:·went: 0.0%L2, 6:·to: 0.0%L2, 7:·the: 0.0%L2, 8:·store: 0.0%L2, 9:,: 0.0%L2, 10:·John: 100.0%L2, 11:·gave: 0.1%L2, 12:·a: 0.0%L2, 13:·drink: -0.1%L2, 14:·to: 0.0%L3, 0:<|endoftext|>: 0.0%L3, 1:When: 0.0%L3, 2:·Mary: 0.0%L3, 3:·and: 0.0%L3, 4:·John: 0.0%L3, 5:·went: 0.0%L3, 6:·to: 0.0%L3, 7:·the: 0.0%L3, 8:·store: 0.0%L3, 9:,: 0.0%L3, 10:·John: 99.6%L3, 11:·gave: 0.3%L3, 12:·a: 0.0%L3, 13:·drink: -0.1%L3, 14:·to: 0.1%L4, 0:<|endoftext|>: 0.0%L4, 1:When: 0.0%L4, 2:·Mary: 0.0%L4, 3:·and: 0.0%L4, 4:·John: 0.0%L4, 5:·went: 0.0%L4, 6:·to: 0.0%L4, 7:·the: 0.0%L4, 8:·store: 0.0%L4, 9:,: 0.0%L4, 10:·John: 99.0%L4, 11:·gave: 1.1%L4, 12:·a: 0.0%L4, 13:·drink: -0.1%L4, 14:·to: 0.0%L5, 0:<|endoftext|>: 0.0%L5, 1:When: 0.0%L5, 2:·Mary: 0.0%L5, 3:·and: 0.0%L5, 4:·John: 0.0%L5, 5:·went: 0.0%L5, 6:·to: 0.0%L5, 7:·the: 0.0%L5, 8:·store: 0.0%L5, 9:,: 0.0%L5, 10:·John: 96.0%L5, 11:·gave: 4.0%L5, 12:·a: 0.2%L5, 13:·drink: -0.2%L5, 14:·to: -0.1%L6, 0:<|endoftext|>: 0.0%L6, 1:When: 0.0%L6, 2:·Mary: 0.0%L6, 3:·and: 0.0%L6, 4:·John: 0.0%L6, 5:·went: 0.0%L6, 6:·to: 0.0%L6, 7:·the: 0.0%L6, 8:·store: 0.0%L6, 9:,: 0.0%L6, 10:·John: 96.1%L6, 11:·gave: 3.7%L6, 12:·a: 0.2%L6, 13:·drink: -0.1%L6, 14:·to: 0.0%L7, 0:<|endoftext|>: 0.0%L7, 1:When: 0.0%L7, 2:·Mary: 0.0%L7, 3:·and: 0.0%L7, 4:·John: 0.0%L7, 5:·went: 0.0%L7, 6:·to: 0.0%L7, 7:·the: 0.0%L7, 8:·store: 0.0%L7, 9:,: 0.0%L7, 10:·John: 91.6%L7, 11:·gave: 5.3%L7, 12:·a: 0.4%L7, 13:·drink: -0.1%L7, 14:·to: 2.4%L8, 0:<|endoftext|>: 0.0%L8, 1:When: 0.0%L8, 2:·Mary: 0.0%L8, 3:·and: 0.0%L8, 4:·John: 0.0%L8, 5:·went: 0.0%L8, 6:·to: 0.0%L8, 7:·the: 0.0%L8, 8:·store: 0.0%L8, 9:,: 0.0%L8, 10:·John: 65.1%L8, 11:·gave: 3.4%L8, 12:·a: 0.1%L8, 13:·drink: -0.1%L8, 14:·to: 31.5%L9, 0:<|endoftext|>: 0.0%L9, 1:When: 0.0%L9, 2:·Mary: 0.0%L9, 3:·and: 0.0%L9, 4:·John: 0.0%L9, 5:·went: 0.0%L9, 6:·to: 0.0%L9, 7:·the: 0.0%L9, 8:·store: 0.0%L9, 9:,: 0.0%L9, 10:·John: 7.5%L9, 11:·gave: 3.0%L9, 12:·a: 0.1%L9, 13:·drink: 0.0%L9, 14:·to: 89.7%L10, 0:<|endoftext|>: 0.0%L10, 1:When: 0.0%L10, 2:·Mary: 0.0%L10, 3:·and: 0.0%L10, 4:·John: 0.0%L10, 5:·went: 0.0%L10, 6:·to: 0.0%L10, 7:·the: 0.0%L10, 8:·store: 0.0%L10, 9:,: 0.0%L10, 10:·John: -0.9%L10, 11:·gave: 2.4%L10, 12:·a: 0.1%L10, 13:·drink: 0.0%L10, 14:·to: 98.5%L11, 0:<|endoftext|>: 0.0%L11, 1:When: 0.0%L11, 2:·Mary: 0.0%L11, 3:·and: 0.0%L11, 4:·John: 0.0%L11, 5:·went: 0.0%L11, 6:·to: 0.0%L11, 7:·the: 0.0%L11, 8:·store: 0.0%L11, 9:,: 0.0%L11, 10:·John: 0.2%L11, 11:·gave: 1.6%L11, 12:·a: 0.0%L11, 13:·drink: -0.1%L11, 14:·to: 98.3%layer

Select a cell to see its value.

Information that separates clean from corrupted sits at the repeated name, the subject of the second clause (position 10), in early layers, then moves to the final token in the later layers. Reading off where each row “lights up” shows where the circuit carries the signal.

How these numbers were produced

Model: gpt2 (124M) via transformer_lens HookedTransformer.from_pretrained. Task: indirect object identification over 32 prompt pairs (4 templates × 4 name pairs × 2 orders). In the corrupted prompt the second-clause subject is swapped, which flips the answer. Metric: mean over prompts of logit(IO) - logit(S) at the final position. A value of 0 equals the corrupted run and 1 equals the clean run. The clean run is correct on 100% of prompts. Activation patching runs the model once per component. Attribution patching approximates the same quantity with a single backward pass, using a first-order Taylor expansion. Across all 144 heads the two agree with Pearson r = 0.985.

Reproduce: python3 scripts/experiments/compute_patching.py (torch 2.8.0, transformer-lens 2.17.0; about 57 s on a laptop CPU, deterministic). Generated 2026-11-05. The setup follows the companion notebook on circuit discovery, scaled up to more prompts.

A patching effect shows that a component matters for this metric on these prompts, not what it computes.

Go further

References