Positional Encoding
Positional encoding is a technique for injecting token-order information into the input representations of sequence models that lack inherent ordering structure — most critically, the Transformer architecture, whose self-attention mechanism is permutation-equivariant by design. Without positional encoding, a Transformer would produce identical outputs for "the cat sat on the mat" and any permutation of those words, making it blind to syntax and meaning that depends on word order. Remarkably, the sinusoidal encoding scheme introduced in the original "Attention Is All You Need" paper allows a model trained on sequences of length N to generalize — with some degradation — to longer sequences at inference time, a property not obviously guaranteed by its construction.
The self-attention operation computes relationships between every pair of tokens in a sequence, but it does so using only the content of those tokens — it has no built-in sense of which token came first or last. Positional encoding solves this by adding (or concatenating) a position-dependent signal to each token embedding before attention is computed, so that two identical tokens at different positions produce different representations entering the attention layers. The "aha moment" is recognizing that attention is a set operation, and positional encoding is what secretly converts your sequence into an ordered structure the model can reason about. The encoding just needs to be unique per position, consistent across sequences, and expressible in the same embedding space — leaving enormous design freedom in how you actually construct it.
How It Works
Sinusoidal Positional Encoding (Vaswani et al., 2017)
The original formulation adds a fixed, deterministic vector to each token embedding. For a sequence position and embedding dimension index , the encoding is defined across the full -dimensional space by alternating sine and cosine functions at geometrically decreasing frequencies:
Explanation: The even-indexed dimensions of the positional vector for token at position `pos` are set to a sine wave whose frequency decreases exponentially as the dimension index `i` increases.
Explanation: The odd-indexed dimensions mirror the even ones with a cosine instead of sine, giving each frequency band a two-dimensional sinusoidal basis — analogous to encoding an angle as both its sine and cosine to make it uniquely recoverable.
Symbol definitions:
- : integer token position in the sequence
- : dimension pair index
- : total embedding dimensionality (e.g., 512 in the base Transformer)
- : the wavelength base; chosen so wavelengths range from (highest frequency) to (lowest)
The final input to the first Transformer layer is the sum of the token embedding and its positional encoding:
Explanation: Token embedding and positional signal live in the same -dimensional space, so they can be added directly — the model learns to disentangle the two sources of information through its projection matrices.
The Relative Offset Property
A key reason sinusoidal encodings are theoretically appealing is that can be expressed as a linear function of for any fixed offset . Specifically, using angle-addition identities:
Explanation: The positional encoding at any offset `k` from position `pos` is a rotation of the encoding at `pos` — meaning attention weight dot-products can in principle learn to compute relative distances without ever explicitly seeing position integers. This linearity means the dot product depends only on , not on the absolute value of , giving the model a built-in geometric structure that mirrors how we think about sequence relationships.
Learned Absolute Positional Embeddings
An alternative: treat each position index as a token, maintain a learnable embedding table , and add to the token embedding. BERT and GPT-2 both use this approach. The downside is a hard sequence-length cap of and no guaranteed generalization beyond it. ```python import torch import torch.nn as nn import math class SinusoidalPositionalEncoding(nn.Module): def __init__(self, d_model: int, max_len: int = 5000, dropout: float = 0.1): super().__init__() self.dropout = nn.Dropout(p=dropout)
# Build the PE matrix once; shape [max_len, d_model] pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len).unsqueeze(1).float() # [max_len, 1] div_term = torch.exp( torch.arange(0, d_model, 2).float() (-math.log(10000.0) / d_model) ) # [d_model/2] pe[:, 0::2] = torch.sin(position div_term) # even dims pe[:, 1::2] = torch.cos(position * div_term) # odd dims pe = pe.unsqueeze(0) # [1, max_len, d_model] self.register_buffer("pe", pe) # not a parameter def forward(self, x: torch.Tensor) -> torch.Tensor:
# x: [batch, seq_len, d_model] x = x + self.pe[:, :x.size(1), :] return self.dropout(x)
class LearnedPositionalEncoding(nn.Module): def __init__(self, d_model: int, max_len: int = 512): super().__init__() self.embedding = nn.Embedding(max_len, d_model) def forward(self, x: torch.Tensor) -> torch.Tensor: positions = torch.arange(x.size(1), device=x.device).unsqueeze(0) return x + self.embedding(positions) ```
Rotary Positional Embedding (RoPE)
Introduced by Su et al. (2021) and used in LLaMA, GPT-NeoX, and many modern LLMs, RoPE encodes position by rotating query and key vectors in 2D subspaces rather than adding a fixed vector to token embeddings. For a query vector at position and key vector at position , the attention score becomes:
Explanation: By applying a rotation matrix to queries and to keys before computing their dot product, the resulting score depends only on the relative offset , natively giving the model relative position sensitivity without modifying the architecture. Here is a block-diagonal rotation matrix constructed from the same sinusoidal frequencies, applied directly to the head dimension of Q and K projections. RoPE has become the dominant positional encoding scheme in large-scale language models as of 2024.
Vaswani was a senior research scientist at Google Brain when he led the team that published "Attention Is All You Need" (2017), which introduced both the Transformer architecture and the sinusoidal positional encoding scheme that remains a standard baseline today. His specific contribution to positional encoding was the insight that fixed sinusoidal functions of different frequencies would give the model a way to attend to relative positions through learned linear combinations — analogous to how Fourier analysis decomposes signals. In a remarkable twist, Vaswani later left Google to co-found Essential AI, and the paper he is most famous for — arguably the most influential ML paper of the 2010s — was nearly not published because internal reviewers initially doubted that attention alone, without recurrence, could be competitive.
Su is a Chinese AI researcher and prolific blogger (his blog "科学空间" has been influential in the Chinese ML community) who derived RoPE in 2021 as a theoretically principled approach to encoding relative positions through geometric rotations in complex space. His key insight was that the inner product of two rotated vectors naturally factorizes into a function of their positional difference, making relative encoding exact rather than approximate. RoPE was initially published on his blog before appearing as a formal paper, and its adoption in Meta's LLaMA family and EleutherAI's GPT-NeoX made it arguably the most widely deployed positional encoding scheme in production LLMs by 2023–2024.
Intuition
Imagine you're a librarian who needs to place books on shelves without any labels — just the content of each book. You could read every book and arrange them by topic, but you'd lose track of which copy is which when you have duplicates, and you'd have no sense of order. Positional encoding is like stamping each book with a unique barcode when it arrives: the barcode doesn't change what's inside the book, but it tells you exactly where it belongs in the sequence of arrivals. Now think about how to design that barcode. You could use sequential integers (1, 2, 3, ...) — that's learned absolute embedding. But the sinusoidal scheme does something cleverer: it's like encoding the time on a clock face, where the hour hand tells you roughly where you are in the day (low frequency, coarse), the minute hand narrows it down (medium frequency), and the second hand gives exact precision (high frequency). Each dimension pair in the positional encoding is one of these "hands," oscillating at a different rate. The model can read the combination of all hands to pinpoint exactly which position it's looking at — and crucially, the difference between two positions (e.g., "5 minutes apart") looks the same regardless of what time of day it is, giving the model relative position sensitivity for free. RoPE takes this even further: instead of adding a clock-stamp to each word's meaning before showing it to the attention mechanism, RoPE rotates the word's meaning vector by an angle proportional to its position — so when the attention mechanism compares two words, the angle between them encodes exactly how far apart they are. It's the difference between writing the time on a note attached to a compass needle vs. pointing the compass needle to indicate the time.