Prove it: attention can't see order
Self-attention pools word vectors from every position at once — the math is a weighted sum, and sums don't care about order. Below, two sentences are turned into pooled vectors (the stripe patterns). Toggle position encoding OFF and shuffle: the two stripes become bit-for-bit identical, no matter how scrambled sentence B gets.
Toy setup: each word gets a fixed 24-dim vector and the sentence vector is a pooled sum (what attention reduces to). With encoding ON, each word vector is bound to its slot's sinusoidal code before pooling — the same word-meets-position interaction attention's Q·K dot products exploit. Real transformers are bigger but share the same blindness.
Every position gets a wave barcode
The classic fix: give position p a vector of sines and cosines at different frequencies — fast waves on top distinguish neighbors, slow waves below distinguish paragraph-scale distances. Each column in the heatmap is one position's barcode. Now starve it: drag dimensions down and watch far-apart positions start to collide.
We use wavelength base 100 instead of the paper's 10,000 so the slow waves visibly change within 48 positions — same formula, zoomed in.
The negation trap — same words, opposite meaning
Order blindness isn't a cosmetic bug. These sentence pairs use the exact same multiset of words, but mean the opposite — because "not" flips whatever comes next. Score them both ways and watch the bag-of-words model literally return the same number for both.
Scramble it — position codes carry the receipt
Once a position code is added into each token's vector, the token carries its slot number with it wherever attention shuffles the data. Shuffle the tokens below, then hit restore: with codes ON, each token's barcode is decoded back to a slot and the sentence snaps back perfectly. With codes OFF there is nothing to sort by — restoring is a blind guess.
Decoding here is nearest-neighbor: each token's carried barcode is matched against the 9 known position codes. That's a toy stand-in for what attention layers learn to do implicitly — but the information content is the real thing.
Past the edge of the map — learned vs sinusoidal
There are two classic ways to get position codes: learn a lookup table (GPT-2 style, one row per position, trained up to some length) or compute sinusoids (a formula that works at any position). Drag the query past position 32 — the table's edge — and watch one scheme keep producing clean barcodes while the other returns garbage.
The "learned" table here is random-but-fixed vectors for positions 0–31, which is what an untrained embedding table is; past row 31 the index simply doesn't exist, so we show the undefined read as noise. Real GPT-2 hard-truncates at 1024 for exactly this reason.