8  Attention and Transformers

NoteLearning objectives
  • Explain why different output steps may need different information from the input
  • Describe attention as scoring, normalising and combining a collection of representations
  • Trace attention over encoder states and spatial image features
  • Compute attention using queries, keys and values, for one query and for several queries together
  • Distinguish cross-attention, self-attention, multiple heads, causal masks and padding masks
  • Explain why attention needs positional information
  • Assemble a transformer block and distinguish token mixing from per-token computation
  • Explain how sequence length affects computation and memory, and what mixed precision and gradient accumulation change
  • Compare a fixed-context digit reader with an attention-based reader using generated outputs

Skills ladder. Extend an encoder–decoder with attention, inspect its alignments, and compare exact-string accuracy and character error rate across input lengths.

Chapter 7 developed recurrent encoder–decoders that can translate a sentence or describe an image. In the versions we saw, the decoder receives a single summary of the input before generating its output.

But what happens when different output steps need different details from that input?

We begin with that limitation and develop a way to form a new context for each output step. We first follow the operation over a sequence and an image, then express it using queries, keys and values. Self-attention lets the input elements exchange information directly, and position information, residual connections and per-token transformations turn it into a transformer block. Chapter 9 applies these blocks to image patches.

8.1 The fixed-width context bottleneck

The encoder–decoder models from the previous chapter pass a fixed-size summary from the encoder to the decoder. For copying and translation, it comes from the encoder’s final recurrent state; for the captioner, it comes from the CNN’s image features. This context vector, \(c\), must carry the information the decoder needs to produce the output. Its width is fixed: a vector of \(d\) numbers must summarise the input whether it contains three symbols, three hundred, or three million.

For our copying task, the decoder must recover every digit in the right order. As the string grows, more detail must fit into the same context vector. Other tasks, such as assigning a single label to the sequence, may require a less detailed summary than the copying task. The difficulty therefore depends on both the input’s length and what the output requires.

When the encoder finishes reading 4 2 7, what remains available to the decoder? Step through Figure 8.1 across the boundary between reading and writing, then increase the input length while keeping the context width fixed.

Figure 8.1: The copy model’s encoder reads 4 2 7 into the states h1, h2 and h3, and only h3, the sixteen-number context vector, crosses to the decoder. Blue marks the encoder, teal the decoder and gold the carried state. Step runs the model one operation at a time, and vary the sizes changes the input length and the context width independently. As the input grows, what happens to the column that crosses?

A wider context gives the model more room to represent the input, but the network must still learn what to retain and how to recover it. There is no simple rule that one state coordinate stores one symbol. Copying errors can arise from difficulties in learning and decoding the representation, as well as from compressing a long input into a fixed-width state. The decoder’s evolving state must also serve two roles: retaining the input context and tracking progress through the output sequence.

8.2 Attention: a context for each output step

Different decoder steps may need different parts of the input. In our copying task, producing the first output digit requires information about the first input digit; producing the next requires information about the next. A context vector tailored to the current output step could make that information easier to recover than a single summary used for the whole output sequence.

To make this possible, we retain the encoder’s hidden state at every input position. At each output step, the decoder uses its current state to assign a weight to each encoder state, then forms a new context vector as their weighted sum. States with larger weights contribute more to that context. As the decoder moves through the output, the weights can change, allowing the context to emphasise different parts of the input.

This mechanism is called attention [1]. Each context vector still has a fixed width, but it is assembled when needed from a collection of encoder states that grows with the input. The decoder can revisit that collection at every step, so the entire input no longer has to pass through a single final summary.

Bahdanau et al. read the input with a bidirectional encoder: one recurrent network reads it from left to right and another from right to left, and the state kept for each position joins the two, so it describes that position in the context of the whole input [1].

We can inspect which encoder states contribute at each output step. The attention matrix in Figure 8.2 is recorded from a recurrent copy model with attention that we trained on English text, with a state width of 16 (the side quest below compares widths): each row is an output position, each column an input position, and each row sums to one. The 40-character input “alice was beginning to get very tired of” is copied exactly, and the largest weight lies on the matching input position in 35 of the 40 rows, with the other five maxima one character away. Exact copying does not require every row’s maximum to sit on the diagonal, because a recurrent encoder state carries surrounding history and the decoder has a state of its own. Bahdanau et al.’s translation alignments use the same output-by-input view, departing from the diagonal where English and French word order differ [1].

A 40 by 40 matrix of attention weights, shaded from white to gold, has the characters of alice was beginning to get very tired of along both axes, with spaces drawn as open boxes. The weight runs down the diagonal. Five cells one position off the diagonal are outlined in ink as row maxima, and a note beneath the matrix counts them as 5 of 40 rows. A colour bar runs from zero to one.
Figure 8.2: The width-16 copy model’s attention weights follow the diagonal while it copies “alice was beginning to get very tired of”. Each row is an output position and sums to one; each column is an input position. The five boxed cells are the row maxima that fall one character off the diagonal.

Now compare the two routes to the input. The experiment in Figure 8.3 uses GRUs to copy strings. Compare narrow and wide contexts as input length increases. Then switch between per-symbol accuracy, which counts correct output positions, and every-symbol accuracy, which requires all positions in a string to be correct. Getting most symbols right can still leave many strings with at least one error.

Figure 8.3: The recorded copying accuracy of three decoders is plotted against string length. The width selector sets the fixed-context decoder’s context; the attention decoder has width 16, and the no-context decoder, which never receives the input, width 128. Per-symbol accuracy counts correct output positions; every-symbol accuracy requires the whole string to be correct. As the strings lengthen, which decoder falls away first?

Experiment note. Each context width uses a separately trained model. Evaluation generates outputs by selecting the highest-probability symbol at each step. Both accuracy measures check the positions corresponding to the input string; neither checks whether the next output is the stop symbol. The recorded curves describe these trained models, not theoretical limits on what each vector width could encode.

