Learn: Multi-Head Attention & the Transformer Block
What you're learning
How to go from one scaled dot-product attention (lesson 01-scaled-dot-product-attention) to the full transformer layer that LLMs actually stack. By the end you should be able to: explain why splitting attention into heads buys you more than one big head; write the full MHA formula and count its parameters; assemble the block (MHA → residual → LayerNorm, then FFN → residual → LN) and say why pre-LN beat post-LN for deep stacks; and derive the per-layer FLOPs/params that feed the training-compute rule.
This lesson builds directly on 01-scaled-dot-product-attention — if the mechanism and the cost of one head aren’t automatic, reread it first.
1. Learning map
graph TD A["Scaled dot-product attention<br/>(lesson 01): one head"] --> B["Why more than one head?<br/>representation subspaces"] B --> C["Multi-head attention<br/>split d into h heads, concat, W^O"] C --> D["Sublayer wrapper<br/>residual + LayerNorm"] D --> E["FFN / MLP sublayer<br/>2 linears + GELU, d_ff = 4d"] D --> F["Pre-LN vs Post-LN<br/>(Xiong et al. 2020)"] C --> G["Transformer block<br/>attention sublayer + MLP sublayer"] E --> G F --> G G --> H["Params ~12d² / layer<br/>FLOPs ~24bsd² + 4bs²d"] H --> I["C ≈ 6ND training rule<br/>(cross-link roofline)"] style C fill:#44a,color:#fff style G fill:#4a4,color:#fff style H fill:#a83,color:#fff style I fill:#a44,color:#fff
2. Intuition — why many heads beat one big head
A single attention head produces one set of attention weights per query: one softmax distribution over the keys. That means one relationship, computed in one projected subspace. But language (and vision, and code) has many relationships holding simultaneously between the same two tokens: a verb agrees with its subject (syntax), a pronoun binds to its antecedent (coreference), a token attends to its immediate left neighbor (local/positional), a closing bracket looks back to its opener (structure). Forcing all of that through one softmax makes the head average these patterns together — and an average of a “look at the subject” distribution and a “look at the previous token” distribution is a blurry distribution that does neither well.1
Multi-head attention’s move is embarrassingly simple: run independent scaled dot-product attentions in parallel, each in its own low-dimensional projected subspace, then concatenate their outputs and mix them with a learned projection. Each head gets its own , so each is free to specialize: one head can learn the projection that makes “attend to the syntactic head” easy, another the projection for “attend to the previous token.” Empirically, trained heads do fall into interpretable families — positional/previous-token heads, syntactic heads, rare-token and coreference heads — though the specialization is soft and heads are partly redundant.1
Key insight — heads are cheap because they're narrow
The heads don’t cost extra: we take the same and split it into slices of width . So heads of dim cost (almost) exactly the same parameters and FLOPs as one head of dim — you get parallel, specialized views of the sequence essentially for free. Multi-head is a reshape, not an enlargement.
Common misconception — "more heads = more capacity"
Adding heads while holding fixed does not add parameters or FLOPs; it repartitions the same budget into more, narrower subspaces. Push too high and each becomes so small the per-head softmax loses expressiveness (too few dimensions to separate keys). There’s a sweet spot; typical LLMs use or . (This is also exactly the tension GQA/MQA later exploit — sharing K/V across heads to shrink the KV-cache. Out of scope here.)
3. Math — multi-head attention and the block
3.1 Multi-head attention
Let the input be ( = sequence length, ). Choose heads, each of dimension . For head , project into the head’s subspace with learned matrices :
Each head runs the same scaled dot-product attention from lesson 01, but at the reduced dimension (note the scaling uses , not ):
Concatenate the head outputs back to width and apply the output projection :
In practice the per-head projections are packed into single matrices (one big GEMM each), the result reshaped to , attention done batched over the head axis, then reshaped back — but the math above is what that computes.
What is for
Concatenation just stacks the heads side by side; nothing has mixed information across heads yet. is the learned mixer that lets the layer combine “what head 3 found” with “what head 7 found” into each output coordinate. Dropping (or making it block-diagonal) would leave the heads siloed. It also maps the concatenated -vector back into the residual stream’s basis.
3.2 The FFN / MLP sublayer
After attention mixes information across positions, the position-wise feed-forward network mixes it across features, independently at each position. Two linear layers with a nonlinearity, expanding to an inner width (canonically ):1
The original transformer used ReLU for ; modern LLMs use GELU2 (a smooth, probabilistically-motivated gate, with the standard-normal CDF) or gated variants (SwiGLU). The FFN holds most of a transformer’s parameters — of the per layer (see §5).
3.3 Wrapping each sublayer: residual + LayerNorm
Each of the two sublayers (MHA, FFN) is wrapped in a residual connection and layer normalization. Where the LN goes defines the two conventions:
Post-LN (original Transformer1) — normalize after adding the residual:
Pre-LN (now standard in deep LLMs3) — normalize the input to the sublayer, add the raw residual:
The full block is these two wrapped sublayers in sequence: attention first, then FFN.
Why pre-LN won for deep stacks
Xiong et al. (2020) showed that in post-LN, the expected gradient magnitude at initialization grows with depth, so training deep transformers requires a learning-rate warmup stage to avoid blowing up early — and it’s still delicate. In pre-LN, the LayerNorm sits inside the residual branch, so the residual path is a clean identity: gradients flow straight through the sum without being renormalized at every layer. This bounds the gradient scale, makes deep stacks train stably, and largely removes the need for warmup and heavy LR tuning.3 For the 100+-layer stacks in frontier models, that stability is decisive — which is why pre-LN (usually with RMSNorm) is the default. The tradeoff: pre-LN can leave the residual stream’s variance growing with depth, so a final LN before the output head is standard.
Don't confuse the two orderings
Pre-LN vs post-LN is not cosmetic — a deep post-LN model trained without warmup often diverges, while the same architecture in pre-LN trains fine. When reproducing an old paper, check which it used; swapping the ordering silently changes the optimization landscape.
4. Illustration — the transformer block
The diagram shows one pre-LN block: the two sublayers, each with its LayerNorm on the input branch and a residual add. Data flows top to bottom; the straight-down arrows are the residual highways.
graph TD X["Input x (s × d)"] --> LN1["LayerNorm"] LN1 --> MHA["Multi-Head Attention<br/>h heads, d_h = d/h<br/>Q,K,V,O projections"] X -->|residual| ADD1(("+")) MHA --> ADD1 ADD1 --> LN2["LayerNorm"] LN2 --> FFN["FFN / MLP<br/>d → d_ff=4d → d<br/>GELU"] ADD1 -->|residual| ADD2(("+")) FFN --> ADD2 ADD2 --> OUT["Output (s × d)"] style MHA fill:#44a,color:#fff style FFN fill:#4a4,color:#fff style ADD1 fill:#a83,color:#fff style ADD2 fill:#a83,color:#fff
Figure 1 — One pre-LN transformer block. The attention sublayer mixes information across positions; the FFN sublayer mixes across features per position. Each sublayer normalizes its input and adds a raw residual, so the vertical path (the residual stream) is an unobstructed identity from input to output. Post-LN would instead place each LayerNorm after its residual add, on the trunk.
5. FLOPs & params per layer
Let = batch, = sequence length, , and . Use the convention that a GEMM multiplying costs FLOPs (the 2 = one multiply + one add). Interactive: Attention FLOPs & KV-cache calculator.
5.1 Attention sublayer
Q, K, V, O projections. Each is a GEMM = FLOPs. Four of them (three input projections + ):
(The "" in the brief counts multiply-adds; for FLOPs gives .) Note this is independent of — splitting into heads just reshapes these same matrices.
Attention scores + values ( and ). Summed over all heads, the head axis collapses (), so:
This is the term — it dominates once , and it’s the term FlashAttention (see 06-memory-wall-and-flashattention) makes memory-cheap without changing its FLOP count.
5.2 FFN sublayer
Two GEMMs, and :
5.3 Totals and the rule
Parameters per layer (weights, ignoring biases/LN):
Now connect to scaling. For the whole model, non-embedding params . Per token, the forward pass does FLOPs (the "" term divided by tokens is per token per layer — matching across the stack, when the term is subdominant). Backprop costs the forward, so training costs forward:
This is the workhorse estimate behind compute budgeting and scaling laws — derived straight from the per-layer count above. It ignores the attention term, which is a good approximation only while ; at long context the term is not negligible and undercounts. See the roofline/perf-modeling treatment in 03-performance-modeling-roofline for when that matters.
The two regimes in one glance
Per layer, the terms () scale linearly in ; the attention-matrix term () scales quadratically. Their crossover is around : below it the projections+FFN dominate (model is “compute-in-the-weights”); above it attention’s takes over. That crossover is exactly why long-context work obsesses over the attention term.
6. Retrieval practice
Quiz 1: Splitting into heads of width — does this increase the parameter count and FLOPs of the projections versus a single head of width ? Why or why not?
Answer
No (to first order). The per-head projections stacked over heads form matrices of total size — identical to a single full-width projection. So Q/K/V/O together are still params and FLOPs regardless of . Multi-head is a reshape of the same budget into narrower, independent subspaces, not an enlargement. What changes is expressiveness/inductive bias (parallel specialized attention patterns), not cost. (The / FLOPs are also -independent since .)
Quiz 2: In pre-LN, where exactly does the LayerNorm sit relative to the residual add, and why does that make deep transformers trainable without warmup?
Answer
Pre-LN normalizes the input to the sublayer, inside the residual branch: . The residual trunk is therefore a clean identity — gradients flow through the additive skip without being renormalized at each layer, so their magnitude stays bounded with depth. Post-LN instead normalizes the trunk after the add (), which Xiong et al. showed makes expected gradients grow with depth at init, requiring a learning-rate warmup to train stably.3 Pre-LN removes that fragility, which is why deep LLM stacks use it (typically with a final LN before the output head to control residual-stream variance growth).
Quiz 3: A transformer layer has roughly parameters. Break that down by component, and identify where most of the parameters live.
Answer
Attention: , each → . FFN: () and () → . Total (ignoring biases and LN params, which are and negligible). Most parameters (~two-thirds) live in the FFN, not attention — a fact that motivates a lot of MoE and FFN-sparsity work, since the FFN is the fattest single target.
Quiz 4: Why does the rule undercount training FLOPs at very long context, and which term is being dropped?
Answer
comes from the forward FLOPs/token (× 3 for fwd+bwd), where captures only the weight GEMMs (projections + FFN), which scale linearly in . It drops the attention-matrix term per layer, which scales quadratically in and has no weights (so it isn’t in ). While that term is negligible; once grows past it dominates the per-layer cost, so increasingly under-predicts actual FLOPs. That’s precisely the regime where efficient-attention and FlashAttention economics matter (see 06-memory-wall-and-flashattention).
7. Practice problems
Practice problem 1: Count params and FLOPs of a concrete block
Problem: A pre-LN transformer block with , (so ), . Batch , sequence , BF16. (a) Parameters in the block. (b) Forward FLOPs, split into the weight-GEMM part and the attention-matrix part. (c) Which dominates here, and at what would they be equal?
Worked solution:
(a) Params. ≈ 201 M params/layer (attention M, FFN M).
(b) FLOPs. Weight GEMMs: ≈ 0.82 TFLOP. Attention matrix: ≈ 0.069 TFLOP.
(c) Dominance. Weight term is ~12× the attention term here → projections+FFN dominate at . They’re equal when . Above ~24k tokens, attention’s term overtakes. (Matches the ” crossover” tip.)
Practice problem 2: Reason about the estimate
Problem: A model has non-embedding params and is trained on tokens at short context. (a) Estimate total training FLOPs via . (b) If instead trained mostly at with , is an over- or under-estimate, and roughly why?
Worked solution:
(a) FLOPs (84 ZettaFLOP). (For scale, ~1000 H100-days at ~1 PFLOP/s sustained.)
(b) Under-estimate. omits the attention-matrix term , which is quadratic in and grows relative to the weight GEMMs once . At (past the crossover) attention contributes a non-trivial extra fraction of per-layer FLOPs that ignores, so true compute exceeds the estimate. The correction grows with ; for careful long-context budgeting, add the (fwd+bwd) term explicitly. See 03-performance-modeling-roofline.
8. Primary source & going deeper
- Primary source (read this): Vaswani et al., “Attention Is All You Need” — arXiv:1706.03762.1 Read §3.2 (scaled dot-product + multi-head attention) and §3.3 (position-wise FFN); the block structure and , , defaults are here. Note it uses post-LN.
- Pre-LN analysis: Xiong et al., “On Layer Normalization in the Transformer Architecture” — arXiv:2002.047453 — the gradient-at-init argument for why pre-LN trains without warmup.
- GELU: Hendrycks & Gimpel, “Gaussian Error Linear Units (GELUs)” — arXiv:1606.08415.2
Ask the teacher
This is a compressed treatment. If any step is fuzzy — the mixing argument, the pre-LN gradient bound, the crossover derivation, or how MHA batches over the head axis in real code — ask for a deeper drill or a worked code walkthrough. Follow-up questions are the point.
9. What’s next
- 03-positional-information (next) — attention as defined here is permutation-equivariant: it has no notion of token order. The next lesson adds positional information (sinusoidal, learned, and RoPE/ALiBi), the missing ingredient that makes the block sequence-aware.
- 01-scaled-dot-product-attention (back) — revisit the single-head mechanism now that you’ve seen how of them compose; the scaling and softmax saturation arguments there apply per head.
Further threads: GQA/MQA & the KV-cache (sharing K/V across heads for cheaper inference), MoE FFNs (sparsifying the that dominates params), and normalization variants (RMSNorm, and where the final LN goes).
Reference topic: attention-mechanisms | Glossary: attention-glossary | Filed: 2026-09-10
References
Footnotes
-
[established] Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Łukasz Kaiser, Illia Polosukhin, “Attention Is All You Need” — arXiv:1706.03762 (NeurIPS 2017). arxiv.org/abs/1706.03762. Source of the multi-head attention formulation (§3.2), the position-wise FFN with (§3.3), the , defaults, post-LN residual wrapping, and the observation that heads attend in different representation subspaces. ↩ ↩2 ↩3 ↩4 ↩5
-
[established] Dan Hendrycks, Kevin Gimpel, “Gaussian Error Linear Units (GELUs)” — arXiv:1606.08415 (2016). arxiv.org/abs/1606.08415. Defines , the smooth activation used in the FFN of most modern transformers. ↩ ↩2
-
[established] Ruibin Xiong, Yunchang Yang, Di He, Kai Zheng, Shuxin Zheng, Chen Xing, Huishuai Zhang, Yanyan Lan, Liwei Wang, Tie-Yan Liu, “On Layer Normalization in the Transformer Architecture” — arXiv:2002.04745 (ICML 2020). arxiv.org/abs/2002.04745. Shows post-LN has depth-growing expected gradients at init (needs LR warmup), while pre-LN bounds them and trains deep stacks stably without warmup. ↩ ↩2 ↩3 ↩4