Multi-Head Attention

Imagine reading the sentence "The trophy didn't fit in the suitcase because it was too big." To resolve "it," a model must track several things at once. It needs subject-object structure, size semantics, and clausal position. A single Scaled Dot-Product Attention computation forces one weighted average over all these signals at once. This blurs distinctions that matter for different linguistic decisions. Multi-head attention solves this by running several independent attention computations in parallel. Each has its own learned projections. This way, one head can track coreference while another tracks syntax. A third head can track local word order. This idea, introduced in the Transformer architecture, is arguably the single most consequential design choice in modern NLP. Every large language model in production stacks dozens of multi-head attention layers. This includes both encoder-only classifiers and decoder-only generators. Each layer has anywhere from 8 to 128 heads. The mechanism gives the model a way to represent multiple types of relationships between tokens. It does this without forcing them to compete inside one similarity function. Empirically, different heads specialize. Some attend to adjacent tokens, some to syntactic dependents, and some to rare long-range coreference links. Ablation studies show that pruning certain heads barely hurts performance. Pruning others collapses it entirely. The big picture is that multi-head attention is a form of representational parallelism. Instead of computing attention once in a large space, the model computes it many times in smaller subspaces. The concatenation then recombines the results. This is analogous to how convolutional networks use multiple filters. These filters detect different features at the same spatial location. Multi-head attention lets the same pair of tokens be scored by many different "lenses" simultaneously. Crucially, this parallelism is nearly free in terms of computational cost. The total dimensionality is held fixed and split across heads, rather than added on top. This article gives a precise definition of multi-head attention. It includes a step-by-step algorithm with pseudocode, and a diagram of the data flow. It also offers an honest complexity and correctness analysis. Finally, it provides a fully worked numerical trace and a discussion of the pitfalls that trip up implementers, along with the history behind the idea.

Key takeaways
  • Multi-head attention runs several scaled dot-product attention computations in parallel, each in a lower-dimensional subspace.
  • Each head has its own learned query, key, and value projection matrices, letting heads specialize in different relations.
  • Head outputs are concatenated and passed through one shared output projection to recombine information.
  • Total compute and parameter count roughly match single-head attention at the full model dimension, so multi-head is nearly free.
  • Correctness follows because concatenation-then-projection can express any linear recombination a single wide head could, plus more via independent softmaxes.
  • It underlies every modern Transformer encoder and decoder, from BERT to GPT-family models.
The core insight

Multi-head attention lets a model attend to information from multiple representation subspaces at once, instead of averaging everything through a single similarity function.

The idea

Standard Scaled Dot-Product Attention takes a query matrix QQ, key matrix KK, and value matrix VV, and computes

Attention(Q,K,V)=softmax(QK⊤dk)V.\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right) V.

This produces one weighted average of value vectors per query, using one notion of "similarity." The problem is that natural language relations are heterogeneous: subject-verb agreement, coreference, negation scope, and positional adjacency are all different kinds of relevance, and a single softmax over a single projection space must compromise between them. Multi-head attention addresses this by linearly projecting the queries, keys, and values into hh different, lower-dimensional subspaces, running scaled dot-product attention independently in each subspace (a "head"), and then concatenating the results before a final linear projection. Formally, for head ii,

headi=Attention(QWiQ,  KWiK,  VWiV),\text{head}_i = \text{Attention}(QW_i^Q,\; KW_i^K,\; VW_i^V),

and the overall output is

MultiHead(Q,K,V)=Concat(head1,…,headh) WO.\text{MultiHead}(Q,K,V) = \text{Concat}(\text{head}_1, \dots, \text{head}_h) \, W^O.

Here WiQ,WiK∈Rdmodel×dkW_i^Q, W_i^K \in \mathbb{R}^{d_{\text{model}} \times d_k}, WiV∈Rdmodel×dvW_i^V \in \mathbb{R}^{d_{\text{model}} \times d_v}, and WO∈Rhdv×dmodelW^O \in \mathbb{R}^{h d_v \times d_{\text{model}}} are learned parameters. In the standard configuration, dk=dv=dmodel/hd_k = d_v = d_{\text{model}} / h, so splitting into hh heads keeps the total number of parameters and the total computation comparable to a single attention operation over the full dmodeld_{\text{model}} dimension — the key architectural insight that makes multi-head attention essentially free relative to a single wide head. Terminology worth fixing precisely: dmodeld_{\text{model}} is the model's hidden dimension (e.g., 512 or 4096); hh is the number of heads; dkd_k is the per-head query/key dimension; dvd_v is the per-head value dimension. The queries, keys, and values themselves may come from the same sequence (self-attention) or from two different sequences (cross-attention, used in Transformer Decoder Stack to attend over encoder outputs).