In these experiments, wider contexts generally support accurate copying over longer strings. Training choices also matter: Sutskever et al. improved translation by reversing the input order while leaving the output order unchanged. This made some dependencies easier to learn without increasing the context width [2].

The no-context decoder provides a useful comparison. It receives a zero initial state rather than the encoder’s summary, so its output does not depend on the input string it is asked to copy. Some symbols may still match by chance, so performance is not zero. With text, it can also draw on a language prior: patterns learned from the training examples. A plausible sequence is not necessarily a recovery of the input. Because the text and digit sources differ in alphabet size and predictability, their raw accuracies do not provide a controlled comparison of context capacity.

The attention model copies longer strings more reliably in this experiment, including some longer than those used in training. This does not establish reliability at arbitrary lengths. The important architectural change is the additional route to the input.

The same score–normalise–combine operation can read a spatial feature grid. We now return to image captioning to see what changes when the source is an image.

8.3 Image captioning with attention

Return to the captioner introduced in the previous chapter. For the scene photograph, a partial caption might end with “a dog is sitting under a tree with a”. Generating “ball” requires information about the small object beside the dog, which may be easier to recover by returning to the image features than by relying on the summary supplied at the beginning.

Show, Attend and Tell retains a spatial CNN feature grid so that the decoder can request a different visual summary at each word [3]. Each location supplies a feature vector. These vectors have receptive fields that extend beyond their grid cells, so a feature at one location need not describe only the pixels directly beneath it.

Let \(x_i\in\mathbb{R}^{d}\) be the feature at image location \(i\) in a grid of \(M\) locations, and \(s_{t-1}\) the decoder’s preceding hidden state. A learned alignment function \(f_{\mathrm{align}}\) assigns a scalar relevance score \(e_{ti}\) to each location. Softmax converts the scores into non-negative weights \(\alpha_{ti}\) that sum to one. Their weighted sum is the visual context \(c_t\), a different quantity from the LSTM cell state that Chapter 7 wrote with the same symbol:

\[ e_{ti}=f_{\mathrm{align}}(x_i,s_{t-1}),\qquad \alpha_{ti}=\frac{\exp(e_{ti})}{\sum_{j=1}^{M}\exp(e_{tj})},\qquad c_t=\sum_{i=1}^{M}\alpha_{ti}x_i. \]

A score measures a learned match; a weight specifies a share of the mixture. The context has the same width as an individual feature vector, and because it is recomputed at every output step, information no longer has to survive exclusively in the decoder’s carried state. The decoder uses this context together with its preceding state and previous word to generate the next word.

The VGG encoder supplies a \(14\times14\times512\) feature map: 196 locations, each represented by 512 numbers. Xu et al.’s soft model also learns a scalar gate \(\beta_t=\sigma(f_\beta(s_{t-1}))\), using the sigmoid \(\sigma\) to place it between zero and one, and the decoder receives the gated context \(\beta_t c_t\) together with its preceding state and previous word. The spatial weights in Figure 8.4 are illustrative, not measured predictions of that recurrent model.

The diagram has two horizontal bands. In the upper band, a teal LSTM at step t minus 1 passes its gold state, s t minus 1, to the LSTM at step t, which passes s t on to the right, takes the previous word, a, from below and emits the next word, ball, from its top. In the lower band, the scene photograph under a blue 14 by 14 grid of 196 feature vectors feeds a score box, which also receives s t minus 1 from above; softmax follows, then a faded copy of the photograph with gold weights on the ball, then a weighted sum whose output, c t, rises in blue into the LSTM at step t.
Figure 8.4: At each decoding step of an attention captioner, the preceding state \(s_{t-1}\) scores all 196 grid features, softmax turns the scores into weights that sum to one, and their weighted sum \(c_t\) enters the decoder. Here the decoder takes \(c_t\) with the previous word, “a”, and produces “ball”. The weights are illustrative and shaded relative to the largest.

Soft attention forms the weighted sum deterministically, so ordinary backpropagation passes through the weights. Xu et al. also studied hard attention, which samples a location from the weight distribution; sampling a discrete location prevents ordinary differentiation through that choice, so they trained it using a variational lower bound and a REINFORCE-style gradient estimator. Both variants choose visual information while retaining a recurrent caption decoder.

The next widget lets us inspect recorded attention from BLIP, a model that generates captions from images [4]. For each generated word, it shows weights over the image features. The request comes from text representations and the information comes from the image: this is called cross-attention. We can follow that exchange without knowing BLIP’s full architecture yet; the rest of the chapter develops the machinery it uses.

BLIP’s image encoder takes \(384\times384\) inputs and \(16\times16\) patches, giving a \(24\times24\) grid of 576 patch tokens — one element represented by one vector — plus a summary token, [CLS]. Its decoder has 12 layers with 12 attention heads each; the displayed map averages six heads, chosen for how much their maps change between words, so it is a selected view rather than all of the model’s attention. Heads are explained in Section 8.5.

Does an object word draw a tighter map than a function word? Commit to an answer, then compare the named objects with “with” in Figure 8.5, reading each word’s peak weight and the number of patches that hold half its attention rather than the brightness of its map.

Figure 8.5: BLIP’s cross-attention weights over the 576 image patches change with each word it generates. The photograph is dimmed so that the gold weights stay visible, and the same weights are drawn beside it as a 24 by 24 grid. The outlined patches hold half the weight, and the count under each word gives their number. Each map is scaled to its own strongest patch unless all words is selected. Which words draw the tightest maps?

The recorded caption is “a dog is sitting under a tree with a ball”. Each map is scaled to its own strongest patch, so compare the peak weights and the half-weight counts rather than the brightness: a bright region need not contain most of the attention, and an object word need not have a more concentrated map than a function word.

