VerifiedarXiv:2104.0986425 min
Architecture · Position encoding

RoPE: RoFormer, Enhanced Transformer with Rotary Position Embedding

Rotate each query and key by an angle set by its position, and the attention score depends on position only through the distance between the two tokens.

RoFormer replaces the position vector that a Transformer adds to each token with a rotation of the query and key inside attention. The rotation has no learned parameters, and LLaMA, Mistral, PaLM and GPT-NeoX all use it.

Explaining the paperRoFormer: Enhanced Transformer with Rotary Position EmbeddingSu, Lu, Pan, Murtadha, Wen, Liu · Zhuiyi Technology · arXiv 2021, revised 2023 · arXiv:2104.09864 ↗

The construction rests on one identity: rotating a vector by mθ and another by nθ, then taking their dot product, gives the same number as rotating only the second by (n − m)θ. The page builds RoPE from that identity, runs it on an eight-number example, follows the paper's decay bound and its linear-attention variant, and ends with how Position Interpolation, NTK-aware scaling and YaRN change the rotation speeds to run past the training length.

Attention ignores word order

Self-attention weighs every pair of tokens by a dot product. For a query at position mm and a key at position nn, with head width dd, the weight is

am,n=exp⁡ ⁣(qm⊤kn/d)∑j=1Nexp⁡ ⁣(qm⊤kj/d),om=∑n=1Nam,n vna_{m,n} = \frac{\exp\!\big(\mathbf{q}_m^\top \mathbf{k}_n/\sqrt{d}\big)}{\sum_{j=1}^{N}\exp\!\big(\mathbf{q}_m^\top \mathbf{k}_j/\sqrt{d}\big)}, \qquad \mathbf{o}_m = \sum_{n=1}^{N} a_{m,n}\,\mathbf{v}_n
(1)

and the output om\mathbf{o}_m is a weighted average of the value vectors. In the original Transformer the query and key are linear projections of the token embeddings, qm=Wqxm\mathbf{q}_m = \mathbf{W}_q\mathbf{x}_m and kn=Wkxn\mathbf{k}_n = \mathbf{W}_k\mathbf{x}_n, and an embedding is a function of the word alone. Move “mat” from position 6 to position 2 and its key does not change, so its score against “sat” does not change. Permute the whole sentence and every output is permuted the same way: self-attention is permutation-equivariant. “The cat sat on the mat” and “the mat sat on the cat” give the same outputs, attached to different slots.

Figure 1 shows the weights from the query “sat” to five words. Cycle the word order and watch the heights and the corner readout for “mat”: they travel with the words and no number changes.

Figure 1 · attention without position
originalq·k/√d(sat,mat) = -0.05weight = 0.13 (never moves)
Attention weights from the query “sat” to five words. The highlighted key “mat” has a corner readout of its scaled score q⊤k/d\mathbf{q}^\top\mathbf{k}/\sqrt{d} and its softmax weight. The slider rotates the word order; each bar moves with its word and keeps its height, because without a position signal the score depends only on the two content vectors.

Every Transformer therefore injects position somewhere. Before RoFormer the options came in two families, which the paper surveys in its Section 2: absolute encodings add a vector for position mm to the token at mm, and relative encodings change each pair's score according to the offset between the two tokens.

Position encodings before RoPE