How it works

The computation proceeds in five stages: linear projection, splitting into heads, per-head scaled dot-product attention, concatenation, and a final output projection.

Step 1 — Project. The input sequence, represented as a matrix X∈Rn×dmodelX \in \mathbb{R}^{n \times d_{\text{model}}} (nn tokens), is linearly transformed into Q=XWQQ = XW^Q, K=XWKK = XW^K, V=XWVV = XW^V for self-attention (or Q=XWQQ = XW^Q with K,VK, V from a different sequence for cross-attention).

Step 2 — Split. Each of Q,K,V∈Rn×dmodelQ, K, V \in \mathbb{R}^{n \times d_{\text{model}}} is reshaped/split along the feature dimension into hh chunks of size dkd_k (or dvd_v), giving hh triples (Qi,Ki,Vi)(Q_i, K_i, V_i). In practice this split is implemented as a single large projection whose output is reshaped, not as hh separate matrix multiplies, which is what keeps the implementation efficient on parallel hardware.

Step 3 — Attend per head. Each head independently computes

headi=softmax ⁣(QiKi⊤dk+M)Vi,\text{head}_i = \text{softmax}\!\left(\frac{Q_i K_i^\top}{\sqrt{d_k}} + M\right) V_i,

where MM is an optional mask (e.g., the causal mask used in decoder self-attention, or a padding mask).

Step 4 — Concatenate. The hh outputs, each in Rn×dv\mathbb{R}^{n \times d_v}, are concatenated along the feature axis to form a matrix in Rn×hdv=Rn×dmodel\mathbb{R}^{n \times h d_v} = \mathbb{R}^{n \times d_{\text{model}}}.

Step 5 — Output projection. The concatenated matrix is passed through a shared linear layer WO∈Rdmodel×dmodelW^O \in \mathbb{R}^{d_{\text{model}} \times d_{\text{model}}}, which mixes information across heads before the result is passed on (typically added to a residual connection and normalized, as part of a full Transformer Encoder Stack layer). ``` function MultiHeadAttention(X_q, X_kv, num_heads h, d_model, mask=None):

# X_q: queries source, shape (n_q, d_model)

# X_kv: keys/values source, shape (n_kv, d_model) (X_kv = X_q for self-attention) assert d_model % h == 0 d_k = d_model / h d_v = d_model / h Q_full = X_q @ W_Q # (n_q, d_model), W_Q: (d_model, d_model) K_full = X_kv @ W_K # (n_kv, d_model) V_full = X_kv @ W_V # (n_kv, d_model)

# reshape into heads: (n, d_model) -> (h, n, d_k) Q_heads = split_heads(Q_full, h, d_k) # h tensors of shape (n_q, d_k) K_heads = split_heads(K_full, h, d_k) # h tensors of shape (n_kv, d_k) V_heads = split_heads(V_full, h, d_v) # h tensors of shape (n_kv, d_v) head_outputs = empty list of length h for i in 0 .. h-1: scores_i = (Q_heads[i] @ transpose(K_heads[i])) / sqrt(d_k) # (n_q, n_kv) if mask is not None: scores_i = scores_i + mask # mask uses -infinity at disallowed positions weights_i = softmax(scores_i, axis=-1) # rows sum to 1 head_outputs[i] = weights_i @ V_heads[i] # (n_q, d_v) concat = concatenate(head_outputs, axis=-1) # (n_q, h d_v) = (n_q, d_model) output = concat @ W_O # (n_q, d_model), W_O: (d_model, d_model) return output ``` Two implementation details matter for correctness. First, the mask must be applied before* the softmax, as additive negative infinity (or a very large negative number), so that masked positions receive zero probability mass after normalization — applying it after softmax would leave residual probability on forbidden positions. Second, the split into heads must be a genuine partition of the feature dimension (each head sees a disjoint slice of dmodeld_{\text{model}} coordinates), not an overlapping or randomly resampled subset, so that the total information available across all heads equals the total information in QQ, KK, VV with no duplication or loss.

