The dot product

Multiply two vectors position by position and add the results. The single number you get is large and positive when the vectors point the same way, zero when they are at right angles, and negative when they point apart. It is how a language model measures similarity, and every attention score is one.

Basics used here
Key idea
a · b = a₁b₁ + a₂b₂ + … ; equals |a| |b| cos θ; sign tells same or opposite direction; cosine similarity; projection
Real world
A shopping bill. Quantities [2, 1, 3] (bread, milk, apples) dotted with prices [1.20, 0.90, 0.40] gives 2×1.20 + 1×0.90 + 3×0.40 = 4.50 pounds.
In an LLM
To decide where to look, each token’s query is dotted with every earlier token’s key. In “The cat sat on the”, the last “the” has the largest dot product with “cat”, so it pays most attention to “cat”.

Multiply and add

The of two vectors of the same length multiplies them position by position and adds everything up:

a⋅b=a1b1+a2b2+⋯+anbn\mathbf{a} \cdot \mathbf{b} = a_1 b_1 + a_2 b_2 + \dots + a_n b_n

For a=[3,1]\mathbf{a} = [3, 1] and b=[2,2]\mathbf{b} = [2, 2]: 3×2+1×2=83 \times 2 + 1 \times 2 = 8. Two lists in, one number out. Both vectors must have the same length, or there is nothing to pair up.

The arithmetic is simple. What makes it useful is what the number means.

What the number measures

The same number can be computed from the arrows’ lengths and the angle θ\theta between them:

a⋅b=∣a∣ ∣b∣ cos⁡θ\mathbf{a} \cdot \mathbf{b} = |\mathbf{a}|\,|\mathbf{b}|\,\cos\theta

∣a∣|\mathbf{a}| is the length of the arrow (the norms lesson covers it). cos⁡θ\cos\theta is 1 when the arrows point the same way, 0 at a right angle and −1 when they point in opposite directions. So:

  • Positive: roughly the same direction (angle under 90°).
  • Zero: at right angles. The vectors are called orthogonal: they share nothing.
  • Negative: roughly opposite directions.

There is also a picture. Shine a light straight down onto the line through a\mathbf{a}: b\mathbf{b} casts a shadow on it, called its projection. The dot product is the shadow’s length times a\mathbf{a}’s length, negative if the shadow falls backwards.

Drag both arrows and try the three buttons:

a · b = 3.0×1.5 + 0.5×2.0 = 5.50
= |a| × |b| × cos θ = 3.04 × 2.50 × 0.72
a · b5.50
angle θ44°
cos θ0.72
shadow of b on a1.81
Positive: a and b point roughly the same way (angle 44°, less than 90°). b’s shadow falls along a. The closer the angle gets to 0°, the bigger the dot product for the same lengths.
Drag the two arrows. The green or red bar on a’s line is the shadow b casts on a. The dot product is that shadow’s length times a’s length.
example · a shopping bill

You buy 2 loaves, 1 pint of milk and 3 apples: the quantity vector [2,1,3][2, 1, 3]. The prices are [1.20,0.90,0.40][1.20, 0.90, 0.40] pounds. The bill is their dot product, 2×1.20+1×0.90+3×0.40=4.502 \times 1.20 + 1 \times 0.90 + 3 \times 0.40 = 4.50 pounds. Every till in every shop computes dot products. And “how much does this basket match what is on offer” is the same calculation with discounts in place of prices.

Similarity: cosine

The dot product grows with the lengths of the vectors as well as with their alignment. To measure direction alone, divide by both lengths. This is the :

cos⁡θ=a⋅b∣a∣ ∣b∣\cos\theta = \frac{\mathbf{a} \cdot \mathbf{b}}{|\mathbf{a}|\,|\mathbf{b}|}

It always lies between −1 and 1. Here it is for 48 real GPT-2 word embeddings, each 768 numbers long. Nobody told GPT-2 that cats and dogs are both animals; the similarity comes from training.

Loading GPT-2 data…
example · “cat” and “dog” in GPT-2

The embeddings of “ cat” and “ dog” have cosine similarity 0.55: an angle of about 57° in 768 dimensions. “ cat” and “ France” have 0.25, about 76°. Countries are tightly grouped: “ France” and “ Germany” have 0.70. Search engines and retrieval systems use exactly this: turn a question and every document into vectors, and return the documents with the highest cosine.

Attention scores are dot products

Inside every attention head, each token makes a query vector (what it is looking for) and a key vector (what it contains). The score for “token i looks at token j” is the dot product of i’s query with j’s key. Here is the toy head from the Transformers course:

query from:
query
123q(the)1.500.150.50
k(The)0.20.02.0
1.30
1.50×0.2 + 0.15×0.0 + 0.50×2.0 = 1.30
k(cat)2.00.20.0
3.03
1.50×2.0 + 0.15×0.2 + 0.50×0.0 = 3.03
k(sat)0.42.00.0
0.90
1.50×0.4 + 0.15×2.0 + 0.50×0.0 = 0.90
k(on)0.00.60.0
0.09
1.50×0.0 + 0.15×0.6 + 0.50×0.0 = 0.09
k(the)0.20.00.0
0.30
1.50×0.2 + 0.15×0.0 + 0.50×0.0 = 0.30
“the” scores highest against “cat” (3.03): its query and that key point in the most similar direction. Small words have a query that looks for a thing, and “cat” has a key that says “I am a thing”. A real head does exactly this with 64 numbers per query instead of 3, for every pair of tokens at once.
The toy attention head from the Transformers course on “The cat sat on the”. Pick the token that is looking; each row is its query dotted with one key.

A real GPT-2 head does this with 64 numbers per query, for every pair of tokens. A 1,000-token text needs a million of these dot products per head, which is why they are organised as one matrix multiplication.

going deeper

Why the two formulas agree

In 2D, write a=∣a∣[cos⁡α,sin⁡α]\mathbf{a} = |\mathbf{a}|[\cos\alpha, \sin\alpha] and b=∣b∣[cos⁡β,sin⁡β]\mathbf{b} = |\mathbf{b}|[\cos\beta, \sin\beta]. Then

a⋅b=∣a∣∣b∣(cos⁡αcos⁡β+sin⁡αsin⁡β)=∣a∣∣b∣cos⁡(α−β).\mathbf{a} \cdot \mathbf{b} = |\mathbf{a}||\mathbf{b}|(\cos\alpha\cos\beta + \sin\alpha\sin\beta) = |\mathbf{a}||\mathbf{b}|\cos(\alpha - \beta).

In any dimension the same follows from the law of cosines applied to the triangle a,b,a−b\mathbf{a}, \mathbf{b}, \mathbf{a} - \mathbf{b}.

The projection of b\mathbf{b} onto a\mathbf{a} is the vector a⋅ba⋅a a\dfrac{\mathbf{a}\cdot\mathbf{b}}{\mathbf{a}\cdot\mathbf{a}}\,\mathbf{a}, and its signed length is a⋅b/∣a∣\mathbf{a}\cdot\mathbf{b} / |\mathbf{a}|.

Properties

  • Symmetric: a⋅b=b⋅a\mathbf{a}\cdot\mathbf{b} = \mathbf{b}\cdot\mathbf{a}.
  • Distributes: a⋅(b+c)=a⋅b+a⋅c\mathbf{a}\cdot(\mathbf{b} + \mathbf{c}) = \mathbf{a}\cdot\mathbf{b} + \mathbf{a}\cdot\mathbf{c}, and (c a)⋅b=c (a⋅b)(c\,\mathbf{a})\cdot\mathbf{b} = c\,(\mathbf{a}\cdot\mathbf{b}).
  • a⋅a=∣a∣2\mathbf{a}\cdot\mathbf{a} = |\mathbf{a}|^2.

In code

import numpy as np
a, b = np.array([3.0, 1.0]), np.array([2.0, 2.0])
a @ b                                    # 8.0  (same as np.dot(a, b))
cos = a @ b / (np.linalg.norm(a) * np.linalg.norm(b))   # 0.894
 
import torch.nn.functional as F
F.cosine_similarity(x, y, dim=-1)        # for torch tensors

Random vectors in high dimensions

Two random directions in 768 dimensions are almost orthogonal: their cosine is typically within about ±1/768≈±0.04\pm 1/\sqrt{768} \approx \pm 0.04 of zero. That is why the GPT-2 values above, all at least 0.14, are not chance: the word embeddings share a common direction (they are “anisotropic”), and related words share more. Ethayarajh, 2019, measures the same effect in GPT-2’s hidden states.

In papers

Related

  • vectors - A vector is a list of numbers, and the same thing as an arrow. You can add vectors and stretch them, and both have a simple picture. Inside a language model every token is a vector of hundreds or thousands of numbers.
  • norms - A norm measures how long a vector is. The usual one is the straight-line length; another adds up the sizes of the numbers. Dividing a vector by its length keeps its direction and makes its length 1. Language models do this to every hidden state, many times per token, with LayerNorm or RMSNorm.
  • matrix-multiplication - To multiply two matrices, take each row of the first and each column of the second and compute their dot product. The inner sizes must match, and the outer sizes give the shape of the result. This one operation is most of the work a language model does.