The original Transformer adds a fixed sinusoidal vector pm\mathbf{p}_m to each embedding: coordinate pair tt of pm\mathbf{p}_m is the sine and cosine of m/100002t/dm/10000^{2t/d}, so each pair oscillates at its own frequency. BERT and GPT-2 instead learn pm\mathbf{p}_m as a table with one row per position up to a maximum length, and a learned table has no row for any position past that maximum. Either way the query becomes Wq(xm+pm)\mathbf{W}_q(\mathbf{x}_m + \mathbf{p}_m), and the score expands into four terms (the paper's Eq. 6):

qm⊤kn=xm⊤Wq⊤Wkxn+xm⊤Wq⊤Wkpn+pm⊤Wq⊤Wkxn+pm⊤Wq⊤Wkpn\mathbf{q}_m^\top\mathbf{k}_n = \mathbf{x}_m^\top\mathbf{W}_q^\top\mathbf{W}_k\mathbf{x}_n + \mathbf{x}_m^\top\mathbf{W}_q^\top\mathbf{W}_k\mathbf{p}_n + \mathbf{p}_m^\top\mathbf{W}_q^\top\mathbf{W}_k\mathbf{x}_n + \mathbf{p}_m^\top\mathbf{W}_q^\top\mathbf{W}_k\mathbf{p}_nqm⊤kn=xm⊤Wq⊤Wkxn+xm⊤Wq⊤Wkpn+pm⊤Wq⊤Wkxn+pm⊤Wq⊤Wkpn\begin{aligned} \mathbf{q}_m^\top\mathbf{k}_n &= \mathbf{x}_m^\top\mathbf{W}_q^\top\mathbf{W}_k\mathbf{x}_n + \mathbf{x}_m^\top\mathbf{W}_q^\top\mathbf{W}_k\mathbf{p}_n \\ &\quad + \mathbf{p}_m^\top\mathbf{W}_q^\top\mathbf{W}_k\mathbf{x}_n + \mathbf{p}_m^\top\mathbf{W}_q^\top\mathbf{W}_k\mathbf{p}_n \end{aligned}
(2)

The first term compares content with content. The second and third compare one token's content with the other token's absolute position, and the fourth compares the two absolute positions through the learned matrix Wq⊤Wk\mathbf{W}_q^\top\mathbf{W}_k. Nothing in (2) makes these terms depend on mm and nn only through their difference, so the same two words three tokens apart can score differently at positions (3, 6) and at (103, 106), and the model has to learn from its training positions alone that the offset is what matters.

Relative encodings edit (2) directly. Shaw, Uszkoreit and Vaswani (2018) add to the key a learned vector for the clipped distance clip(m−n,rmin⁡,rmax⁡)\mathrm{clip}(m-n, r_{\min}, r_{\max}). Transformer-XL replaces pn\mathbf{p}_n by a sinusoidal encoding of m−nm-n and the query-side position terms by two learned vectors. T5 drops the position terms and adds one learned scalar per relative distance bucket, bm,nb_{m,n}, to the content score. Each of these is a term computed for a particular (m,n)(m, n) pair, and RoFormer's introduction notes that because they “add the position information to the context representation” they are “unsuitable for the linear self-attention architecture”. The linear-attention section below shows why.

RoFormer asks for the relative property up front. Find functions fqf_q and fkf_k that put position into the query and key such that their inner product depends on the two embeddings and the offset only (the paper's Eq. 11):

⟨fq(xm,m), fk(xn,n)⟩=g(xm,xn,m−n)\big\langle f_q(\mathbf{x}_m, m),\, f_k(\mathbf{x}_n, n)\big\rangle = g(\mathbf{x}_m, \mathbf{x}_n, m-n)
(3)

If (3) holds, a pair of tokens at a given offset gets the same score at position 5 and at position 50,000, and attention needs no extra term per pair.

How RoPE works: rotate the query and key

Start with d=2d = 2, so the projected query q=Wqxm\mathbf{q} = \mathbf{W}_q\mathbf{x}_m and key k=Wkxn\mathbf{k} = \mathbf{W}_k\mathbf{x}_n are arrows in a plane. RoPE rotates the query by the angle mθm\theta and the key by nθn\theta, for a fixed rate θ\theta:

fq(xm,m)=Rmθ Wqxm,fk(xn,n)=Rnθ Wkxn,Rα=(cos⁡α−sin⁡αsin⁡αcos⁡α)f_q(\mathbf{x}_m, m) = \mathbf{R}_{m\theta}\,\mathbf{W}_q\mathbf{x}_m, \quad f_k(\mathbf{x}_n, n) = \mathbf{R}_{n\theta}\,\mathbf{W}_k\mathbf{x}_n, \quad \mathbf{R}_{\alpha} = \begin{pmatrix}\cos\alpha & -\sin\alpha\\ \sin\alpha & \cos\alpha\end{pmatrix}fq(xm,m)=Rmθ Wqxm,fk(xn,n)=Rnθ Wkxn,Rα=(cos⁡α−sin⁡αsin⁡αcos⁡α)\begin{gathered} f_q(\mathbf{x}_m, m) = \mathbf{R}_{m\theta}\,\mathbf{W}_q\mathbf{x}_m, \quad f_k(\mathbf{x}_n, n) = \mathbf{R}_{n\theta}\,\mathbf{W}_k\mathbf{x}_n, \\ \mathbf{R}_{\alpha} = \begin{pmatrix}\cos\alpha & -\sin\alpha\\ \sin\alpha & \cos\alpha\end{pmatrix} \end{gathered}
(4)

A rotation keeps lengths, and its transpose is the rotation by the opposite angle, so Rmθ⊤Rnθ=R(n−m)θ\mathbf{R}_{m\theta}^\top\mathbf{R}_{n\theta} = \mathbf{R}_{(n-m)\theta}. The score is therefore

(Rmθq)⊤(Rnθk)=q⊤Rmθ⊤Rnθ k=q⊤R(n−m)θ k(\mathbf{R}_{m\theta}\mathbf{q})^\top(\mathbf{R}_{n\theta}\mathbf{k}) = \mathbf{q}^\top\mathbf{R}_{m\theta}^\top\mathbf{R}_{n\theta}\,\mathbf{k} = \mathbf{q}^\top\mathbf{R}_{(n-m)\theta}\,\mathbf{k}
(5)

and both absolute positions have dropped out: the right side depends on the content vectors and on n−mn-m. In geometric terms, a dot product is ∣q∣∣k∣|\mathbf{q}||\mathbf{k}| times the cosine of the angle between the arrows. Rotating the query by mθm\theta and the key by nθn\theta changes that angle by (n−m)θ(n-m)\theta, so the score is ∣q∣∣k∣cos⁡((n−m)θ+φ)|\mathbf{q}||\mathbf{k}|\cos((n-m)\theta + \varphi), where φ\varphi is the angle from q\mathbf{q} to k\mathbf{k} before any rotation.

A numerical check with θ=0.1\theta = 0.1 and q=k=(1,0)\mathbf{q} = \mathbf{k} = (1, 0): at m=5m = 5, n=7n = 7 the query points at 0.5 rad and the key at 0.7 rad, and (0.878,0.479)⋅(0.765,0.644)=0.980(0.878, 0.479)\cdot(0.765, 0.644) = 0.980, which is cos⁡0.2\cos 0.2. At m=105m = 105, n=107n = 107 the arrows point at 10.5 and 10.7 rad, both different from before, and the dot product is again cos⁡0.2=0.980\cos 0.2 = 0.980.

The paper states the same solution with complex numbers (its Eq. 12). Read the two coordinates of a 2D vector as the real and imaginary parts of one complex number; rotating by mθm\theta is then multiplication by eimθe^{\mathrm{i}m\theta}, and the dot product of two vectors aa and bb is Re[a b∗]\mathrm{Re}[a\,b^*]:

fq=(Wqxm) eimθ,fk=(Wkxn) einθ,⟨fq,fk⟩=Re[(Wqxm)(Wkxn)∗ ei(m−n)θ]f_q = (\mathbf{W}_q\mathbf{x}_m)\,e^{\mathrm{i}m\theta}, \quad f_k = (\mathbf{W}_k\mathbf{x}_n)\,e^{\mathrm{i}n\theta}, \quad \langle f_q, f_k\rangle = \mathrm{Re}\big[(\mathbf{W}_q\mathbf{x}_m)(\mathbf{W}_k\mathbf{x}_n)^*\,e^{\mathrm{i}(m-n)\theta}\big]fq=(Wqxm) eimθ,fk=(Wkxn) einθ,⟨fq,fk⟩=Re[(Wqxm)(Wkxn)∗ ei(m−n)θ]\begin{gathered} f_q = (\mathbf{W}_q\mathbf{x}_m)\,e^{\mathrm{i}m\theta}, \quad f_k = (\mathbf{W}_k\mathbf{x}_n)\,e^{\mathrm{i}n\theta}, \\ \langle f_q, f_k\rangle = \mathrm{Re}\big[(\mathbf{W}_q\mathbf{x}_m)(\mathbf{W}_k\mathbf{x}_n)^*\,e^{\mathrm{i}(m-n)\theta}\big] \end{gathered}
(6)

The paper writes the offset as m−nm-n here and as n−mn-m in its matrix form; the two differ by the sign of θ\theta, and this page uses n−mn-m throughout. Figure 2 draws the 2D case at θ=0.4\theta = 0.4, with unit vectors so that the score is the cosine alone.

Figure 2 · the score depends only on n − m
Unit vectors Rmq (teal) and Rnk (amber), each rotated by its own position; the dashed ghosts are the unrotated q0\mathbf{q}_0 and k0\mathbf{k}_0. The right panel gives n−mn-m and the score cos⁡((n−m)θ+φ)\cos((n-m)\theta + \varphi). Move mm and nn separately and the score changes; turn on lock offset and moving either slider moves both, with the score fixed. θ=0.4\theta = 0.4 is chosen for legibility; in a d=128d = 128 head the fastest plane has θ1=1\theta_1 = 1 and the slowest θ64≈1.15×10−4\theta_{64} \approx 1.15\times10^{-4}.

Why a rotation and not some other position-dependent map? Section 3.4.1 of the paper derives it. Write fqf_q, fkf_k and gg each as a length and an angle. Setting n=mn = m in (3), and requiring that position 0 leaves a vector unchanged, gives two conditions: the product of the query and key lengths at any common position equals ∣q∣∣k∣|\mathbf{q}||\mathbf{k}|, and the difference of their angles equals the difference before encoding. The paper takes the “straightforward solution” for the lengths, which is to leave them alone, and finds the angle must be the content angle plus a term ϕ(m)\phi(m) shared by queries and keys. Setting n=m+1n = m + 1 then shows that ϕ(m+1)−ϕ(m)\phi(m+1) - \phi(m) is the same for every mm, so ϕ(m)=mθ+γ\phi(m) = m\theta + \gamma, and the paper sets γ=0\gamma = 0. A map that keeps the length and adds an angle growing linearly with position is a rotation by mθm\theta. The length condition admits other solutions in principle; the paper picks the simplest and does not claim it is unique.

Many planes, many speeds

A real head has d=64d = 64 or 128128 dimensions. RoPE splits the dd coordinates into d/2d/2 adjacent pairs, (x1,x2),(x3,x4),…(x_1, x_2), (x_3, x_4), \ldots, treats each pair as its own plane, and rotates plane ii by mθim\theta_i:

RΘ,md=(Rmθ1Rmθ2⋱Rmθd/2)\mathbf{R}^d_{\Theta,m} = \begin{pmatrix} \mathbf{R}_{m\theta_1} & & & \\ & \mathbf{R}_{m\theta_2} & & \\ & & \ddots & \\ & & & \mathbf{R}_{m\theta_{d/2}} \end{pmatrix}
(7)
θi=10000−2(i−1)/d,i=1,2,…,d/2\theta_i = 10000^{-2(i-1)/d}, \qquad i = 1, 2, \ldots, d/2
(8)

A dot product of two dd-vectors is the sum of the d/2d/2 per-plane dot products, and (5) holds in each plane, so the full score is xm⊤Wq⊤RΘ,n−mdWkxn\mathbf{x}_m^\top\mathbf{W}_q^\top\mathbf{R}^d_{\Theta,n-m}\mathbf{W}_k\mathbf{x}_n with RΘ,n−md=(RΘ,md)⊤RΘ,nd\mathbf{R}^d_{\Theta,n-m} = (\mathbf{R}^d_{\Theta,m})^\top\mathbf{R}^d_{\Theta,n} (the paper's Eq. 16). The rates come from the fixed schedule (8), so the projection matrices Wq\mathbf{W}_q and Wk\mathbf{W}_k remain the only learned weights and RoPE adds no parameters. The base 10000 and the geometric spacing are the sinusoidal encoding's; the paper says it follows Vaswani et al. in choosing them.

At d=128d = 128 there are 64 planes. Plane 1 turns θ1=1\theta_1 = 1 rad per token, a full turn every 2π≈6.282\pi \approx 6.28 tokens. Each later plane is slower by a factor 100002/128≈1.15510000^{2/128} \approx 1.155: plane 13 has a wavelength (tokens per full turn, 2π/θi2\pi/\theta_i) of about 35 tokens, plane 29 about 353, plane 47 about 4,700, and plane 64, with θ64=10000−126/128≈1.15×10−4\theta_{64} = 10000^{-126/128} \approx 1.15\times10^{-4}, about 54,000.

One plane alone cannot locate an offset: at θ=0.1\theta = 0.1, offsets 0 and 63 differ by 6.3 rad, almost exactly one full turn, so the plane gives them nearly the same angle. A fast plane separates neighbors (adjacent tokens differ by 1 rad in plane 1) but repeats every 6 tokens; a slow plane does not repeat within any practical context, but adjacent tokens differ by only 0.000115 rad in plane 64. Taken together, the 64 angles pin down the offset at every scale, the way the hour, minute and second hands of a clock fix a time that no single hand could.

Figure 3 shows five of the 64 planes as dials driven by one position. At the default m=64m = 64, plane 1 has made about ten turns and plane 64 about a thousandth of one; push the position past 54,000 to watch plane 64 finish its first turn.

Figure 3 · one position, five rotation speeds
64
Planes 1, 13, 29, 47 and 64 of a d=128d = 128 head, each a dial turning at θi=10000−2(i−1)/d\theta_i = 10000^{-2(i-1)/d}, from the fastest to the slowest. One slider sets the position for all five; it is logarithmic, from 0 to 99,999. Beside each dial are its wavelength in tokens and the number of turns it has made at position mm.

Figure 4 tests (3) numerically at d=16d = 16, with random token vectors and random projection matrices. A query and a key a fixed offset apart slide along the sequence together. The amber curve adds sinusoidal position vectors before the projection, as in (2); the teal curve applies (7) after it. Change the offset or draw new tokens: the teal spread stays at 0.00 and the amber curve keeps moving with the shift, because the cross terms in (2) depend on mm and nn separately.

Figure 4 · the shift test, additive vs rotary
340
A query at m=sm = s and a key at n=s+offsetn = s + \text{offset}, slid along the sequence by ss from 0 to 240, with d=16d = 16. Amber: sinusoidal vectors added to the embeddings before projection. Teal: RoPE applied to the projected query and key. The readout gives both scores at the marked shift and each curve's spread over all shifts. New tokens redraws the content vectors and projections.

Implementing RoPE without a matrix multiply

RΘ,md\mathbf{R}^d_{\Theta,m} is a d×dd\times d matrix with only 2d2d nonzero entries, so multiplying by it densely would waste almost all of the d2d^2 multiplies. Section 3.4.2 of the paper writes the same product element-wise, with ⊗\otimes for element-wise multiplication:

RΘ,mdx=(x1x2x3x4⋮)⊗(cos⁡mθ1cos⁡mθ1cos⁡mθ2cos⁡mθ2⋮)+(−x2x1−x4x3⋮)⊗(sin⁡mθ1sin⁡mθ1sin⁡mθ2sin⁡mθ2⋮)\mathbf{R}^d_{\Theta,m}\mathbf{x} = \begin{pmatrix}x_1\\x_2\\x_3\\x_4\\\vdots\end{pmatrix}\otimes\begin{pmatrix}\cos m\theta_1\\\cos m\theta_1\\\cos m\theta_2\\\cos m\theta_2\\\vdots\end{pmatrix} + \begin{pmatrix}-x_2\\x_1\\-x_4\\x_3\\\vdots\end{pmatrix}\otimes\begin{pmatrix}\sin m\theta_1\\\sin m\theta_1\\\sin m\theta_2\\\sin m\theta_2\\\vdots\end{pmatrix}
(9)

The second vector swaps the two coordinates of each pair and negates the first of them, which is all a 2D rotation needs besides the cosine term. The cosine and sine tables depend only on the position, so they are computed once per sequence length and shared by every layer and head.

A worked example at d=8d = 8: four planes with rates θ=(1,0.1,0.01,0.001)\theta = (1, 0.1, 0.01, 0.001). Take the projected query and key

q=(0.5, 1.0, −1.0, 0.5, 0.8, 0.2, 0.3, −0.6),k=(1.0, 0.3, 0.4, −0.7, 0.6, 0.9, −0.2, 0.5)\mathbf{q} = (0.5,\ 1.0,\ -1.0,\ 0.5,\ 0.8,\ 0.2,\ 0.3,\ -0.6), \qquad \mathbf{k} = (1.0,\ 0.3,\ 0.4,\ -0.7,\ 0.6,\ 0.9,\ -0.2,\ 0.5)q=(0.5, 1.0, −1.0, 0.5, 0.8, 0.2, 0.3, −0.6),k=(1.0, 0.3, 0.4, −0.7, 0.6, 0.9, −0.2, 0.5)\begin{aligned} \mathbf{q} &= (0.5,\ 1.0,\ -1.0,\ 0.5,\ 0.8,\ 0.2,\ 0.3,\ -0.6), \\ \mathbf{k} &= (1.0,\ 0.3,\ 0.4,\ -0.7,\ 0.6,\ 0.9,\ -0.2,\ 0.5) \end{aligned}

whose plain dot product is 0.35, made of per-plane parts 0.80, −0.75, 0.66 and −0.36. Put the query at m=2m = 2: the planes turn by 2, 0.2, 0.02 and 0.002 rad, and (9) gives

RΘ,28 q=(−1.117, 0.039, −1.079, 0.291, 0.796, 0.216, 0.301, −0.599)\mathbf{R}^8_{\Theta,2}\,\mathbf{q} = (-1.117,\ 0.039,\ -1.079,\ 0.291,\ 0.796,\ 0.216,\ 0.301,\ -0.599)RΘ,28 q=(−1.117, 0.039, −1.079, 0.291,0.796, 0.216, 0.301, −0.599)\begin{aligned} &\mathbf{R}^8_{\Theta,2}\,\mathbf{q} = (-1.117,\ 0.039,\ -1.079,\ 0.291, \\ &\quad 0.796,\ 0.216,\ 0.301,\ -0.599) \end{aligned}

Put the key at n=5n = 5 and the score is −1.2547. Its four per-plane parts are −0.672, −0.864, 0.642 and −0.360. Plane 4 has turned the pair by only 0.003 rad relative to each other and keeps its unrotated part of −0.36; plane 1 has turned them by 3 rad, and its part has gone from +0.80 to −0.67. Move both tokens to (102, 105) or to (1002, 1005) and the score is −1.2547 again, to every printed digit. Move the key alone to n=6n = 6 and the score becomes −1.7763; to n=50n = 50, −0.7853.

In code, RoPE is a function applied to the projected queries and keys of every attention layer, just before the scores. The listing uses NumPy-style names and the 0-based index θi=10000−2i/d\theta_i = 10000^{-2i/d}, i=0,…,d/2−1i = 0, \ldots, d/2-1, which gives the same set of rates as (8).

# RoPE for one attention head. x: (seq_len, d) token states, d even.
def rope(v, base=10000.0):              # v: (seq_len, d), already projected
    seq_len, d = v.shape
    i = arange(d // 2)                  # plane index, 0-based here
    theta = base ** (-2 * i / d)        # (d/2,) fixed rates, theta[0] = 1
    ang = arange(seq_len)[:, None] * theta   # (seq_len, d/2): m * theta_i
    c, s = cos(ang), sin(ang)
    a, b = v[:, 0::2], v[:, 1::2]       # the two coordinates of every plane
    out = empty_like(v)
    out[:, 0::2] = a * c - b * s        # 2D rotation of each pair
    out[:, 1::2] = a * s + b * c
    return out

q = rope(x @ W_q)                       # rotate after projecting
k = rope(x @ W_k)
v = x @ W_v                             # values are never rotated
scores = q @ k.T / sqrt(d)              # entry (m, n) depends on n - m
# no new parameters: gradients reach W_q and W_k through the rotation

The pairing of coordinates differs between code bases. Meta's LLaMA reference code pairs adjacent coordinates, as in (9), by viewing them as complex numbers. Hugging Face's Llama implementation pairs coordinate jj with j+d/2j + d/2 (its rotate_half), and its checkpoint conversion script permutes the rows of Wq\mathbf{W}_q and Wk\mathbf{W}_k so that both layouts compute the same scores. Weights trained under one layout and loaded into code using the other without that permutation still run, but they rotate the wrong pairs of coordinates.

Why the attention score decays with distance

Read each plane of the query and key as a complex number, q(i)q_{(i)} and k(i)k_{(i)}. The score (5), summed over planes, is then a sum of d/2d/2 rotating terms:

(RΘ,mdq)⊤(RΘ,ndk)=Re∑i=1d/2hi ei(n−m)θi,hi=q(i)‾ k(i)(\mathbf{R}^d_{\Theta,m}\mathbf{q})^\top(\mathbf{R}^d_{\Theta,n}\mathbf{k}) = \mathrm{Re}\sum_{i=1}^{d/2} h_i\, e^{\mathrm{i}(n-m)\theta_i}, \qquad h_i = \overline{q_{(i)}}\,k_{(i)}
(10)

The coefficient hih_i holds plane ii's content; its real part is that plane's unrotated dot product. (The paper's Eq. 35 conjugates the key instead and gets the exponent (m−n)θi(m-n)\theta_i; the two sums are complex conjugates with the same real part.)

Set the content aside by taking every hi=1h_i = 1. What remains is a sum of 64 unit arrows ei(n−m)θie^{\mathrm{i}(n-m)\theta_i}. At offset 0 they all point along the real axis and the sum has length 64. As the offset grows, plane 1's arrow turns 1 rad per token and plane 64's turns 0.000115 rad per token, so the arrows fan out around the circle and partly cancel. Once they point in roughly unrelated directions, the sum behaves like a random walk of 64 unit steps, whose length is of order 64=8\sqrt{64} = 8. That d/2\sqrt{d/2} level is a heuristic for intuition; the paper's result is the bound below. In Figure 5, drag the offset and compare the bold sum with the dashed circle.

Figure 5 · the 64 rotating terms at one offset
The 64 terms ei(n−m)θie^{\mathrm{i}(n-m)\theta_i} of a d=128d = 128 head as arrows on the unit circle, colored from teal (plane 1, fastest) to amber (plane 64, slowest). The bold arrow is their sum, scaled so that a length of 64 reaches the circle; the dashed circle marks d/2=8\sqrt{d/2} = 8. Drag the offset from 0, where all arrows align, up to 49,999 (the slider is logarithmic).

The paper bounds the sum with Abel summation, the discrete version of integration by parts. Let SjS_j be the partial sum of the first jj unit arrows. Each term of (10) is hih_i times a difference of consecutive partial sums, and regrouping the sum around the partial sums (with hd/2+1=0h_{d/2+1} = 0) moves the differences onto the hih_i. The triangle inequality then gives (the paper's Eq. 37, with 1-based indices):

∣∑i=1d/2hi ei(n−m)θi∣  ≤  (max⁡i ∣hi+1−hi∣)∑j=1d/2∣Sj∣,Sj=∑i=1jei(n−m)θi\Big|\sum_{i=1}^{d/2} h_i\, e^{\mathrm{i}(n-m)\theta_i}\Big| \;\le\; \Big(\max_i\, |h_{i+1}-h_i|\Big)\sum_{j=1}^{d/2} |S_j|, \qquad S_j = \sum_{i=1}^{j} e^{\mathrm{i}(n-m)\theta_i}∣∑i=1d/2hi ei(n−m)θi∣  ≤  (max⁡i ∣hi+1−hi∣)∑j=1d/2∣Sj∣,Sj=∑i=1jei(n−m)θi\begin{gathered} \Big|\sum_{i=1}^{d/2} h_i\, e^{\mathrm{i}(n-m)\theta_i}\Big| \;\le\; \Big(\max_i\, |h_{i+1}-h_i|\Big)\sum_{j=1}^{d/2} |S_j|, \\ S_j = \sum_{i=1}^{j} e^{\mathrm{i}(n-m)\theta_i} \end{gathered}
(11)

The first factor depends only on the content of the query and key. The second depends only on the offset and the rates. The paper plots its average, 1d/2∑j∣Sj∣\tfrac{1}{d/2}\sum_j |S_j|, against the offset (its Figure 2), observes that it decays, and ties this to the intuition that “a pair of tokens with a long relative distance should have less connection”. Figure 6 plots the same factor, normalized to 1 at offset 0 (before normalizing it starts at (d/2+1)/2≈d/4(d/2+1)/2 \approx d/4, since ∣Sj∣=j|S_j| = j there).

Figure 6 · the geometric factor of the decay bound
The factor 2d∑j∣Sj∣\tfrac{2}{d}\sum_j |S_j| for d=128d = 128 against the offset ∣m−n∣|m-n|, normalized to 1 at offset 0. The base slider replaces the 10000 in (8), from 100 to 1,000,000. PI ×4 divides positions by 4; NTK ×4 multiplies the base by 4128/126≈4.094^{128/126} \approx 4.09. The faint dashed teal curve is unpatched RoPE at the same base. The dotted line at 32 tokens is a demonstration training length, not a real model's.

At base 10000 the factor halves within the first 16 tokens and then oscillates on a slowly falling trend. A larger base slows every plane and moves the fall to longer offsets. Two limits on what (11) says: it bounds the size of the score and does not predict it, so a query and key with matching content can still score high at long range; and the geometric factor does not fall monotonically, because at some offsets several planes come back into partial alignment and the factor rises for a while.

RoPE inside linear attention

Softmax attention (1) forms all N2N^2 query-key scores for a sequence of NN tokens. Linear attention (Katharopoulos et al., 2020) replaces exp⁡(q⊤k/d)\exp(\mathbf{q}^\top\mathbf{k}/\sqrt{d}) by a product of feature maps ϕ(q)⊤ϕ(k)\phi(\mathbf{q})^\top\phi(\mathbf{k}), with the positive map ϕ(x)=elu(x)+1\phi(x) = \mathrm{elu}(x) + 1. Attention becomes (the paper's Eq. 18)

Attnm=∑nϕ(qm)⊤ϕ(kn) vn∑nϕ(qm)⊤ϕ(kn)\mathrm{Attn}_m = \frac{\sum_{n} \phi(\mathbf{q}_m)^\top\phi(\mathbf{k}_n)\,\mathbf{v}_n}{\sum_{n} \phi(\mathbf{q}_m)^\top\phi(\mathbf{k}_n)}
(12)

and matrix products can be regrouped. Written as a row vector, the numerator is ϕ(qm)⊤S\phi(\mathbf{q}_m)^\top \mathbf{S} with

S=∑n=1Nϕ(kn) vn⊤∈Rd×d,z=∑n=1Nϕ(kn)\mathbf{S} = \sum_{n=1}^{N}\phi(\mathbf{k}_n)\,\mathbf{v}_n^\top \in \mathbb{R}^{d\times d}, \qquad \mathbf{z} = \sum_{n=1}^{N}\phi(\mathbf{k}_n)
(13)

and the denominator is ϕ(qm)⊤z\phi(\mathbf{q}_m)^\top\mathbf{z}. S\mathbf{S} and z\mathbf{z} do not depend on mm: one pass over the keys builds them, and each query then costs one vector-matrix product, so the total grows as NN instead of N2N^2. At N=4096N = 4096 and d=64d = 64, softmax attention forms about 16.8 million scores per head, while linear attention adds 4,096 outer products into one 64×6464\times 64 matrix. For causal attention each query may only see keys up to its own position, so S\mathbf{S} becomes a running sum over n≤mn \le m: still one pass, but each query reads its own prefix sum rather than one shared matrix.

An additive bias does not survive this regrouping. Inside softmax attention, a bias bm,nb_{m,n} turns exp⁡(qm⊤kn)\exp(\mathbf{q}_m^\top\mathbf{k}_n) into exp⁡(qm⊤kn) ebm,n\exp(\mathbf{q}_m^\top\mathbf{k}_n)\,e^{b_{m,n}}, a factor that depends on the query position and the key position together. The linear-attention analogue would multiply each term of (12) by a pair-dependent number, which cannot be moved into a sum shared by all queries, so every pair has to be visited again. This argument is ours; RoFormer only contrasts its multiplicative scheme with the additive ones.

A rotation acts on each vector separately. The paper's Eq. 19 applies it to the outputs of the feature maps and leaves the denominator unrotated:

Attnm=∑n(RΘ,mdϕ(qm))⊤(RΘ,ndϕ(kn)) vn∑nϕ(qm)⊤ϕ(kn)\mathrm{Attn}_m = \frac{\sum_{n} \big(\mathbf{R}^d_{\Theta,m}\phi(\mathbf{q}_m)\big)^\top\big(\mathbf{R}^d_{\Theta,n}\phi(\mathbf{k}_n)\big)\,\mathbf{v}_n}{\sum_{n} \phi(\mathbf{q}_m)^\top\phi(\mathbf{k}_n)}
(14)

In the numerator (RΘ,md)⊤RΘ,nd=RΘ,n−md(\mathbf{R}^d_{\Theta,m})^\top\mathbf{R}^d_{\Theta,n} = \mathbf{R}^d_{\Theta,n-m} again, so each pair's weight is ϕ(qm)⊤RΘ,n−mdϕ(kn)\phi(\mathbf{q}_m)^\top\mathbf{R}^d_{\Theta,n-m}\phi(\mathbf{k}_n), relative for any choice of ϕ\phi. The accumulator survives because the query's rotation does not depend on nn and moves out of the sum. The paper prints only (14); the factored form is our derivation:

∑n(RΘ,mdϕ(qm))⊤RΘ,ndϕ(kn) vn⊤=(RΘ,mdϕ(qm))⊤[∑nRΘ,ndϕ(kn) vn⊤]\sum_{n}\big(\mathbf{R}^d_{\Theta,m}\phi(\mathbf{q}_m)\big)^\top\mathbf{R}^d_{\Theta,n}\phi(\mathbf{k}_n)\,\mathbf{v}_n^\top = \big(\mathbf{R}^d_{\Theta,m}\phi(\mathbf{q}_m)\big)^\top\Big[\sum_{n}\mathbf{R}^d_{\Theta,n}\phi(\mathbf{k}_n)\,\mathbf{v}_n^\top\Big]∑n(RΘ,mdϕ(qm))⊤RΘ,ndϕ(kn) vn⊤=(RΘ,mdϕ(qm))⊤[∑nRΘ,ndϕ(kn) vn⊤]\begin{aligned} &\sum_{n}\big(\mathbf{R}^d_{\Theta,m}\phi(\mathbf{q}_m)\big)^\top\mathbf{R}^d_{\Theta,n}\phi(\mathbf{k}_n)\,\mathbf{v}_n^\top \\ &\quad = \big(\mathbf{R}^d_{\Theta,m}\phi(\mathbf{q}_m)\big)^\top\Big[\sum_{n}\mathbf{R}^d_{\Theta,n}\phi(\mathbf{k}_n)\,\mathbf{v}_n^\top\Big] \end{aligned}
(15)

The bracket is built in one pass with each key rotated by its own position, and each query is rotated by its own position before reading it, so the cost stays linear in NN. Rotation can make some weights ϕ(qm)⊤RΘ,n−mdϕ(kn)\phi(\mathbf{q}_m)^\top\mathbf{R}^d_{\Theta,n-m}\phi(\mathbf{k}_n) negative even though ϕ\phi is positive, so the paper keeps the denominator unrotated “to avoid the risk of dividing zero” and says the resulting weights are “not strictly probabilistic normalized”. Figure 7 contrasts the two data flows.

Figure 7 · one accumulator vs every pair
Attention over NN tokens two ways. RoPE + linear: each key is rotated by its position and added into one accumulator S\mathbf{S}, which each rotated query reads, so the work grows as NN. Softmax, with or without an additive bias: every query meets every key in an N×NN\times N grid. The bars compare NN with N2N^2 as the slider moves NN from 4 to 96.

What the paper measured

Translation. On WMT 2014 English to German (about 4.5 million sentence pairs), a Transformer-base trained in fairseq scores 27.3 BLEU and the same model with RoPE scores 27.5 (Table 1). The paper reports no variance across runs, so the 0.2-point difference has no error bar.

Pre-training. The authors trained bert-base-uncased and the same model with RoPE on BookCorpus and Wikipedia (batch 64, sequences of 512, 100k steps, AdamW at 1e-5), and the RoPE model's masked-language-model loss falls faster (Figure 3, left). The paper describes this as replacing BERT's “sinusoidal” position encoding, but BERT's position embeddings are learned, as the paper's own Section 2.2 says.

GLUE. Fine-tuning that model gives Table 2:

modelMRPCSST-2QNLISTS-BQQPMNLI (m/mm)
BERT (as printed)88.993.590.585.871.284.6/83.4
RoFormer89.590.788.087.086.480.2/79.8

RoFormer is higher on MRPC, STS-B and QQP and lower on SST-2, QNLI and MNLI. The two rows also come from different evaluation sets. The BERT row is, digit for digit, BERT-base's GLUE test-server result from Devlin et al.'s Table 1, while Section 4.3.2 says RoFormer's numbers are “the best-averaged results on the validation set”. The 15-point QQP gap therefore cannot be credited to RoPE, and the table supports no conclusion stronger than “roughly comparable”.

Linear attention. On enwik8 (character-level Wikipedia), a 12-layer Performer with 768 dimensions and 12 heads, at sequence length 1024, reaches a lower training loss sooner with RoPE than without (Figure 3, right). This is a loss curve with and without RoPE inside one linear-attention model; there is no bits-per-character table and no comparison with BERT.

Long Chinese documents. The authors pre-trained a Chinese RoFormer on about 34GB of text in six stages with maximum lengths between 128 and 1,536, then evaluated on CAIL2019-SCM (Xiao et al., 2019): 8,964 triplets of court-case descriptions, mostly longer than 512 characters, where the task is to decide whether case B or case C is closer to case A. Test accuracy (Table 5) is 67.77% for BERT-512, 68.10% for WoBERT-512, 68.29% for RoFormer-512 and 69.79% for RoFormer-1024. At the same 512-token input RoFormer is 0.19 points above WoBERT; the larger gain comes with doubling the input to 1,024 tokens, which the absolute-position baselines were not run at. The text calls this a 1.5% improvement; Table 5 gives 1.69 points on test and 2.00 on validation.

The paper's limitations section concedes that it lacks “thorough explanations” for why RoFormer converges faster, and that for the long-text results “we have not come up with a faithful explanation”.

RoPE spread through its engineering properties rather than through these results. It has no parameters, so there is no position table to outgrow and nothing position-specific to fine-tune. It is applied to the query and key tensors before attention, so it composes with linear attention as above and runs unchanged inside exact attention kernels such as FlashAttention. Its rates and positions are explicit numbers that can be changed after training, which the next section relies on. GPT-NeoX, PaLM, LLaMA and Mistral use RoPE; GPT-3 and OPT used learned absolute positions and BLOOM used ALiBi, a fixed linear distance penalty added to each score.

Running RoPE past its training length

Call the trained context LL and the target L′L', and the extension factor s=L′/Ls = L'/L. Llama 2 was trained at L=4096L = 4096; running it at 32,768 tokens means s=8s = 8. Unchanged RoPE fails there in a specific way, which the YaRN paper describes in terms of wavelengths. With d=128d = 128, planes 47 through 64 have wavelengths longer than 4,096 tokens, so during training those 18 planes never completed a turn: plane ii only produced angles between 0 and 4096 θi4096\,\theta_i. At position 30,000 the same planes reach angles the model was never trained on. The fast planes complete many turns within 4,096 tokens, so every angle they reach at a longer context already occurred in training. The three patches below all slow the slow planes and differ in what they do to the fast ones.

Position Interpolation (Chen et al., 2023) divides every position by ss, which divides every rate by ss. Every angle at the new length then falls inside the trained range. Dividing every rate also lowers resolution: at s=8s = 8, plane 1 turns 0.125 rad per token instead of the 1 rad it turned in training, so adjacent tokens are eight times closer in angle in that plane. PI extended LLaMA models to 32,768 tokens with a fine-tune of at most 1,000 steps.

NTK-aware scaling (bloc97, 2023, written up in the YaRN paper's Appendix A.2) raises the base instead:

b′=b⋅sd/(d−2)b' = b\cdot s^{d/(d-2)}
(16)

which slows plane ii by the factor s2(i−1)/(d−2)s^{2(i-1)/(d-2)}. Plane 1 is unchanged, plane 64 is slowed by exactly ss, and the planes in between are slowed by less than ss. At s=4s = 4, d=128d = 128 the base becomes 10000×4.0910000 \times 4.09. The fast planes keep their resolution, but planes 47 to 63 are slowed by less than ss and still reach angles beyond their trained range.

YaRN (Peng et al., 2023) treats each plane according to how many turns it makes in the trained context, ri=L/λir_i = L/\lambda_i with wavelength λi=2π/θi\lambda_i = 2\pi/\theta_i. A ramp γ(r)\gamma(r) is 0 for r<αr < \alpha, 1 for r>βr > \beta and linear in between, and each rate becomes

θi′=(1−γ(ri)) θis+γ(ri) θi,α=1, β=32\theta_i' = \big(1-\gamma(r_i)\big)\,\frac{\theta_i}{s} + \gamma(r_i)\,\theta_i, \qquad \alpha = 1,\ \beta = 32
(17)

so planes that turn more than 32 times are left alone, planes that turn less than once are divided by ss as in PI, and planes in between are blended. The YaRN paper calls this rescaling “NTK-by-parts”, and YaRN is NTK-by-parts plus an attention temperature: queries and keys are both scaled by 1/t=0.1ln⁡s+1\sqrt{1/t} = 0.1\ln s + 1, which is 1.208 at s=8s = 8. YaRN does not change the base. It extended Llama 2 to 128k tokens with s=32s = 32.

Figure 8 plots all 64 wavelengths before and after each patch. At s=8s = 8: unchanged RoPE has 18 planes past their trained angles and plane 1 at 1 rad per token; NTK-aware has 17 such planes and plane 1 at 1 rad; PI has none, with plane 1 at 0.125 rad; YaRN has none, with plane 1 at 1 rad.

Figure 8 · what each long-context patch does to the 64 rates
8×
Wavelengths of the 64 planes of a d=128d = 128 head on a log scale: dashed for unchanged RoPE, dots after the selected patch. The solid line is the trained context L=4,096L = 4{,}096, the dashed amber line the target sLsL. Amber dots mark planes that would turn past every angle they reached in training. Switch methods and drag ss from 1 to 32; the readout gives plane 1's turn per token and the number of amber planes, and for YaRN the temperature factor.

None of the three changes the RoFormer construction. Each one changes the rates θi\theta_i or the positions fed into (7), and (5) holds for any rates, so scores still depend only on the offset (scaled by 1/s1/s under PI). Each patch is usually followed by a short fine-tune at the new length: at most 1,000 steps for PI's LLaMA models and 400 steps for YaRN's s=16s = 16 Llama 2 model.

Provenance Verified against primary literatureHow we verify
Su et al., RoFormer (2021; v5 2023)The source: the goal (Eq. 11), the 2D solution and its derivation (Eq. 12, Sec. 3.4.1), the d/2-plane rotation and its schedule (Eq. 14-16), the element-wise form (Eq. 34), the long-term decay bound (Eq. 35-37), RoPE with linear attention (Eq. 18-19), and the experiments in Tables 1-5.
Vaswani et al. (2017)The sinusoidal encoding with base 10000 and geometrically spaced frequencies. RoFormer takes the base and the spacing from it ("Following Vaswani et al.") and applies them as rotation rates instead of added vectors.
Shaw et al. (2018), Transformer-XL, T5The relative encodings RoFormer surveys in its Sec. 2.3: a learned vector per clipped distance, a sinusoidal encoding of m - n with two learned vectors, and a learned scalar bias per distance. All of them edit terms of the expanded score.
Katharopoulos et al. (2020)Linear attention with phi(x) = elu(x) + 1 and the associativity rewrite that builds one d-by-d accumulator. The non-causal accumulator is shared by every query; the causal one is a running prefix sum.
Devlin et al. (2019), Table 1BERT-base GLUE test-server results: 84.6/83.4, 71.2, 90.5, 93.5, 85.8, 88.9. These are the BERT numbers in RoFormer's Table 2, which reports its own model on the validation sets.
Meta llama/model.py; HF modeling_llama.pyReference RoPE code. Meta pairs adjacent coordinates with torch.view_as_complex (precompute_freqs_cis, apply_rotary_emb); Hugging Face pairs coordinate j with j + d/2 (rotate_half) and permutes the W_q, W_k rows when converting checkpoints.
Chen et al. (2023); Peng et al. (2023)Position Interpolation (m -> m/s) and YaRN (NTK-by-parts per-plane rescaling with alpha = 1, beta = 32, plus sqrt(1/t) = 0.1 ln s + 1). Both postdate RoFormer v1 by more than two years and are not in the paper.
correctionRoFormer's GLUE comparison (Table 2) is not like for like: the BERT row matches, digit for digit, BERT-base's GLUE test-server results from Devlin et al.'s Table 1, while Sec. 4.3.2 says RoFormer's numbers are best-averaged validation results, so the 15-point QQP gap (71.2 vs 86.4) cannot be credited to RoPE. Even taken at face value the table is mixed (RoFormer is lower on SST-2, QNLI and MNLI), not the "consistently overcomes its alternatives" of the abstract. Sec. 4.2 says it replaces BERT's "sinusoidal" position encoding, but BERT's positions are learned, as the paper's own Sec. 2.2 says. The other tables are modest too (WMT 2014 En-De 27.5 vs 27.3 BLEU, +0.2; enwik8 only as a Performer loss curve with and without RoPE, with no BERT comparison; the CAIL2019-SCM gain comes at 1,024 tokens, and the text's "1.5%" over WoBERT is 1.69 points on test and 2.00 on validation in Table 5). RoPE was adopted for its engineering properties, not for these numbers. The long-term decay result is an upper bound on the score's size, not an exact curve, and the bound oscillates rather than falling monotonically. The base 10000 is borrowed from Vaswani et al. Conventions: this page writes the offset as n - m, the result of R_m^T R_n = R_(n-m) and the form of the paper's Eq. 16; the paper's Eq. 11-12 write m - n, and the two differ only by the sign of theta, with the decay depending only on |m - n|. The schedule index runs i = 1..d/2 as in Eq. 15; the paper's Sec. 3.3 and most code use i = 0..d/2-1 with the same set of rates. Eq. 16 prints x^T W_q R W_k x_n where x_m^T W_q^T R W_k x_n is meant. Popular accounts that group YaRN with NTK-aware scaling as "raising the base" are wrong: YaRN rescales each plane separately (NTK-by-parts) and adds an attention temperature.

Questions you might still have

?

Is RoPE an absolute or a relative position encoding?
Both, at different places. Each query and key is rotated by its own absolute position, which is the only position information that enters the model. The attention score between them depends only on the difference n - m, because the transpose of one rotation times another is the rotation by the difference of the angles.

?

Are the values rotated too?
No. RoFormer defines the rotation for queries and keys only (its Eq. 14 is written for f_q and f_k), and in its linear-attention form (Eq. 19) the values v_n enter unrotated. Position affects the output only through which values get weight.

?

Why split the vector into d/2 planes instead of one rotation of the whole d-dimensional space?
A single plane repeats: at rate theta it returns to the same angle every 2 pi / theta tokens, so at theta = 0.1 it gives offsets 0 and 63 nearly the same angle. Splitting into 64 planes (for d = 128) with rates from 1 down to about 1.15e-4 radians per token gives wavelengths from about 6 to about 54,000 tokens, and the combination of all 64 angles identifies the offset at every scale. Block-diagonal rotations also cost only a few element-wise operations per coordinate.

?

Does the long-term decay mean distant tokens cannot attend to each other?
No. The paper proves an upper bound on the size of the score: a content-dependent factor times a geometric factor that shrinks, with oscillations, as the offset grows. A query and key whose content matches can still produce a large score at a long distance; the decay only limits how large it can be for given content.

?

Why does an additive relative bias not work with linear attention when a rotation does?
Linear attention gets its O(N) cost by summing phi(k_n) v_n^T over all keys into one matrix that every query reuses. An additive bias b(m, n) inside the exponential becomes a factor that depends on the query and the key position together, so it cannot be moved into a sum shared by all queries. A rotation acts on each vector separately: rotate each key by its own position before adding it into the accumulator, rotate each query by its own position before reading it, and the product of the two rotations still gives the offset. This argument is the explainer's; the paper states only that additive schemes are unsuitable and that RoPE is multiplicative.

?

Does RoPE work with FlashAttention?
Yes. RoPE is applied to the query and key tensors before attention, so any exact attention kernel, including FlashAttention, runs unchanged on the rotated tensors. The FlashAttention explainer covers how such a kernel computes exact attention while moving less data through GPU memory.

?

How do models stretch RoPE to a longer context than they were trained on?
By changing the rates or the positions fed to the rotation. Position Interpolation divides every position by the extension factor s. NTK-aware scaling raises the base 10000 by s^(d/(d-2)), which leaves the fastest plane unchanged and slows the slowest by exactly s. YaRN leaves planes that complete more than 32 turns in the trained context alone, divides planes that complete less than one turn by s, blends the planes in between, and adds an attention temperature. All three usually come with a short fine-tune; PI extended LLaMA to 32,768 tokens within 1,000 steps.

Footnotes & further reading

  1. The paper: Su, Lu, Pan, Murtadha, Wen, Liu, RoFormer: Enhanced Transformer with Rotary Position Embedding (Zhuiyi Technology, 2021; revised through 2023).
  2. The sinusoidal schedule RoPE borrows the base 10000 from: Vaswani et al., Attention Is All You Need (2017), covered in the Transformer explainer.
  3. The relative-position predecessors: Shaw, Uszkoreit, Vaswani, Self-Attention with Relative Position Representations (2018); Dai et al., Transformer-XL (2019); and T5's scalar bias, in Raffel et al., Exploring the Limits of Transfer Learning (2019), covered in the T5 explainer.
  4. The linear-attention rewrite RoPE composes with: Katharopoulos, Vyas, Pappas, Fleuret, Transformers are RNNs: Fast Autoregressive Transformers with Linear Attention (2020); and the Performer used in the experiments, Choromanski et al., Rethinking Attention with Performers (2020).
  5. The BERT GLUE numbers RoFormer compares against: Devlin et al., BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding (2019), Table 1, “GLUE Test results, scored by the evaluation server”.
  6. Reference implementations: Meta's llama/model.py (precompute_freqs_cis, apply_rotary_emb) and Hugging Face's modeling_llama.py (rotate_half, apply_rotary_pos_emb).
  7. Long-context extensions of RoPE: Chen et al., Extending Context Window of Large Language Models via Positional Interpolation (2023), which rescales the position index; Peng et al., YaRN: Efficient Context Window Extension of Large Language Models (2023), which defines NTK-aware scaling (a base change, Appendix A.2), NTK-by-parts (a per-plane rescaling) and YaRN (NTK-by-parts plus an attention temperature).