Figure
Multi-head attention data flow: one input splits into h parallel attention computations, then recombines
Multi-Head Attention Input X (n × d_model) Project: Q, K, V split into h heads Head 1 Q₁K₁ᵀ/√dₖ softmax × V₁ → head₁ Head 2 Q₂K₂ᵀ/√dₖ softmax × V₂ → head₂ ⋯ Head h QₕKₕᵀ/√dₖ softmax × Vₕ → headₕ Concat(head₁..headₕ) → output proj W_O → MultiHead(Q,K,V)

Complexity & correctness

Time complexity. For a sequence of length nn, computing the projections Q,K,VQ, K, V costs O(n dmodel2)O(n \, d_{\text{model}}^2) total (matrix multiplication of an n×dmodeln \times d_{\text{model}} matrix by a dmodel×dmodeld_{\text{model}} \times d_{\text{model}} matrix), independent of how many heads it is later split into, since the split is just a reshape. Within each head, computing QiKi⊤Q_i K_i^\top costs O(n2dk)O(n^2 d_k), and applying the result to ViV_i costs another O(n2dv)O(n^2 d_v). Summed over hh heads with dk=dv=dmodel/hd_k = d_v = d_{\text{model}}/h, this totals

h⋅O(n2⋅dmodel/h)=O(n2 dmodel),h \cdot O(n^2 \cdot d_{\text{model}}/h) = O(n^2 \, d_{\text{model}}),

exactly the same asymptotic cost as a single attention head operating at the full dimension dmodeld_{\text{model}}. The final output projection costs O(n dmodel2)O(n \, d_{\text{model}}^2). So the overall cost of multi-head attention is

O(n2 dmodel+n dmodel2),O(n^2 \, d_{\text{model}} + n \, d_{\text{model}}^2),

identical in order to single-head attention at the same total dimension. This is the precise sense in which multi-head attention is "free": splitting into more heads does not change the asymptotic compute, it only changes what each unit of compute represents.

Space complexity. The dominant memory cost is storing the attention weight matrices, one n×nn \times n matrix per head, totaling O(h⋅n2)O(h \cdot n^2) entries — though since dkd_k shrinks as hh grows, the total floating-point storage for weights is O(hn2)O(h n^2) while the values stored per head shrink, so total activation memory remains O(n2⋅h+n⋅dmodel)O(n^2 \cdot h + n \cdot d_{\text{model}}), dominated in practice by the h n2h \, n^2 term for long sequences. This is the well-known quadratic-in-sequence-length bottleneck of standard attention, unaffected by the head count in its scaling behavior with nn.

Correctness / expressive-power argument. Two claims need justification: that splitting into heads does not lose expressive power compared to one big attention computation, and that it strictly gains power by allowing independent attention patterns. No loss: set h=1h = 1, dk=dv=dmodeld_k = d_v = d_{\text{model}}, and WO=IW^O = I. This recovers exactly single-head scaled dot-product attention as a special case, so the multi-head formulation is strictly more general. Strict gain: with h>1h > 1, each head computes its own softmax distribution over the sequence, softmax(QiKi⊤/dk)\text{softmax}(Q_i K_i^\top / \sqrt{d_k}). Because softmax is a genuinely nonlinear, saturating function, the average of several different softmax distributions over value subspaces is not representable as a single softmax distribution applied uniformly across the same value space unless the per-head attention patterns happen to coincide. Concretely, consider two heads: head 1 attends almost entirely to position jj, head 2 attends almost entirely to position k≠jk \ne j. A single softmax over the concatenated key space can produce mass on both jj and kk, but it cannot simultaneously deliver head 1's exact value vector from position jj in one output subspace and head 2's exact value vector from position kk in a different, disjoint subspace, while combining both through independent weightings that a single shared softmax could not realize without conflating the two attention distributions. The output projection WOW^O then linearly recombines these otherwise-inaccessible joint patterns, so the composed function class is strictly larger than what one shared-softmax head can express at equal total dimension. This is why multi-head attention is not merely a computational convenience but a genuine increase in the hypothesis space, consistent with the empirical finding that different heads learn qualitatively different attention patterns (positional, syntactic, coreferential) that a single head cannot simultaneously represent without averaging them away.

