Chapter 4 · Section 4.7 · 55 min

What attention costs and what it can do

"What happens to the cost of your model when you double the context length?" is one of the most common questions in a systems interview, and the two most common answers are both wrong. "It quadruples, because attention is quadratic" ignores that most of a Transformer's compute is not attention. "It doubles, because the parameters are the same" ignores that attention's share grows with length until, at long enough contexts, it is almost everything. This section counts the costs exactly, for real model sizes, so you can give the right answer with numbers.

Then we turn from what attention costs to what it buys. We look at the attention patterns trained models actually show, build an induction head by hand (the two-head circuit behind much of in-context learning), and review what is proven about the power and the limits of attention. The section ends with a map of the ways people have made attention cheaper, each of which is a later chapter.

Counting FLOPs, one matrix product at a time

The convention throughout the book is that multiplying an m×km\times k matrix by a k×nk\times n matrix costs 2mkn2mkn floating-point operations (FLOPs), one multiply and one add per term of each of the mnmn dot products. Take one multi-head attention layer of width dd, with hh heads of width dk=d/hd_k = d/h, and one sequence of TT tokens. The forward pass does six products.

stepproductFLOPs
queries(T×d)(d×d)(T\times d)(d\times d)2Td22Td^2
keys and valuestwo of (T×d)(d×d)(T\times d)(d\times d)4Td24Td^2
scores QK⊤\mathbf{Q}\mathbf{K}^\tophh of (T×dk)(dk×T)(T\times d_k)(d_k\times T)2T2hdk=2T2d2T^2 hd_k = 2T^2d
weighted values AV\mathbf{A}\mathbf{V}hh of (T×T)(T×dk)(T\times T)(T\times d_k)2T2d2T^2d
output projection(T×d)(d×d)(T\times d)(d\times d)2Td22Td^2
softmax, scale, maskelementwise on hT2hT^2 scoresa few per score, small next to the products

The total is

FLOPsattn layer=8Td2⏟projections+4T2d⏟scores and values.\text{FLOPs}_{\text{attn layer}} = \underbrace{8Td^2}_{\text{projections}} + \underbrace{4T^2d}_{\text{scores and values}} .

In plain words, the projections cost the same per token at any length, while the score and value products cost per token in proportion to the length.

The first term is linear in TT, like every other weight multiplication in the model. Only the second, the attention core, is quadratic. With a causal mask, only the T(T+1)/2T(T+1)/2 scores on and below the diagonal are needed, and kernels such as FlashAttention skip the masked blocks, so the core costs about 2T2d2T^2d. (A naive implementation computes all T2T^2 scores and throws half away.)

To see where the compute goes, divide by TT to get per-token costs and compare with the rest of a Transformer block. Every attention layer is followed by a feed-forward network applied to each token separately, which §5.3 builds. In its classic form it is two matrices, d×4dd\times 4d and 4d×d4d\times d, costing 2×2×4d2=16d22 \times 2 \times 4d^2 = 16d^2 FLOPs per token. So per token and per layer,

8d2+16d2⏟weight products, 24d2versus4Td⏟attention core, full    or    ≈2Td⏟causal.\underbrace{8d^2 + 16d^2}_{\text{weight products, } 24d^2} \quad\text{versus}\quad \underbrace{4Td}_{\text{attention core, full}} \;\;\text{or}\;\; \underbrace{\approx 2Td}_{\text{causal}} .

The ratio of the core to everything else is 4Td/24d2=T/(6d)4Td/24d^2 = T/(6d), or T/(12d)T/(12d) with a causal mask. With a causal mask, the core is a minor cost while T≪12dT \ll 12d and the dominant one when T≫12dT \gg 12d. This is the criterion Kaplan et al. (2020) use to drop the context term from their compute estimate, which is fine when dd is larger than T/12T/12. (Their per-token count for this term, 2nlayernctxdattn2n_{\text{layer}}n_{\text{ctx}}d_{\text{attn}}, is our causal count.) For training, multiply everything by 3, since the backward pass costs about twice the forward pass (§4.3, and §5.6 for the whole model).