The recorded caption is “a dog is sitting under a tree with a ball”. The attention for “dog” has a peak patch weight of 3.51%, and its largest 35 patches together hold half the attention; for “tree” the corresponding values are 1.45% and 55 patches. A uniform distribution over the patch grid would give each patch about 0.174%. Even where an overlay makes one region appear bright, these are spread-out mixtures.

One might expect a function word to spread its attention more widely than an object word. In this selected view of one caption, “with” does not: it peaks at 6.35%, with half its attention in 10 patches, and “ball” peaks at 7.50%, with half in 11. Scaling each map to its own maximum, as the widget does by default, makes a weak peak look as bright as a strong one. Switching the scale to all words makes the magnitudes comparable across words, and neither display changes the underlying weights.

An attention map shows weights in one computation, not the cause of the final prediction. Jain and Wallace found weak agreement with gradient-based importance and substantially different attention distributions that preserved predictions in their NLP classification and question-answering settings [5]. Wiegreffe and Pinter tested LSTM binary classifiers and argued that conclusions depend on the definition of explanation, the baseline and whether the whole model is considered; their tests included uniform attention, variation across training runs and adversarially trained alternatives [6]. Neither paper establishes what this BLIP caption would do if an image region were removed. A causal claim needs an intervention and a measured change in behaviour, with the intervention itself specified.

Xu et al.’s caption decoder remains recurrent, because it needs its previous state to make the next query. The operation that scores and combines vectors carries no such requirement, and can read spatial features, encoder states or any other collection of vectors.

8.4 Computing attention: queries, keys and values

So far, we have used attention to read encoder states and image features. Here, we name the roles in the computation and express it in a form that handles multiple requests at once. Figure 8.6 provides an overview. Work through the query, key and value stages here, then return to self-attention, masking and multiple heads in the next section.

Figure 8.6: Attention is built up in seven stages on one table that stays in place, each stage adding one piece. Stages 1 to 3 are recurrent: a single context vector, then a context for each output step, then the same operation over an image grid. Stages 4 to 7 compute every row at once and add learned keys and values, queries taken from the same set, and finally a causal mask and several heads. A dotted ring marks what is new.

8.4.1 One query: score, normalise and combine

For each caption word, the decoder makes a request, and the image locations provide information that may answer it. We give the three parts of this computation distinct names: the query describes what is requested, a key helps determine how relevant a source location is, and its value provides the information to combine.

In recurrent captioning, the preceding decoder state (\(s_{t-1}\)) supplies the query, while each image location supplies a key and a value. The query and key determine that location’s score; softmax compares the scores across locations to produce the weights. Each value is multiplied by its weight and added to the context. A key and value refer to the same location, but they need not be the same vector.

Learned projections let a source feature vector provide one representation for matching and another for the information being combined. These are learned linear maps; we do not assign meanings such as “object identity” or “colour” to particular coordinates. A token is one element of a sequence, represented by one vector. In Figure 8.7 each token has a two-dimensional key and a three-dimensional value, displayed as a colour so that the mixture can be seen, and we move the query ourselves. It illustrates the arithmetic without running a learned captioning model.

The captioning model scored each location with a small learned network. Keeping the same score, normalise and combine, but making the scoring a dot product of projected representations, is the whole of the change. For a query \(q\) and keys \(k_i\) of width \(d_k\), scaled dot-product attention computes scores \(e_i=q\cdot k_i/\sqrt{d_k}\), turns them into weights \(\alpha_i=\exp(e_i)/\sum_j\exp(e_j)\) with a softmax, and returns \(o=\sum_i\alpha_i v_i\). The dot product depends on both direction and magnitude, so it is not cosine similarity unless the vectors have also been normalised. Before any subsequent projection, the output is a weighted average of the values, and need not resemble any single one of them.

The widget’s opening setting shows the arithmetic in full. With \(q=(1.2,0.6)\) and tokens a, b and c whose keys are \(k_a=(1.4,0.9)\), \(k_b=(-1.1,1.3)\) and \(k_c=(-0.8,-1.4)\), the unscaled dot products are \(2.22\), \(-0.54\) and \(-1.80\), and dividing by \(\sqrt{2}\) gives approximately \(1.570\), \(-0.382\) and \(-1.273\). Softmax turns those into weights of about \(83.3\%\), \(11.8\%\) and \(4.9\%\). The values are colours, three numbers between zero and one for red, green and blue: \(v_a=(0.86,0.20,0.18)\) is a red, \(v_b=(0.22,0.62,0.28)\) a green and \(v_c=(0.48,0.30,0.78)\) a violet. Their weighted sum is approximately \((0.77,0.25,0.22)\), an output that favours token a while still including the other values. Set the query to zero and every score is equal, so the weights are equal too, however different the keys.

In Figure 8.7 each token’s key is an arrow and its value is a colour. Point the query between two keys, and say which colour the output will lean towards before reading it off. Then lengthen the query without turning it, and see whether your answer changes. The vector width stays two; this tests score magnitude rather than changing \(d_k\). Finally, switch the scaling off and see whether the same query spreads its weight more or less evenly.

Figure 8.7: Scaled dot-product attention mixes the values of three to five tokens in proportions set by one query. Each token’s key is a blue arrow and its value is a colour. The query’s dot products with the keys, divided by \(\sqrt{2}\), are the scores; softmax turns them into weights, and the output colour mixes the values in those proportions. Drag the query towards one key: which colour does the output approach?

8.4.2 Several queries together

For several queries, place one input vector per row. Let \(X_q\in\mathbb{R}^{N_q\times d_q}\) supply the queries and \(X_s\in\mathbb{R}^{N_s\times d_s}\) supply the keys and values. The learned matrices have shapes \(W_Q\in\mathbb{R}^{d_q\times d_k}\), \(W_K\in\mathbb{R}^{d_s\times d_k}\) and \(W_V\in\mathbb{R}^{d_s\times d_v}\). Thus

