Transformers and language models
Softmax and dot products
A dot product scores how well two vectors agree. Softmax turns any list of scores into weights that are positive and sum to 1.
Attention needs two small tools. The first measures how well a query and a key agree. The second turns those agreement scores into weights. Both are simple, and the rest of the topic depends on them.
Concept
Dot product. For two vectors of the same length, a · b = a₁b₁ + a₂b₂ + …. Multiply matching entries and add them up. The result is large when the vectors point the same way.
Dot products measure agreement
Take a query q = [1, 2, 0] and a key k = [2, 1, 3]:
q · k = 1·2 + 2·1 + 0·3
= 2 + 2 + 0
= 4A key that points the same way as the query gives a big number. A key that points away gives a small or negative one. Attention uses this as a cheap relevance score.
Softmax turns scores into weights
Scores can be any real numbers. Attention needs weights that are positive and add up to 1, so it applies softmax:
weight_i = exp(score_i) / Σ_j exp(score_j)Each score is pushed through exp, which makes it positive. Then each value is divided by the total, so the results sum to 1. Larger scores get larger shares, but softmax is soft: even a low score keeps some weight.
Take three keys with scores [2.0, 1.0, 0.1]:
exp: [7.389, 2.718, 1.105] sum = 11.212
weight: [0.659, 0.242, 0.099] sums to 1.000The top score gets about two-thirds of the weight, but the others are not zeroed out.
Subtract the max before exponentiating
Large scores overflow exp. The fix is to subtract the largest score first. This does not change the weights, because the same factor appears on top and bottom.
import numpy as np
def softmax(scores):
# Subtracting the max leaves the result unchanged but keeps exp() from overflowing.
e = np.exp(scores - scores.max())
return e / e.sum()
print(np.round(softmax(np.array([2.0, 1.0, 0.1])), 3))
print(np.round(softmax(np.array([1002.0, 1000.0, 997.0])), 4))Output:
[0.659 0.242 0.099]
[0.8756 0.1185 0.0059]Without the subtraction, exp(1002) overflows to inf in float64. The second call still works.
Tip
Adding the same number to every score changes nothing. softmax([5, 5]) and softmax([0, 0]) both give [0.5, 0.5]. Only the differences between scores matter.
Common mistakes
- Expecting softmax to pick a winner. It spreads weight across all entries. A hard pick would be an argmax, which is not differentiable.
- Forgetting the sum-to-1 rule. The outputs are shares, not raw scores. A score of 8 does not mean an 8 in the output.
- Computing
expon raw scores. Subtract the max first, or large inputs turn intoinfandNaN.
Check yourself
- If all scores are equal, what are the weights for
nentries? Each weight is1/n. - Why does softmax of
[5, 5]equal softmax of[0, 0]? Adding the same constant to every score cancels out in the division.
Key takeaways
- A dot product is large when two vectors point the same way.
- Softmax makes scores positive and normalizes them to sum to 1.
- Softmax is soft: every entry keeps some weight, unless it is masked out.
- Subtract the max before
expto avoid overflow.
Further learning
Next, see how queries, keys and values use these two tools in queries, keys and values.
Related
Self-attention
The operation at the core of every modern language model. Each position builds a weighted average of the others, with weights set by query-key matches.
Queries, keys and values
Self-attention scores every pair of positions with a query and a key, then mixes value vectors using those scores. The √d_k factor keeps the softmax well behaved.
Linear algebra for ML
Vectors, matrices and matrix multiplication, the language every model is written in. Learn the shapes, then batching, FLOP counts and low-rank tricks.