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


7. Practice problems


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

  1. 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.
  2. 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

  1. [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

  2. [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

  3. [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