\[ Q=X_qW_Q\in\mathbb{R}^{N_q\times d_k},\quad K=X_sW_K\in\mathbb{R}^{N_s\times d_k},\quad V=X_sW_V\in\mathbb{R}^{N_s\times d_v}. \]

The computation is

\[ S=\frac{QK^\top}{\sqrt{d_k}}\in\mathbb{R}^{N_q\times N_s},\qquad A=\operatorname{softmax}_{\mathrm{row}}(S),\qquad O=AV\in\mathbb{R}^{N_q\times d_v}. \]

Row \(t\) of \(A\) holds all the weights used for output \(t\), and its columns index the source vectors, so the row-wise softmax normalises each query’s choices separately. The number of queries and the number of source vectors can differ; what the source must supply is one value for each key. The opening setting of Figure 8.7 is this computation with \(N_q=1\), \(N_s=3\), \(d_k=2\) and \(d_v=3\), with the keys and values given directly rather than projected.

The scale factor addresses how scores tend to grow with key width. A simple case shows why: if \(q\) and \(k\) are both vectors of \(d_k\) ones, then \(q\cdot k=d_k\), so doubling the width doubles the score. Components with mixed signs partly cancel, so the scores of learned vectors need not grow in this way; what matters for softmax is how widely the scores vary, and that can still grow with the width. Under independent, zero-mean, unit-variance component assumptions, a dot product has variance \(d_k\). Its standard deviation — the scale of its fluctuations — is therefore \(\sqrt{d_k}\). Large differences between scores can make softmax concentrate almost all the weight on one key, leaving small gradients for many changes to the scores. Dividing by \(\sqrt{d_k}\) removes this width-dependent variance in that model [7]. That is a rationale, not a guarantee about trained representations.

Write \(q\cdot k=\sum_{j=1}^{d_k}q_jk_j\). Suppose all components across the two vectors are independent, each with mean zero and variance one. Then

\[ \mathbb{E}[q_jk_j]=0,\qquad \operatorname{Var}(q_jk_j)=\mathbb{E}[q_j^2]\mathbb{E}[k_j^2]=1. \]

Distinct products have zero covariance, so

\[ \operatorname{Var}(q\cdot k)=d_k,\qquad \operatorname{Var}\!\left(\frac{q\cdot k}{\sqrt{d_k}}\right)=1. \]

The assumptions describe the rationale for the scaling. Correlated or differently scaled learned components need not satisfy them exactly.

The spread of \(q\cdot k\) grows with \(d_k\); Figure 8.8 measures what that does to the weights. One draw is noisy, so it also averages the same measurement over many: the red curve is the heaviest weight a softmax puts on one key as the width grows, and the gold curve is the same quantity once \(\sqrt{d_k}\) has been divided out. At a Vaswani head’s width of 64 the unscaled softmax is already spending most of its weight on a single key.

Figure 8.8: Without the scaling, softmax over four keys tends to put more of its weight on a single key as the key width grows; dividing by \(\sqrt{d_k}\) largely removes that trend. The left panel shows one draw at the width the reader sets, and the right panel averages the heaviest weight over 160 independent draws, because one draw is too noisy to show the trend. Predict the heaviest weight at width 64 before setting it.

For comparison, the scoring function Bahdanau et al. used can be written as

\[ e_{ti}=w_{\mathrm{align}}^\top\tanh(W_s s_{t-1}+W_h h_i), \]

where \(h_i\) is an encoder state, \(s_{t-1}\) a decoder state, and \(W_s\), \(W_h\) and \(w_{\mathrm{align}}\) are learned parameters [1]. We call the learned scoring vector \(w_{\mathrm{align}}\) to distinguish it from the value vectors. Both forms score, normalise and combine. What dot-product attention changes is the scoring step, replacing the small nonlinear scoring network with a dot product of projected representations.

8.5 From cross-attention to self-attention

In cross-attention, queries come from one collection of representations and keys and values from another, as when a text decoder reads image features. Attention gave the recurrent decoder access to its whole input, but left the decoder itself unchanged: it still needed the preceding state before it could process the next word. Self-attention removes that requirement by letting every input position make its own query of the token collection. All queries come from representations already available at the start of the layer, so no state has to be carried through the positions to compute this layer’s outputs.

8.5.1 Self-attention

Let \(X\in\mathbb{R}^{N\times d}\) contain \(N\) token vectors of width \(d\). Self-attention uses the same collection for queries, keys and values:

\[ Q=XW_Q,\qquad K=XW_K,\qquad V=XW_V,\qquad O=\operatorname{softmax}_{\mathrm{row}}\!\left(\frac{QK^\top}{\sqrt{d_k}}\right)V. \]

There is one output row per input token. The matrix products can compute these rows together because none requires another output row from the same layer. This describes how the layer processes available inputs; the causal-mask discussion below explains why generating new tokens still proceeds one step at a time.

Each row of the attention matrix is one token’s query weighing every token. The token making the query also remains among the keys and values, so unmasked self-attention can include the token’s own representation in its output. Without position information or a mask, each token keeps its output when the tokens are reordered, as Figure 8.10 at the end of this section shows.

8.5.2 Multiple heads

One attention head produces one weighted mixture for each query. Several heads let the model form different mixtures in parallel, using different learned representations. Their outputs remain separate until an output projection combines them, so the model can use information from several mixtures in the same update.

Multi-head attention repeats the operation with separate learned projections, so head \(j\) produces \(O_j=\operatorname{Attention}(XW_Q^{(j)},XW_K^{(j)},XW_V^{(j)})\), whose weights and mixture can differ from those of another head. The head outputs are concatenated along their feature coordinates, then an output projection combines them to produce an update of width \(d\):

\[ \operatorname{MHA}(X)=\operatorname{Concat}(O_1,\ldots,O_h)W_O. \]

