The last chapter ended on a shift-invariant relative bias — a lookup table keyed by distance, bolted onto the score after the fact. What if position could fall out of the dot product itself, with no separate bias term and no embedding ever added to the content? Rotate the query and key instead of translating them, and it does.
The key sits fixed at position 0. Step the query's position up and its arrow spins around the origin — the vector's length never changes, only its angle. Watch the dot product: it isn't tracking where the query "is" in any absolute sense, it's tracking how far its angle has swung away from the key's.
RoPE rotates a 2D pair of coordinates by an angle proportional to position, before the dot product is ever taken:
- — the token's position in the sequence.
- — the fixed angular rate: how many radians the pair rotates per position step.
- — the rotation matrix applied to that coordinate pair before the dot product.
- Rotation preserves length, and preserves relative angle
is orthogonal: it never stretches a vector, only turns it. Turning two vectors by the same angle leaves the angle between them — and so their dot product — completely unchanged.
- Turning them by different amounts is the same as turning one by the difference
. The rotated dot product between a query at position and a key at position is identical to rotating the key alone by and leaving the query untouched. Only the difference of the two positions ever enters the calculation.
- A real model repeats this across many frequency pairs
Full RoPE splits the embedding into coordinate pairs, each with its own — exactly the geometric spacing of frequencies from the sinusoidal scheme, just used to rotate instead of to add. This demo uses one pair to keep every angle exact and checkable by hand.
Slide the query's position continuously. The key stays anchored at position 0, so the angle swept by the slider is the relative distance — and the dot product it produces depends on nothing else. At , four steps is a full turn: the vector — and the dot product — returns exactly to where it started every four positions.
, , (a quarter turn per position step):
- Distance 0: the plain dot product
. With no rotation at all, this is just the ordinary dot product.
- Distance 2: rotate the key by a half turn
, , so . Then .
- Same distance, different absolute positions — identical answer
Query at position 1, key at position 3 (still 2 apart):
- , , so
- , , so
Their dot product: — exactly matching the distance-2 score computed from positions 0 and 2.
The key sits at position 0. Find the query position, among the candidates, that makes the RoPE dot product land within 0.05 of -1.00 — the value a relative distance of 2 produces.
Rotating a query and key by an angle proportional to position makes their dot product depend only on the difference of the two angles — the relative distance between them — never on either position by itself. That's relative position falling directly out of the geometry, with no added embedding and no separate bias table to look up. It's also exactly why RoPE runs into trouble past the sequence lengths it was trained on: push far enough and the model is rotating into angles it never saw during training. The next chapter is about stretching that trained range without retraining at all.