Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Multi-head attention

In the previous chapter, we added the QQ, KK, VV role separation to self-attention. But one limitation remains: all tokens share the same single set of QQ, KK and VV.

It is like a person who can look at a problem from only one perspective, and cannot understand that the same word can mean different things in different contexts. Take the word “apple”:

  • in “eat an apple”, it is a fruit;

  • in “Apple phone”, it is a brand.

The current model can understand it in only one way, and cannot capture these two different meanings at the same time.

Multi-head attention

The solution is multi-head attention: split the embedding vector of a token into several parts, called heads; generate a separate set of QQ, KK, VV linear projections for each part; let each develop its own independent attention; and finally concatenate them together:

  • each head has its own QQ, KK, VV linear projections and attends to a different feature subspace;

  • each head develops independently and picks up a different logic in the data;

  • the heads work in parallel and are combined at the end, so the model can understand the context from several angles.

Split and merge

Suppose the embedding size is 64 and the number of heads is 2. Then:

  • the embedding size of each head is 64 / 2 = 32;

  • the input shape changes from (batch size, context size, 64) to (batch size, context size, 2, 32);

  • transpose it to (batch size, 2, context size, 32), so that each head can compute its attention independently;

  • after the computation, transpose back to (batch size, context size, 2, 32), then concatenate into (batch size, context size, 64).

Scaling factor

The embedding size of each head is EMBEDDING_SIZE / HEADS, so the dd in the scaling factor 1/d1 / \sqrt{d} is now EMBEDDING_SIZE / HEADS.

Number of parameters

The number of parameters of multi-head attention is exactly the same as that of single-head attention: the weight matrices of the three linear projections QQ, KK and VV are still (embedding size, embedding size). The only difference is that the computation splits the vector into several parts and computes each independently.

💡 Tip: computing multi-head attention is not a stack of several attentions, but a parallel computation after expanding the dimensions inside the same attention.

Dataset

Character-encoding dataset

Lower triangular matrix layer

Activation functions

Gaussian error linear unit (GELU)

Loss function

GPT cross-entropy loss function

Model

GPT embedding layer

GPT attention layer

We add multi-head support to the GPT attention layer.

The forward pass gains two steps, split and merge:

  • generate QQ, KK and VV: obtain the query, key and value through three linear layers;

  • split the heads: divide the embedding vector into several parts;

  • compute attention: each head independently computes the attention score matrix, scales, masks, computes the weights, and takes the weighted sum;

  • merge the heads: concatenate and combine the multi-head attention.

How the shape of the attention changes during split and merge:

split:(batch,context,embedding)→split(batch,context,heads,per-head embedding)→transpose(batch,heads,context,per-head embedding)\text{split}: (\text{batch}, \text{context}, \text{embedding}) \xrightarrow{\text{split}} (\text{batch}, \text{context}, \text{heads}, \text{per-head embedding}) \xrightarrow{\text{transpose}} (\text{batch}, \text{heads}, \text{context}, \text{per-head embedding})
merge:(batch,heads,context,per-head embedding)→transpose(batch,context,heads,per-head embedding)→merge(batch,context,embedding)\text{merge}: (\text{batch}, \text{heads}, \text{context}, \text{per-head embedding}) \xrightarrow{\text{transpose}} (\text{batch}, \text{context}, \text{heads}, \text{per-head embedding}) \xrightarrow{\text{merge}} (\text{batch}, \text{context}, \text{embedding})

Therefore, the multi-head mechanism is handled only inside the GPT attention layer. The shape of the output does not change, and the later steps need no modification.

GPT feed-forward network layer

GPT Transformer block

heads needs to be passed in when creating it.

GPT output layer

GPT model

heads needs to be passed in when creating it.

GPT trainer

Hyperparameters

Learning rate

Batch size

Number of epochs

Context size

Embedding size

Number of heads

This is the hyperparameter that defines the number of heads in multi-head attention.

Number of Transformer blocks

Modeling

When creating the model, we need to pass HEADS in as an additional model parameter.

Training

Evaluation

prediction:	1742 steps, each (4, 32, 65)
loss:	1.851641697875394

Inference

ROMEO:
Where as her, mise. what I shall bestill tranter is it fate,
Why onot untock: papon you have for you wife?

HORTA:
I what a the know
You will the'll cof Pefier there and which:
Chold we man use to love, thing the mall geread; thou reavedss lovela, by off 

In this chapter, we added the multi-head mechanism to attention: split the embedding vector into several parts, give each part its own QQ, KK, VV linear projections, compute attention independently, and finally concatenate and combine the results. The model can therefore understand the context from several angles.

With this, we have implemented the complete self-attention mechanism and built, step by step, the core component of the GPT model:

  • self-attention: tokens see each other;

  • causal attention: mask the future to prevent peeking at the answers;

  • weighted attention: separate the roles of QQ, KK and VV;

  • multi-head attention: understand the context in parallel from several angles.

Exercises

  1. Try changing HEADS from 2 to 4 or 8 and observe how the training speed and results change. Is more heads always better?