AI Grimoire
Sheet
statusstandard
difficultyintermediate
timeO(n²·d)
memoryO(h·n²)
described2017
revisedyesterday

Multi-Head Attention

Not one attention operation over d dimensions but h of them over d/h, run in parallel and summed. The parameter count is unchanged; what changes is how many things the layer can attend to at once.

Standing

Current standardPart of the default recipe. Present in most frontier models trained today, and the thing a new design departs from rather than argues for.

Universal. The open question is the number of heads and how their keys and values are shared, not whether to split them.

judged as of 2026-09 · what the labels mean

Theory

A single attention operation produces one weighted average per query. Whatever the model wants from a position — the subject of the sentence, the matching bracket, the last occurrence of this token — it must be extracted by one softmax over one similarity function. Multi-head attention runs hh of them over disjoint dh=d/hd_h = d/h-dimensional subspaces and adds the results.

MHA(X)=i=1hAttention ⁣(XWiQ,  XWiK,  XWiV)WiO\mathrm{MHA}(X) = \sum_{i=1}^{h} \mathrm{Attention}\!\left( X W^Q_i,\; X W^K_i,\; X W^V_i \right) W^O_i
eq. 1 — h independent reads, one writeVaswani et al. §3.2.2

Written as a sum rather than a concatenation, the structure is easier to read. Each head has its own read matrices WiQ,WiK,WiVRd×dhW^Q_i, W^K_i, W^V_i \in \R^{d \times d_h} and its own write matrix WiORdh×dW^O_i \in \R^{d_h \times d}, and it contributes to the residual stream independently of the others. Heads do not interact within a layer; they only ever meet by adding into the same stream.

The parameter count does not change

With dh=d/hd_h = d/h, the four projections total 4d24 d^2 regardless of hh. Splitting into more heads is free in parameters and nearly free in FLOPs — it buys parallel reads rather than capacity.

h(3ddh+dhd)=4d2for any h dividing dh \cdot \bigl( 3 \, d \, d_h + d_h \, d \bigr) = 4 d^2 \quad\text{for any } h \text{ dividing } d
eq. 2 — per-layer projection parameters

What does change is the attention matrices: hh of them, each n×nn \times n. That term is why context length is expensive, and why it is the first thing FlashAttention refuses to materialise.

What a head is for

The circuits literature treats each head as a pair of low-rank operators: a QKQK matrix deciding where to read, and an OVOV matrix deciding what to write. The two are independent, which is why a head can be described by where it attends without reference to what it copies — and why induction heads can be identified by their attention pattern alone.

Pruning studies find heads are not equally load-bearing: many can be removed at test time with almost no loss, while a few are individually critical. The redundancy appears to be useful during training and largely surplus afterwards.

Implementation

python · torch ≥ 2.1
import torch
from torch import Tensor, nn


class MultiHeadAttention(nn.Module):
    def __init__(self, d_model: int, n_heads: int) -> None:
        super().__init__()
        assert d_model % n_heads == 0
        self.h = n_heads
        self.d_head = d_model // n_heads
        self.qkv = nn.Linear(d_model, 3 * d_model, bias=False)
        self.proj = nn.Linear(d_model, d_model, bias=False)

    def forward(self, x: Tensor, causal: bool = True) -> Tensor:
        b, n, _ = x.shape
        # One matmul for all three projections, then split heads out.
        q, k, v = self.qkv(x).chunk(3, dim=-1)
        q, k, v = (
            t.view(b, n, self.h, self.d_head).transpose(1, 2) for t in (q, k, v)
        )

        out = torch.nn.functional.scaled_dot_product_attention(
            q, k, v, is_causal=causal
        )
        # Concatenate the heads back into the model dimension.
        out = out.transpose(1, 2).reshape(b, n, self.h * self.d_head)
        return self.proj(out)

Fusing WQ,WK,WVW^Q, W^K, W^V into one Linear is worth doing: it turns three small matmuls into one large one, which matters more than it looks at batch sizes where the GEMMs are launch-bound. The transpose(1, 2) before and after is the only real cost of the head decomposition, and it is a view plus a contiguous copy, not arithmetic.

Params / layer
67 M
Same at h = 1
67 M
Attn matrices
1.0 GB
d = 4096, h = 32, n = 4096, fp16

Related

References

[1]Vaswani et al. — Attention Is All You Need (2017)arXiv:1706.03762
[2]Elhage et al. — A Mathematical Framework for Transformer Circuits (2021)transformer-circuits
[3]Michel et al. — Are Sixteen Heads Really Better than One? (2019)arXiv:1905.10650