With \(h\) heads and fixed total width, the usual choice is \(d_k=d_v=d/h\) per head, which requires \(d\) to be divisible by \(h\) and makes the concatenation return width \(d\), with \(W_O\in\mathbb{R}^{d\times d}\). Adding heads therefore divides that width rather than giving every head the full model width. Separate heads provide separate learned mixtures; whether any of them specialises in a relationship a person would name is something to establish by examining the trained model.

8.5.3 Causal and padding masks

A causal mask prevents a query at position \(t\) from using a key at position \(i>t\). Add a mask \(M\) to the scores before softmax, with \(M_{ti}=0\) for \(i\leq t\) and \(M_{ti}=-\infty\) otherwise; since \(\exp(-\infty)=0\), future positions receive no weight.

During next-token training, the full target sequence is known. We shift it to form the inputs: for example, inputs <sos> 4 2 7 predict targets 4 2 7 <eos>. The input at position \(t\) therefore contains the preceding token, and may attend to itself and earlier inputs without seeing its target. The causal mask prevents access to later inputs that would reveal the answer, allowing all training positions to be processed together. During autoregressive generation, each selected token becomes the next input, so it must be generated before the following step can run.

A padding mask separately excludes the filler positions used to batch sequences of unequal lengths. Each active query must retain at least one permitted key, or its softmax is undefined.

In Figure 8.10, switching on the causal mask and then reordering the tokens costs a token its access to everything placed after it — a change in the information permitted, not merely a rearrangement of matrix rows. The mask defines a direction through the sequence without requiring a recurrent state update.

8.5.4 Comparing routes between positions

Compare how information travels between two distant positions in Figure 8.9. A recurrent network passes it along a chain of state updates. A convolution combines nearby positions, so information travels farther as successive layers expand the receptive field. Full self-attention gives each position a direct connection to every position its mask permits [7].

Three panels each show five positions. In the recurrence panel, a gold path along a chain takes four steps from position 1 to position 5. In the convolution panel, with width 3, stride 1 and no dilation, four layers are stacked and a gold path moves one position per layer, reaching position 5 at layer 4. In the self-attention panel, one layer connects every position to every other, and a single gold edge joins position 1 to position 5.
Figure 8.9: Information from the first of five positions reaches the last by different routes. A recurrent chain needs four state updates. Stacked width-three convolutions widen the reach by one position per layer, so four layers are needed. One self-attention layer connects every pair of positions directly, in a single step.

A short path can help information and gradients travel between distant positions, but the model must still learn which relationships are useful. Direct connections also have a cost: full attention compares pairs of positions, so longer sequences create many more comparisons. We return to that cost in the computation and memory section.

The arithmetic comparison follows the quantities used by Vaswani et al.: sequence length \(n\), representation width \(d\), and convolution kernel width \(k\) [7]. A recurrent layer has a chain of \(O(n)\) sequential operations and costs \(O(nd^2)\) for dense state updates. A contiguous, stride-one convolution costs \(O(knd^2)\) and computes its positions in parallel within a layer. Distant positions communicate only after enough layers have expanded the receptive field, which takes \(O(n/k)\) layers for kernels wider than one, in the convention used in their discussion. Their Table 1 instead lists a dilated convolution’s \(O(\log_k n)\) path; the figure here draws the contiguous case.

Full self-attention gives any position a direct path to any other permitted position. Its score and value matrix products cost \(O(n^2d)\) at fixed total head width, and the query, key, value and output projections add \(O(nd^2)\). The constant number of sequential stages refers to dependencies across positions, not to constant runtime on a finite GPU.

Without position information or a mask, reordering the input tokens leaves each token’s output representation unchanged: the output moves with its token. This property is called permutation equivariance. Attention can use the tokens’ content to decide what to combine, but it cannot distinguish different orders of the same collection. A fixed causal mask changes this because moving a token changes which tokens it can use.

A permutation matrix \(P\) reorders rows, so the reordered input is \(PX\). The query, key and value rows move with their tokens. The scores become \(PSP^\top\) and the weights become \(PAP^\top\): both their rows and columns are reordered. The output is therefore

\[ (PAP^\top)(PV)=PAV=PO, \]

using \(P^\top P=I\). The output array is reordered, while each token keeps the same output vector.

Reorder the tokens in Figure 8.10 and follow one of them. Before it moves, predict where its rows in \(X\), \(Q\), \(K\), \(V\) and \(O\) will move, whether the numbers in those rows will change, and what will happen to the attention matrix. Then add position vectors, or switch on the causal mask, and make the same reordering.

Figure 8.10: In self-attention without position information, reordering the tokens moves each row of \(X\), \(Q\), \(K\), \(V\) and \(O\) with its token, and \(A\) permutes its rows and columns together. Position vectors and a causal mask each tie part of the computation to places in the sequence. Reorder the tokens in each mode: does a token’s output row keep its values?

8.6 Giving attention a sense of position

Attention needs a way to distinguish the same content appearing at different places. We can supply it by adding a position vector to each token embedding. At position \(p\), the content vector \(e_p\in\mathbb{R}^d\) receives a position vector \(\mathrm{PE}(p)\in\mathbb{R}^d\), giving \(x_p=e_p+\mathrm{PE}(p)\). Both have the same width, so the sum fits the attention layer without changing its shape.

The position vectors stay attached to their locations. Moving a word to another location therefore pairs its content with a different position vector, giving the model information about both what is present and where it occurs. These combined vectors enter the learned query, key and value projections.

One option is to learn a table of position vectors during training. Another is to generate them from a fixed formula. The original transformer’s sinusoidal encoding uses pairs of sine and cosine waves: some coordinates change rapidly with position, while others change slowly. Together they provide a pattern the model can use to distinguish positions and their relationships [7].

