1740 words
9 minutes
RoPE
2026-03-04

这个公式其实是数学中的**旋转矩阵(Rotation Matrix)在二维空间的应用。我们可以从极坐标(Polar Coordinates)**的角度来推导,这样最直观。


1. 准备工作:极坐标表示#

假设一个点 P(x,y)P(x, y) 在圆心为原点的圆上,它距离原点的距离(半径)为 rr,与 xx 轴的正方向夹角为 α\alpha

根据三角函数,我们可以把它的坐标写成:

  • x=rcosαx = r \cos\alpha
  • y=rsinαy = r \sin\alpha

2. 进行旋转#

现在,我们要把这个点逆时针旋转一个角度 θ\theta。旋转后的新点记为 P(x,y)P'(x', y')

新点 PP' 的半径依然是 rr,但它与 xx 轴的夹角变成了 α+θ\alpha + \theta

所以新坐标可以表示为:

  • x=rcos(α+θ)x' = r \cos(\alpha + \theta)
  • y=rsin(α+θ)y' = r \sin(\alpha + \theta)

3. 使用三角恒等式展开#

利用高中的三角函数加法公式:

cos(α+θ)=cosαcosθsinαsinθ\cos(\alpha + \theta) = \cos\alpha \cos\theta - \sin\alpha \sin\theta

sin(α+θ)=sinαcosθ+cosαsinθ\sin(\alpha + \theta) = \sin\alpha \cos\theta + \cos\alpha \sin\theta

我们将这两个展开式代入 xx'yy' 的表达式中:

x=r(cosαcosθsinαsinθ)=(rcosα)cosθ(rsinα)sinθx' = r(\cos\alpha \cos\theta - \sin\alpha \sin\theta) = (r \cos\alpha) \cos\theta - (r \sin\alpha) \sin\theta

y=r(sinαcosθ+cosαsinθ)=(rsinα)cosθ+(rcosα)sinθy' = r(\sin\alpha \cos\theta + \cos\alpha \sin\theta) = (r \sin\alpha) \cos\theta + (r \cos\alpha) \sin\theta

4. 代回原始坐标#

记得第一步里的 x=rcosαx = r \cos\alphay=rsinαy = r \sin\alpha 吗?把它们替换进去,就得到了你看到的公式:

  • x=xcosθysinθx' = x \cos\theta - y \sin\theta
  • y=ycosθ+xsinθy' = y \cos\theta + x \sin\theta (整理一下顺序即 xsinθ+ycosθx \sin\theta + y \cos\theta

线性代数视角(更进一步)#

在机器学习和 Transformer 的论文(如 RoPE)中,通常会写成矩阵乘法的形式,看起来更简洁:

[xy]=[cosθsinθsinθcosθ][xy]\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix}

为什么 RoPE 要用这个?

因为这种旋转变换是线性的,而且它有一个神奇的特性:它保持向量的长度(模长)不变,只改变方向。 这使得模型在处理位置信息时,不会因为位置太远而导致向量数值爆炸。


下面我给一个“能手算完”的玩具例子:5 个词、8 维(4 个 pair),分别算一遍不使用 RoPE 和使用 RoPE 的 QKQK^\top。我会把每一步都写出来(包括每个 pair 的旋转、每个距离的点积分解与求和),最后把 5×55 \times 5 的分数矩阵写出来。

设定前提(为了让计算可控)#

这些简化不影响你要理解的结论:

  • 位置:5 个词的位置是 p=0,1,2,3,4p=0, 1, 2, 3, 4

  • 维度d=84d=8 \Rightarrow 4 个二维 pair:Pair 1 (维 1-2), Pair 2 (维 3-4), Pair 3 (维 5-6), Pair 4 (维 7-8)

  • 角速度:每个 pair 的“每移动 1 步的旋转角速度”取一个简单的值(玩具版):

    ω1=1,ω2=0.5,ω3=0.25,ω4=0.125(单位:弧度/位置)\omega_1=1, \quad \omega_2=0.5, \quad \omega_3=0.25, \quad \omega_4=0.125 \quad (\text{单位:弧度/位置})

    (注:真实 RoPE 用的是 ωi=θ2i/d\omega_i=\theta^{-2i/d} 这种形式,但计算流程完全一样。)

  • 最关键的简化:所有 Token 的原始 QQKK 都取同一个向量:

    v=[1,0,1,0,1,0,1,0]v=[1, 0, 1, 0, 1, 0, 1, 0]

    也就是每个 pair 都是 [1,0][1, 0]。这样 RoPE 后每个 pair 会变成 [cos(pω),sin(pω)][\cos(p\omega), \sin(p\omega)],点积能清晰地看到“只和距离 Δ=tp\Delta=t-p 有关”。


1. 不使用 RoPE:直接算 QKQK^\top#

1.1 先写出 QQKK

5 个词都一样,所以:

Q=[vvvvv],K=[vvvvv]Q = \begin{bmatrix} v \\ v \\ v \\ v \\ v \end{bmatrix}, \quad K = \begin{bmatrix} v \\ v \\ v \\ v \\ v \end{bmatrix}

