Part XII — Modern Sequence Architectures: RoPE, FlashAttention & State-Space Models · Chapter 1

Positional encodings: Sinusoidal vs. Relative

Hook

A dot product qkq\cdot k doesn't know where qq or kk sat in the sentence — it's the same number regardless. If attention is built entirely out of dot products, how does it ever learn that "dog bites man" and "man bites dog" aren't the same sentence?

Intuition

Swap which token comes first. The score computed from content alone never budges — it can't, since nothing about it mentions position at all. The moment position gets added in, the swap changes the number.

Formalize

Sinusoidal positional encoding builds a vector out of sines and cosines at geometrically spaced frequencies, one pair of dimensions per frequency, and adds it directly to the token's content embedding before anything else happens:

PE(pos,2i)=sin ⁣(pos100002i/d),PE(pos,2i+1)=cos ⁣(pos100002i/d)PE_{(pos,\,2i)} = \sin\!\left(\frac{pos}{10000^{2i/d}}\right), \qquad PE_{(pos,\,2i+1)} = \cos\!\left(\frac{pos}{10000^{2i/d}}\right)
  • pospos — the token's position in the sequence: 0,1,2,0, 1, 2, \dots
  • ii — which frequency pair of dimensions this is, out of d/2d/2 total pairs.
  • dd — the embedding dimension: how many numbers make up the encoding vector.
  1. Every dimension pair spins at its own rate
    • Pair i=0i=0 has a rate of 100000=110000^0=1, so it completes a full rotation roughly every 2π6.32\pi\approx6.3 positions — fast.
    • Pair i=1i=1 divides pospos by 100002/d10000^{2/d} first, so for the same pospos it's barely turned at all.

    Stacking fast and slow pairs together lets nearby positions look different in the fast dimensions while far-apart positions still differ in the slow ones.

  2. Added, not appended

    PEposPE_{pos} is added elementwise to the content embedding, so a query·key dot product afterward mixes content and position inseparably — exactly what the intuition demo just showed happening to the score.

  3. A relative scheme skips the embedding entirely

    Instead of writing where a token is into its vector, a relative scheme (used by T5 and Transformer-XL) adds a bias term straight onto the attention score, looked up by the distance jij-i between the query and key positions. Slide the whole sequence over and every distance stays the same, so the bias — and the score — doesn't move at all.

Play
relative score (distance = 1) stays fixed at -0.80 no matter where the pair starts; the absolute score keeps changing

The bold curve is the sinusoidal score for a query and key that are always exactly one position apart, as the pair's starting offset slides from 0 to 20 — it wanders, because it reads each token's absolute position. The dashed line is the relative-bias score for that same distance of 1: flat, because distance is all it ever looks at.

Worked example

Tokens A=(1,0,0.5,0.5)A=(1,0,0.5,-0.5) and B=(0,1,0.5,0.5)B=(0,1,-0.5,0.5), content score AB=0.5A\cdot B = -0.5, with d=4d=4 (one fast frequency pair, one slow one):

  1. Position 0 is the trivial case

    sin(0)=0\sin(0)=0 and cos(0)=1\cos(0)=1 at every frequency, so PE0=(0,1,0,1)PE_0 = (0,1,0,1) exactly, regardless of dd.

  2. Position 10, then 11 — the sinusoidal score
    • At pos=10pos=10: rate i=0i=0 is 11, rate i=1i=1 is 100001/2=0.0110000^{-1/2}=0.01, so PE10=(sin(10),cos(10),sin(0.1),cos(0.1))(0.544,0.839,0.0998,0.995)PE_{10}=(\sin(10),\,\cos(10),\,\sin(0.1),\,\cos(0.1))\approx(-0.544,\,-0.839,\,0.0998,\,0.995).
    • At pos=11pos=11: PE11=(sin(11),cos(11),sin(0.11),cos(0.11))(1.0,0.0044,0.110,0.994)PE_{11}=(\sin(11),\,\cos(11),\,\sin(0.11),\,\cos(0.11))\approx(-1.0,\,0.0044,\,0.110,\,0.994).

    Elementwise sums:

    • A+PE10=(10.544, 00.839, 0.5+0.0998, 0.5+0.995)(0.456,0.839,0.600,0.495)A+PE_{10} = (1-0.544,\ 0-0.839,\ 0.5+0.0998,\ -0.5+0.995) \approx (0.456,\,-0.839,\,0.600,\,0.495)
    • B+PE11=(01.0, 1+0.0044, 0.5+0.110, 0.5+0.994)(1.0,1.004,0.390,1.494)B+PE_{11} = (0-1.0,\ 1+0.0044,\ -0.5+0.110,\ 0.5+0.994) \approx (-1.0,\,1.004,\,-0.390,\,1.494)

    Dot product: 0.456(1.0)+(0.839)(1.004)+0.600(0.390)+0.495(1.494)0.456(-1.0) + (-0.839)(1.004) + 0.600(-0.390) + 0.495(1.494) 0.4560.8430.234+0.7390.793\approx -0.456 - 0.843 - 0.234 + 0.739 \approx -0.793 — close to, but not equal to, the relative score below.

  3. The relative score for the same pair, distance 1

    AB+bias(1)=0.5+(0.3)=0.8A\cdot B + \text{bias}(1) = -0.5 + (-0.3) = -0.8. This number doesn't depend on which two positions were 1 apart — only that they were.

Checkpoint

Find the offset, among the candidates, where the sinusoidal score for a pair one apart lands within 0.05 of the relative score (-0.80).

Pick an offset to try it
Summary
PE(pos,2i)=sin ⁣(pos100002i/d),PE(pos,2i+1)=cos ⁣(pos100002i/d)PE_{(pos,\,2i)} = \sin\!\left(\frac{pos}{10000^{2i/d}}\right), \qquad PE_{(pos,\,2i+1)} = \cos\!\left(\frac{pos}{10000^{2i/d}}\right)

Both schemes exist to break the symmetry a plain dot product can't break on its own. Sinusoidal encoding bakes absolute position into the content itself, at a range of frequencies chosen so nearby and far-apart positions both stay distinguishable. Relative encoding skips the embedding and biases the score by distance directly, which is what makes it naturally shift-invariant — a property that turns out to matter enormously once a model needs to handle sequences longer than the ones it was trained on. The next two chapters build on that absolute/relative split directly: first rotating query and key vectors so relative position falls out of the dot product for free, then stretching that rotation scheme to contexts far beyond what it ever saw during training.