For even width \(d\), the formula below gives one sine–cosine pair for each \(i=0,\ldots,d/2-1\). The quantity \(\omega_i\) controls how quickly that pair changes; \(2i\) and \(2i+1\) are its coordinate indices, starting at zero:

\[ \omega_i=10000^{-2i/d},\qquad \mathrm{PE}(p,2i)=\sin(\omega_i p),\qquad \mathrm{PE}(p,2i+1)=\cos(\omega_i p). \]

Binary counting offers a useful comparison. Written in binary, the lowest bit of a position flips at every step, the next bit every two steps and the next every four, so each column changes at half the rate of the one before, and together the columns give every position a distinct code. The sinusoidal encoding is built in a similar way from smooth waves. Its frequencies \(\omega_i\) are geometrically spaced, so the pairs vary at different rates and together carry positional information at several scales, as Figure 8.11 shows. Unlike the bits, whose periods always double, the ratio between successive wavelengths depends on the width \(d\). Each coordinate also varies continuously between \(-1\) and \(1\) rather than jumping between two values, and, as a side quest below shows, a fixed offset acts on each pair in the same way at every position.

Positions 0 to 63 run down the side of two matrices. The left matrix shows the eight bits of each position in two tones; its columns alternate every 1, 2, 4 and more positions, and their periods, 2 to 256, are printed above them. The right matrix shows the 26 coordinates of the sinusoidal code on a red, white and blue scale. Its fast columns alternate quickly and its slow ones barely change, and each pair is labelled with its wavelength, from 6.3 to 30,938.
Figure 8.11: Binary counting and the sinusoidal position code both describe a position with columns that change at different rates. Each bit has twice the period of the bit before it; each sine–cosine pair of a width-26 code has a wavelength about \(10000^{2/26}\approx2.03\) times that of the pair before. The bits jump between two values, while the sinusoids vary smoothly between \(-1\) and \(1\). Positions 0 to 63 are shown.

The important construction is a position-dependent vector of the same width as the content, which can be added before attention. A learned table and a fixed formula are both valid choices. A formula can produce codes beyond the positions seen during training, but that alone does not guarantee accurate predictions on longer sequences.

What should that position vector be? A raw integer index distinguishes positions, but its magnitude grows with the sequence and a single coordinate gives the network little structure to work with. A normalised index bounds the magnitude, at the cost of tying the code to a chosen range, and the widget’s version divides by its displayed position range. A learned table assigns a trainable vector to each supported position, which can work well, although entries beyond its range require another decision. The widget’s random table is untrained, so its appearance is not evidence against learned embeddings; Vaswani et al. found nearly identical translation results with learned and sinusoidal position embeddings in their comparison [7].

Addition retains width \(d\) and lets the position code enter the same query, key and value projections as the content. Concatenating content and position would instead increase the input width unless a further projection reduced it, and learned codes remain a valid construction. Vaswani et al. chose sinusoids partly because they hypothesised that a formula defined beyond the training positions could help length extrapolation, but being able to compute a code at a new position does not guarantee good predictions there.

Wavelengths. A sinusoidal code starts with a sine and a cosine at the same angular frequency \(\omega\). The pair \((\sin(\omega p),\cos(\omega p))\) stays bounded as \(p\) increases and changes smoothly with position, but one pair repeats after its wavelength, so the full code combines pairs with different wavelengths.

The wavelengths \(\lambda_i=2\pi/\omega_i\) form a geometric progression whose shortest member is \(2\pi\) and whose longest, since the final pair index is \(d/2-1\), is \(2\pi\,10000^{(d-2)/d}\). At \(d=64\) the range runs from approximately 6.28 to 47,117 positions. The often quoted \(2\pi\cdot10000\) is a limiting value, not a wavelength attained by this finite vector.

Equal offsets and dot products. The paired coordinates also give equal offsets the same relationship. The dot product of the codes for positions \(p\) and \(q\) is

\[ \mathrm{PE}(p)\cdot\mathrm{PE}(q) =\sum_{i=0}^{d/2-1}\cos\!\bigl(\omega_i(p-q)\bigr). \]

This expression depends only on \(p-q\). Positions 3 and 4 therefore have the same dot product as positions 23 and 24, about 30.917 at width 64, and equal offsets form bands in the similarity matrix. The cosine terms oscillate, so depending on distance is not the same as decreasing steadily as distance grows. The identity concerns the position codes alone: adding content embeddings introduces further terms, and learned attention projections can change the similarity.

A fixed offset rotates each pair. Let \(u_i(p)=[\sin(\omega_i p),\cos(\omega_i p)]^\top\). For a fixed offset \(\Delta\), the angle-addition identities give

\[ u_i(p+\Delta)= \begin{bmatrix} \cos(\omega_i\Delta)&\sin(\omega_i\Delta)\\ -\sin(\omega_i\Delta)&\cos(\omega_i\Delta) \end{bmatrix}u_i(p). \]

The matrix depends on the offset and frequency, but not on the starting position. It is orthogonal, so applying it to both members of a pair preserves their dot product. Placing one such matrix per frequency on a block diagonal gives a linear transformation of the whole code for each fixed offset. This is a property the model can exploit, not a guarantee that a learned projection will do so.

Figure 8.12 shows how the relationship between two position codes changes with their separation; the side quest above explains the pattern. Must their dot product fall at every increase in the gap? Compare pairs at a fixed gap, then widen it and see. Compare the sinusoidal result with the normalised index and the untrained random table. The readout gives the selected pair’s dot product and the range over every pair at the same gap, so the same-gap claim can be checked numerically.

Figure 8.12: Sinusoidal position codes for 64 positions sit beside the dot product of every pair of codes, where the selected pair is boxed and every pair at the same gap is outlined in gold. Beneath them, one plot moves the pair with its gap held fixed and the other widens the gap from the first position. Which of the four encodings keep the dot product fixed as the pair moves?

8.7 Assembling the transformer

