Circuits, explained · Part 5 of 7 · Covers Two-Layer Attention-Only Transformers, Three Kinds of Composition, Path Expansion of Logits and of Attention Scores, Analyzing a Two-Layer Model, Term Importance Analysis, Virtual Attention Heads

Two-Layer Models: How Heads Compose

With a second layer, one head can read what an earlier head wrote. We follow the paper's three kinds of composition, expand the logits and the attention scores into paths, and measure which paths matter in a real two-layer model.

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.

A one-layer model can only look up tables of token pairs and skip-trigrams. Give it a second layer, and a head can read what another head wrote a moment before. That small change is where the paper's most interesting results begin.

The real model here is attn-only-2l: two layers of attention, eight heads per layer, and nothing else. We run it on 3,072 tokens of ordinary English text from WikiText.

Why depth matters

Three kinds of composition

Every head reads the stream through three matrices and writes back through one. So there are three places where a later head can pick up an earlier head's work.

A layer-0 head writes into the stream. A layer-1 head can read that write in three places.streamlayer-0 head h₁writes WOV of h₁layer-1 head h₂WQ: queryQ-compositionWK: keyK-compositionWV: valueV-compositionQ and K change the attention pattern of h₂. V changes what h₂ moves: h₂ then acts like a new head.
Three kinds of composition. A layer-0 head writes into the stream. A layer-1 head reads the stream through W_Q, W_K and W_V. If its W_Q reads the layer-0 head's output, that is Q-composition; if its W_K does, K-composition; if its W_V does, V-composition.

The logits as a sum of paths

Here is the paper's whole equation, with its picture of each term:

The derivation

The expansion is the same algebra as (1+a)(1+b)=1+a+b+ab(1+a)(1+b)=1+a+b+ab, with matrices. Write H1H_1 for the heads of the first layer and H2H_2 for the second. From Part 2, one head is Ah⊗WOVhA^h\otimes W_{\mathrm{OV}}^h: its attention pattern AhA^h mixes tokens, and WOVh=WOhWVhW_{\mathrm{OV}}^h=W_{\mathrm{O}}^hW_{\mathrm{V}}^h acts inside each token. A layer adds its heads to the stream, so a layer is Id+∑hAh⊗WOVh\text{Id}+\sum_h A^h\otimes W_{\mathrm{OV}}^h.

So the whole model is:

T=(Id⊗WU)⋅(Id+∑h∈H2Ah⊗WOVh)⋅(Id+∑h∈H1Ah⊗WOVh)⋅(Id⊗WE)\begin{aligned} T={}&(\text{Id}\otimes W_{\mathrm{U}})\\ &\cdot\Big(\text{Id}+\sum_{h\in H_2}A^h\otimes W_{\mathrm{OV}}^h\Big)\\ &\cdot\Big(\text{Id}+\sum_{h\in H_1}A^h\otimes W_{\mathrm{OV}}^h\Big)\\ &\cdot(\text{Id}\otimes W_{\mathrm{E}}) \end{aligned}

Multiply the two middle brackets out. You get four groups: Id⋅Id\text{Id}\cdot\text{Id}, layer-2 heads times Id\text{Id}, Id\text{Id} times layer-1 heads, and layer-2 heads times layer-1 heads. The mixed-product rule from Part 2, (A⊗B)(C⊗D)=(AC)⊗(BD)(A\otimes B)(C\otimes D)=(AC)\otimes(BD), turns each product of two heads into one term:

(Ah2⊗WOVh2)(Ah1⊗WOVh1)=(Ah2Ah1)⊗(WOVh2WOVh1)\begin{aligned} &(A^{h_2}\otimes W_{\mathrm{OV}}^{h_2})(A^{h_1}\otimes W_{\mathrm{OV}}^{h_1})\\ &=(A^{h_2}A^{h_1})\otimes(W_{\mathrm{OV}}^{h_2}W_{\mathrm{OV}}^{h_1}) \end{aligned}

Now attach Id⊗WU\text{Id}\otimes W_{\mathrm{U}} on the left and Id⊗WE\text{Id}\otimes W_{\mathrm{E}} on the right, and use the same rule once more. The result is the paper's bottom line:

T=Id⊗WUWE+∑h∈H1∪H2Ah⊗(WUWOVhWE)+∑h2∈H2∑h1∈H1(Ah2Ah1)⊗(WUWOVh2WOVh1WE)\begin{aligned} T={}&\text{Id}\otimes W_{\mathrm{U}}W_{\mathrm{E}}\\ &+\sum_{h\in H_1\cup H_2}A^h\otimes\big(W_{\mathrm{U}}W_{\mathrm{OV}}^hW_{\mathrm{E}}\big)\\ &+\sum_{h_2\in H_2}\sum_{h_1\in H_1}(A^{h_2}A^{h_1})\\ &\qquad\otimes\big(W_{\mathrm{U}}W_{\mathrm{OV}}^{h_2}W_{\mathrm{OV}}^{h_1}W_{\mathrm{E}}\big) \end{aligned}

Read it group by group. The first line is the direct path: embed a token and unembed it at once, which is the bigram table of Part 1. The second line has one term per head, in either layer, that reads the embeddings directly. These are the same skip-trigram terms as in the one-layer model. The last two lines hold one term for every pair of a layer-2 head and a layer-1 head. In each, the layer-1 head moves information, and then the layer-2 head moves the result again.

A toy example. Take a stream of one number per token and three tokens, x0=(1,2,3)x_0=(1,2,3). Each layer has one head. In layer 1, each token reads the token before it (token 1 reads itself), and the OV "matrix" is the number w1=0.5w_1=0.5. In layer 2, token 2 reads tokens 1 and 2 half each, the others read themselves, and w2=2w_2=2.

Two layers, one head each, a 1-number stream: the output is a sum of four pathstoken 1token 2token 3direct path: x₀123head 1: w₁ A₁ x₀0.50.51head 2: w₂ A₂ x₀236virtual head: w₂ w₁ A₂A₁ x₀112sum of the four4.56.512the model: x₂4.56.512x₀ = (1, 2, 3), w₁ = 0.5, w₂ = 2A₁: each token reads the one before(token 1 reads itself)A₂: token 2 reads tokens 1 and 2half each; others read themselves
The toy path expansion. The direct path is (1, 2, 3). Head 1 alone adds (0.5, 0.5, 1). Head 2 alone, reading the embeddings, adds (2, 3, 6). The virtual head, head 2 reading what head 1 wrote, adds (1, 1, 2). The four rows add up to (4.5, 6.5, 12), exactly the two-layer output.

Run the model the normal way first. After layer 1, x1=x0+w1A1x0=(1.5,2.5,4)x_1=x_0+w_1A_1x_0=(1.5,2.5,4). After layer 2, x2=x1+w2A2x1=(4.5,6.5,12)x_2=x_1+w_2A_2x_1=(4.5,6.5,12). Now add the four paths. Token 3 gets 3+1+6+2=123+1+6+2=12. The sum matches at every token, so no route was missed and none was counted twice.

On the real model. Our script does the same on attn-only-2l, with 3,072 tokens. It keeps the attention patterns and the layer-norm scales from a normal run, and holds them fixed. Then every step is a matrix product, so the expansion is exact. It builds the direct path, the 16 single-head terms and the 64 virtual-head terms, adds them, and compares with the model:

python
o0 = [A0[:, h] @ (x0n @ W_V[0, h]) @ W_O[0, h] for h in range(8)]       # what each layer-0 head writes
virt[h2][h1] = A1[:, h2] @ (cen(o0[h1]) / s1 @ W_V[1, h2]) @ W_O[1, h2]  # layer-1 head h2 moving what h1 wrote
full = direct + sum(o0) + sum(o1_single) + sum(all virt)                # then centre, scale and unembed
plain text
== 2. PATH EXPANSION OF THE LOGITS ON REAL TEXT (patterns and layer-norm scales frozen)
  stream before layer 1 rebuilt from the terms: max |diff| = 5.7e-06
  logits rebuilt as direct + 16 head terms + 64 virtual heads: max |diff| from the model = 4.2e-05 (logits range -18.2 .. 25.8)

The 81 terms rebuild every logit to within 0.00005, on logits that run from -18.2 to 25.8. So the expansion is not an approximation. It is the model, written another way.

We test the claim about virtual heads later, in the term importance section. Our model gives a more mixed answer than the paper's.

The attention scores as a sum of paths

The derivation

Write the stream at position ii before layer 2 as a sum of paths. It is the embedding, plus what each layer-1 head hh moved into position ii:

