Cheat sheets

Positional Encoding: Sinusoidal, RoPE, ALiBi

Pick, build and check a position scheme. Sinusoidal, learned, RoPE, YaRN and ALiBi side by side, in Python.

  • Concepts and terms
  • Tasks and commands
  • Annotated code
  • Diagrams
  • Comparisons
  • Defaults and numbers
  • Troubleshooting
  • Questions and tips

Source

Side by side#

SchemeActs onExtrapolationTraining costUsed by
Absolute sinusoidalEmbeddings, sumpoorfreeoriginal transformer, early BERT
Learned absoluteEmbeddings, lookupnonetinyGPT-2, GPT-3
RoPERotates Q and Kgood with scalingfreeLlama 2/3/4, Qwen 2/3, Mistral, DeepSeek-V3, Kimi
RoPE + YaRNRotates Q and Kexcellentfine-tune stageQwen2-1M, Llama 3.1 128K
ALiBiAttention scoresexcellentfreeBLOOM, MPT, Baichuan

From Lesson 07.04, Lesson 19.32

Where each scheme acts#

lookupsumXposdotaddclientToken ids(B, T)storeToken embedding(B, T, D)processAdd absolute PEsinusoidal orlearnedprocessQ and Kper headprocessRoPErotate Q and KprocessScoresq dot k over sqrt dprocessALiBi biasminus m_h timesdistanceprocessSoftmaxthen times VlookupsumXposdotaddclientToken ids(B, T)storeToken embedding(B, T, D)processAdd absolute PEsinusoidal or learnedprocessQ and Kper headprocessRoPErotate Q and KprocessScoresq dot k over sqrt dprocessALiBi biasminus m_h timesdistanceprocessSoftmaxthen times V

From Lesson 07.04, Lesson 19.32

The three schemes in code#

def sinusoidal_pe(n, d, base=10000.0):add to embeddings
theta = pos / (base ** (2 * i / d))one frequency per pair i
pe[pos][2 * i] = math.sin(theta)even dim
pe[pos][2 * i + 1] = math.cos(theta)odd dim
def apply_rope(x, pos, base=10000.0):call on Q and on K
c = math.cos(theta)same theta as above
out[2 * i] = a * c - b * s2D rotation of pair i
out[2 * i + 1] = a * s + b * c
def alibi_slopes(n_heads):one slope per head
return [2 ** (-8 * (h + 1) / n_heads) for h in range(n_heads)]
row.append(-m * abs(i - j))bias for head slope m
row.append(float("-inf"))causal and j > i

From 07.04 code/main.py

Tasks in code#

TaskCode
Sinusoidal table, n positionssinusoidal_pe(n, d, base=10000.0)
Rotate one Q or K vectorapply_rope(x, pos, base=10000.0)
ALiBi bias per headalibi_bias(n_heads, seq_len, causal=True)
Learned table, one row per positionLearnedPositionalEmbedding(max_context_length, d_model)
Fixed table as a bufferSinusoidalPositionalEmbedding(max_context_length, d_model)
Sum token and position vectorsEmbeddingComposer(token_emb, learned_pos)
Neighbour similarity diagnosticneighbour_cosine_curve(table, max_offset=8)
Run the demopython3 code/main.py

From 07.04 code/main.py, 19.32 code/main.py, Lesson 19.32

Defaults and numbers#

SettingDefaultNote
base10000.0Sinusoidal and RoPE
rope_theta500000.0Llama 3 8B, scaled from 10k
causalTruealibi_bias masks j > i
DEFAULT_INIT_STD0.02Learned table init
max_offset8neighbour_cosine_curve
max_context_length128DemoConfig
d_model64Try 32, watch the bands
GPT-2 learned table1024Context 1025 is off the end

From 07.04 code/main.py, 19.32 code/main.py, Lesson 10.14

Check the RoPE relative property#

1Vectorsdraw q and k with rng.gauss(0, 1), d = 16.2Rotateapply_rope(q, pq) and apply_rope(k, pk) with thesame function.3Scoredot(q_rot, k_rot) for pairs (3, 5), (7, 9),(100, 102), (1024, 1026).4Expectall rows with gap=2 give the same dot productwithin floating-point error.5Base sweepscore at pos=4096 and pos=4098 for base 10000,100000, 1_000_000.6Readlarger base gives slower rotation and longercontext without phase wrap.

From 07.04 code/main.py, Lesson 07.04

Long context with RoPE#

base
the RoPE frequency scaler. Increase it to extend context at inference.
NTK-aware
rescale base to base * (scale_factor)^(d/(d-2)) when extending from 4K to 16K+.
YaRN
per-dimension interpolation that preserves attention entropy. Llama 3.1 128K uses it.
LongRoPE
evolutionary search picks per-dimension scale factors. Phi-3-Long uses it.
Position interpolation
shrink positions by the extension factor. Fine-tune for 1–5B tokens.
Result
Llama 3 extended from 8K to 128K context with RoPE scaling.

From Lesson 07.04, Lesson 10.14

Config fields to read#

CommandWhat it does
rope_thetaRoPE base frequency
max_position_embeddingsTraining context length
model.config.rope_scalingScaling type and factor, for example yarn
"position": "rope-yarn"Qwen 2.5 72B in the calculator
"position": "rope-sliding"Gemma 2 9B, RoPE plus sliding layers
"position": "learned"GPT-2 Small, 1024 positions
sliding_windowLast W tokens for sliding layers
layer_typesWhich layers are full or sliding

From Lesson 10.14, 10.14 code/main.py, Lesson 07.04

Troubleshooting#

SymptomCauseFix
seq_len <n> exceeds max_context_length <L>Input longer than the tableRaise max_context_length
d_model must be even for sinusoidalOdd d_modelUse an even d_model
token and positional embeddings must share d_modelTwo widthsBuild both with one d_model
Output the same for shuffled tokensNo position signalAdd a position scheme
Learned model fails past trained lengthThe row does not existUse RoPE with scaling
Sinusoidal fails beyond max_lenNo training at those positionsUse RoPE or ALiBi
Same gap, different RoPE scoresRotation on Q or K onlyRotate both with apply_rope
Long context degrades with RoPEPhase wrap at small baseRaise base, try YaRN

From 19.32 code/main.py, Lesson 19.32, Lesson 07.04, 07.04 code/main.py, Lesson 10.14

Use X when#

  • Use RoPE for a new decoder model. Every Llama, Mistral, Qwen, DeepSeek, and Gemma uses RoPE.
  • Use RoPE + YaRN when you extend context and can pay a fine-tune stage.
  • Use ALiBi when length extrapolation matters most and you want no embeddings.
  • Use sinusoidal when you want a parameter-free input table. It is historical for frontier models.
  • Use learned absolute only with a fixed maximum context, as in GPT-2.
  • Apply RoPE and ALiBi at the attention step, not at the input.

From Lesson 07.04, Lesson 19.32, Lesson 10.14

Questions#

Why does attention need position?
It is order-blind. Shuffled rows of X give shuffled output rows.
Why is RoPE relative?
The dot product picks up a cos of the gap times theta on each pair.
Sum or concatenate?
Sum. It keeps D constant through the network.
Parameter cost?
Learned adds max_context_length * D. Sinusoidal adds zero.
Why did RoPE win?
No architecture change, relative position, and a base knob for long context.
Learned vs sinusoidal at init?
Learned neighbours look random. Sinusoidal decays smoothly.

From Lesson 07.04, Lesson 19.32, Lesson 10.14