LLMsLoading progress…

Masking and multiple heads

Calculate query-key scores, scaled softmax weights and the weighted value output for one attention head.

Hiding the future, and splitting into heads

When a model predicts the next token, a position must not see the tokens after it. A causal mask sets the scores of future positions to −∞ before the softmax, so they get weight exactly 0 and the rest still add up to 1. In the worked example, if only the first key is allowed the output becomes [2, 0].

One head looks at one kind of relationship. Multi-head attention splits the model width into h slices, runs attention separately in each (each with its own projected subspace), joins the results and multiplies by an output matrix.

query ↓ / key →token 1token 2token 3token 4
token 11maskedmaskedmasked
token 20.270.73maskedmasked
token 30.670.090.24masked
token 40.170.170.170.48

The mask is applied to the scores as −∞ before the softmax, so each row still sums to 1 over the positions that remain.

number of heads2
model width 8 split into 2 heads of width 4; each head attends on its own slice, then the head outputs are joined and multiplied by an output matrix Wo
Toggle the mask on a 4-token example, then choose a number of heads for a model of width 8.

Predict first. Should forbidden positions keep a small positive softmax weight?

Chapter context

Attention computes a data-dependent mixture of value vectors. A query scores candidate keys, a normalization turns scores into weights, and those weights combine values. Keys decide how to look; values supply what is gathered.

Chapter reference: math, worked example & code

This section belongs to the whole chapter, so it is the same on every lesson in it and may cover a different lesson's topic. The code for the experiment you just ran is inside the experiment itself.

Math and notation

Q∈Rnq×dk, K∈Rnk×dk, V∈Rnk×dv.Q\in\mathbb R^{n_q\times d_k},\ K\in\mathbb R^{n_k\times d_k},\ V\in\mathbb R^{n_k\times d_v}. S=QKT/dk+M,A=softmax⁡rows(S),O=AV.S=QK^T/\sqrt{d_k}+M,\quad A=\operatorname{softmax}_{rows}(S),\quad O=AV.

M is zero at allowed positions and conceptually negative infinity at excluded positions. Every query needs a defined policy if all its keys are masked.

Worked example

Use q=[1,0], K=[[1,0],[0,1]], V=[[2,0],[0,2]], and d_k=2. Dot scores [1,0] become [1/sqrt(2),0]. Exponentiate and normalize to approximately [0.669762,0.330238]. The output is [2×0.669762,2×0.330238]≈[1.339523,0.660477]. If only the first key is causally allowed, the output becomes [2,0].

Reference code

The following example uses the Python standard library and does not call a remote service.

from math import sqrt,exp,isclose
q=[1,0]; keys=[[1,0],[0,1]]; values=[[2,0],[0,2]]
scores=[sum(a*b for a,b in zip(q,k))/sqrt(2) for k in keys]
weights=[exp(s-max(scores)) for s in scores]
weights=[w/sum(weights) for w in weights]
out=[sum(weights[i]*values[i][j] for i in range(2)) for j in range(2)]
assert isclose(sum(weights),1)
assert isclose(weights[0],.6697615493266569)
assert isclose(out[0],1.3395230986533138)
assert isclose(out[1],.6604769013466862)

Python examples are provided for study and local execution; this page does not execute Python.

Common mistakes

Attention scores are not weights before normalization. Causal masking happens before softmax. Attention weights alone are not a full causal explanation of a model decision.