x1,i=WEti+∑h∈H1∑i′Aii′h WOVhWEti′x_{1,i}=W_{\mathrm{E}}t_i+\sum_{h\in H_1}\sum_{i'}A^h_{ii'}\,W_{\mathrm{OV}}^hW_{\mathrm{E}}t_{i'}

Here tit_i is the one-hot vector of token ii, as in Part 2. The score of a layer-2 head hh for destination ii and source jj is sij=x1,i⊤WQKhx1,js_{ij}=x_{1,i}^{\top}W_{\mathrm{QK}}^hx_{1,j}. Put the sum in on both sides. Each side has a "direct" part and a "moved by a head" part, so the product has four groups. Write di=WEtid_i=W_{\mathrm{E}}t_i for the direct part and mim_i for the part that layer-1 heads moved in:

sij=di⊤WQKh dj+mi⊤WQKh dj+di⊤WQKh mj+mi⊤WQKh mj\begin{aligned} s_{ij}={}&d_i^{\top}W_{\mathrm{QK}}^h\,d_j+m_i^{\top}W_{\mathrm{QK}}^h\,d_j\\ &+d_i^{\top}W_{\mathrm{QK}}^h\,m_j+m_i^{\top}W_{\mathrm{QK}}^h\,m_j \end{aligned}

The first term is the no composition group: both sides are plain embeddings, as in a one-layer model. The second is the Q-composition group: a layer-1 head prepared the query: it changes what the destination is looking for. The third is the K-composition group: a layer-1 head prepared the key, which changes what each source offers. In the last group, layer 1 prepared both.

A toy example. Let the query be q=qd+qhq=q_d+q_h with a direct part qd=(1,0)q_d=(1,0) and a moved part qh=(0,1)q_h=(0,1). Let the key be k=kd+khk=k_d+k_h with kd=(2,1)k_d=(2,1) and kh=(1,3)k_h=(1,3). The four terms are qd⋅kd=2q_d\cdot k_d=2, qh⋅kd=1q_h\cdot k_d=1, qd⋅kh=1q_d\cdot k_h=1 and qh⋅kh=3q_h\cdot k_h=3. They add up to 7, and indeed (1,1)⋅(3,4)=7(1,1)\cdot(3,4)=7.

On the real model. Our script splits the scores of all eight layer-1 heads into these four groups, with the layer-0 patterns frozen. The groups add up to the model's scores to within 0.00007. Then it asks a functional question. If we delete one group, how much does the attention pattern change? We measure the change with the total variation distance.

plain text
  no-composition + Q + K + Q-and-K terms vs the model's scores: max |diff| = 6.5e-05
    head 1.6: without K terms 0.75, without Q terms 0.20, without Q-and-K 0.23; no-composition term alone 0.58
    head 1.7: without K terms 0.45, without Q terms 0.24, without Q-and-K 0.15; no-composition term alone 0.38
Layer-1 heads: how much the attention pattern changes without one kind of term0 = the same pattern, 1 = completely different (total variation, mean over positions)head 1.0head 1.0, without K terms: 0.580.58head 1.0, without Q terms: 0.590.59head 1.1head 1.1, without K terms: 0.510.51head 1.1, without Q terms: 0.800.80head 1.2head 1.2, without K terms: 0.530.53head 1.2, without Q terms: 0.650.65head 1.3head 1.3, without K terms: 0.530.53head 1.3, without Q terms: 0.810.81head 1.4head 1.4, without K terms: 0.440.44head 1.4, without Q terms: 0.760.76head 1.5head 1.5, without K terms: 0.510.51head 1.5, without Q terms: 0.740.74head 1.6head 1.6, without K terms: 0.750.75head 1.6, without Q terms: 0.200.20head 1.7head 1.7, without K terms: 0.450.45head 1.7, without Q terms: 0.240.24without the K-composition termswithout the Q-composition termsHead 1.6 (the induction head ofPart 6) depends on its K termsand hardly on its Q terms.
For each layer-1 head, how much its attention pattern changes when the K-composition terms are removed (orange) and when the Q-composition terms are removed (blue), on 3,072 tokens of WikiText. Head 1.6 changes by 0.75 without its K terms and only 0.20 without its Q terms.

Head 1.6 stands out. Remove its K-composition terms, and its pattern changes by 0.75, which means it now looks almost somewhere else. Remove its Q-composition terms, and it changes by only 0.20. So this head mostly relies on keys that layer 1 prepared. Part 6 shows that head 1.6 is an induction head. On repeated random tokens its induction score is 0.71, and no other head is above 0.04.

Heads 1.0 to 1.5 change a lot without either kind of term, between 0.44 and 0.81. So almost every layer-1 head uses Q- or K-composition in some way. This measure cannot say whether that use is useful for the predictions, only that the pattern depends on it.

Measuring composition from the weights

The paper then reverse-engineers one two-layer model. It starts with a map of which heads compose.

The measure, step by step

The score for K-composition is:

K-comp(h1,h2)=∥WQKh2WOVh1∥F∥WQKh2∥F  ∥WOVh1∥F\text{K-comp}(h_1,h_2)=\frac{\|W_{\mathrm{QK}}^{h_2}W_{\mathrm{OV}}^{h_1}\|_F}{\|W_{\mathrm{QK}}^{h_2}\|_F\;\|W_{\mathrm{OV}}^{h_1}\|_F}

Read it left to right. On top is the size of the combined map "head h1h_1 writes, then head h2h_2 reads the result as a key". Below are the sizes of the two maps on their own. The ratio can never be more than 1, because the norm of a product is at most the product of the norms.

A toy example. First the norm. For the matrix [1220]\begin{bmatrix}1&2\\2&0\end{bmatrix}, the norm is 1+4+4+0=3\sqrt{1+4+4+0}=3. Now take a stream of three numbers. Head 1 reads dimension 1 and writes it, doubled, into dimension 3. So its WOVW_{\mathrm{OV}} has a single entry 2, in row 3 and column 1. Head 2's query reads dimension 1 and its key reads dimension 3: WQKW_{\mathrm{QK}} has a single 1, in row 1 and column 3.

The product WQKWOVW_{\mathrm{QK}}W_{\mathrm{OV}} has a single entry 2, so its norm is 2. The norms of the two factors are 1 and 2. The K-composition score is 2/(1⋅2)=12/(1\cdot2)=1: perfect alignment. The Q-composition score uses WQK⊤W_{\mathrm{QK}}^{\top}, whose query side reads dimension 3. The product is zero, so the score is 0. A third head whose key reads dimension 2 also scores 0, because head 1 never writes there.

On the real model. Our script computes all three scores for all 64 pairs of heads. For the random baseline, it averages the score of 200 pairs of random 512 × 512 matrices of rank 64:

plain text
== 4. COMPOSITION SCORES  ||W_A W_B||_F / (||W_A||_F ||W_B||_F)  (paper shapes, layer-0 head h1 -> layer-1 head h2)
  random baseline (two random rank-64 512 x 512 matrices, mean of 200): 0.0442
  Q-composition: max 0.084 (head 1.3 reads head 0.4), mean 0.042, pairs above baseline + 0.05: 0 of 64
  K-composition: max 0.124 (head 1.6 reads head 0.3), mean 0.040, pairs above baseline + 0.05: 1 of 64
  V-composition: max 0.055 (head 1.1 reads head 0.5), mean 0.029, pairs above baseline + 0.05: 0 of 64
  layer-0 heads, mean attention to the previous token: 0.0 0.19, 0.1 0.06, 0.2 0.04, 0.3 0.49, 0.4 0.02, 0.5 0.15, 0.6 0.08, 0.7 0.01
Composition scores minus the random baseline (darker = stronger), attn-only-2lQ-composition1.01.0 → 0.0: 0.001.0 → 0.1: 0.001.0 → 0.2: 0.001.0 → 0.3: 0.001.0 → 0.4: 0.251.0 → 0.5: 0.081.0 → 0.6: 0.001.0 → 0.7: 0.021.11.1 → 0.0: 0.001.1 → 0.1: 0.001.1 → 0.2: 0.001.1 → 0.3: 0.001.1 → 0.4: 0.311.1 → 0.5: 0.001.1 → 0.6: 0.001.1 → 0.7: 0.001.21.2 → 0.0: 0.001.2 → 0.1: 0.001.2 → 0.2: 0.001.2 → 0.3: 0.001.2 → 0.4: 0.351.2 → 0.5: 0.001.2 → 0.6: 0.001.2 → 0.7: 0.001.31.3 → 0.0: 0.001.3 → 0.1: 0.081.3 → 0.2: 0.001.3 → 0.3: 0.001.3 → 0.4: 0.501.3 → 0.5: 0.011.3 → 0.6: 0.001.3 → 0.7: 0.021.41.4 → 0.0: 0.001.4 → 0.1: 0.001.4 → 0.2: 0.001.4 → 0.3: 0.001.4 → 0.4: 0.211.4 → 0.5: 0.001.4 → 0.6: 0.001.4 → 0.7: 0.001.51.5 → 0.0: 0.001.5 → 0.1: 0.001.5 → 0.2: 0.001.5 → 0.3: 0.001.5 → 0.4: 0.451.5 → 0.5: 0.061.5 → 0.6: 0.001.5 → 0.7: 0.001.61.6 → 0.0: 0.081.6 → 0.1: 0.141.6 → 0.2: 0.001.6 → 0.3: 0.001.6 → 0.4: 0.081.6 → 0.5: 0.001.6 → 0.6: 0.001.6 → 0.7: 0.041.71.7 → 0.0: 0.001.7 → 0.1: 0.111.7 → 0.2: 0.191.7 → 0.3: 0.001.7 → 0.4: 0.391.7 → 0.5: 0.131.7 → 0.6: 0.051.7 → 0.7: 0.230.00.10.20.30.40.50.60.7K-composition1.01.0 → 0.0: 0.001.0 → 0.1: 0.001.0 → 0.2: 0.001.0 → 0.3: 0.001.0 → 0.4: 0.211.0 → 0.5: 0.001.0 → 0.6: 0.001.0 → 0.7: 0.001.11.1 → 0.0: 0.001.1 → 0.1: 0.001.1 → 0.2: 0.001.1 → 0.3: 0.001.1 → 0.4: 0.371.1 → 0.5: 0.001.1 → 0.6: 0.001.1 → 0.7: 0.001.21.2 → 0.0: 0.001.2 → 0.1: 0.001.2 → 0.2: 0.001.2 → 0.3: 0.001.2 → 0.4: 0.391.2 → 0.5: 0.001.2 → 0.6: 0.001.2 → 0.7: 0.001.31.3 → 0.0: 0.001.3 → 0.1: 0.001.3 → 0.2: 0.001.3 → 0.3: 0.001.3 → 0.4: 0.401.3 → 0.5: 0.001.3 → 0.6: 0.001.3 → 0.7: 0.001.41.4 → 0.0: 0.001.4 → 0.1: 0.001.4 → 0.2: 0.001.4 → 0.3: 0.001.4 → 0.4: 0.281.4 → 0.5: 0.001.4 → 0.6: 0.001.4 → 0.7: 0.001.51.5 → 0.0: 0.001.5 → 0.1: 0.001.5 → 0.2: 0.001.5 → 0.3: 0.001.5 → 0.4: 0.411.5 → 0.5: 0.001.5 → 0.6: 0.001.5 → 0.7: 0.001.61.6 → 0.0: 0.461.6 → 0.1: 0.291.6 → 0.2: 0.001.6 → 0.3: 1.001.6 → 0.4: 0.181.6 → 0.5: 0.001.6 → 0.6: 0.001.6 → 0.7: 0.011.71.7 → 0.0: 0.001.7 → 0.1: 0.001.7 → 0.2: 0.001.7 → 0.3: 0.001.7 → 0.4: 0.181.7 → 0.5: 0.001.7 → 0.6: 0.021.7 → 0.7: 0.210.00.10.20.30.40.50.60.7V-composition1.01.0 → 0.0: 0.001.0 → 0.1: 0.001.0 → 0.2: 0.001.0 → 0.3: 0.001.0 → 0.4: 0.001.0 → 0.5: 0.001.0 → 0.6: 0.001.0 → 0.7: 0.001.11.1 → 0.0: 0.001.1 → 0.1: 0.001.1 → 0.2: 0.001.1 → 0.3: 0.001.1 → 0.4: 0.001.1 → 0.5: 0.131.1 → 0.6: 0.001.1 → 0.7: 0.001.21.2 → 0.0: 0.001.2 → 0.1: 0.001.2 → 0.2: 0.001.2 → 0.3: 0.001.2 → 0.4: 0.001.2 → 0.5: 0.001.2 → 0.6: 0.001.2 → 0.7: 0.001.31.3 → 0.0: 0.001.3 → 0.1: 0.001.3 → 0.2: 0.001.3 → 0.3: 0.001.3 → 0.4: 0.001.3 → 0.5: 0.011.3 → 0.6: 0.001.3 → 0.7: 0.051.41.4 → 0.0: 0.001.4 → 0.1: 0.001.4 → 0.2: 0.001.4 → 0.3: 0.001.4 → 0.4: 0.001.4 → 0.5: 0.001.4 → 0.6: 0.001.4 → 0.7: 0.001.51.5 → 0.0: 0.001.5 → 0.1: 0.001.5 → 0.2: 0.001.5 → 0.3: 0.001.5 → 0.4: 0.001.5 → 0.5: 0.001.5 → 0.6: 0.101.5 → 0.7: 0.001.61.6 → 0.0: 0.001.6 → 0.1: 0.001.6 → 0.2: 0.051.6 → 0.3: 0.001.6 → 0.4: 0.001.6 → 0.5: 0.001.6 → 0.6: 0.001.6 → 0.7: 0.001.71.7 → 0.0: 0.001.7 → 0.1: 0.001.7 → 0.2: 0.001.7 → 0.3: 0.001.7 → 0.4: 0.001.7 → 0.5: 0.001.7 → 0.6: 0.001.7 → 0.7: 0.000.00.10.20.30.40.50.60.7rows: layer-1 head that reads; columns: layer-0 head that wrote. Hover a cell for its value.
Q-, K- and V-composition scores between every layer-0 head (columns) and every layer-1 head (rows) of attn-only-2l, minus the random baseline of 0.044. The brightest cell is in the K-composition map: head 1.6 reading head 0.3, with a score of 0.124. The column of head 0.4 is a little above the baseline in the Q and K maps.

The picture repeats the paper's story on a different model. Most scores sit near the random baseline of 0.044. Only one pair stands clearly above it: head 1.6 reading head 0.3, with K-composition 0.124. Head 0.3 is the head that attends most to the previous token, with a mean weight of 0.49. Head 1.6 is the induction head we met above. So the weights alone point to a previous-token head feeding the keys of an induction head.

There is a second, weaker signal in the maps: the column of head 0.4. Averaged over the eight layer-1 heads, its Q-composition is 0.069 and its K-composition 0.068. Every other layer-0 head stays at or below 0.046. No single cell of that column passes our threshold, but the whole column sits above the baseline.

The functional test of the previous section agrees. Remove the K term of head 0.4 alone, and the patterns of six layer-1 heads change by 0.35 to 0.46. Head 0.4 puts 65% of its weight on the start token, so much of what it writes is the same at every position. Many layer-1 heads seem to use that vector to tune their scores. Our tests show that they depend on it, not what they use it for.

plain text
  Q-composition, mean over the 8 layer-1 heads, per layer-0 head: 0.0 0.029, 0.1 0.041, 0.2 0.040, 0.3 0.029, 0.4 0.069, 0.5 0.046, 0.6 0.040, 0.7 0.044
  K-composition, mean over the 8 layer-1 heads, per layer-0 head: 0.0 0.027, 0.1 0.035, 0.2 0.034, 0.3 0.035, 0.4 0.068, 0.5 0.037, 0.6 0.038, 0.7 0.041

The correction

After publication, the authors found a bug that affected the composition diagram.

Which terms matter

The paper chose to ignore the virtual heads because it saw no V-composition. It then checks that choice with an experiment.

Our script does the same thing in a different way. It already has every term from the path expansion, so it just adds up the orders it wants, and unembeds the sum. With frozen patterns and frozen layer-norm scales, this gives the same partial models.

The marginal effect of order nn is a simple difference:

Δn=L≤n−L≤n−1\Delta_n=\mathcal{L}_{\le n}-\mathcal{L}_{\le n-1}

Here L≤n\mathcal{L}_{\le n} is the loss when all terms up to order nn are kept. For order 0, the paper compares with the uniform guess. A negative Δn\Delta_n means order nn helps. The paper also divides by the number of terms, to get the help per term.

On the real model. Here is the same table for attn-only-2l on our 3,072 tokens:

plain text
== 3. TERM IMPORTANCE: LOSS WHEN ONLY SOME TERMS ARE KEPT (nats per token, lower is better)
  uniform guess over 48,262 tokens: ln(48262) = 10.78
  order 0 (direct path only):                 10.11   marginal -0.68  (-0.68 per term, 1 term)
  order <= 1 (+ 16 single-head terms):         6.06   marginal -4.04  (-0.253 per term)
  order <= 2 (+ 64 virtual heads):            4.93   marginal -1.13  (-0.0177 per term)
  the model itself:                           4.93
How much each order of terms lowers the loss (nats per token)the paper (12 heads per layer, its own text)order 0: direct pathorder 0: direct path: -1.8-1.8order 1: 24 head termsorder 1: 24 head terms: -5.2-5.2order 2: 144 virtual headsorder 2: 144 virtual heads: -0.3-0.3our run (attn-only-2l, 8 heads per layer, 3,072 WikiText tokens)order 0: direct pathorder 0: direct path: -0.68-0.68order 1: 16 head termsorder 1: 16 head terms: -4.04-4.04order 2: 64 virtual headsorder 2: 64 virtual heads: -1.13-1.13Our losses: uniform 10.78, direct path 10.11, + heads 6.06, + virtual heads 4.93 (= the model, 4.93).
The loss drop from each order of terms. Top, the paper's model: direct path 1.8 nats, single heads 5.2, virtual heads 0.3. Bottom, our run of attn-only-2l on 3,072 WikiText tokens: direct path 0.68, single heads 4.04, virtual heads 1.13.

The broad shape is the same: the single-head terms do most of the work, with 4.04 of the 5.85 nats. The full sum gives 4.93 nats, exactly the model's own loss, which is one more check on the expansion.

Two numbers differ from the paper. The direct path helps less, only 0.68 nats. One reason is our method: the final layer-norm scale is frozen at the full model's value. A partial sum is smaller than the full stream, so its logits come out flatter. The paper does not say how it handled layer norm here.

The second difference matters more. In our model the virtual heads give 1.13 nats, not 0.3. That is nearly four times the paper's number, from fewer virtual heads (64 instead of 144). So the claim "virtual heads do not matter" does not carry over to this model as it stands. The next measurements show where this comes from.

plain text
    largest virtual heads (h2 o h1): 1.7 o 0.7 +0.723, 1.7 o 0.3 +0.334, 1.7 o 0.4 +0.298, 1.7 o 0.5 +0.288, 1.7 o 0.2 +0.200
    virtual heads: 51 of 64 above +0.01; median +0.0364
  virtual heads split by what the layer-0 head read (check 1.0e-05): from the start token -0.90, from real tokens -0.07 (each added alone to order <= 1)

Removing one virtual head at a time, the largest is 1.7 ∘ 0.7: without it, the loss rises by 0.72. All five largest run through head 1.7. Now split every layer-0 head's output into two parts: what it copied from the start token, and what it copied from real tokens. The virtual heads that start from the start token give 0.90 nats. The virtual heads that start from real tokens give only 0.07.

Loss drop from adding the virtual heads to the direct path + head terms (nats)all 64 virtual headsall 64 virtual heads: -1.13-1.13via the start tokenvia the start token: -0.90-0.90via real tokensvia real tokens: -0.07-0.07Largest single virtual heads (loss rise when removed): 1.7 ∘ 0.7 +0.72, 1.7 ∘ 0.3 +0.33, 1.7 ∘ 0.4 +0.30
Adding all 64 virtual heads to the direct path and single heads lowers the loss by 1.13 nats. The part that a layer-0 head copied from the start token gives 0.90 nats. The part copied from real tokens gives only 0.07 nats.

So the large number has a plain cause. Many layer-0 heads park their attention on the start token: head 0.7 puts 60% of its weight there. The start token is the same in every sequence, so such a head writes a nearly fixed vector. Head 1.7 then moves that vector again. This acts like a learned bias delivered through two heads, not like a rule about the text. Virtual heads that carry real token information give 0.07 nats, which is close to the paper's small number.

Our model shows the same split:

plain text
  head terms split by layer:
    layer-0 heads: -0.26 vs direct path only, -0.26 vs direct path + layer-1 heads
    layer-1 heads: -3.78 vs direct path only, -3.78 vs direct path + layer-0 heads

The layer-1 heads give 3.78 nats and the layer-0 heads only 0.26. In our model, the two numbers of each row happen to be almost the same. In the paper's model they differ a lot for the first layer, so there the two layers overlap in what they do.

Virtual attention heads

The paper ends the section with a closer look at the term it decided to skip.

Is Ah2Ah1A^{h_2}A^{h_1} really an attention pattern? Each row of Ah1A^{h_1} adds up to 1, and so does each row of Ah2A^{h_2}. A row of the product is a weighted average of rows of Ah1A^{h_1}, with weights that add up to 1. So it also adds up to 1. And if neither head looks into the future, neither does the product. On the real model, the rows of 1.7 ∘ 0.7 add up to 1 to within 0.0000005, and its future entries are 0.

A₁: previous tokent1t1 → t1: 1.001.00t2t2 → t1: 1.001.00t2 → t2: 0.000.00t3t3 → t1: 0.000.00t3 → t2: 1.001.00t3 → t3: 0.000.00t4t4 → t1: 0.000.00t4 → t2: 0.000.00t4 → t3: 1.001.00t4 → t4: 0.000.00t1t2t3t4×A₂: previous tokent1t1 → t1: 1.001.00t2t2 → t1: 1.001.00t2 → t2: 0.000.00t3t3 → t1: 0.000.00t3 → t2: 1.001.00t3 → t3: 0.000.00t4t4 → t1: 0.000.00t4 → t2: 0.000.00t4 → t3: 1.001.00t4 → t4: 0.000.00t1t2t3t4=A₂A₁: two tokens backt1t1 → t1: 1.001.00t2t2 → t1: 1.001.00t2 → t2: 0.000.00t3t3 → t1: 1.001.00t3 → t2: 0.000.00t3 → t3: 0.000.00t4t4 → t1: 0.000.00t4 → t2: 1.001.00t4 → t3: 0.000.00t4 → t4: 0.000.00t1t2t3t4
Two previous-token patterns on four tokens, and their product. In each of the first two, every token reads the one before it (token 1 reads itself). In the product, token 3 reads token 1 and token 4 reads token 2: the virtual head looks two tokens back. Every row still adds up to 1.

In our model the guess is only partly true. Head 0.0 itself puts 0.23 of its weight two tokens back, so this model does have a head that looks two back. The virtual head that looks two back the most is 1.4 ∘ 0.0, with only 0.12, and removing it costs just 0.02 nats.

plain text
  most important: 1.7 o 0.7: pattern [0.76, 0.0, 0.0, 0.0]; rows add up to 1 (max |sum - 1| 4.8e-07); future entries 0; V-composition score 0.036; removing it: loss +0.723
  most two-back: 1.4 o 0.0: pattern [0.35, 0.03, 0.09, 0.12]; rows add up to 1 (max |sum - 1| 7.2e-07); future entries 0; V-composition score 0.015; removing it: loss +0.021

Each pattern list gives the mean weight on the start token, on the token itself, one back and two back. The most important virtual head, 1.7 ∘ 0.7, puts 0.76 on the start token and almost nothing anywhere else. That is the start-token path we found above, now seen as a single virtual head.

The paper's next section takes up the one kind of composition that really matters in its two-layer model: the K-composition behind induction heads. That is Part 6.

Run it yourself

The two scripts behind this part are circuits_part5.py (the path expansions, term importance, composition scores and virtual heads on attn-only-2l) and circuits_part5_toy.py (the hand-sized examples). The first one uses the WikiText-2 test set from Hugging Face and runs on the CPU in a few minutes.

bash
pip install torch datasets "transformer_lens<4"
python circuits_part5.py        # writes results/part5.json and results/part5_stdout.txt
python circuits_part5_toy.py    # writes results/part5_toy.json
Terminal output of circuits_part5.py: the model and the number of terms, the logits rebuilt from 81 paths, the losses for each order of terms, the composition scores, the four groups of attention-score terms for every layer-1 head, and two virtual heads
The real output of circuits_part5.py.
Terminal output of circuits_part5_toy.py: four paths adding up to a two-layer output, two previous-token patterns multiplying into a two-back pattern, one attention score as four terms, and composition scores on a three-dimensional stream
The real output of circuits_part5_toy.py.

The paper and the code

The paper · our scripts