Self-attention lets tokens exchange information. A transformer block follows that exchange with a multilayer perceptron (MLP), a feedforward network that nonlinearly transforms the features each token now holds, applied separately to every token. That division is what the block is built around: attention moves information between tokens, the MLP works on what each token is left holding. Both sit inside residual connections, with layer normalisation controlling the scale of their inputs. The block below uses pre-norm ordering: normalise before each sublayer, then add its output to the saved input. For an input \(X\in\mathbb{R}^{N\times d}\),

\[ U=X+\operatorname{MHA}(\operatorname{LN}_1(X)),\qquad Y=U+\operatorname{MLP}(\operatorname{LN}_2(U)). \]

Both \(U\) and \(Y\) have shape \(N\times d\). The original transformer put the normalisation after each residual addition instead, \(\operatorname{LN}(X+\operatorname{Sublayer}(X))\), which is called post-norm [7]; Figure 8.13 and the widget here use pre-norm throughout, and why that ordering is the common choice now is taken up once the components are in place.

Four thick gold vertical residual streams run from x1 to x4 at the bottom to y1 to y4 at the top, with the shape N by d marked at X, U and Y. Each stream branches through LN1 into a blue multi-head attention band, in which every branch connects to every other, and adds back at a circled plus to give U. Each then branches again through LN2, a d to rd layer, GELU and an rd to d layer, with N by rd on the thick wires, and adds back to give Y. The equations U = X + MHA(LN1(X)) and Y = U + MLP(LN2(U)) are printed beside their additions.
Figure 8.13: In a pre-norm transformer block, attention combines information across tokens, while the MLP processes each token separately with shared weights. Each sublayer’s output is added back to its input through a residual connection, first giving \(U\) and then \(Y\). Four of the \(N\) token lanes are drawn.

8.7.1 Residual connections

The first residual path saves \(X\) while the attention sublayer computes an update. Adding that update requires the same token count and feature width as \(X\). In the configuration above, concatenating the heads already gives width \(d\); the output projection mixes their contributions while preserving that width. The second path saves \(U\) while the MLP computes another update. A residual addition neither concatenates features nor creates more tokens; it adds corresponding coordinates. What the two paths preserve is a direct route through the block for representations and gradients, which the learned branches modify rather than replace.

8.7.2 Layer normalisation

Layer normalisation standardises the features within one token [8]. For a row \(x\in\mathbb{R}^d\), compute \(\mu=d^{-1}\sum_jx_j\) and \(\sigma^2=d^{-1}\sum_j(x_j-\mu)^2\), then

\[ \operatorname{LN}(x)_j=\gamma_j\frac{x_j-\mu}{\sqrt{\sigma^2+\epsilon}}+\beta_j. \]

The learned scale \(\gamma\) and bias \(\beta\) have width \(d\), and \(\epsilon\) is a small positive constant for numerical stability. Each token has its own mean and variance, while sharing the learned scale and bias with the other tokens in that layer. Like batch normalisation in Section 2.6, this normalises activations and then applies a learned affine transformation; unlike batch normalisation, it estimates nothing across the examples in a minibatch, so it needs no running batch statistics at inference.

8.7.3 The per-token MLP

The MLP expands each token from \(d\) to \(rd\) features, applies a nonlinearity, then contracts it back to \(d\), where \(r\) is the expansion ratio, typically four in the configuration we examine:

\[ \operatorname{MLP}(Z)=\operatorname{GELU}(ZW_1+b_1)W_2+b_2, \qquad W_1\in\mathbb{R}^{d\times rd},\quad W_2\in\mathbb{R}^{rd\times d}. \]

GELU, the Gaussian error linear unit, is a smooth element-wise activation \(\operatorname{GELU}(z)=z\Phi(z)\), where \(\Phi\) is the standard normal cumulative distribution function; the original transformer used ReLU, and GELU is the choice in the ViT-style block examined here. The same MLP weights process every token, and the MLP never reads another token’s row — which is the division the block is built around.

Which side of the sublayer the normalisation sits on changes optimisation. Xiong et al. analysed the large gradients near the output at initialisation in post-norm transformers, and linked them to the usefulness of learning-rate warm-up, which starts with smaller updates [9]. Their pre-norm analysis had better-behaved initial gradients, and their experiments trained comparable models without warm-up. That evidence motivates the pre-norm choice here. Whether warm-up is needed still depends on the model and the training setup.

8.7.4 From blocks to models

Because input and output are both \(N\times d\), blocks stack, each with its own learned parameters. Position codes distinguish where content entered, attention combines content across permitted positions, the MLP transforms each row, and the residual paths carry the previous representation around both updates. A pre-norm stack commonly applies a final layer norm after its last block as well. Dropout, which randomly suppresses selected activations during training, can be included in the branches; the diagram omits it to keep the data paths visible.

The arrangement of blocks and masks determines how the model is used:

Arrangement Information available to a token Typical output
Encoder-only All unpadded input tokens through self-attention Contextual input representations for a prediction head
Decoder-only Its own and preceding input positions through causal self-attention A distribution for the next token
Encoder–decoder Encoder inputs through unmasked self-attention; preceding target context through causal self-attention; encoder outputs through cross-attention An output sequence conditioned on a separate input

In the last arrangement a decoder block gains an additional cross-attention sublayer, with queries from the decoder and keys and values from the encoder. This is how captioning connects image representations to a text decoder. The same causal-mask rules govern training and generation.

The block accepts vectors without asking whether they came from words or image regions, and those vectors are constructed from image patches in Chapter 9. First, trace the whole block in Figure 8.14: predict which selected operations can change a token using another token’s content, and check the shapes entering each residual addition.

Figure 8.14: A pre-norm transformer block at ViT-B/16’s sizes takes 197 tokens of width 768 through layer normalisation, twelve-head self-attention, an MLP four times as wide and two residual additions. The data view gives the shape at each step; the cost view divides one forward pass between per-token work and the comparisons between tokens. Which operations let one token’s output depend on another token’s content?

