Circuits, explained · Part 6 of 7 · Covers Analyzing a Two-Layer Model, Induction Heads (function, how they work, checking the theory), the correction to the composition diagram, Pointer Arithmetic with Positional Embeddings
Induction Heads
How a two-layer model learns to continue a pattern it saw earlier in the text. We find the two heads that do it in a real model, test them on random tokens, and break them on purpose.
A Mathematical Framework for Transformer Circuits. Nelson Elhage, Neel Nanda, Catherine Olsson, Tom Henighan, Nicholas Joseph, Ben Mann, Amanda Askell, Yuntao Bai, Anna Chen, Tom Conerly, Nova DasSarma, Dawn Drain, Deep Ganguli, Zac Hatfield-Dodds, Danny Hernandez, Andy Jones, Jackson Kernion, Liane Lovitt, Kamal Ndousse, Dario Amodei, Tom Brown, Jack Clark, Jared Kaplan, Sam McCandlish, Chris Olah. Transformer Circuits Thread, 2021.
Read "Mrs Brindlewick" once, and you can finish "Mrs Br..." the next time it appears. A two-layer transformer learns to do the same with two attention heads that work as a team. This part takes that team apart, in the paper's order and on a real model.
The paper calls the second head of the team an induction head. It is the best-known result of the paper, and later work found the same kind of head in large models. We use the open two-layer model attn-only-2l from the earlier parts. Each piece below shows the exact lines of the paper, then explains them.
The paper's two-layer model has 12 heads per layer and no position vectors in the stream. We cannot get those weights. Our model is the open attn-only-2l: two attention layers, eight heads per layer, and no MLP layers. It has one difference that matters later: it adds a learned position vector to the stream of each token.
plain text
== 1. THE MODEL: attn-only-2l (TransformerLens) layers 2, heads per layer 8, d_model 512, d_head 64, vocabulary 48,262, context 1024 position: standard (learned position vectors added to the stream; the paper's model has none in the stream) the paper's two-layer model has 12 heads per layer; ours has 8, so head numbers differ
We name heads as in Part 2: head 0.3 is head 3 of layer 0, and head 1.6 is head 6 of layer 1. Head numbers in our model have no link to the numbers in the paper's model.
Part 5 showed three ways in which a layer-1 head can read what a layer-0 head wrote. The paper now looks at one real two-layer model and asks which of those ways it uses.
The paper shows the connections as a diagram. Each dot is a head, and a line joins two heads when a layer-1 head reads strongly from a layer-0 head.
We measured the same score on our model, from the previous-token head into the head we will call the induction head. Part 5 defines it. Here it is enough to know that random matrices of the same shapes score 0.044:
plain text
== 7. K-COMPOSITION SCORE ||W_QK^h W_OV^p||_F / (||W_QK^h||_F ||W_OV^p||_F), INTO THE INDUCTION HEAD into 1.6: 0.0 0.081, 0.1 0.067, 0.2 0.038, 0.3 0.124, 0.4 0.058, 0.5 0.044, 0.6 0.040, 0.7 0.045 the same measure for random rank-64 matrices of these shapes: 0.044 (average of 20)
Head 0.3 scores 0.124, almost three times the random level. Head 0.0 is second with 0.081. The other layer-0 heads are near the random level. So our model has the same shape as the paper's: one main layer-0 head feeds the key of head 1.6.
The paper then invites the reader to look at the attention patterns on the first paragraph of a well-known novel. It shows a special kind of pattern there.
The two heads of an induction circuit on a made-up name. In layer 0, a previous-token head gives each position a note that says which token came before it; the position of "indle" gets the note "Br". In layer 1, the induction head stands on the second "Br". Its query looks for the note "Br", finds it at "indle", attends there, and copies "indle" as the prediction.
Our sentence with a made-up name shows the difference. The tokenizer splits " Brindlewick" into " Br", "indle" and "wick". We gave both models the text "The new teacher was Mrs Brindlewick. On Monday the class met Mrs Brindlewick", and looked at the second copy of the name:
plain text
== 10. A MADE-UP NAME IN A SENTENCE attn-only-1l: at ' Mrs' (pos 15) the next token ' Br' gets probability 0.01 attn-only-1l: at ' Br' (pos 16) the next token 'indle' gets probability 0.82 attn-only-1l: at 'indle' (pos 17) the next token 'wick' gets probability 0.00 attn-only-2l: at ' Mrs' (pos 15) the next token ' Br' gets probability 0.63; head 1.6 reads '<|BOS|>' (pos 0) with 0.55, adds +4.84 to the logit of ' Br' attn-only-2l: at ' Br' (pos 16) the next token 'indle' gets probability 0.93; head 1.6 reads 'indle' (pos 7) with 0.93, adds +11.95 to the logit of 'indle' attn-only-2l: at 'indle' (pos 17) the next token 'wick' gets probability 0.98; head 1.6 reads 'wick' (pos 8) with 0.75, adds +13.82 to the logit of 'wick'
The two-layer model gets all three pieces: 0.63, 0.93 and 0.98. On "indle", head 1.6 reads the earlier "wick" with weight 0.75 and adds +13.82 to the logit of "wick". That is the rule from the paper, exactly.
The one-layer model gets "indle" right (0.82), which is a skip-trigram at work: "indle" appeared earlier, so a copying head raised it. But it gives "wick" a probability of 0.00. Its copying heads cannot tell which earlier token is the one to repeat.
The first row of the two-layer model is less clean. On " Mrs", head 1.6's largest single weight (0.55) is on the first token, its parking spot. Yet it still adds +4.84 to " Br". Our log does not show where the rest of its weight went, so we only report what it shows.
Text from a novel has a weakness as evidence. A name like "Dursley" is also a common pattern in training text, so other heads may help. The paper removes that help.
We built 100 sequences. Each is the first token, then 50 random tokens, then the same 50 tokens again. We measure the loss of each model on each copy.
The loss of one token is
ℓ=−lnpright
Here pright is the probability the model gave to the token that really came next. Take three small cases by hand. If p=0.5, the loss is ln2≈0.69. If p=0.05, it is about 3.0. A model that guesses evenly over our 48,262 tokens gives each one p=1/48,262, so its loss is ln48,262≈10.78.
python
logits = model(toks) # toks: [100, 101] = BOS + 50 random + the same 50loss = -logits.log_softmax(-1)[:, :-1].gather(-1, toks[:, 1:, None])[..., 0]first, second = loss[:, 1:50].mean(), loss[:, 51:].mean() # first copy, second copy
plain text
== 2. REPEATED RANDOM TOKENS: [BOS] t1 ... t50 t1 ... t50, 100 sequences, tokens drawn uniformly from the vocabulary a model that guesses uniformly over 48,262 tokens has loss ln(48262) = 10.78 nats on every token attn-only-1l: loss on the first copy 15.52, on the second copy 14.83 nats; top-1 right: first 0.0%, second 0.0% attn-only-2l: loss on the first copy 15.04, on the second copy 3.41 nats; top-1 right: first 0.0%, second 55.9% probability the 2-layer model gives the right token on the second copy, on average: exp(-3.41) = 0.03
On the first copy both models do worse than an even guess: about 15 nats against 10.78. They are sure of next tokens that real text would have, and random text punishes that. On the second copy the one-layer model barely moves, from 15.52 to 14.83. The two-layer model drops to 3.41 nats, and its top guess is right 55.9% of the time.
Read 3.41 back as a probability: e−3.41≈0.03. That number is an average of logarithms, so it is pulled down by the hard tokens. More than half of the tokens are the top guess, which shows that most predictions are much better than 0.03.
Loss at each position, averaged over 100 sequences. The one-layer model stays near 15 nats on both copies. The two-layer model falls from about 15 to about 3 nats right where the second copy starts, at position 51.
The drop is sharp and happens at once. The model does not slowly get used to the string. One token into the repeat, it can already use the rule. A one-layer model cannot, which matches the paper's claim that induction heads need two layers.
Which heads do this? We give every head two scores on the repeated sequences. The previous-token score is the average weight a head puts on the position just before. The induction score is the average weight, on the second copy, on the token right after the earlier copy of the present token.
plain text
== 3. WHICH HEADS DO WHAT, MEASURED ON THE REPEATED SEQUENCES previous-token score (average attention to the token just before): layer 0: 0.0 0.20, 0.1 0.05, 0.2 0.03, 0.3 0.52, 0.4 0.02, 0.5 0.05, 0.6 0.08, 0.7 0.01 layer 1: 1.0 0.07, 1.1 0.10, 1.2 0.10, 1.3 0.09, 1.4 0.08, 1.5 0.04, 1.6 0.02, 1.7 0.03 induction score (on the second copy, average attention to the token after the earlier copy of the present token): layer 0: 0.0 0.00, 0.1 0.00, 0.2 0.00, 0.3 0.00, 0.4 0.00, 0.5 0.00, 0.6 0.01, 0.7 0.00 layer 1: 1.0 0.00, 1.1 0.00, 1.2 0.00, 1.3 0.00, 1.4 0.00, 1.5 0.00, 1.6 0.66, 1.7 0.03 previous-token head: 0.3; induction head: 1.6 (the next best layer-1 head is 1.7 with 0.03) a head that spread its weight evenly over the 51 to 100 earlier tokens would score about 0.013
The answer is clear. Head 0.3 puts 0.52 of its weight on the previous token, and head 0.0 is a weaker second with 0.20. Head 1.6 puts 0.66 of its weight on the exact right source, out of 51 to 100 choices. An even spread would score about 0.013, so 0.66 is about fifty times more. No layer-0 head scores above 0.01, which is expected: one layer cannot do this.
This is the same pair as the composition scores showed: head 0.3 feeds head 1.6. Here is what the two patterns look like on a short string of 8 random tokens, repeated:
Two attention patterns on BOS and 8 random tokens t1 to t8, repeated. Head 0.3 (left) puts weight just left of the diagonal, on the previous token. Head 1.6 (right) puts nearly all weight on BOS during the first copy, and a stripe of weight seven places back during the second copy: on the token after the earlier copy.
plain text
head 1.6 on the first copy (nothing to find): weight on BOS, averaged over positions 2..8: 0.95 head 1.6 on the second copy: weight on the token after the earlier copy, averaged: 0.41
During the first copy head 1.6 parks 0.95 of its weight on the first token, as the paper said. During the second copy it moves to the stripe. On this short string the stripe holds 0.41 on average, less than the 0.66 of the long strings. Both are far above the even spread.
We now know what head 1.6 does. The question is how a head can find "the token after an earlier copy". A head only scores pairs of positions with its query and key. Neither of them, alone, knows about the next token.
The paper writes the trick as a term of the QK circuit. We build it from the pieces of Part 2 and Part 5. Leave out positions and layer norm for now, as the paper does.
The stream at a source position j, as layer 1 reads it, holds the token's embedding plus what layer 0 wrote. Keep only the previous-token head p, and say that it reads the position just before with weight 1:
xj=WEtj+WOVpWEtj−1
Read it left to right. tj is the one-hot vector of the token at j, and WEtj is its embedding. The second term is head p's output: the embedding of the token beforej, passed through its OV matrix. The destination i has only its own embedding, xi=WEti, in this simple view.
The attention score of the layer-1 head h is sij=xi⊤WQKhxj. Put the two streams in and multiply out:
The first line is the plain QK circuit of Part 2: present token against source token. The second line is new. It compares the present token ti with the token before the source, tj−1. Call its matrix W:
W=WE⊤WQKhWOVpWE
W is a token-by-token table, like the circuits of Part 2. Its entry in row a, column b says how much a destination token a likes a source whose previous token is b. Now suppose W is large on its diagonal and small elsewhere. Then the score is large exactly when tj−1=ti: the token before the source equals the present token. That is the induction rule, written as a matrix.
A tiny example by hand. Our toy script builds the whole circuit with three tokens, a, b and c. The stream has six numbers. Three say "this token is a, b or c". Three say "the token before me was a, b or c". The sequence is a b c a. We want the last "a" to predict "b".
Layer 0 is a previous-token head. It copies each token's "this token" numbers into the "token before" numbers of the next position. Layer 1 is the induction head, with WQK that multiplies "this token" at the destination with "token before" at the source, times 4:
plain text
== A. AN INDUCTION HEAD BUILT BY HAND (tokens a, b, c; sequence a b c a) stream after layer 0 (first 3 = this token, last 3 = previous token): [[1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0, 1.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 1.0]] scores from the last position (token a) to positions 1..4: [0.0, 4.0, 0.0, 0.0] softmax: [0.017, 0.948, 0.017, 0.017] (e^4 / (e^4 + 3) = 0.948) induction head output read as logits for a, b, c: [0.035, 0.948, 0.017] -> predicts 'b'
Check it by hand. Position 2 holds "b", with the note "the token before me was a", and the last position holds "a". Only position 2 has a note that matches "a", so only it scores 4. The softmax gives it e4/(e4+3)≈0.948. The head's OV circuit copies what is at position 2, which is "b". So "b" gets 0.948, the largest logit.
The W table of this toy is 4 times the identity, a pure "same matching" table:
plain text
== B. THE K-COMPOSITION TERM W_E^T W_QK W_OV^prev W_E (3 x 3, one row and column per token) term = [[4.0, 0.0, 0.0], [0.0, 4.0, 0.0], [0.0, 0.0, 4.0]]; eigenvalues [4.0, 4.0, 4.0]; positivity 1.00
Does head 1.6 really get its match from head 0.3? We can check it on the real model, with positions, biases and layer norm included. The stream that layer 1 reads is a sum: embedding plus position, plus each layer-0 head's output, plus a bias. Layer norm only divides the sum by one number per position. So the key, and the score, also split into one part per piece.
python
parts = {'embed+pos': cache['hook_embed'] + cache['hook_pos_embed']}for p in range(8): parts[f'0.{p}'] = cache['blocks.0.attn.hook_z'][:, :, p] @ model.W_O[0, p] # what head 0.p wrotekeys = {k: (centre(v) / scale) @ model.W_K[1, 6] for k, v in parts.items()} # the key, one part at a time
For each part we compare its share of the score at the right source with its share at an average allowed source. The difference is the lift: how much that part helps the right source win.
plain text
== 8. WHERE THE INDUCTION HEAD'S KEY COMES FROM (head 1.6, the repeated sequences) share of the attention score, at the induction target vs averaged over all allowed sources: from 0.3: target +6.30, average source +2.12, lift +4.18 from 0.0: target +3.01, average source +0.77, lift +2.24 from embed+pos: target +3.34, average source +3.09, lift +0.25 from 0.1: target +0.63, average source +0.39, lift +0.24 from 0.6: target +1.43, average source +1.33, lift +0.10 from 0.2: target +1.23, average source +1.16, lift +0.07 from 0.5: target -0.94, average source -0.96, lift +0.02 from bias: target +9.76, average source +9.78, lift -0.02 from 0.4: target +1.41, average source +1.41, lift +0.00 from 0.7: target -0.74, average source -0.75, lift +0.00 key bias part: +5.49 (the same for every source, so the softmax ignores it) sum of the parts at the target 30.93; the model's own score 30.93
How much each part of the stream lifts head 1.6's score at the right source, above an average source. Head 0.3 gives +4.18 and head 0.0 gives +2.24. The token and position embeddings give only +0.25, and every other layer-0 head gives less than 0.3.
The parts add up to the model's own score, 30.93, so the split is exact. Almost all of the lift comes from what heads 0.3 and 0.0 wrote: +4.18 and +2.24. The source token's own embedding gives only +0.25. So head 1.6 does not choose its source by what the source is. It chooses it by the note that the previous-token heads left there. That is K-composition, measured.
The tests so far ran the model on text. The paper also checks the theory from the weights alone, with no text at all.
The statistic is
positivity(M)=∑k∣λk∣∑kλk
The top sums the eigenvalues λk of M, and the bottom sums their sizes. If every eigenvalue is positive, top and bottom are equal and the score is 1. If every eigenvalue is negative, the score is −1. A copying matrix sends each token back toward itself, so its eigenvalues are mostly positive and its score is near 1.
The "copy" matrix keeps each token, so it scores 1. The "swap" matrix turns a into b and b into a, so it copies nothing and scores 0. The "mixed" one keeps one token and flips the other: (2−1)/(2+1)=0.33.
The real tables are 48,262 × 48,262, too big for eigenvalues. But a product AB and the product in the other order, BA, have the same non-zero eigenvalues. So the eigenvalues of WUWOVWE are those of the 512 × 512 matrix WOVWEWU. The same trick works for the K-composition term.
plain text
== 5. COPYING: EIGENVALUE POSITIVITY OF THE OV CIRCUIT W_U W_OV W_E (1 = all eigenvalues positive, -1 = all negative) layer 1 positivity: 1.0 +0.72, 1.1 +0.11, 1.2 +0.94, 1.3 +0.57, 1.4 +0.03, 1.5 +0.71, 1.6 +1.00, 1.7 +1.00 layer 1 share of tokens 1000..2999 whose top output is the token itself: 1.0 0.01, 1.1 0.00, 1.2 0.01, 1.3 0.01, 1.4 0.00, 1.5 0.00, 1.6 0.99, 1.7 0.26 OV of 1.6: attend to ' Paris' -> raises [' Paris', 'Paris', ' Geneva', ' São', ' Madrid']== 6. SAME MATCHING: EIGENVALUE POSITIVITY OF THE K-COMPOSITION TERM W_E^T W_QK^h W_OV^p W_E (p = a layer-0 head) with the previous-token head 0.3: 1.0 +0.10, 1.1 -0.08, 1.2 -0.24, 1.3 +0.85, 1.4 -0.36, 1.5 -0.06, 1.6 +1.00, 1.7 +0.98
Head 1.6 scores +1.00 on both. Its OV circuit is a near-perfect copier: for 99% of tokens 1,000 to 2,999, the top output is the token itself. Its K-composition table with head 0.3 is a near-perfect matcher. These two numbers come from the weights only, with no text.
Here is the same plot for our model:
The eight layer-1 heads of attn-only-2l. Across: OV circuit positivity. Up: positivity of the K-composition term with head 0.3. Heads 1.6 and 1.7 sit in the top right corner, near (1, 1). The other six heads are spread out.
Two heads land in the corner: 1.6, and 1.7 at (+1.00, +0.98). Head 1.7 is a surprise, because its induction score on our sequences was only 0.03. Its weights have the recipe, but on this data it rarely acts on it. When we remove it (next section), the loss on the second copy rises from 3.41 to 3.77, so it helps a little. These numbers do not say why it attends so weakly. Its plain QK circuit, the first line of our derivation, may pull against the match.
Our run adds a control. The same positivity for head 1.6, but with the other layer-0 heads in place of 0.3:
plain text
head 1.6 with each other layer-0 head: 0.0 +0.64, 0.1 +0.01, 0.2 -0.02, 0.4 -0.59, 0.5 +0.57, 0.6 +0.13, 0.7 -0.12 direct term W_E^T W_QK^h W_E (no layer-0 head): 1.0 +0.69, 1.1 +0.68, 1.2 +0.75, 1.3 +0.52, 1.4 +0.87, 1.5 +0.46, 1.6 -0.64, 1.7 -0.24
With other heads the score falls to between -0.59 and +0.64. The next best is head 0.0, the second previous-token head. And head 1.6's direct term, present token against source token, is negative (-0.64). On its own, head 1.6 slightly avoids a source that equals the present token. It only matches through the shifted note.
The weights tell a clean story. A last test is to remove a part and see what breaks. This is our own test; the paper's term-importance section, in Part 5, uses a related idea.
python
mean = cache['blocks.0.attn.hook_z'][:, :, 3].mean((0, 1)) # head 0.3's average result vectordef hook(z, hook): z[:, :, 3] = mean # same vector at every position return zlogits = model.run_with_hooks(toks, fwd_hooks=[('blocks.0.attn.hook_z', hook)])
plain text
== 9. ABLATIONS: REPLACE ONE HEAD'S RESULT VECTORS WITH THEIR AVERAGE OVER ALL POSITIONS AND SEQUENCES no ablation: loss first 15.04, second 3.41; induction score of 1.6 0.66 ablate 0.3 (the previous-token head): loss first 13.68, second 11.85; induction score of 1.6 0.06 ablate 0.0 (the second most previous-token head): loss first 14.27, second 6.33; induction score of 1.6 0.37 ablate 0.7 (the least previous-token layer-0 head): loss first 17.97, second 4.15; induction score of 1.6 0.64 ablate 1.6 (the induction head): loss first 14.25, second 13.04; induction score of 1.6 0.66 ablate 1.7 (the second induction-like head): loss first 15.04, second 3.77; induction score of 1.6 0.66 ablate 1.1 (the least induction-like layer-1 head): loss first 14.86, second 3.33; induction score of 1.6 0.64
Loss on the second copy after replacing one head with its average output. With no ablation it is 3.41 nats. Replacing head 0.3 raises it to 11.85, and replacing head 1.6 raises it to 13.04. Replacing head 0.0 raises it to 6.33. The other heads change it by less than 0.8.
Remove head 0.3, and head 1.6 loses its way: its induction score falls from 0.66 to 0.06. The loss on the second copy jumps from 3.41 to 11.85. Head 1.6 itself is untouched, yet it no longer finds the right source. The note it searched for is gone.
Remove head 1.6, and its pattern is unchanged (0.66), because nothing before it changed. But its output is gone, and the loss on the second copy rises to 13.04. So the two heads are both needed: one to find the place, one to copy.
The controls behave as expected. Head 0.0 is a partial helper (6.33). Heads 1.7, 1.1 and 0.7 change the second-copy loss by less than 0.8. Head 0.7 has one odd effect: the first-copy loss rises to 17.97. That copy is random text, so the change says little about induction, and we do not explain it here.
What these tests cannot show: mean ablation is only one way to remove a head. Other ways, such as setting it to zero, can give different numbers. And random tokens are not real text. They isolate induction, but they say nothing about how much the model uses it on ordinary prose.
The paper's appendix notes that the K-composition circuit is not the only way to build an induction head. Our model has position vectors in its stream, so this note applies to it.
Next, in Part 7: what the paper left out, MLP layers above all. Then what came after: induction heads in large models, superposition, dictionary learning and circuit tracing. Part 7 also ties the whole series together.
Run it yourself
The script circuits_part6.py runs every real-model test of this part: the repeated random tokens, the head scores, the eigenvalue positivity, the composition scores, the split of the key and the ablations. circuits_part6_toy.py builds the three-token induction circuit by hand. Both run on the CPU; the first one took a few minutes while other jobs ran on the same machine.