其中 v=[1,0,1,0,1,0,1,0]v=[1, 0, 1, 0, 1, 0, 1, 0]

1.2 计算任意一个分数项 (QK)p,t=QpKt=vv(QK^\top)_{p,t} = Q_p \cdot K_t = v \cdot v

把 8 维逐项相乘再求和:

vv=11+00+11+00+11+00+11+00=4v \cdot v = 1\cdot1 + 0\cdot0 + 1\cdot1 + 0\cdot0 + 1\cdot1 + 0\cdot0 + 1\cdot1 + 0\cdot0 = 4

1.3 得出完整的 QKQK^\top 矩阵

整个 QKQK^\top 是一个全 4 的矩阵:

QK=[4444444444444444444444444]QK^\top = \begin{bmatrix} 4 & 4 & 4 & 4 & 4 \\ 4 & 4 & 4 & 4 & 4 \\ 4 & 4 & 4 & 4 & 4 \\ 4 & 4 & 4 & 4 & 4 \\ 4 & 4 & 4 & 4 & 4 \end{bmatrix}

解释:不带位置时,注意力分数完全不知道谁离谁近,所有位置一视同仁。


2. 使用 RoPE:先旋转,再算 QKQ'K'^\top#

2.1 RoPE 对每个 pair 怎么旋转

对任意位置 pp 和任意一个 pair(角速度 ω\omega),二维旋转结果是:

原始 pair 是 [1,0][1, 0],旋转角为 θ=pω\theta=p\omega,所以:

[1,0]R(p)[cos(pω),sin(pω)][1, 0] \xrightarrow{R(p)} [\cos(p\omega), \sin(p\omega)]

因此 token 在位置 pp 的 8 维向量(4 个 pair 拼起来)是:

qp=kp=[cos(pω1),sin(pω1),cos(pω2),sin(pω2),cos(pω3),sin(pω3),cos(pω4),sin(pω4)]q'_p = k'_p = [\cos(p\omega_1), \sin(p\omega_1), \cos(p\omega_2), \sin(p\omega_2), \cos(p\omega_3), \sin(p\omega_3), \cos(p\omega_4), \sin(p\omega_4)]

2.2 算出 5 个位置的 qpq'_p(四舍五入到 4 位小数)

  • 位置 p=0p=0

    q0=[1.0000,0.0000,1.0000,0.0000,1.0000,0.0000,1.0000,0.0000]q'_0 = [1.0000, 0.0000, 1.0000, 0.0000, 1.0000, 0.0000, 1.0000, 0.0000]

  • 位置 p=1p=1(角分别是 1, 0.5, 0.25, 0.125):

    q1=[0.5403,0.8415,0.8776,0.4794,0.9689,0.2474,0.9922,0.1247]q'_1 = [0.5403, 0.8415, 0.8776, 0.4794, 0.9689, 0.2474, 0.9922, 0.1247]

  • 位置 p=2p=2(角分别是 2, 1, 0.5, 0.25):

    q2=[0.4161,0.9093,0.5403,0.8415,0.8776,0.4794,0.9689,0.2474]q'_2 = [-0.4161, 0.9093, 0.5403, 0.8415, 0.8776, 0.4794, 0.9689, 0.2474]

  • 位置 p=3p=3(角分别是 3, 1.5, 0.75, 0.375):

    q3=[0.9900,0.1411,0.0707,0.9975,0.7317,0.6816,0.9305,0.3663]q'_3 = [-0.9900, 0.1411, 0.0707, 0.9975, 0.7317, 0.6816, 0.9305, 0.3663]

  • 位置 p=4p=4(角分别是 4, 2, 1, 0.5):

    q4=[0.6536,0.7568,0.4161,0.9093,0.5403,0.8415,0.8776,0.4794]q'_4 = [-0.6536, -0.7568, -0.4161, 0.9093, 0.5403, 0.8415, 0.8776, 0.4794]

    (因为我们设定了 Q=KQ=K,所以 kp=qpk'_p=q'_p)


3. 一步一步计算 QKQ'K'^\top#

分数矩阵元素是:(QK)p,t=qpkt=qpqt(Q'K'^\top)_{p,t} = q'_p \cdot k'_t = q'_p \cdot q'_t

3.1 先完整算一个具体例子:(p=0,t=1)(p=0, t=1)

把 8 维逐项乘加。因为 q0q'_0 的每个 pair 都是 [1,0][1, 0],所以每个 pair 只取到了对方的 cos\cos 分量:

q0q1=0.5403+0.8776+0.9689+0.99223.3790q'_0 \cdot q'_1 = 0.5403 + 0.8776 + 0.9689 + 0.9922 \approx 3.3790

所以 (QK)0,13.3790(Q'K'^\top)_{0,1} \approx 3.3790

3.2 再算一个“不是从全 1 取 cos\cos”的例子:(p=1,t=2)(p=1, t=2)

