来源 本文主要参考苏剑林的《Transformer 升级之路:2、博采众长的旋转式位置编码》,以及 RoFormer、Linear Transformer 与 Performer 论文。
三十秒速览 在上一篇《重读 Transformer 升级之路(1):Sinusoidal 位置编码追根溯源》中,每对 sin/cos 像一只“位置钟”:它为位置生成一根指针。RoPE 更进一步,不再把位置向量加到 token 上,而是用位置对应的角度直接旋转内容产生的 Query 和 Key。位置 m 旋转 mθ,位置 n 旋转 nθ;两者做内积时,共同的绝对旋转会被抵消,只留下 n−m。在标准 Attention 中,这个相对旋转进入 softmax 之前的 score;在线性 Attention 中,只要旋转仍能分别作用于 Query 和 Key,先聚合 Key/Value 的计算顺序就可以保留。不过,“还能线性计算”不等于“权重仍然非负且和为 1”,这两个问题必须分开。
先约定本文会反复使用的符号:
| 符号 | 含义 |
|---|
| m,n | Query 与 Key 所在的绝对位置 |
| Δ=m−n | Query 相对 Key 的位移 |
| xm | 位置 m 的 token representation |
| qm,kn,vn | 尚未加入位置信息的 Query、Key、Value |
| dh | 单个 attention head 的 Query/Key 维度,本文假设为偶数 |
| R(α) | 在二维平面中逆时针旋转 α 的矩阵 |
| Rm | 把一个完整 attention head 的每对维度分别旋转 mθi 的分块矩阵 |
| θi | 第 i 对维度每前进一个 token 所旋转的弧度 |
| ϕ,φ | 线性 Attention 中作用于 Query、Key 的特征映射 |
1. RoPE 想补上 Sinusoidal PE 的哪块缺口?
先把位置编码放到一边。标准 self-attention 会从 token representation 产生三组向量:
qm=WQxm,kn=WKxn,vn=WVxn.
Query 可以理解为位置 m 当前“想找什么”,Key 表示位置 n “能用什么特征被找到”,Value 则是找到它之后真正取走的信息。Query 与 Key 的内积
sm,n=qm⊤kn
决定两者有多匹配。
问题在于:如果 qm 和 kn 都没有携带位置,那么这个匹配只比较内容,不知道两者相距几步。
上一篇文章介绍的 Sinusoidal 位置编码,会先构造位置向量 pm,再把它加到 token representation 上。为了和后面的 RoPE 使用同一种描述方式,先把“加上位置向量”写成一个位置变换:
Fadd(xm,m)=xm+pm.
这里的第二个输入 m 告诉函数应该取哪一个 pm。将变换后的 token 投影成 Query 和 Key,可得
q^mk^n=WQFadd(xm,m)=qm+WQpm,=WKFadd(xn,n)=kn+WKpn.
现在再把它们的内积完整展开:
q^m⊤k^n=qm⊤kn+qm⊤WKpn+(WQpm)⊤kn+(WQpm)⊤(WKpn).
四项依次是内容—内容、内容—位置、位置—内容和位置—位置。上一篇证明的是 Sinusoidal 向量本身具有漂亮的相对相位结构,例如 pm⊤pn 只依赖 m−n;但上面这个完整 score 还经过 WQ,WK,并混入另外三项,所以它并没有被强制写成“位置只通过 m−n 出现”的形式。
这就自然引出下一步:既然位置最终是为了影响 Query—Key 的比较,能不能直接在 Query 和 Key 上规定更合适的位置变换?记这两个变换为
qmpos=FQ(qm,m),knpos=FK(kn,n).
我们希望它们满足
FQ(qm,m)⊤FK(kn,n)=g(qm,kn,m−n).
右侧仍然依赖 Query 和 Key 的内容;受到限制的只有位置变量,它只能以 m−n 的形式出现。RoPE 接下来给出的具体选择,就是让 FQ 和 FK 都使用由位置决定的旋转。
这个目标还有一个很直观的检验。如果把两个 token 同时向后平移 c 个位置,那么它们的相对距离没有改变:
(m+c)−(n+c)=m−n.
因此,我们也希望平移前后的内容匹配保持相同。接下来只需要构造一种满足这个目标的简单变换。
2. 先把二维旋转拆开看懂
2.1 旋转矩阵到底做了什么?
在二维平面中,向量
u=[u1u2]
逆时针旋转 α 后,会变成
R(α)u=[cosαsinα−sinαcosα][u1u2]=[u1cosα−u2sinαu1sinα+u2cosα].
例如,取 u=[1,0]⊤,它原本指向横轴正方向。旋转 π/2 后:
R(π/2)[10]=[01−10][10]=[01],
正好变成指向纵轴正方向。旋转改变的是向量的方向,不改变它的长度。
2.2 为什么转置等于反向旋转?
把旋转矩阵转置,就是交换它的行与列:
R(α)⊤=[cosα−sinαsinαcosα].
另一方面,由
cos(−α)=cosα,sin(−α)=−sinα,
可得
R(−α)=[cosα−sinαsinαcosα].
两个矩阵逐项相同,因此
R(α)⊤=R(−α).
几何上也很好理解:先把一根指针旋转 α,再想把它恢复原状,就要反方向旋转 −α。
2.3 为什么连续两次旋转可以把角度相加?
先旋转 β,再旋转 α,对应的矩阵乘法是
R(α)R(β).
为了看清每一项,暂时把 cosα,sinα 简写成 cα,sα,把 cosβ,sinβ 简写成 cβ,sβ:
R(α)R(β)=[cαsα−sαcα][cβsβ−sβcβ]=[cαcβ−sαsβsαcβ+cαsβ−(cαsβ+sαcβ)cαcβ−sαsβ].
再使用正弦、余弦的和角公式:
cos(α+β)sin(α+β)=cαcβ−sαsβ,=sαcβ+cαsβ,
上面的乘积就变成
R(α)R(β)=[cos(α+β)sin(α+β)−sin(α+β)cos(α+β)]=R(α+β).
因此
R(α)R(β)=R(α+β).
如果只记一句话,就是:旋转做乘法,角度做加法。
3. RoPE 的核心为什么只有一行?
现在取一对二维 Query 和 Key:
qm=[q1q2],kn=[k1k2].
选择一个固定的每步转角 θ。RoPE 在位置 m 把 Query 旋转 mθ,在位置 n 把 Key 旋转 nθ:
q~m=R(mθ)qm,k~n=R(nθ)kn.
对旋转后的向量做内积:
q~m⊤k~n=(R(mθ)qm)⊤(R(nθ)kn)=qm⊤R(mθ)⊤R(nθ)kn=qm⊤R(−mθ)R(nθ)kn=qm⊤R((n−m)θ)kn.
每一步分别用了:
- (AB)⊤=B⊤A⊤;
- R(α)⊤=R(−α);
- R(α)R(β)=R(α+β)。
最终式子中的位置只剩下 n−m:
q~m⊤k~n=qm⊤R((n−m)θ)kn.
虽然 Query 和 Key 各自按照绝对位置 m,n 旋转,但它们相遇做内积时,看到的只是相对位置。
如果把两个位置同时平移 c,同样有
R((m+c)θ)⊤R((n+c)θ)=R(−(m+c)θ)R((n+c)θ)=R((n−m)θ).
公共的 c 被消掉了。这正是“整体平移不改变相对关系”的矩阵版本。
图 1|整体平移改变绝对角度,却不改变相对旋转。 为了只展示位置造成的旋转,图中让 Query 与 Key 从同一参考方向出发,并以 θ = 30° 示意。左右两组位置分别是 (1, 3) 与 (4, 6);后一组都增加 3,但位置差始终为 2,因此相对夹角始终是 2θ。图为作者制作的机制示意图。
4. “旋转内容”到底改变了什么?
上一节证明了位置只以 m−n 出现,但这还没有回答一个更直观的问题:同一对 Query 和 Key,为什么换一个相对位置,匹配分数就会改变?
令
Δ=m−n.
因为 n−m=−Δ,二维 RoPE score 可以写成
qm⊤R(−Δθ)kn.
为了不把任何一步藏起来,先把右侧的两个因子重新写出来:
kn=[k1k2],
以及
R(−Δθ)=[cos(−Δθ)sin(−Δθ)−sin(−Δθ)cos(−Δθ)]=[cos(Δθ)−sin(Δθ)sin(Δθ)cos(Δθ)].
第二个等号使用了“余弦是偶函数、正弦是奇函数”:cos(−x)=cosx,sin(−x)=−sinx。
现在先做矩阵与向量的乘法:
R(−Δθ)kn=[cos(Δθ)−sin(Δθ)sin(Δθ)cos(Δθ)][k1k2]=[k1cos(Δθ)+k2sin(Δθ)−k1sin(Δθ)+k2cos(Δθ)].
再把 Query 的转置也明确写成一行向量:
qm⊤=[q1q2].
于是,内积可以一行一行地算:
qm⊤R(−Δθ)kn=[q1q2][k1cos(Δθ)+k2sin(Δθ)−k1sin(Δθ)+k2cos(Δθ)]=q1[k1cos(Δθ)+k2sin(Δθ)]+q2[−k1sin(Δθ)+k2cos(Δθ)]=q1k1cos(Δθ)+q1k2sin(Δθ)−q2k1sin(Δθ)+q2k2cos(Δθ)=(q1k1+q2k2)cos(Δθ)+(q1k2−q2k1)sin(Δθ).
所以 RoPE score 包含两部分:
原始同方向匹配(q1k1+q2k2)cos(Δθ)+两个坐标的交叉匹配(q1k2−q2k1)sin(Δθ).
这里最容易产生的误解,是把 RoPE 想成“给原始点积乘一个距离余弦”。只有第一项像这样;第二项还会交叉比较 Query 的第一维与 Key 的第二维,以及 Query 的第二维与 Key 的第一维。
这个式子究竟在说什么?我们用两个对照实验回答。为了让旋转结果能心算,暂时取 θ=π/2,也就是相差一个位置便旋转 90∘。这只是放大机制的玩具例子,不是实际模型只使用的频率。
| 实验 | Query q | 原始 Key k | Δ | 旋转后的 Key R(−Δθ)k | RoPE score |
|---|
| A1 | [1,0] | [1,0] | 0 | [1,0] | 1 |
| A2 | [1,0] | [1,0] | 1 | [0,−1] | 0 |
| B1 | [1,0] | [0,1] | 0 | [0,1] | 0 |
| B2 | [1,0] | [0,1] | 1 | [1,0] | 1 |
先看实验 A。两行的内容向量完全相同,只改变相对位置:
Δ=0:Δ=1:[1,0][1,0]⊤=1,[1,0][0,−1]⊤=0.
这说明:即使内容不变,相对位置也会先转动 Key,再改变它与 Query 的匹配分数。
再看实验 B。Query 与 Key 原本正交,所以同位置时 score 为 0;当 Δ=1 时,R(−π/2) 把 Key 从 [0,1] 转成 [1,0],正好与 Query 同向,于是 score 变成 1。
这组例子只想说明一件事: RoPE 让“用什么坐标方向比较两段内容”取决于相对位置。它不是给距离加一个固定奖励或惩罚,也不保证越远 score 越小。
真实 attention head 会同时使用很多不同的 θi,而且 q,k 是模型学出来的内容向量。因此,位置差决定每一对坐标怎样转,内容决定转完以后是否匹配;所有维度的结果最后再相加。
5. 从一对维度扩展到完整 Attention Head
真实模型中,一个 attention head 通常有几十或上百个维度。RoPE 把这些维度两两配对:
(q0,q1), (q2,q3), …, (qdh−2,qdh−1).
第 i 对维度使用自己的每步转角 θi。完整旋转可以写成一个分块对角矩阵:
Rm=diag(R(mθ0),R(mθ1),…,R(mθdh/2−1)).
常见的频率调度沿用 Sinusoidal PE:
θi=b−2i/dh,
经典底数为 b=10000。较大的 θi 转得快,对局部位置差更敏感;较小的 θi 转得慢,在较长距离上变化更缓慢。
完整 score 就是所有二维块的 score 相加:
q~m⊤k~n=i=0∑dh/2−1[Aicos(Δθi)+Bisin(Δθi)],
其中 Ai,Bi 由第 i 对 Query/Key 内容决定。
旋转还保持向量长度。因为
Rm⊤Rm=I,
所以
∥Rmqm∥2=qm⊤Rm⊤Rmqm=qm⊤qm=∥qm∥2.
位置改变的是方向,不是 Query 或 Key 的模长。
不过,多频率 score 仍然是内容相关的有限三角和。它可能随距离振荡,不保证严格单调变小,也不保证远处 token 一定获得更低的 Attention。更准确的说法是:几何频率提供了多尺度相位结构,并在许多频率混合时带来振荡式去相关的倾向;这不是一条硬编码的距离惩罚。
6. RoPE 在标准 Attention 中放在哪里?
对单个 attention head,计算顺序可以写成五步。
第一步:从输入产生 Q、K、V
qm=WQxm,kn=WKxn,vn=WVxn.
第二步:只旋转 Q 和 K
这里的 Rm 不是一个没有定义的新矩阵。它就是上一节的完整 head 旋转;为免读者来回翻找,再写一次:
RmRn=diag(R(mθ0),…,R(mθdh/2−1)),=diag(R(nθ0),…,R(nθdh/2−1)).
Rm 负责按位置 m 旋转 Query 的每一对维度,Rn 负责按位置 n 旋转 Key 的每一对维度。因此
qmrope=Rmqm,knrope=Rnkn.
第三步:计算所有 Query—Key score
sm,n=dh(qmrope)⊤knrope.
第四步:加入 mask,再做 softmax
这里用的是加法 mask。我们把 Mm,n 定义为
Mm,n={0,−∞,位置 m 可以读取位置 n,位置 m 不可以读取位置 n.
它和 score 相加以后再进入指数函数:
am,n=∑jexp(sm,j+Mm,j)exp(sm,n+Mm,n).
所以这里确定是加号:允许读取时,exp(sm,n+0)=exp(sm,n);禁止读取时,exp(sm,n−∞)=0。实际代码常用数据类型能够表示的极小负数代替 −∞。
如果实现里出现的是 0/1 布尔 mask,那是另一种表示法:它通常会先被转换成这里的 0/−∞ 加法 mask,或者在指数结果上做等价的乘法。本文的 M 从一开始就定义在 softmax 之前的 logit 空间里。
第五步:用权重聚合未旋转的 Value
om=n∑am,nvn.
Value 通常不需要旋转。RoPE 的目标是让“位置 m 应该从位置 n 取多少信息”这个配对分数带有相对位置;一旦 am,n 已经包含这种信息,它就可以直接选择和组合 Value。
用接近代码的写法表示,就是:
q, k, v = project(x)
q_rope = q * cos(position) + rotate_half(q) * sin(position)
k_rope = k * cos(position) + rotate_half(k) * sin(position)
score = q_rope @ k_rope.T / sqrt(head_dim)
weight = softmax(score + mask)
output = weight @ v
其中,对每个二维块 [a,b],
rotate_half([a,b])=[−b,a],
正好对应旋转矩阵中与 sin 相乘的部分。
这里还要划清一个边界:标准 Attention 仍然需要计算所有 m,n 组合,形成 N×N 的 score matrix。RoPE 增加的是位置结构,不会把 O(N2) 的标准 Attention 自动变成线性复杂度。
7. 线性 Attention 为什么叫“线性”?
这里的“线性”是指计算量随序列长度 N 线性增长,不是说整个模块没有非线性函数。
为了直接看出它与标准 Attention 的差别,先暂时省略 RoPE 和 mask。标准 Attention 是
omstd=∑n=1Nexp(qm⊤kn/dh)∑n=1Nexp(qm⊤kn/dh)vn.
其中每个系数 exp(qm⊤kn/dh) 都由一对具体的 Query 和 Key 共同产生。长度为 N 时,一共有 N2 对,因而不能先把所有 Key/Value 压成一个与 Query 无关的有限汇总量。
线性 Attention 改写了这个最关键的“成对系数”。它选择或近似一种可以拆成两侧特征的相似度:
sim(qm,kn)=ϕ(qm)⊤φ(kn).
令
um=ϕ(qm),zn=φ(kn),
于是它的归一化输出是
omlin=∑n=1Num⊤zn∑n=1N(um⊤zn)vn.
把两种形式并排看,差别集中在中间那一列:
| 标准 Attention | 线性 Attention |
|---|
| Query—Key 系数 | exp(qm⊤kn/dh) | um⊤zn |
| 是否先形成所有配对 | 是,共 N2 对 | 不必,可以先汇总 Key/Value |
| 归一化 | 对每个 Query 做 softmax | 除以 ∑num⊤zn |
| 关于序列长度的计算量 | O(N2) | 特征维度固定时为 O(N) |
因此,线性 Attention 的关键不只是“公式里没写 softmax”,而是 um 与 zn 可以分开计算,随后利用矩阵乘法的结合律改变求和顺序。
因为 um 与求和编号 n 无关,它可以被移到求和外面:
n=1∑N(um⊤zn)vnn=1∑Num⊤zn=um⊤(n=1∑Nznvn⊤),=um⊤(n=1∑Nzn).
于是可以先为整段序列计算两个汇总量:
SV=n=1∑Nznvn⊤,S1=n=1∑Nzn,
再让每个 Query 读取它们:
om=um⊤S1um⊤SV.
这次没有显式构造 N×N 的 Attention matrix。当特征维度固定时,计算量关于序列长度 N 是线性的。
在 causal 场景中,只需把整段求和换成前缀状态:
SV,m=SV,m−1+zmvm⊤,S1,m=S1,m−1+zm.
位置 m 只能读取截至当前位置累积的状态,因此不会看到未来 token。
8. RoPE 怎样进入线性 Attention?
8.1 为什么 RoPE 不会破坏乘法重排?
假设特征维度同样可以两两配对。对 Query/Key 特征分别旋转:
um′=Rmum,zn′=Rnzn.
它们的相似度仍然只依赖相对旋转:
(um′)⊤zn′=um⊤Rn−mzn.
同时,分子仍可重排为
n∑[(um′)⊤zn′]vn=(um′)⊤(n∑zn′vn⊤).
因此可以先聚合
SV′=n∑zn′vn⊤,
再让旋转后的 Query 读取它。RoPE 的位置变换发生在每个 Query 和 Key 自己身上,不需要先知道某个完整的 N×N score matrix,所以线性 Attention 最重要的乘法重排仍然成立。
8.2 为什么分母会遇到麻烦?
很多线性 Attention 选择值域非负的 ϕ,φ。这样
um⊤zn≥0,
分母是非负相似度之和,输出可以理解为 Value 的加权平均。
旋转却不保持“每个坐标都非负”。例如
R(π)[10]=[−10].
因此,即使 um,zn 原本都只有非负坐标,旋转后的
(um′)⊤zn′
也可能为负。如果直接把它们加到分母中,正负项可能互相抵消,分母甚至可能接近 0。
RoFormer 给出的线性 Attention 形式,是只在分子中使用旋转后的特征,分母仍使用原始非负特征:
om=um⊤(∑nzn)(um′)⊤(∑nzn′vn⊤).
这样做保留了两点:
- 分子与分母都能通过预聚合按线性复杂度计算;
- 分母沿用未旋转的非负特征,降低正负抵消导致除零的风险。
但代价也必须说清楚。Value vn 的实际系数是
wm,n=∑jum⊤zj(um′)⊤zn′.
wm,n 可以为负,而且一般不满足
n∑wm,n=1.
所以这时的输出仍是一个有归一化尺度的内容聚合,却不再是严格的概率加权平均。
8.4 先旋转还是先做特征映射?
阅读不同实现时,还会遇到两种看似相近、实际不同的顺序:
| 顺序 | 形式 | 主要性质 |
|---|
| 先映射,再旋转 | Rmϕ(qm) | 相对旋转恒等式精确成立,但非负特征会被转成有正有负 |
| 先旋转,再映射 | ϕ(Rmqm) | 若 ϕ 是正随机特征,可近似旋转后 softmax kernel,并保留非负性,但这是核近似而非上一行的精确等式 |
例如 Performer 的 FAVOR+ 使用正随机特征近似 softmax kernel。先对原始 Query/Key 使用 RoPE,再对旋转后的向量做这种特征映射,可以近似标准 RoPE Attention,同时继续利用线性计算。它与上一小节的 RoFormer 线性公式是两种不同的组合,不能只用一句“把 RoPE 加进去”混为一谈。
9. “适合线性 Attention”真正需要什么条件?
线性 Attention 真正需要的,不是某一种特定位置编码名称,而是带位置的相似度能够分解为
sim(qm,kn,m,n)=am(qm)⊤bn(kn).
只要 Query 侧的 am 与 Key 侧的 bn 可以分别计算,Key/Value 就仍有机会先聚合。
RoPE 很自然地满足这个条件:
am(qm)=Rmϕ(qm),bn(kn)=Rnφ(kn).
许多直接加在完整 Attention matrix 上的相对位置 bias,则要等到每一对 m,n 的 score 已经出现后才能使用,因而不能直接套用同一个重排。
但这不构成 RoPE 的唯一性定理。其他只要能够分解的位置函数也可以与线性 Attention 配合。例如 cosFormer 使用可分解的余弦位置重加权,在保持非负性的同时实现线性计算。因此,更准确的结论是:
RoPE 的优势,是用分别作用于 Query 与 Key 的绝对位置旋转,构造出显式的相对位置交互;这种可分解结构天然适合线性 Attention,但它不是唯一可能的结构。
10. 这些推导证明了什么,又没有证明什么?
它严格给出或直接展示了:
- 二维 RoPE 是保持模长的旋转;
- Rm⊤Rn=Rn−m,所以 Query—Key score 中的位置只以相对位移出现;
- 整体平移 Query 与 Key 不会改变它们的相对旋转;
- RoPE score 不只是原始点积乘一个距离余弦,还包含内容坐标之间的交叉匹配;
- RoPE 可以分别施加到 Query 与 Key,因此不会自动破坏线性 Attention 的乘法重排。
它没有证明:
- RoPE 是满足相对位置目标的唯一解;
- RoPE score 会随距离严格单调下降;
- 使用 RoPE 后模型一定偏爱附近 token;
- 能计算训练长度以外的旋转角,就代表模型一定能可靠完成长度外推;
- 任意线性 Attention 加入 RoPE 后都仍有非负、和为 1 的概率权重;
- RoPE 会降低标准 Attention 的 O(N2) 复杂度。
11. 一页速查
| 问题 | 最短答案 |
|---|
| RoPE 旋转什么? | 每个 attention head 中投影后的 Query 和 Key。 |
| 为什么每两个维度配成一对? | 二维正好可以表示一个保持长度的平面旋转。 |
| 为什么得到相对位置? | R(mθ)⊤R(nθ)=R((n−m)θ)。 |
| RoPE 是把一个位置向量加到内容上吗? | 不是,它直接旋转内容产生的 Q/K。 |
| RoPE 只是给点积乘一个余弦吗? | 不是,还会产生由正弦控制的交叉坐标匹配。 |
| 为什么通常不旋转 Value? | 相对位置已经进入选取 Value 的 Attention 权重,Value 本身可以直接被聚合。 |
| 标准 Attention 会因此变成线性复杂度吗? | 不会,仍需计算 N2 个 Query—Key score。 |
| 为什么 RoPE 适合线性 Attention? | 它能分别作用于 Query 与 Key,保留可分解计算。 |
| 线性 Attention 中权重仍是概率吗? | 不一定。旋转特征可能产生负相似度,取决于特征映射和归一化方案。 |
| RoPE 是线性 Attention 唯一可用的相对位置方案吗? | 不是。关键条件是位置相关相似度能否分解。 |
整篇文章最值得记住的一句话是:
RoPE 不是给 token 贴上一个位置标签,而是让 Query 与 Key 在各自的位置坐标系里旋转;两者比较时,绝对坐标相消,只留下相对位移。
参考文献与图像来源
- 苏剑林(2021)。《Transformer 升级之路:2、博采众长的旋转式位置编码》。本文以该文提出的问题与 RoPE 构造为阅读起点,重新组织了二维旋转、标准 Attention 和线性 Attention 的教学顺序。
- Su, J. et al. (2021). RoFormer: Enhanced Transformer with Rotary Position Embedding。RoPE 的标准形式、性质与线性 Attention 方案。
- Katharopoulos, A. et al. (2020). Transformers are RNNs: Fast Autoregressive Transformers with Linear Attention。基于核特征与乘法结合律的线性 Attention。
- Choromanski, K. et al. (2021). Rethinking Attention with Performers。使用正交正随机特征近似 softmax Attention。
- Qin, Z. et al. (2022). cosFormer: Rethinking Softmax in Attention。可分解的余弦位置重加权说明 RoPE 并非线性 Attention 中位置结构的唯一选择。
- 图 1 为作者制作的机制示意图。