LLMsLoading progress…

Softmax weights

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

From scores to weights

The scaled scores of one query go through a softmax: exponentiate each, then divide by the sum. The weights are positive and add up to 1 across the keys of that query. Every query has its own row; rows are independent.

In code you subtract the row maximum before exponentiating. That changes no weight (it cancels in the division) but stops exp() from overflowing when scores are large.

score 10.71score 20score 3-1
keyscorescore − maxexp(score − max)weight
10.71010.5972
20-0.710.49310.2945
3-1-1.710.18140.1083
weights add up to 1 Subtracting the maximum changes no weight, but stops exp() from overflowing on large scores.

With several queries, each query has its own row of weights and each row sums to 1 separately, so the whole matrix does not sum to 1.

Three scores, their weights, and the maximum-subtraction trick.

Predict first. Must attention weights sum to one across every query in the whole batch?

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.