这里必须把每个 pair 都做完:

  • Pair 1 (ω1=1\omega_1=1)

    [0.5403,0.8415][0.4161,0.9093]=0.2248+0.76520.5403[0.5403, 0.8415] \cdot [-0.4161, 0.9093] = -0.2248 + 0.7652 \approx 0.5403

    (理论值即 cos(1)\cos(1))

  • Pair 2 (ω2=0.5\omega_2=0.5)

    [0.8776,0.4794][0.5403,0.8415]=0.4742+0.40340.8776[0.8776, 0.4794] \cdot [0.5403, 0.8415] = 0.4742 + 0.4034 \approx 0.8776

  • Pair 3 (ω3=0.25\omega_3=0.25)

    [0.9689,0.2474][0.8776,0.4794]=0.8503+0.11860.9689[0.9689, 0.2474] \cdot [0.8776, 0.4794] = 0.8503 + 0.1186 \approx 0.9689

  • Pair 4 (ω4=0.125\omega_4=0.125)

    [0.9922,0.1247][0.9689,0.2474]=0.9613+0.03090.9922[0.9922, 0.1247] \cdot [0.9689, 0.2474] = 0.9613 + 0.0309 \approx 0.9922

    把 4 个 pair 加起来:

    q1q20.5403+0.8776+0.9689+0.9922=3.3790q'_1 \cdot q'_2 \approx 0.5403 + 0.8776 + 0.9689 + 0.9922 = 3.3790

    你会发现:距离 Δ=1\Delta=1(1,2)(1, 2) 得分与 (0,1)(0, 1) 完全一样!


4. 把“所有距离”都算出来,然后拼成 5×55 \times 5 矩阵#

由于每个 pair 满足三角恒等式:

cos(pω)cos(tω)+sin(pω)sin(tω)=cos((tp)ω)\cos(p\omega)\cos(t\omega) + \sin(p\omega)\sin(t\omega) = \cos((t-p)\omega)

总分数公式直接化简为:

Score(p,t)=i=14cos((tp)ωi)\text{Score}(p,t) = \sum_{i=1}^4 \cos((t-p)\omega_i)

接下来我们对每个距离 Δ=tp\Delta = |t-p| 进行求和:

  • Δ=0\Delta=0S0=1+1+1+1=4.0000S_0 = 1 + 1 + 1 + 1 = 4.0000
  • Δ=1\Delta=1S1=0.5403+0.8776+0.9689+0.9922=3.3790S_1 = 0.5403 + 0.8776 + 0.9689 + 0.9922 = 3.3790
  • Δ=2\Delta=2S2=0.4161+0.5403+0.8776+0.9689=1.9707S_2 = -0.4161 + 0.5403 + 0.8776 + 0.9689 = 1.9707
  • Δ=3\Delta=3S3=0.9900+0.0707+0.7317+0.9305=0.7429S_3 = -0.9900 + 0.0707 + 0.7317 + 0.9305 = 0.7429
  • Δ=4\Delta=4S4=0.65360.4161+0.5403+0.8776=0.3481S_4 = -0.6536 - 0.4161 + 0.5403 + 0.8776 = 0.3481

最终拼出的矩阵(每条对角线相同,即 Toeplitz 矩阵):

QK=[S0S1S2S3S4S1S0S1S2S3S2S1S0S1S2S3S2S1S0S1S4S3S2S1S0][4.00003.37901.97070.74290.34813.37904.00003.37901.97070.74291.97073.37904.00003.37901.97070.74291.97073.37904.00003.37900.34810.74291.97073.37904.0000]Q'K'^\top = \begin{bmatrix} S_0 & S_1 & S_2 & S_3 & S_4 \\ S_1 & S_0 & S_1 & S_2 & S_3 \\ S_2 & S_1 & S_0 & S_1 & S_2 \\ S_3 & S_2 & S_1 & S_0 & S_1 \\ S_4 & S_3 & S_2 & S_1 & S_0 \end{bmatrix} \approx \begin{bmatrix} 4.0000 & 3.3790 & 1.9707 & 0.7429 & 0.3481 \\ 3.3790 & 4.0000 & 3.3790 & 1.9707 & 0.7429 \\ 1.9707 & 3.3790 & 4.0000 & 3.3790 & 1.9707 \\ 0.7429 & 1.9707 & 3.3790 & 4.0000 & 3.3790 \\ 0.3481 & 0.7429 & 1.9707 & 3.3790 & 4.0000 \end{bmatrix}


5. 你要的“距离长短”到底在哪里#

对比两种结果:

  1. 不使用 RoPE:所有位置之间分数都一样(全是 4.0000),模型从 QKQK^\top 里完全看不出距离。
  2. 使用 RoPE:分数随距离 tp|t-p| 的增大而稳步下降(4.0000 \rightarrow 3.3790 \rightarrow 1.9707 \rightarrow 0.7429 \rightarrow 0.3481),距离信息就完美体现在了最终的 QKQ'K'^\top 数值衰减里。

RoPE
https://lxy-alexander.github.io/blog/posts/llm/rope/
Author
Alexander Lee
Published at
2026-03-04
License
CC BY-NC-SA 4.0