Now real numbers. The cell below takes three widths with the classic block, GPT-2 small (d=768d = 768), a width of 4,096, and GPT-3 175B (d=12,288d = 12{,}288), and counts causal attention at several context lengths.

Python · cell 1

At GPT-2's context of 1,024 tokens the attention core is about a tenth of the compute. At width 4,096 it is about 14% at 8,192 tokens and 73% at 128K, with the crossover at 12d=49,15212d = 49{,}152 tokens. GPT-3 at its training context of 2,048 spent about 1% there. So the honest answer to "what happens when you double the context?" depends on where you start. Well below the crossover, cost per token barely changes and total cost roughly doubles. Well above it, cost per token doubles too, and total cost roughly quadruples. Real models change the weight term a little. Llama 3 8B (d=4096d = 4096) shares its keys and values across heads and uses a wider, gated feed-forward network, which moves its crossover to about 53,000 tokens and puts about 71% of its forward FLOPs in the core at 128K. §5.6 counts whole models, unembedding and backward pass included.

Where does the compute go, and when does attention take over?
Forward FLOPs per token and per layer, split into the projections, the feed-forward network, and the attention core (scores and weighted values), for real model shapes.
Loading interactive figure…
Interview

Count the FLOPs of an attention layer

Implement attention_flops(T, d, h, causal=False) returning a dictionary with the forward-pass FLOPs of one multi-head attention layer on one sequence, under the 2mkn2mkn convention, with keys "q", "kv" (keys and values together), "scores", "values", "out", and "total". Head width is dk=d/hd_k = d/h. With causal=True, count only the T(T+1)/2T(T+1)/2 score entries per head that are not masked, for both the scores and the weighted values. Ignore the softmax.

Hidden tests, hints, and AI help, from $1.99 a month.

Memory, the cost that bites first

FLOPs tell you how long a job takes on a perfect machine. Memory tells you whether it runs at all, and for attention, memory is usually the first wall you hit. Three quantities matter.

The score matrices. A naive implementation materializes S\mathbf{S} and A\mathbf{A}, which are hT2hT^2 numbers per layer and per sequence, and keeps A\mathbf{A} for the backward pass (§4.3). Take a model with 32 layers of 32 heads, the shape of Llama 3 8B. At T=8,192T = 8{,}192 in bfloat16 (2 bytes), one layer's attention weights take 32×81922×232 \times 8192^2 \times 2 bytes =4= 4 GiB, and all 32 layers take 128 GiB, for a single sequence, more than any single GPU holds. At 128K tokens one layer would need a full TiB. Korthikanti et al. (2022) count the activation memory of a whole layer as about sbh(34+5as/h)sbh(34 + 5as/h) bytes (sequence length ss, batch bb, width hh, aa heads, in their notation), and the 5as/h5as/h term is exactly the score-sized tensors (the softmax output, 2 bytes per entry, plus the dropout mask and the dropped-out weights, 1 and 2 bytes). At long contexts it dwarfs everything else.

Everything else is linear. The other activations of a layer (inputs, Q\mathbf{Q}, K\mathbf{K}, V\mathbf{V}, outputs) are O(Td)O(Td), so they grow linearly with length.

The cache at inference. Generating text one token at a time keeps every past key and value, so that each new token does not recompute them. That is 2Ld2Ld numbers per token for LL layers of ordinary multi-head attention, a cache that grows linearly with the context and, for long conversations, can outgrow the weights. §6.5 builds it and counts it for real models, and §12.5 shows how sharing keys and values across heads shrinks it (to 128 KiB per token for Llama 3 8B in bfloat16).

