学习目标
学完本文,应能从旋转矩阵和复数两种形式写出 RoPE,解释为什么它保持向量长度,并独立证明旋转后的 Query、Key 点积只依赖相对位置 n−m。
先修知识
1. 从二维旋转开始
二维向量 u=(x,y)⊤ 旋转角度 ϕ 后为:
R(ϕ)u=[cosϕsinϕ−sinϕcosϕ][xy]
旋转不会改变向量范数:
∥R(ϕ)u∥2=∥u∥2

把 (x,y) 看成复数 z=x+iy,旋转就等价于:
z′=zeiϕ
这也是 PyTorch 实现中可以使用 view_as_complex 和复数乘法的原因。
2. 把位置变成旋转角度
对于位置 m 和第 i 个二维特征对,定义频率:
θi=base−2i/d
标准 base 常取 10000。位置 m 对应的旋转角为 mθi:
qm,i′=R(mθi)qm,i
kn,i′=R(nθi)kn,i

3. 为什么点积只依赖相对距离
旋转矩阵满足:
R(α)⊤=R(−α)
R(α)R(β)=R(α+β)
因此:
(qm′)⊤kn′=(Rmqm)⊤(Rnkn)=qm⊤Rm⊤Rnkn=qm⊤Rn−mkn
绝对位置 m,n 最终以差值 n−m 的形式进入注意力分数。

若采用相反的旋转方向,最后可能得到 m−n。符号方向不是重点,只要 Q、K 的约定始终一致即可。
4. 扩展到高维
当 head dimension 为偶数 d 时,把通道按相邻两维分成 d/2 组:
(x0,x1),(x2,x3),…,(xd−2,xd−1)
高维旋转矩阵是多个二维旋转块组成的块对角矩阵:
Rmd=diag(R(mθ0),R(mθ1),…,R(mθd/2−1))

每组通道使用不同频率,因此模型可以同时感知细粒度的近距离变化和缓慢变化的长距离关系。
5. 张量形状
以 Query 为例:
Q: [batch, heads, seq_len, head_dim]
Q_pairs: [batch, heads, seq_len, head_dim / 2, 2]
rotation factors: [seq_len, head_dim / 2]
Q_rotated: [batch, heads, seq_len, head_dim]
要求 head_dim 为偶数。广播时,位置维必须与 seq_len 对齐,频率维必须与 head_dim / 2 对齐。
6. RoPE 保留了什么、改变了什么
- 保留 Q、K 每个二维对的长度;
- 改变向量方向,使其携带绝对位置对应的相位;
- 点积把两者的绝对相位差化成相对位置;
- Value 通常不旋转,因为位置关系已经进入注意力权重。
常见误区
误区一:RoPE 给整个向量只使用一个角度
不同二维通道对应不同的 θi,是多频率旋转。
误区二:把前半维与后半维随意配对
不同实现可能使用“相邻配对”或“前后半区配对”,但频率布局和 rotate_half 必须匹配,不能只改一处。
误区三:RoPE 改变了向量的模长
理想旋转矩阵是正交矩阵,因此只改变方向,不改变范数。
一句话总结
RoPE 通过给 Q、K 的每组二维特征施加随位置变化的旋转,使两个位置的点积只保留旋转角之差,从而显式编码相对位置。
复习卡片
- 二维旋转:R(ϕ);
- 复数形式:zeiϕ;
- 第 i 组角度:mθi;
- 高频通道变化快,低频通道变化慢;
- 核心证明:Rm⊤Rn=Rn−m。
自测问题
- 为什么旋转不会改变 Q、K 的范数?
- 复数乘法与二维旋转矩阵如何对应?
- 高维 RoPE 为什么使用块对角矩阵?
- 为什么标准实现通常不旋转 V?
下一篇
LLaMA(8):RoPE 可以表示绝对位置信息吗?
参考与推荐阅读