Tradeoffs. More heads means smaller dkd_k per head, and if dkd_k becomes very small (e.g., dmodel=512d_{\text{model}} = 512, h=64h = 64 gives dk=8d_k = 8), each head's dot products become noisier and less expressive individually — there is a practical sweet spot (commonly dk∈{32,…,128}d_k \in \{32, \dots, 128\}) below which adding heads degrades quality even though it does not change the asymptotic complexity. Also, the quadratic-in-nn term dominates for long sequences regardless of hh, which is why long-context models turn to sparse or linear attention variants rather than tuning head count.

Worked example

Take a toy setup with dmodel=4d_{\text{model}} = 4, h=2h = 2, so dk=dv=2d_k = d_v = 2, and a sequence of n=3n = 3 tokens: "The cat sat." Suppose after embedding and projection (numbers simplified for hand-tracing), the per-head query, key, and value matrices are:

Head 1 (rows = tokens: The, cat, sat):

Q1=(100111),K1=(100111),V1=(100122)Q_1 = \begin{pmatrix} 1 & 0 \\ 0 & 1 \\ 1 & 1 \end{pmatrix}, \quad K_1 = \begin{pmatrix} 1 & 0 \\ 0 & 1 \\ 1 & 1 \end{pmatrix}, \quad V_1 = \begin{pmatrix} 1 & 0 \\ 0 & 1 \\ 2 & 2 \end{pmatrix}

Head 2:

Q2=(111−101),K2=(111−101),V2=(011011)Q_2 = \begin{pmatrix} 1 & 1 \\ 1 & -1 \\ 0 & 1 \end{pmatrix}, \quad K_2 = \begin{pmatrix} 1 & 1 \\ 1 & -1 \\ 0 & 1 \end{pmatrix}, \quad V_2 = \begin{pmatrix} 0 & 1 \\ 1 & 0 \\ 1 & 1 \end{pmatrix}

Step-by-step for Head 1, query "cat" (row 2, Q1=[0,1]Q_1 = [0, 1]): Scores against each key (Q1⋅K1,jQ_1 \cdot K_{1,j}):

key (token)dot productscaled by 1/2≈0.7071/\sqrt{2} \approx 0.707
The: [1,0]00
cat: [0,1]10.707
sat: [1,1]10.707

Softmax over [0,0.707,0.707][0, 0.707, 0.707]: exp⁡(0)=1\exp(0)=1, exp⁡(0.707)≈2.028\exp(0.707)\approx 2.028, so weights ≈[1/5.056, 2.028/5.056, 2.028/5.056]=[0.198,0.401,0.401]\approx [1/5.056,\, 2.028/5.056,\, 2.028/5.056] = [0.198, 0.401, 0.401]. Weighted sum of V1V_1 rows: 0.198⋅[1,0]+0.401⋅[0,1]+0.401⋅[2,2]=[0.198+0.802,  0.401+0.802]=[1.000,1.203]0.198\cdot[1,0] + 0.401\cdot[0,1] + 0.401\cdot[2,2] = [0.198 + 0.802,\; 0.401 + 0.802] = [1.000, 1.203]. So head1("cat")≈[1.00,1.20]\text{head}_1(\text{"cat"}) \approx [1.00, 1.20].

Step-by-step for Head 2, query "cat" (row 2, Q2=[1,−1]Q_2 = [1, -1]): Scores against each key (Q2⋅K2,jQ_2 \cdot K_{2,j}):

keydot productscaled by 0.707
The: [1,1]00
cat: [1,-1]21.414
sat: [0,1]-1-0.707

Softmax over [0,1.414,−0.707][0, 1.414, -0.707]: exp⁡(0)=1\exp(0)=1, exp⁡(1.414)≈4.114\exp(1.414)\approx 4.114, exp⁡(−0.707)≈0.493\exp(-0.707)\approx 0.493. Sum ≈5.607\approx 5.607. Weights ≈[0.178,0.734,0.088]\approx [0.178, 0.734, 0.088]. Weighted sum of V2V_2: 0.178⋅[0,1]+0.734⋅[1,0]+0.088⋅[1,1]=[0.734+0.088,  0.178+0.088]=[0.822,0.266]0.178\cdot[0,1] + 0.734\cdot[1,0] + 0.088\cdot[1,1] = [0.734+0.088,\; 0.178+0.088] = [0.822, 0.266]. So head2("cat")≈[0.82,0.27]\text{head}_2(\text{"cat"}) \approx [0.82, 0.27].