The first of these is a problem of the algorithm, not of attention. FlashAttention computes exactly the same output without ever storing S\mathbf{S} or A\mathbf{A}, keeping only O(T)O(T) statistics per head, by working in tiles and using the online softmax (§12.3). Its FLOPs are the same as the naive algorithm's (slightly more, because of recomputation in the backward pass), yet it is much faster. The reason is that the naive algorithm is limited by memory traffic, not arithmetic. Writing and rereading hT2hT^2 numbers from GPU memory takes longer than the matrix products that produce them (§12.1, and the roofline model of §11.2).

Python · cell 2

The quadratic column is why nobody trains long-context models with naive attention, and the linear one is what FlashAttention keeps instead.

What trained heads look like

So much for cost. What does the model get for it? Looking at the attention weights of trained models reveals a small zoo of recurring patterns. These are empirical findings, seen across many models, and the widget below draws each one on a short sequence that repeats itself.

  • Previous-token heads put nearly all weight on position t−1t-1, a bright line just below the diagonal. You built one in Exercise 4.2b.
  • Positional and local heads attend to a fixed offset or a small window, like a learned convolution.
  • Sink heads put most of their weight on the first token, the "attend to nothing" behavior of §4.4. Xiao et al. (2023) found this in most layers of the language models they studied.
  • Broad heads spread their weight evenly over the past, computing something like a running average.
  • Duplicate-token heads attend to earlier occurrences of the current token.
  • Induction heads attend to the token after an earlier occurrence of the current token, which shows up as a stripe parallel to the diagonal once text starts repeating.
What attention patterns do trained heads show?
Six patterns that recur across trained language models, each produced by a causal head on a sequence that repeats. Click a row label to inspect one query.
Loading interactive figure…

Induction heads, built by hand

The last pattern deserves a closer look, because it implements an algorithm. Suppose the text so far contains "... Harry Potter ... Harry" and the model must guess the next token. A good guess is "Potter", because when a sequence repeats, the token that followed last time is likely to follow again. Formally, the rule is if the current token is A, find an earlier position where A appeared, and predict the token that came right after it, written [A][B]…[A]→[B][A][B] \dots [A] \to [B]. Olsson et al. (2022) called heads that implement this induction heads, and gave several lines of evidence that they are a major mechanism of in-context learning in Transformers. They form during a sudden change early in training, visible as a bump in the loss curve, and the model's ability to use earlier context improves sharply at the same moment.

No single attention head can do this. To attend to "the token after A", the head would need the key at that position to say "the token before me was A", and a token's own vector does not contain its predecessor. The trick is two heads in two layers. Elhage et al. (2021) describe it precisely.

  1. In layer 1, a previous-token head copies each token's identity into the next position. After it runs, position jj carries both "I am wjw_j" and "the token before me was wj−1w_{j-1}".
  2. In layer 2, the induction head uses the current token as its query ("I am A, who came after an A?") and reads the "previous token" information as its keys. The score qt⊤kj\mathbf{q}_t^\top\mathbf{k}_j is high exactly when wj−1=wtw_{j-1} = w_t. Its value copies the token identity wjw_j, which is the prediction.

The second head's keys are built from the output of the first head. Elhage et al. call this K-composition, and it is the simplest example of heads cooperating to compute something neither can compute alone. We can build the whole circuit with explicit weights. The residual stream is the concatenation of three blocks of coordinates, a one-hot token id, a one-hot position, and a slot where layer 1 writes the previous token's id. Each head reads from some blocks and writes to others, which is how real models use the residual stream too (§5.1).

Research

Build an induction head

The setup provides a two-layer, attention-only model whose residual stream has width d=2V+Td = 2V + T, laid out as [token one-hot (V) | position one-hot (T) | previous-token slot (V)], with the slices TOK, POS, PREV returned by layout(V, T). Layer 1 is a working previous-token head that writes wj−1w_{j-1} into the PREV slot of position jj. Write induction_weights(V, T, c=20.0) returning (W_Q, W_K, W_V), each of shape (d, V), for the layer-2 head, whose output (shape (T, V)) is read directly as next-token logits. The model is causal and its scores are not scaled. On sequences made of a BOS token followed by a random block of distinct tokens repeated twice, your head must predict the second copy almost perfectly.

