Contents The Transformer Era Course home

Chapter 16Self-Attention and the Transformer

The problem attention solves

Part III closed with an evaluation chapter and Part IV opened with a representation one. This chapter picks the architecture thread back up where Chapter 13 put it down.

That chapter ended with two complaints gating could not touch.

The first is sequential computation. A recurrence needs ht1h_{t-1} before it can produce hth_t, so the time steps cannot run in parallel. That is a hard ceiling, and it arrived precisely when hardware became massively parallel.

The second is the bottleneck. Everything the model knows about the prefix has to fit in one fixed-size vector, however long the prefix is.

Both complaints have one root. Information is forced to travel through the sequence, one step at a time.

So remove the travelling. Let every position look directly at every other position, in one operation, with nothing in between.

Distance stops mattering, because there is no distance any more. And the computation parallelises, because nothing waits for anything.

That is attention.

Where it began

Attention did not arrive with the transformer. It arrived as a patch on a recurrent translation system .

Encoder-decoder translation compressed the whole source sentence into one vector, then decoded from it. Long sentences degraded badly, for the obvious reason.

Bahdanau’s fix let the decoder look back at all the encoder states, and learn a weighting over them at each output step. The bottleneck opened.

The transformer took the next step, and its title says it. Attention was not a patch on recurrence. It could replace it entirely.

Queries, keys, and values

The mechanism borrows its vocabulary from databases, and the analogy is exact enough to be useful.

A query is what a position is looking for. A key advertises what a position offers. A value is what it actually contributes.

In a dictionary lookup you match one query against one key and take that value. Attention is the soft version. Match the query against every key, turn the match scores into weights, and take the weighted average of all the values.

Each of the three is a learned linear projection of the input:

Q=XWQ,K=XWK,V=XWV,(16.1)\begin{equation} Q = X W^Q, \qquad K = X W^K, \qquad V = X W^V, \label{eq:qkv} \quad\text{(16.1)} \end{equation}

where XX holds the input vectors, one row per position.

The whole operation is then one line:

Attention(Q,K,V)=softmax(QKdk)V.(16.2)\begin{equation} \operatorname{Attention}(Q, K, V) \;=\; \operatorname{softmax}\!\left(\frac{Q K^{\top}}{\sqrt{d_k}}\right) V . \label{eq:attention} \quad\text{(16.2)} \end{equation}

Read it right to left. QKQK^{\top} scores every query against every key. Dividing by dk\sqrt{d_k} keeps those scores in a workable range. The softmax turns each row into a distribution. Multiplying by VV takes the weighted average.

Building queries, keys and values. Each input vector is projected three ways by three learned matrices. The same three matrices are used at every position.

The word self in self-attention means QQ, KK and VV all come from the same sequence. Every position queries the sentence it is part of, including itself.

One query, worked

Take the lecture’s example. A query for who, and three keys, in three dimensions. The values equal the keys, to keep the arithmetic short.

q=(0.1,0.2,0.3),k𝑖𝑠=(0.4,0.5,0.6),k𝑡𝑒=(0.2,0.1,0.3),q = (0.1,\, 0.2,\, 0.3), \qquad k_{\mathit{is}} = (0.4,\, 0.5,\, 0.6), \qquad k_{\mathit{the}} = (0.2,\, 0.1,\, 0.3), k𝑏𝑒𝑠𝑡=(0.6,0.7,0.8).k_{\mathit{best}} = (0.6,\, 0.7,\, 0.8) .

Here dk=3d_k = 3, so the scale is 3=1.7321\sqrt{3} = 1.7321.

key qkq \cdot k /dk/\sqrt{d_k} exp\exp α\alpha
is 0.3200 0.1848 1.2029 0.3369
the 0.1300 0.0751 1.0779 0.3019
best 0.4400 0.2540 1.2892 0.3611
sum 3.5701 1.0000

The output is the weighted sum of the values:

ζ=0.3369v𝑖𝑠+0.3019v𝑡𝑒+0.3611v𝑏𝑒𝑠𝑡=(0.4118,0.4514,0.5816).\zeta \;=\; 0.3369\,v_{\mathit{is}} + 0.3019\,v_{\mathit{the}} + 0.3611\,v_{\mathit{best}} \;=\; (0.4118,\, 0.4514,\, 0.5816).

Now read the α\alpha column: 0.340.34, 0.300.30, 0.360.36. That is nearly uniform. Its entropy is 1.58111.5811 bits against a maximum of 1.58501.5850.

So this query attended to everything about equally, and the output is close to a plain average. The mechanism ran correctly and selected nothing, because these three keys all point in much the same direction.

That is worth seeing once. Attention is not magic. It selects only when the keys give it something to select on.

Attention that discriminates

Same machinery, keys that disagree. Three dimensions standing for animal, vehicle and verb.

k𝑑𝑜𝑔=(0.9,0,0.1),k𝑡𝑟𝑢𝑐𝑘=(0,0.9,0.1),k𝑏𝑎𝑟𝑘𝑒𝑑=(0.1,0,0.9).k_{\mathit{dog}} = (0.9,\, 0,\, 0.1), \quad k_{\mathit{truck}} = (0,\, 0.9,\, 0.1), \quad k_{\mathit{barked}} = (0.1,\, 0,\, 0.9).