Concatenate and project: the two head outputs are concatenated into a 4-dimensional vector [1.00, 1.20, 0.82, 0.27][1.00,\, 1.20,\, 0.82,\, 0.27], and this passes through WO∈R4×4W^O \in \mathbb{R}^{4 \times 4} (omitted here for brevity, but any linear map) to produce the final multi-head attention output for the token "cat." Note that head 1's softmax was fairly flat (weights near 0.2, 0.4, 0.4), pooling broadly across the sentence, while head 2's softmax sharply favored "cat" itself (weight 0.734) — a concrete numerical illustration of the correctness argument above: two heads produced qualitatively different attention patterns over the same input that a single shared softmax could not have realized simultaneously.

Common pitfalls & traps

PitfallWhy it happensConsequence
Applying mask after softmaxConfusing "zero out weights" with "zero out scores"Leaks probability mass to forbidden positions (e.g., future tokens in a decoder)
Wrong reshape order when splitting headsReshaping (n,dmodel)(n, d_{\text{model}}) into (n,h,dk)(n, h, d_k) vs. (h,n,dk)(h, n, d_k) inconsistentlySilently mixes features from different heads, degrading quality without crashing
Forgetting the dk\sqrt{d_k} scaleCopying single-head attention code without adjusting for smaller per-head dimensionDot products grow with dimension, pushing softmax into saturated, low-gradient regions
Sharing WOW^O per head instead of one joint projectionMisreading the architecture as hh independent output layersPrevents information mixing across heads, reducing expressive power
Assuming more heads always helpsTreating head count as a free hyperparameter to maximizePer-head dimension dkd_k shrinks, hurting individual head quality past a point
Ignoring padding tokens in the maskTreating all sequences in a batch as equal length without masking paddingAttention distributes probability mass onto meaningless padding vectors

Pioneers & history

Multi-head attention was introduced as part of the Transformer architecture, a paper written by a group at Google Brain and Google Research seeking to eliminate recurrence entirely from sequence models. The core insight — that splitting attention into parallel subspaces costs nothing asymptotically while unlocking new expressive power — built directly on top of the additive and dot-product attention mechanisms that had already proven useful for augmenting recurrent encoder-decoder models in machine translation.

Origins · 1 minAshish Vaswani and how this was discovered
AV
Ashish Vaswani
b. 1980s (exact year not widely published) · Lead author of the 2017 Transformer paper, formerly at Google Brain, later co-founder of Adept AI

Vaswani led the team that asked whether attention alone, without any recurrent or convolutional structure, could match or exceed state-of-the-art sequence models. The resulting architecture, built around multi-head self-attention, replaced sequential recurrence with fully parallelizable matrix operations, fundamentally changing the computational profile of sequence modeling and enabling the scale-up that led to modern large language models.

History
2014
— attention mechanisms (Bahdanau-style additive attention) augment recurrent encoder-decoder translation models.
2015
— Luong-style dot-product and local attention variants simplify and speed up attention computation.
2017
— the Transformer architecture introduces scaled dot-product attention split into multiple parallel heads, discarding recurrence entirely.
2018
— BERT and GPT adopt multi-head self-attention as the core building block of large-scale pretraining.
2019
–present — head-pruning and interpretability studies (e.g., analyzing which heads track syntax, coreference, or positional patterns) show that most of a Transformer's heads can be removed with minimal loss, while a small subset carry critical linguistic structure.

Where this matters

Multi-head attention is the computational core of virtually every modern large language model, powering the self-attention layers in encoder architectures like BERT and RoBERTa, decoder-only architectures like the GPT family and LLaMA, and encoder-decoder architectures like T5 and the original machine translation Transformer. It is equally central outside pure NLP: vision Transformers apply the identical mechanism to image patches, and multimodal models use cross-attention variants of the same mechanism to align text tokens with image or audio features. Industrial inference systems optimize specifically around multi-head attention's computational pattern — techniques like key-value caching, grouped-query attention (sharing key/value projections across groups of heads to reduce memory bandwidth), and multi-query attention (a single shared key/value head across many query heads) are direct engineering responses to the cost structure analyzed above. Any system built on the Transformer Encoder Stack or Transformer Decoder Stack — chatbots, code assistants, translation services, search re-rankers — relies on multi-head attention as its fundamental building block, making it one of the highest-leverage ideas to understand deeply in modern NLP.