Hidden tests, hints, and AI help, from $1.99 a month.

Here is the complete circuit running, with accuracy measured position by position on 200 random repeated sequences.

Python · cell 3

A few notes on what this toy does and does not show. Real induction heads use rotary or learned positions rather than one-hot ones, live in models that also have MLPs, and work in superposition with many other features, so they are messier than ours. But the mechanism is the same, and it explains something important. Nothing in the weights stores "Harry Potter". The circuit copies whatever followed the previous occurrence, so it generalizes to sequences it has never seen, which is the essence of in-context learning. Finding such circuits in trained models, by patching activations and tracing which heads feed which, is the program of mechanistic interpretability.

What attention can and cannot compute

Here is what has been proven, stated carefully, because these results are often quoted loosely.

Attention can approximate anything, given room. Yun et al. (2020) proved that Transformers with positional encodings are universal approximators of continuous sequence-to-sequence functions on a compact domain, and that without positional encodings they can approximate any continuous permutation-equivariant function, but nothing else (the symmetry of §4.6). Like every universal approximation theorem, this says nothing about how large the model must be or whether training finds it.

With unbounded precision and unbounded steps, even Turing completeness. Pérez et al. (2021) showed that a Transformer with hard attention, arbitrary-precision numbers, and as many decoding steps as needed can simulate a Turing machine. The assumptions are far from practice, but the result frames the next one.

In one forward pass, with realistic precision, attention is shallow. Merrill and Sabharwal (2023) proved that Transformers whose numbers have precision logarithmic in the input length can be simulated by uniform TC0\mathsf{TC}^0 circuits, constant-depth circuits with threshold gates. If, as most complexity theorists believe, TC0≠NC1\mathsf{TC}^0 \ne \mathsf{NC}^1, then such a Transformer cannot solve NC1\mathsf{NC}^1-complete problems for arbitrary lengths in a single forward pass. Evaluating Boolean formulas, and tracking the state of certain finite automata over a long input (for example, composing a long sequence of permutations of five objects), are examples. The intuition is that a fixed number of layers gives a fixed number of sequential steps, however wide each step is.

Chain of thought adds serial steps. Merrill and Sabharwal (2024) showed that letting a decoder generate intermediate tokens before answering increases its power, by an amount that depends on how many it may generate. A linear number of steps lets it recognize every regular language, and a polynomial number lets it solve exactly the problems solvable in polynomial time. This is one theoretical reason why thinking out loud helps models reason (§18.1).

Single-token sensitivity is a real limitation. Hahn (2020) showed that, if the scores stay bounded, changing one input token changes a soft-attention layer's output by only O(1/T)O(1/T), so a fixed Transformer cannot compute functions such as parity (is the number of 1s odd?) with confidence that stays bounded away from chance as inputs grow. Chiang and Cholak (2022) showed that this is a limit on confidence, not on accuracy. They built a Transformer that recognizes parity exactly, whose confidence does shrink toward chance as length grows, and then used layer normalization to restore it, bringing the cross-entropy arbitrarily close to zero. They also proposed multiplying the scores by log⁡T\log T, which helped length generalization in their experiments.

That last fix points to a practical issue, softmax dilution. Suppose one key is relevant and T−1T-1 are not, and the relevant one has a score higher by Δ\Delta. Its weight is

a⋆=eΔeΔ+T−1,so keeping a⋆=p requires Δ=log⁡p (T−1)1−p≈log⁡T.a^\star = \frac{e^{\Delta}}{e^{\Delta} + T - 1}, \qquad\text{so keeping } a^\star = p \text{ requires } \Delta = \log\frac{p\,(T-1)}{1-p} \approx \log T .

In plain words, as the context grows, a head needs ever larger score gaps to keep its focus, about one extra unit of logit for each factor of ee in context length.