query α𝑑𝑜𝑔\alpha_{\mathit{dog}} α𝑡𝑟𝑢𝑐𝑘\alpha_{\mathit{truck}} α𝑏𝑎𝑟𝑘𝑒𝑑\alpha_{\mathit{barked}} entropy
(5,0,0)(5, 0, 0) 0.8520 0.0634 0.0846 0.7507
(0,0,5)(0, 0, 5) 0.0829 0.0829 0.8343 0.8135
(2,2,2)(2, 2, 2) 0.3333 0.3333 0.3333 1.5850

The first two queries commit. The third cannot, and its entropy sits exactly at the 1.58501.5850 bit maximum for three keys.

Entropy is the useful reading here. Low entropy means the head has made a choice. High entropy means it is averaging. Both are legitimate behaviours, and telling them apart is how attention maps get interpreted.

Why divide by dk\sqrt{d_k}

The scale looks arbitrary. It is not, and the reason is measurable.

Let the entries of qq and kk have unit variance. Their dot product is a sum of dkd_k terms, so its standard deviation grows like dk\sqrt{d_k}.

Feed larger and larger numbers to a softmax and it saturates. Here is what that does, averaged over 200 random draws with eight keys.

dkd_k sd of qkq \cdot k entropy, raw entropy, scaled largest α\alpha, raw
4 1.756 1.7771 2.4764 0.5492
16 3.568 0.9743 2.4970 0.7488
64 7.202 0.5058 2.4844 0.8577
256 14.483 0.2512 2.4555 0.9282
1024 28.591 0.1333 2.4894 0.9611

The maximum possible entropy over eight keys is 33 bits.

Read the raw column. By dk=1024d_k = 1024 the distribution has collapsed onto a single key, which holds 9696 per cent of the weight. This is before any training has happened.

A saturated softmax has almost no gradient. So the head cannot learn its way out of a position it was put in by initialisation alone.

The scaled column barely moves across the whole range. Dividing by dk\sqrt{d_k} cancels exactly the growth the second column shows. That is why the constant is a square root rather than something tuned.

The causal mask

A language model must not read the future. When predicting the token at position ii, only positions jij \le i may contribute.

Enforce it on the scores, before the softmax:

Sij={(QK)ijdk,ji,,j>i.(16.3)\begin{equation} S_{ij} \;=\; \begin{cases} \dfrac{(QK^{\top})_{ij}}{\sqrt{d_k}}, & j \le i, \\[2ex] -\infty, & j > i . \end{cases} \label{eq:causalmask} \quad\text{(16.3)} \end{equation}

Since e=0e^{-\infty} = 0, the blocked positions receive exactly zero weight and the surviving ones renormalise to sum to one.

Take four raw scores and apply it.

the dog barked loudly sum
the 1.0000 . . . 1.0000
dog 0.1824 0.8176 . . 1.0000
barked 0.2312 0.1402 0.6285 . 1.0000
loudly 0.2760 0.1674 0.1015 0.4551 1.0000

Every row sums to one, and that is the entire reason the mask goes before the softmax.

Do it the other way, softmax first and then zero the blocked cells, and the rows no longer sum to one.

the dog barked loudly sum
the 0.4551 . . . 0.4551
dog 0.1230 0.5512 . . 0.6742
barked 0.1878 0.1139 0.5105 . 0.8122
loudly 0.2760 0.1674 0.1015 0.4551 1.0000

The first row now sums to 0.45510.4551. The weight that belonged to the blocked positions has been discarded rather than redistributed.

The damage is worst for the earliest tokens, which have the most future to hide from. Masking first lets the visible positions inherit that weight. Masking second quietly scales the whole row down.

Multiple heads and the rest of the block

One attention operation computes one kind of relationship. Language has many at once, so run several in parallel.

Multi-head attention splits the model dimension DD into hh heads of size dk=D/hd_k = D/h. Each head runs Equation (16.2) independently. The outputs are concatenated and projected once more with WOW^O.

Multi-head attention. Several attention operations run in parallel on slices of the same input, and their outputs are concatenated and projected. No head is told what to specialise in.

Nobody assigns the heads their jobs. They start from different random initialisations, and specialisation emerges because heads that duplicate each other contribute nothing extra to the loss.

Trained heads are often found tracking recognisable things. Some follow syntactic dependencies, some track the previous token, some resolve coreference. Many appear to do nothing identifiable at all.

The rest of the layer

Attention alone is not a layer. Three more pieces complete it.

A feed-forward network is applied at each position independently. It expands to a larger hidden size, applies a non-linearity, and projects back. This is where most of the layer’s parameters live.

A residual connection adds each sublayer’s input to its output. That gives the gradient a path with no multiplication on it, which is the same repair the LSTM cell state made in Chapter 13.

Layer normalisation rescales each position’s vector to zero mean and unit variance, which keeps the scale stable through a deep stack.

Positional encoding

Equation (16.2) has a property that is easy to miss. It is permutation invariant.

Shuffle the input positions and every attention weight follows them unchanged. The mechanism has no idea which token came first.

That is fatal for language, so position must be added to the input explicitly. The original transformer adds sinusoids of different frequencies:

PE(pos,2i)=sin(pos100002i/D),PE(pos,2i+1)=cos(pos100002i/D).(16.4)\begin{equation} PE_{(pos, 2i)} = \sin\!\left(\frac{pos}{10000^{2i/D}}\right), \qquad PE_{(pos, 2i+1)} = \cos\!\left(\frac{pos}{10000^{2i/D}}\right). \label{eq:posenc} \quad\text{(16.4)} \end{equation}

The frequencies span many scales, so nearby positions get similar encodings and distant ones do not. Later models learn the positional vectors instead, or inject relative position directly into the attention scores.

Counting the parameters

Take the original base configuration. |V|=50,000|V| = 50{,}000, D=512D = 512, L=6L = 6 layers, h=8h = 8 heads, feed-forward hidden size H=2048H = 2048.

component formula parameters
attention, WQWKWVWOW^Q W^K W^V W^O 4D24D^2 1,048,576
feed-forward 2DH+H+D2DH + H + D 2,099,712
layer norms 4D4D 2,048
one layer 3,150,336
all six layers L×L \times layer 18,902,016
embeddings |V|D|V| D 25,600,000
total 44,502,016

Two things in that table are worth naming.

The heads are free. Splitting DD into eight heads of 6464 costs nothing, because h×dk=Dh \times d_k = D. Multi-head attention is a reshape, not an extra budget.

The feed-forward block is the larger one, 2.12.1 million against 1.01.0 million. Attention gets the name and the diagrams, and most of the parameters sit next door.

What the sequence length costs

No entry in that table mentions sequence length. The computation does, because every position attends to every position.

tokens nn scores per head relative to n=512n = 512
128 16,384 0.06
512 262,144 1
2,048 4,194,304 16
8,192 67,108,864 256
32,768 1,073,741,824 4096

Quadruple the context and the attention cost rises sixteen-fold. That O(n2)O(n^2) is the price paid for removing the recurrence, and Chapter 23 is largely about paying it down.

Try it yourself. code/worked_examples/attention.py produces every table in this chapter. --one runs the lecture example, --select shows a query that commits and one that cannot, --scale measures the softmax collapsing without the square root, --mask contrasts the two orderings, and --params counts a layer.

Run it in ColabNotebookSource

Why this became everything

The original transformer. An encoder stack on the left, a decoder stack on the right, and the same attention block repeated throughout. Nearly every model in Parts IV and V is a piece of this diagram.

Three properties explain the takeover, and only one of them is about quality.

Parallelism. Every position is computed at once. A recurrent network of the same size takes as many sequential steps as there are tokens, and no amount of hardware fixes that.

Constant path length. Any two positions are one attention step apart. In an RNN they are as far apart as the text between them, which is where the gradient died in Chapter 12.

Scale. Because it trains in parallel, it can be made larger, and larger turned out to keep helping for far longer than anyone expected.

Chapter 17 takes this block and builds the two families that followed, one reading in both directions and one reading forwards only.

Further reading.

is the transformer paper, and it is short. introduced attention as a repair to recurrent translation, which is the clearest way to see what problem it solves. is the diagram-led walkthrough most practitioners learn from. cover the same material with more attention to the encoder decoder distinction.

Attend by hand. Reproduce the lecture example: compute the three dot products, scale by 3\sqrt{3}, exponentiate, normalise, and confirm ζ=(0.4118,0.4514,0.5816)\zeta = (0.4118, 0.4514, 0.5816). Then compute the entropy of the weights and say what it tells you about this particular query.

Make it select. Using the animal, vehicle and verb keys of this chapter, find a query whose largest attention weight exceeds 0.950.95. What did you have to change, the direction of the query or its magnitude? What does that say about the role of the projection matrices WQW^Q and WKW^K?

Kill the scaling. Remove the dk\sqrt{d_k} from Equation (16.2) and measure the entropy of the attention weights for dk=4,64,1024d_k = 4, 64, 1024 over random inputs. At which dkd_k does the largest weight exceed 0.90.9? Explain in two sentences why a saturated softmax cannot train.

Mask in the wrong order. Build a four by four score matrix, apply the causal mask before the softmax and after it, and report both row sums. Which row is worst affected, and why is it that one?

Count a layer. For D=768D = 768, h=12h = 12 and H=3072H = 3072, compute the attention, feed-forward and layer-norm parameters. Which is largest? Now double hh to 2424 and recompute. What changed, and why is the answer surprising?

Permutation invariance. Show that Equation (16.2) gives the same set of outputs when the input rows are permuted. Then explain precisely what Equation (16.4) adds that breaks the symmetry.

The quadratic wall. A model has a context of 4,0964{,}096 tokens. Compute the number of attention scores per head, and the factor by which it grows at 32,76832{,}768 tokens. Then name one strategy from Chapter 23 that avoids computing all of them.