8.8 Computation and memory

8.8.1 More tokens, more work

Doubling the token count \(N\) in the Explore the cost view of Figure 8.14, with width \(d\) and expansion ratio \(r\) held fixed, moves the two kinds of term differently. The query, key, value and output projections, and both MLP linear layers, perform their work once per token, so their operation counts double. The score product \(QK^\top\) and the weighted-value product \(AV\) involve pairs of positions, so their counts quadruple. These are forward-pass arithmetic counts, not measured training times.

The number of learned parameters stays the same when the input contains more tokens. Each token reuses the same projections and MLP, while attention compares more pairs of positions. Quadratic growth matters increasingly as sequences become longer, but it does not mean that the attention products dominate every configuration. Arithmetic counts also differ from measured runtime: implementations and hardware affect how quickly the operations run.

8.8.2 What training keeps in memory

Memory during training is harder to predict than either count. It includes the parameters, their gradients, the optimiser’s state, the activations saved for backpropagation, input tensors and temporary workspace, and an allocator also reserves blocks that may not all contain live tensors. Allocated memory counts storage currently used by tensors, while reserved memory includes space held by the allocator for reuse; the peak of each is measured over a run, and the two peaks need not occur at the same instant. The implementation matters as well: a straightforward attention implementation can store an \(N\times N\) weight matrix per head, whereas implementations that avoid materialising the full matrix can have different memory use despite computing the same attention operation.

8.8.3 Mixed precision and gradient accumulation

Mixed precision uses different numerical formats within one computation. Selected operations and saved intermediates can use a lower-precision format while parameters and optimiser state remain in a higher-precision format. This can reduce memory use, but does not imply that the whole training footprint halves. The measured example in Chapter 9 shows which parts change.

A micro-batch is the set of examples processed in one forward and backward pass. Gradient accumulation adds gradients from several micro-batches before making one optimiser update. With equally sized micro-batches and losses scaled to average across them, the effective batch is the micro-batch size times the number of accumulation steps. Four passes of 32 examples therefore supply an effective batch of 128, while the saved activations need only cover one pass at a time. The gradients persist between passes; the earlier computation graphs need not.

Mixed precision changes the numerical formats used within a pass. Accumulation changes how many passes contribute to an update. They can be used together, and neither removes the need to measure memory for the actual training configuration.

The transformer block is now complete: position information distinguishes locations, attention mixes information across permitted tokens, and the MLP transforms each token’s features. In Chapter 9, image patches supply those tokens. That chapter also contains the detailed ViT cost calculations, recorded GPU measurements and memory-budget widget beside its fine-tuning practical.

Exercises

  1. What changes when the context changes? Compare the copying encoder–decoder from Chapter 7 with one that uses attention. What information can the decoder access at each output step? Each context vector still has a fixed width: explain why the input no longer has to be represented only by the encoder’s final state.
  2. Score, normalise and combine. A query assigns equal scores to three source positions whose value vectors are \((1,0)\), \((0,2)\) and \((2,1)\). Compute the attention weights and output vector. Now use weights \((0.6,0.3,0.1)\) and compute the new output. What information do the weights describe, and why need the output match none of the individual values?
  3. Following the shapes. Two queries attend to three source vectors. Queries and keys have width four; values have width two. Give the shapes of \(Q\), \(K\), \(V\), \(QK^\top\), \(A\) and \(AV\). Along which axis is softmax applied? Explain why there must be one value per key, but not necessarily one key per query.
  4. Which information is available? Draw the allowed attention entries for four positions under unmasked self-attention and under causal self-attention. With inputs <sos> 4 2 7 and targets 4 2 7 <eos>, explain why a position may attend to its own input without seeing its answer. Why can these training positions be processed together while generation proceeds one token at a time? How does a padding mask serve a different purpose?
  5. Content and position. Consider unmasked self-attention with no position information. If the input tokens are reordered, what happens to their corresponding outputs? Explain how adding position vectors changes the experiment when content moves but the position vectors stay attached to their locations. Does a sinusoidal code being defined beyond the training range guarantee good predictions there?
  6. Building a block. Sketch a pre-norm transformer block with both residual paths. Mark which operations combine information from different tokens and which process each token separately. Why must the attention output projection and the MLP return the original feature width? Explain what several heads add beyond a single weighted mixture.
  7. More tokens or a larger batch? With feature width fixed, predict what doubles and what quadruples when token count doubles: projection work, attention score entries, MLP work and parameter count. Then explain how accumulating gradients over four micro-batches changes the effective batch and the activations that must be kept at once. How does mixed precision address a different part of the memory problem?
  8. Testing the new route to the input. Design a comparison between a fixed-context digit reader and an attention-based reader. State what you would keep the same, how you would test lengths seen and unseen during training, and what exact-string accuracy and character error rate would each reveal. If an attention map concentrates on a digit, what does that show about the computation, and what further evidence would you need to claim that region caused the prediction?

Lab 8

Lab 8: adding attention to the Lab 7 digit reader. A bidirectional GRU keeps a state for every column of the strip; a fixed-context reader and an attention reader share it, and are compared by exact-string accuracy and character error rate within and beyond the training lengths, with the attention maps of correct readings and failures.

Open in Colab

Further reading

  • Bahdanau et al. [1] — learning to align and combine encoder states for translation.
  • Xu et al. [3] — generating captions with attention over spatial image features.
  • Vaswani et al. [7] — the transformer’s attention, positional encoding and encoder–decoder blocks.
  • Li et al. [4] — the vision–language model used for the recorded caption-attention example.
  • Rush [10] — an annotated PyTorch implementation of the transformer, with layer normalisation before each sublayer as in this chapter’s block, and the paper’s text alongside the code.