A head trained at 4K tokens that runs at 128K sees its weights spread over 32 times as many competitors, which is one reason long-context extension needs care (§12.7). Several long-context methods scale scores with log⁡T\log T for exactly this reason, such as the "log-n scaling" used in Qwen (Bai et al. 2023) and the "scalable softmax" of Nakanishi (2025).

Python · cell 4
Warm-up

The score gap that keeps a head focused

Implement gap_for_weight(T, p) returning the score gap Δ\Delta that gives a single relevant key weight p among T keys whose other T - 1 scores are equal, and weight_for_gap(T, gap) returning the weight a⋆a^\star for a given gap. Both should work elementwise on NumPy arrays of T.

Hidden tests, hints, and AI help, from $1.99 a month.

Two more limits round out the picture. Dong et al. (2021) proved that a stack of pure attention layers, with no residual connections or MLPs, loses rank doubly exponentially fast with depth, so all tokens collapse toward the same vector. Residual connections and MLPs are what prevent it (§5.1). And for exact attention, quadratic time is probably unavoidable. Keles et al. (2023) proved that computing self-attention, even approximately, needs time quadratic in TT unless the Strong Exponential Time Hypothesis fails, and Alman and Song (2023) located the boundary precisely. With head width O(log⁡T)O(\log T) and every entry of Q\mathbf{Q}, K\mathbf{K}, V\mathbf{V} bounded by BB, attention can be approximated to within 1/poly(T)1/\mathrm{poly}(T) in almost linear time when B=o(log⁡T)B = o(\sqrt{\log T}), and cannot be in truly subquadratic time once BB is of order log⁡T\sqrt{\log T}, under the same hypothesis.

The roads to cheaper attention

Every limitation above has prompted a line of work. Chapter 12 covers most of it, including splitting one sequence across GPUs, and later chapters the alternatives to softmax attention. Here is the map.

approachwhat changesexact?costwhere
FlashAttentiontiling plus online softmax, never store S\mathbf{S}yessame FLOPs, O(T)O(T) memory, far less memory traffic§12.3
MQA, GQA, MLAshare or compress keys and values across headsno, a different modelsmaller KV cache, same core FLOPs§12.5
sliding window, sparse patternseach query sees a subset (a sparser graph)noO(Twd)O(Twd) for window ww§12.6
ring attention, context parallelismsplit the sequence across GPUsyessame FLOPs, memory spread over devices§12.7
linear attention, state-space modelsreplace softmax by a kernel or a recurrencenoO(Td2)O(Td^2), constant memory per steplinear-time models

The last row deserves a sentence of its own. If the softmax of q⊤k\mathbf{q}^\top\mathbf{k} is replaced by a product of feature maps ϕ(q)⊤ϕ(k)\phi(\mathbf{q})^\top\phi(\mathbf{k}), the sum ∑jϕ(kj)vj⊤\sum_j\phi(\mathbf{k}_j)\mathbf{v}_j^\top can be accumulated left to right, and causal attention becomes an RNN with a fixed-size state (Katharopoulos et al. 2020). That idea, refined into selective state-space models such as Mamba, is the main alternative to attention for very long sequences, at the price of the exact, content-addressed lookup this chapter has been building.

In PyTorch

You can measure the quadratic cost directly. The timings below come from PyTorch's CPU kernels, so the absolute numbers depend on your machine, but the trend does not.

🔥 In PyTorchfor a machine with PyTorch

Read more

Watch next

🎬 A Walkthrough of In-Context Learning and Induction Heads Part 1 of 2 (w/ Charles Frye) · Neel NandaOne of the paper's authors explains induction heads and the phase change that comes with them.
🎬 A Walkthrough of A Mathematical Framework for Transformer Circuits · Neel NandaThe QK and OV circuits and head composition, the framework behind the induction head we build in this section.
🎬 FlashAttention - Tri Dao | Stanford MLSys #67 · Stanford MLSys SeminarsThe author of FlashAttention explains why attention is limited by memory traffic, as a preview of Chapter 12.