Ask the tutor: How does multi-head attention's cost and behavior change when combined with key-value caching during autoregressive decoding?

Why not just use one big attention head with the full d_model dimension instead of splitting into many smaller heads?

A single large head computes exactly one softmax-weighted average per query, which forces all relational signals — syntax, coreference, position, negation scope — to compete inside the same similarity function and get blended into one output. Multi-head attention instead computes several independent softmax distributions in parallel, each over a smaller subspace, so different heads can specialize in different relations without interference. The proof-sketch in the correctness section shows this is a strict gain in expressive power at essentially the same computational cost, because concatenation followed by a shared output projection can represent everything a single head can, plus genuinely new combinations that a single softmax cannot realize simultaneously.

Does increasing the number of heads always improve model quality?

No. As head count h grows with d_model fixed, the per-head dimension d_k = d_model / h shrinks, and very small d_k (e.g., single digits) makes each head's dot products noisier and less able to represent fine-grained similarity. Empirically there is a sweet spot, often d_k between 32 and 128, beyond which adding heads trades away per-head quality for diversity without net benefit. Complexity stays asymptotically constant regardless of h, but practical model quality is not monotonic in head count, which is why head count and model width are tuned jointly during architecture search rather than maximized independently.

How does multi-head attention differ in an encoder versus a decoder?

Structurally the mechanism is identical, but the mask and the source of keys/values differ. In encoder self-attention (as in the Transformer Encoder Stack), every token attends to every other token bidirectionally, with no causal mask, since the whole input is available at once. In decoder self-attention (as in the Transformer Decoder Stack), a causal mask blocks each position from attending to future positions, preserving the autoregressive generation order. Decoders additionally use cross-attention, where queries come from the decoder's own hidden states but keys and values come from the encoder's output, letting the decoder condition its generation on the full source sequence.

What does it mean empirically that different heads "specialize," and how do we know this?

Interpretability studies visualize each head's attention weight matrix and find that some heads consistently attend to the immediately preceding or following token (positional heads), some attend to syntactically related words like a verb's subject (syntactic heads), and some attend to distant coreferent mentions (semantic heads). Head-pruning experiments confirm this functionally: removing certain heads barely changes downstream task performance, while removing a small subset of "critical" heads causes sharp performance drops, indicating that the useful information is unevenly distributed across heads rather than redundantly duplicated in all of them.

What is the relationship between multi-head attention and techniques like multi-query or grouped-query attention?

Multi-query attention and grouped-query attention are memory-bandwidth optimizations built directly on top of multi-head attention's structure. In standard multi-head attention, every head has its own key and value projections, meaning the key-value cache used during autoregressive generation grows linearly with the number of heads. Multi-query attention shares a single key/value projection across all query heads, and grouped-query attention shares them across small groups of heads, both trading a small amount of representational diversity for substantially reduced memory traffic during inference, which matters enormously at deployment scale.

Is the output projection W^O necessary, or could the concatenated heads be used directly as the layer output?

W^O is necessary for full expressive power because without it, each head's output subspace would remain isolated in its own coordinate block of the final vector, and subsequent layers would have to work with a partitioned representation rather than a fully mixed one. The shared linear projection lets information from every head interact — for instance, combining a positional signal from one head with a semantic signal from another into a single new feature — which is essential for the residual stream in a Transformer layer to carry a coherently mixed representation forward.

Does multi-head attention solve the quadratic sequence-length cost of attention?

No — multi-head attention changes what is computed within a fixed total cost, but it does not change the fundamental O(n2)O(n^2) scaling in sequence length nn that comes from computing pairwise scores between all query and key positions. This quadratic bottleneck is why long-context applications turn to entirely different techniques, such as sparse attention patterns, linear attention approximations, or retrieval-based methods, rather than adjusting the head count, which only affects the constant factor and per-head quality, not the asymptotic growth rate in nn.

Before this

Where this leads