RoPE encodes the position of each token by rotating consecutive pairs of dimensions in the query and key vectors using position-dependent angles. Because the rotation is applied to both Q and K before their dot product, the attention score between two tokens depends only on their relative distance — the model naturally captures “token A is three positions before token B” without needing a separate positional embedding added to the residual stream.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/itsubaki/gpt/llms.txt
Use this file to discover all available pages before exploring further.
RoPEFunc type alias
RoPEFunc is a curried function type. The outer call accepts the current token offset (used during KV-cache-based generation to indicate how many tokens have already been processed), and returns an autograd-compatible function that applies the rotation to a (B, H, C, D) tensor. Both the forward and backward passes are implemented on the underlying RoPET struct.
Constructor and precomputed tables
RoPE allocates two flat slices — cos and sin — of length contextLen × (embedDim/2). Each entry at pos*halfDim + i holds the cosine or sine of the angle for position pos and dimension pair i. These tables are computed once at model construction time and reused for every forward pass.
Parameters
| Parameter | Description |
|---|---|
theta | Base frequency (default 10000); higher values slow down the frequency decay across dimensions |
embedDim | Must be even; the table covers embedDim/2 dimension pairs |
contextLen | Maximum number of positions; also the bound for the offset + C clamp |
Rotation formula
The forward pass iterates over every(batch, head, position, dimension-pair) combination and applies a 2D rotation:
d:
θ_pos,d = pos / theta^(2d/embedDim). Lower-indexed dimension pairs rotate at high frequency (small denominator) and higher-indexed pairs rotate slowly, giving the model a range of periodicities to represent position at different scales.
The theta hyperparameter
The base theta (default 10000, as in the original RoPE paper) controls the frequency spectrum:
i = 0:freq = 1.0— one full rotation every2πtokens (high frequency).i = embedDim/2 - 1:freq ≈ 1 / theta— very slow rotation (low frequency).
theta (e.g. 500000 used by LLaMA 3) spreads the frequency range further, helping the model generalize to longer contexts. The default 10000 suits shorter contexts like MaxContextLen = 256.
Offset during KV-cache generation
WhenuseCache is active, the attention layer passes a non-zero offset to RoPEFunc for every generation step after the first:
offset shifts the position index so that a single new token at logical position offset receives the correct rotational angles from the precomputed table rather than always starting from position 0.
Position clamping
If the accumulated offset would exceed the precomputed table,clamp prevents an out-of-bounds index:
offset + C > contextLen, the effective offset is set to contextLen - C, so the last C rows of the table are reused. This is a safe fallback but generating beyond contextLen tokens will degrade positional accuracy — stay within MaxContextLen for best results.
Backward pass (conjugate rotation)
RoPE is differentiable. The backward pass applies the conjugate (transpose) rotation to the upstream gradient:The single
RoPEFunc returned by function.RoPE(...) is shared across all transformer blocks. Each call to the closure creates a fresh RoPET struct with the desired offset, but the underlying cos and sin slices are shared by reference, keeping memory usage proportional to contextLen × embedDim / 2 regardless of model depth.