Attention treats its input as a bag of tokens: position has to be injected. Here you compute the classic sinusoidal encoding live from its formula, then rotate real query and key vectors with RoPE and watch the attention score depend only on how far apart two tokens sit.
Sign in to save progress
Attention is order-blind by construction
Self-attention compares every token with every other token through dot products, and a set of dot products has no idea which token came first. Feed it these two sentences with plain word embeddings and it sees the exact same multiset of vectors:
Same three embeddings, radically different meaning. Every transformer therefore injects position into the computation. Two families dominate: add a positional vector to each embedding (sinusoidal, learned), or rotate the query and key vectors by a position-dependent angle (RoPE, used by Llama, Qwen, and most current open models). You will build both below.
Lab 1: the sinusoidal encoding, computed from the formula
PE(pos, 2i) = sin( pos / base^(2i / d_model) ) PE(pos, 2i+1) = cos( pos / base^(2i / d_model) ) base = 10000 in the paper
Every cell below is that formula evaluated live for the sliders you set: nothing is precomputed. Left columns cycle fast (wavelength of a few positions), right columns cycle slowly, so each row becomes a unique fingerprint the model can add to its token embedding. Shrink the base and watch the slow columns speed up; grow d and watch new slow columns appear on the right.
PE[0], first 8 of 32 dimensions (computed from the formula above):
[+0.000, +1.000, +0.000, +1.000, +0.000, +1.000, +0.000, +1.000, ...]
Dimension pair 0 repeats every 6.28 positions; the last pair (15) repeats every 35,333 positions. Together the columns form a smooth binary-clock style fingerprint that is unique per position.
Lab 2: RoPE, position as rotation
Adding a position vector changes what a token IS. Rotary embeddings instead change how tokens MEET: split the query and key vectors into 2D pairs, rotate each pair of q by m times its frequency and each pair of k by n times the same frequency, then take the ordinary dot product. The rotations cancel except for their difference, so the score depends only on the offset m minus n. This toy head has 4 dimensions (two pairs); every number is computed from the vectors and angles on screen.
Fixed head vectors (two 2D pairs each), authored for this demo and rotated live below: q = [0.9, 0.35, 0.55, 0.75], k = [0.7, -0.4, 0.65, 0.25].
Pair 1: theta = 1.00 rad/position (fast)
q turned 4.00 rad
(-0.323, -0.910)
k turned 1.00 rad
(+0.715, +0.373)
dot = -0.570
Pair 2: theta = 0.10 rad/position (slow)
q turned 0.40 rad
(+0.215, +0.905)
k turned 0.10 rad
(+0.622, +0.314)
dot = +0.417
Attention score = pair 1 dot + pair 2 dot = -0.153 at relative offset m - n = 3
Score against relative offset: the gold marker is your live (m, n) score, plotted at its offset. It always lands on the curve.
The proof: slide the whole pair along the sequence
Shift m and n together and both vectors rotate by the same extra angle, so their relative angle, and therefore the score, cannot change. Watch the marker stay put.