Multi-Head Attention

2 min read

Multi-head attention runs Self-Attention multiple times in parallel, each head learning different relationships.

MultiHead(Q,K,V)=Concat(head1,,headh)WO\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \dots, \text{head}_h)W_O headi=Attention(QWQi,KWKi,VWVi)\text{head}_i = \text{Attention}(QW_Q^i, KW_K^i, VW_V^i)

Key design:

  • Total dimension dmodeld_\text{model} split across hh heads: each head has dimension dk=dmodel/hd_k = d_\text{model}/h
  • Typical: dmodel=512d_\text{model} = 512, h=8h = 8 → each head operates in dk=64d_k = 64 dimensions
  • Final projection WOW_O mixes the heads' outputs

Why multiple heads:

  • Different heads can attend to different types of relationships:
    • Head 1: syntactic (subject-verb agreement)
    • Head 2: semantic (coreference)
    • Head 3: positional (nearby tokens)
  • One head per relationship type is more expressive than a single large attention
  • Empirically, some heads become specialized, others become redundant (prunable)

Implementation — reshape to expose the head dimension (DN×HD \to N \times H), transpose so heads and sequence swap, run attention, then reshape back:

batch, seq_len, _ = x.shape
qkv = self.qkv_proj(self.norm(x))                 # (batch, seq_len, 3 * d_model)
qkv = qkv.reshape(batch, seq_len, 3, self.num_heads, self.head_dim)
q, k, v = qkv.unbind(dim=2)                        # (batch, seq_len, heads, head_dim)
q, k, v = (t.transpose(1, 2) for t in (q, k, v))  # (batch, heads, seq_len, head_dim)
 
mask = torch.tril(torch.ones(seq_len, seq_len)).bool()
out = scaled_dot_product_attention(q, k, v, mask)
out = out.transpose(1, 2).reshape(batch, seq_len, -1)  # recover (batch, seq, d_model)
return x + self.out_proj(out)                          # residual

Computation cost: same as single-head attention with full dmodeld_\text{model} (the split makes it equivalent), so multi-head is "free" in compute but adds expressiveness.

Grouped-Query Attention (GQA): modern LLMs share K/V across groups of heads to reduce KV cache memory at inference. Used in LLaMA 2+.

See also: Self-Attention, Residual Connections, Causal Masking

Linked from