Position, sinusoidal, learned, and relative
"Dog bites man" and "man bites dog" contain the same three tokens. To a Transformer built from the parts we have so far, they are the same sentence.
That claim should bother you, so let's check it. In §4.6 we saw that self-attention without a mask is permutation equivariant. Shuffle the input tokens and the outputs come out shuffled the same way, with identical values. The FFN processes each token alone, and LayerNorm normalizes each token alone, so they are equivariant too. A stack of such layers can tell you which tokens are present and how they relate by content, but it has no idea of their order. For language, where order carries most of the meaning, that is fatal.
The first line prints True. Without a mask, order is invisible. The second prints False, which is a hint we will come back to at the end. A causal mask is itself a statement about order, since token may only look at tokens up to .
There are two broad ways to give a model a sense of position. We can tag each token's input vector with its absolute position before the first layer, or we can change attention itself so that its scores depend on the relative offset between query and key. This section covers the first family and the classic relative schemes. Section 5.5 covers the two that dominate modern models, RoPE and ALiBi.
Sinusoidal encodings
The original Transformer (Vaswani et al., 2017) adds a fixed vector to the embedding of the token at position , so the first layer sees . (In this section is that embedding row, not a one-hot vector.) The vector is built from sines and cosines at geometrically spaced frequencies,
Each pair of coordinates is a point going around a circle as increases, at angular speed . The first pair turns once every tokens. The last turns once every tokens, about 60,600 for (and approaching as grows). The wavelengths in between grow geometrically.
In plain words, a position is written as the readings of clocks that tick at very different speeds, from a second hand to a hand that takes tens of thousands of steps to go around.
A binary counter is a good mental picture. Its lowest bit flips every step, the next every two steps, the next every four, and together the bits name every integer uniquely. The sinusoidal encoding is a smooth version, with continuous values instead of bits and a geometric ratio of instead of 2 between neighboring frequencies.
A worked example with . The frequencies are and . Position 0 is , since every sine is 0 and every cosine is 1. Position 1 is . Position 2 is . The fast pair has already swung far, while the slow pair has barely moved.
Vaswani et al. also multiplied the token embeddings by before adding the encoding. The paper does not say why. The usual explanation is scale. Embeddings initialized with entries of size about would otherwise be swamped by position vectors whose entries are of order one.
Property 1, a shift is a rotation
Why sines and cosines, rather than any other set of distinct vectors? Vaswani et al. hypothesized that this choice makes relative positions easy to compute, because the encoding of position is a fixed linear function of the encoding of position . Use the angle-addition formulas on one pair,
Stack one such rotation for every frequency into a block-diagonal matrix , and
In plain words, moving tokens forward rotates each clock by ticks of its own speed, and that rotation does not care where you started.
This is a theorem about the encodings, and it is the seed of RoPE in §5.5. It does not by itself make the model use relative positions, because the model never sees alone (more on that below).
The derivation also answers a question people often skip, which is why each frequency gets both a sine and a cosine. A sine alone fails twice. It does not pin down the angle, since , so one sine reading cannot tell an angle from its mirror image. And the shift is no longer linear, because needs , which a sine-only code does not contain. The pair puts each frequency on a circle, and on a circle a shift is a rotation.
Sinusoidal position encodings
Write sinusoidal_pe(T, d, base=10000.0) returning the (T, d) matrix with row t equal to , using the interleaved layout above (column holds the sine and column the cosine of frequency ). Assume d is even. Vectorize it with an outer product, no loops.
Property 2, dot products depend only on the offset
Take two positions and . Each pair contributes , so
In plain words, how similar two position vectors are depends only on how far apart they are, not on where they sit in the sequence.
The same holds for distances. Expanding the square and using for every ,
so every pair of neighbors is the same distance apart, wherever they sit. For that neighbor distance is , most of it from the fastest few dozen clocks, whose angles change most per step.
Two more facts follow from the similarity formula. It is symmetric, , so the dot product alone cannot tell "before" from "after" (the rotation can, since ). And it tends to fall as grows, because the fast clocks dephase quickly and only the slow ones stay aligned. The fall is not monotonic, but large offsets look much less alike than small ones.
Choosing the base
The base sets the range of wavelengths, from tokens for the fastest pair to about for the slowest. The two ends do different jobs. The fast clocks tell neighbors apart, and the slow clocks say roughly how far along the sequence a token is, smoothly, so that offsets of 64 and of 1,000 look different. If the longest wavelength is shorter than the context, every slow clock wraps around within one sequence and that smooth coordinate is gone. The paper does not explain its choice, but a base of 10,000 puts the longest wavelength at tens of thousands of tokens, far beyond the sentences of the original translation task. RoPE inherits the same frequencies, and long-context models raise the base for exactly this reason (LLaMA 3 uses 500,000, §5.5).
With base 100 the longest wavelength is about 540 tokens, and offsets of 64 and 1,000 are equally unrelated to position 0 (similarity near 0). With base 10,000 similarity falls gradually, 0.43 at offset 64 and 0.28 at 1,000, so distance remains readable across the whole context. A larger base buys smoothness over longer ranges at the price of slightly less contrast between near neighbors.
How the model actually sees position
Here is the catch that most explanations skip. Attention never computes . It computes a query from the sum and a key from , so the score between query position and key position expands into four terms,
with . Write (as columns) and the position term becomes . It is guaranteed to depend on alone when commutes with every (for example, if it is itself block-diagonal with blocks that are scaled rotations), because then . Nothing forces that. The model can learn relative attention from sinusoids, but it is not built in, and the mixed terms let content and absolute position interfere. Ke et al. (2021) argued that these mixed terms mostly add noise and proposed computing content and position scores with separate projections. The rest of this section, and all of §5.5, are attempts to build relative position into the score directly.
The shift matrix M_k
Write shift_matrix(k, d, base=10000.0) returning the (d, d) block-diagonal matrix with for the interleaved encoding of Exercise 5.4a, for any integer k (negative too). Then answer for yourself the interview follow-up, which is why is orthogonal and what equals.
With in hand, we can show that a head can learn exact relative attention from sinusoids, even though nothing forces it to. The construction is a classic interview question. Choose for a gain . Then, writing the position vectors as rows, , because . By Property 2 this depends only on and peaks at , where it equals . So a head whose query and key projections multiply to on the position subspace attends tokens back, at every position. With it is the previous-token head that an induction circuit starts from (§4.7).
A previous-token head from sinusoids
Write relative_head_W(k, d, c=8.0, base=10000.0) returning a (d, d) matrix such that, for the interleaved sinusoidal encodings of Exercise 5.4a stacked as the rows of , the position-only scores satisfy . A causal head with these scores should then put almost all its weight on position . The setup provides _pe(T, d, base), the encoding table.
The same clocks, beyond text
Sines and cosines at geometric frequencies are a general way to feed a scalar to a network so that small and large differences are both visible. Diffusion models embed the noise level, or timestep, of their input exactly this way before adding it to every block, so that a diffusion model can tell nearly clean images from nearly pure noise. Coordinate networks do the same with positions in space. Tancik et al. (2020) showed that passing raw coordinates through such Fourier features is what lets a small MLP fit fine detail, and NeRF's positional encoding (Mildenhall et al., 2020) is one instance. In every case the fast frequencies resolve fine detail and the slow ones give a smooth sense of scale.
Learned absolute positions
The simplest alternative is to learn the position vectors. Keep a table , exactly like the token embedding table of §1.2, and add row to the token at position . BERT uses and GPT-2 uses , which costs parameters in GPT-2 small. Vaswani et al. tried this too and reported nearly identical results to the sinusoids on translation.
Learned positions are flexible, since the model can put whatever structure it finds useful into the table. Their limitation is absolute. There is no row for position , so the model cannot even be run on a longer input, let alone generalize to one. Positions near the end of the table also get fewer useful gradient updates if most training documents are shorter than .
Relative positions
For most of language, what matters is not that a word is the 517th token of a document but that it is two tokens after the verb. That suggests building position into attention as a function of the offset between the key position and the query position . A relative scheme is translation invariant by construction (the same pattern at any position gets the same scores), and it does not need a table indexed by absolute position.
Shaw et al., relative vectors on keys and values
Shaw, Uszkoreit & Vaswani (2018) learned a vector for each clipped offset and added it inside attention,
where are a head's query, key, and value, the softmax weights, and the clipping distance. Offsets farther than share a vector, which caps the parameters at vectors per table. On WMT 2014 translation this gained 1.3 BLEU over absolute positions on English to German and 0.3 on English to French. Varying made little difference once , because stacked layers can propagate precise position information beyond the clipping window.
The naive implementation materializes a tensor of relative vectors, which is expensive. The efficient trick is to compute for every query and every one of the offsets once, a matrix, and gather from it. Huang et al. (2018) found a "skewing" reshape that does the same for unclipped offsets with extra memory.
T5, one learned scalar per offset bucket
Raffel et al. (2020) simplified further for T5. Each head adds a single learned scalar to each attention logit, chosen by the offset,
where is the bias table of head (one of the layer's heads). Each has 32 entries, and the tables are shared by all layers of a stack. Offsets are grouped into buckets, exact for small distances and logarithmically wider for large ones, up to 128 tokens, beyond which all offsets share a bucket. For an encoder (bidirectional), half the buckets are for keys before the query and half for keys after. Within each half, the first 8 buckets hold the distances 0 to 7 exactly, then the buckets cover distances 8 to 11, 12 to 15, 16 to 22, 23 to 31, 32 to 45, 46 to 63, 64 to 90, and finally everything from 91 on. A causal decoder only needs keys at or before the query, so it uses all 32 buckets for that direction, with 16 exact and 16 logarithmic.
In plain words, the model learns how much each head likes to look one token back, two tokens back, and so on, with coarser resolution for faraway tokens, whose precise distance rarely matters.
The design is cheap in parameters ( per stack, so the encoder and the decoder each have their own), and because all far offsets share one bucket, nothing in the scheme changes when the input gets longer than anything seen in training. Press et al. (2022) found that T5's bias extrapolates to longer inputs better than sinusoidal or rotary encodings do, but is considerably slower, since the bias must be materialized for every query-key pair.
T5's relative position buckets
Implement t5_bucket(rel, bidirectional=True, num_buckets=32, max_distance=128) for an integer array rel of offsets (key minus query). It must reproduce T5's rule exactly.
- Let
n = -rel. If bidirectional, halvenum_buckets, addnum_buckets(the halved value) to the result wheren < 0(the key is after the query), and setn = |n|. If not bidirectional, setn = max(n, 0)(keys after the query all land in bucket 0). - Let
max_exact = num_buckets // 2. Distances belowmax_exactget their own bucketn. - Larger distances get
max_exact + int(log(n / max_exact) / log(max_distance / max_exact) * (num_buckets - max_exact)), capped atnum_buckets - 1.
Causal multi-head attention with a relative bias
Write relative_bias_attention(Q, K, V, bias_table) where Q, K, V have shape (H, T, d_k) for H heads and row i of bias_table, shape (H, 32), is head 's table . Compute causal attention per head with logits , using the causal bucket function t5_bucket_causal(rel) provided in the setup. Return the (H, T, d_k) output. No Python loops over heads or positions.
Length generalization
Every position scheme is ultimately judged by one question. Train on sequences of length , then evaluate on longer ones. Does the model still work? This is called length generalization or extrapolation, and it matters because training cost grows with sequence length, so you would like to train short and deploy long.
Each scheme fails or succeeds for a reason you can now state. Learned absolute positions cannot run at all beyond . Sinusoidal encodings can be computed for any , but the model has never seen the combinations of slow-clock angles that occur beyond its training length. Press et al. (2022) found that a sinusoidal model trained on 1,024 tokens improved only up to about 50 extra tokens and then degraded quickly. Relative schemes with clipping or bucketing (Shaw, T5) see nothing new at longer lengths, because every offset beyond the last bucket looks the same, and they extrapolate better. The cost is that the model is blind to distinctions between large offsets.
There is a fourth option that sounds absurd and is not. A causal decoder with no position encoding at all, called NoPE, can still learn about position, because the causal mask makes the computation order-dependent. Token attends over exactly tokens, so, for example, a head that spreads its attention evenly gives each visible token weight , and its output carries information about . Haviv et al. (2022) showed that causal language models without positional encodings are competitive with ones that have them, and conjectured exactly this mechanism, counting predecessors. Kazemnejad et al. (2023) found that NoPE generalized to longer lengths better than common explicit schemes on their reasoning and math tasks. These are empirical results at limited scale. At the frontier, the dominant recipe is RoPE plus a dedicated stage that extends the context, which we preview in §5.5 and develop in §12.7.
In PyTorch
The sinusoidal table is a buffer, not a parameter. It moves with the model between devices and receives no gradient, and registering it with persistent=False keeps it out of the state dict, since it can always be recomputed. Learned positions are an nn.Embedding.
| scheme | where it acts | parameters | relative by construction | beyond training length |
|---|---|---|---|---|
| sinusoidal (Vaswani) | added to input embeddings | 0 | no (only learnable) | defined, but degrades quickly |
| learned absolute (GPT-2, BERT) | added to input embeddings | no | undefined beyond | |
| Shaw relative | added to keys and values in each layer | per layer | yes, clipped at | far offsets look alike |
| T5 bias | scalar added to logits | per stack (shared across layers) | yes, bucketed | extrapolates fairly well, slow |
| NoPE (causal only) | nowhere, the mask implies order | 0 | implicitly | competitive in some studies |
| RoPE, ALiBi | queries and keys, or logits | 0 | yes | see §5.5 |
Read more
- Vaswani et al. (2017). Attention Is All You Need. Section 3.5 introduces the sinusoidal encoding and its shift hypothesis.
- Shaw, Uszkoreit & Vaswani (2018). Self-Attention with Relative Position Representations. Relative vectors inside attention, with the clipping ablation.
- Raffel et al. (2020). Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer. T5, including its bucketed relative bias (Section 2.1).
- Huang et al. (2018). Music Transformer. The skewing trick for memory-efficient relative attention.
- Ke, He & Liu (2021). Rethinking Positional Encoding in Language Pre-training. The four-term expansion and why mixing content with position hurts.
- Haviv, Ram, Press, Izsak & Levy (2022). Transformer Language Models without Positional Encodings Still Learn Positional Information. NoPE.
- Kazemnejad et al. (2023). The Impact of Positional Encoding on Length Generalization in Transformers. A careful comparison of position schemes for extrapolation.
- Tancik et al. (2020). Fourier Features Let Networks Learn High Frequency Functions in Low Dimensional Domains. Why sinusoidal features of a coordinate help an MLP, beyond language.