RoPE 到底旋转了什么?
本课一问:RoPE 的名字里有「旋转」。它转的是什么?为什么「转」一下,注意力就能直接感受到两个 token 相隔多远?
这一课先不碰:超长上下文的扩展(第 5 课);Q、K、V 各自从哪来、多头与 GQA(C3)。这一课只需要知道一件事:注意力给一对 token 打分,用的是 q·k 点积。
从已有出发
三条线索已经摆在桌上:
- 第 1 课:q·k 里没有位置,同一对 token 相隔 1 个还是 100 个位置,分数一样。
- 第 3 课:两个 sinusoidal 位置编码的点积只取决于距离;「往后平移 k 个位置」就是每组转一个固定角度。
- 语言更在乎「相隔多远」,不在乎「第几个」。
目标因此很明确:让注意力分数 qm·kn 带上位置,而且只带上 n − m。
点上面的「位置 RoPE」,能看到它在 Qwen3.8 里的真实形状;读完这一课,那几行字每一个都能解释。
先自己设计:把位置向量加在输入上
第 2、3 课的做法是把位置向量加到 token 向量上。为了看清打分里发生了什么,先把它直接加在 q、k 上,再点积。一对 token 相隔 3 个位置(m = 5、n = 2),然后把整句往后挪:
- ① 朴素方案
- ② 它在哪失败
- ③ 改进方案
看这组 8 维的 q、k(教学构造)
看这组 8 维的 q、k(教学构造)
同一对 q、k、同样的平移,右边 RoPE 那一列一个数都不变。下一节看它为什么不变。
真实的 Transformer 里,位置向量加在 x 上,再乘 WQ、WK。展开 (xm+pm)WQWKᵀ(xn+pn)ᵀ,同样是四项:内容×内容、内容×位置、位置×内容、位置×位置,中间两项仍然看绝对位置。我们项目的单元测试里有同样的对照(tests/test_core.py 的 test_additive_sinusoidal_is_not_relative):把 sinusoidal 加到 q、k 上,点积随整体平移而改变。
改进:不「加」,改成「转」
先回到 2 维,看最干净的情形。下面是旧版课程的 RoPE 演示,原样迁移:
下面是两个普通的 2 维向量(教学构造):q(提问的一方,在位置 m)和 k(被查的一方,在位置 n)。 RoPE 不给它们「加」任何东西,只是按各自的位置把它们转一个角度:位置 m 转 m × 20°,位置 n 转 n × 20°。 拖两个滑杆,盯住右边那个「旋转后点积」。
关键是旋转矩阵是正交矩阵:R(φ)ᵀ = R(−φ),而且两次旋转可以相加:R(α)R(β) = R(α+β)。 于是 m 和 n 只能以 n − m 的形式留下来,绝对位置在点积里被约掉了。 这正是苏剑林推出 RoPE 的方式——先立下「内积后只剩相对位置」这个方程,解出来就是旋转矩阵。
试四件事:① 先只拖 m,看「旋转后点积」一路变;再把 m、n 拖到相等,它精确地回到「旋转前点积」——相对位置 0 等于什么都没发生;② 连点几次「整体平移 +1」,绝对位置从 3、1 推到 7、5,操作记录里「旋转后点积」那一列一个数字都不动,这就是「只依赖 m − n」的现场证据;③ 紧接着点「只把 m +1」做对照,位置差一变,点积立刻跟着变;④ 顺手核对:中间那块「真实算术」是用 2×2 旋转矩阵逐个数字乘出来的,和解说里 cos 公式给出的值完全一致,这不是巧合,是旋转矩阵正交性的必然结果。
把「为什么只剩 m − n」逐项拆开:
这条恒等式是严格推出来的,不依赖任何实验 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条只用到旋转矩阵的正交性与角度可加性;对任意 q、k、任意位置成立。 出处RoFormer §3.4(arXiv 2104.09864) ↗需联网 。
从 2 维到真实维度:多个转速
真实的 q、k 不是 2 维。RoPE 把要旋转的维度两两一组切成若干个 2D 平面,每组各转各的,转速不同:第 i 组在位置 m 转 m·θi,θi = base−2i/d。每一组都单独满足上面的恒等式,各组点积加起来,整体仍然只依赖 m − n。这和第 3 课 sinusoidal 的频率公式同源,区别在于它乘在 q、k 上,不加在输入上。
锚点模型 Qwen3.8 的真实配置(anchor-model.json):每个注意力头 256 维,partial_rotary_factor = 0.25,所以只有 64 维旋转,分成 32 组;base(rope_theta)= 10,000,000。现算每组转一圈要多少个 token:
| 第 i 组 | 转速 θi(弧度/token) | 转一圈要多少 token |
|---|---|---|
| i = 0(最快) | 1 | 6.28 |
| i = 16 | 3.162e-4 | 19,869 |
| i = 31(最慢) | 1.655e-7 | 37,969,062(约 3797 万) |
试三件事:① 把位置拖到 100:前几组已经转了十几圈,最后几组几乎没动——快的组分辨近处,慢的组分辨远处;② 切到 Qwen3-8B 和 DeepSeek LLM 67B,比较它们的 base 和最慢一组的周期;③ 看虚线圈:Qwen3.8 有几组在它的原生上下文 262,144 之内一圈都转不完?记住这个数,第 5 课要用。
常见误解之一:「每个维度都在旋转。」
Qwen3.8 的每个头 256 维里,只有 64 维旋转,另外 192 维完全不转。这 192 维上的打分只看内容,不带任何位置。只转一部分维度(部分旋转)不是 Qwen 的发明,GPT-J、GPT-NeoX 早就只转 25%;转多少是实验选出来的 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条partial_rotary_factor = 0.25 没有理论推导;R2 调研记录了它在 GPT-J / GPT-NeoX 已有先例,Qwen 从 Qwen3-Next 起采用。 出处待补 。
常见误解之二(旧版课程的错误):「低频组要几千个 token 才转完一圈。」
实际远不止。Qwen3.8 最慢一组约 37,969,062 个 token 才转一圈;即使用最早的 base = 10,000、128 维(DeepSeek LLM 67B 的配置),最慢一组也要 54,410 个 token。
把这一步放回真实张量里。下图是 Qwen3.8 一个全注意力层里 Q 的旋转(K 做完全相同的事,只是 4 个头):
| 维度 | 含义 | 真实规模 | 小规模 |
|---|---|---|---|
| T | 序列长度(「小明打了小王」在 Qwen3.8 里是 3 个 token) | 3 | 3 |
| Hq | Q 头数(num_attention_heads) | 24 | 2 |
| Hkv | KV 头数(num_key_value_heads) | 4 | 1 |
| dh | 每头维度(head_dim) | 256 | 8 |
| dr | 旋转的维数 = head_dim × partial_rotary_factor | 64 | 2 |
| dp | 不旋转的维数 | 192 | 6 |
常见误解之三:「RoPE 给 embedding 加了一个位置。」
RoPE 不碰 embedding,也不在输入端做任何事。它发生在每一个全注意力层内部:q_proj、k_proj 算出 Q、K 之后,按位置旋转 Q 和 K,再打分。V 不旋转。Qwen3.8 的 64 层里只有 16 层是全注意力层,RoPE 只在这 16 层起作用;另外 48 层是线性注意力,不用 RoPE(C11 揭晓)。
🔍 真实代码里怎么两两配对?(相邻配对 vs rotate_half)
「两两一组」有两种写法。RoFormer 原文和我们项目的 minillm 把相邻的第 2i、2i+1 维配成一对;HF transformers 里 Llama、Qwen 一系的实现用 rotate_half,把第 i 维和第 i + d/2 维配成一对。GLM-5.3 的 config 里专门有一个字段标明它用哪种:rope_interleave = true(frontier-models.json)。两种写法只差一个固定的维度重排:把这个重排吸收进 WQ、WK 的列顺序,注意力分数完全相同 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条置换矩阵 P 满足 PᵀP = I;对 q、k 同时做 P,点积不变。本课开发时用 numpy 验证过两种写法的点积差为 0。 出处待补 。
🔍 Qwen3.8 config 里的 mrope_section [11, 11, 10] 是什么?
M-RoPE:把 32 个频率对分成三段,分别给时间、图像高、图像宽三种位置用,这是 Qwen2-VL 起为多模态加的(R2 §1.4)。纯文本输入时三种位置编号相同,三段转的是同一个 m,等价于普通的 1D RoPE,本课讲的全部成立。
最后算一笔账:RoPE 的旋转角全由位置和 θ 算出,0 个参数。对照第 2 课,如果 Qwen3.8 用可学习位置覆盖同样的 262,144 个位置,光位置表就要 1,342,177,280 个参数。
位置编码的演进,你在这里
- 解决了注意力对所有 token 一视同仁,一次矩阵乘并行算完。卡在交换「小明打了小王」为「小王打了小明」,每个 token 的输出向量逐位相同,差值 = 0(第 1 课在浏览器里实算)。
- 解决了每个位置一个不同的数,简单直接。卡在编号没有上限:在位置 37,内容只剩位置信号的 2.7%(内容 RMS = 1 时;按项目初始化尺度只剩 0.054%)。
- 解决了位置也查表,和词向量一样训练出来。卡在表有多少行就只能处理多少个位置:GPT-2 的位置表 1,024 行 × 768 维 = 786,432 个参数,位置 1,024 没有对应的行。
- 解决了不背位置,用多组 sin/cos 现算,任意位置都算得出来;两个位置编码的点积只依赖距离。卡在「算得出」不等于「会用」:原文表 3 里它和可学习位置几乎一样(dev PPL 4.92 vs 4.92,BLEU 25.8 vs 25.7);而且加在输入上,整句平移后注意力分数会变。
- 解决了直接告诉注意力「相隔多远」,语言规律在文章各处一样。卡在要改注意力的计算,为每个距离单独加一项,距离还被截断在 [rmin, rmax] 之内(RoFormer §2.3 的综述)。
- 解决了按位置旋转 Q、K,转完再点积,绝对位置被约掉,只剩 n − m;不加参数。卡在能算到任意长,却只在训练见过的角度内可靠:Qwen3 原生 32,768,64 个频率对里有 24 对一圈都没转满;Qwen3.8 原生 262,144,32 对里有 10 对。
- 解决了把新位置折算回见过的范围:Qwen3 32,768 → YaRN ×4 = 131,072;Qwen3.8 262,144 → ×4 ≈ 1M。卡在窗口 ≠ 有效长度:Qwen3.8-Flash-Next 技术报告自报,8 针 MRCR 在 128K 为 97.14,到 1M 只剩 20.71(全注意力版本)。
- 解决了Qwen3.8 只转 25% 的维度;Kimi K3、GLM-5.3-Flash 的全局注意力层不用任何位置编码,顺序交给线性注意力层。卡在Qwen 报告:全注意力层去掉 RoPE,预训练看不出差别,后训练后「停不下来」的比例明显升高——所以它保留了 RoPE。两条路线都做到了百万级上下文,没有唯一正解。
证据三问
| 问 | 本课的回答 |
|---|---|
| ① 它解决什么问题? | 让注意力分数直接依赖相对位置 n − m,位置不再和内容混在一起,而且不加任何参数 |
| ② 数学上为什么可能有效? | RmᵀRn = Rn−m,点积里只剩相对位置 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条恒等式,对任意向量成立。 出处RoFormer §3.4 ↗需联网 ;另外可以证明,多频率下打分的上界随距离衰减(第 5 课画出来),但「衰减是好事」只是动机 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条证明的是上界,不是每个头的实际分数;作者认为「距离越远关联越弱」符合直觉。 出处RoFormer §3.4.3 ↗需联网 |
| ③ 实验上为什么最后选了它? | RoFormer 自己的实验:WMT14 英德翻译 BLEU 27.3 → 27.5;中文长文本 CAIL2019-SCM 上,1024 长度的测试准确率 69.79%,高于 512 长度的 68.29%;EleutherAI 在 125M、1.4B 模型上报告比可学习绝对位置收敛更快 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条提升幅度不大,只在论文的规模与任务上成立;作者在 §4.5.5 承认说不清它为什么收敛更快。后来被大量模型采用,是更多实验累积的结果。 出处RoFormer 表 1、表 5 ↗ |
一句话
RoPE 不给向量加位置,而是按位置把 Q 和 K 转一个角度;转完再点积,绝对位置被约掉,只剩位置差 n − m。
先停在这里:记住「转 Q、K,点积里只剩 n − m;Qwen3.8 只转 64 维」,就可以进 C3。
再深一层:展开上面两个 Dig(配对写法、M-RoPE),再去读苏剑林那篇。
下一个缺口
RoPE 是不是把绝对位置丢了?(岔路)→ 主线:能算出位置,是不是就能读懂长文?
- 岔路:RoPE 丢了绝对位置吗?LLM 的设计是证明出来的吗?
- 主线:第 5 课:能算出位置编码,就能读懂长文吗?
- 回扣:为什么偏偏只转 Q、K,不转 V?这个疑问在 C3 第 6 课 兑现——讲完 Q、K、V 各自的角色之后,答案会很自然。
你的提问
这一课来自一次真实的学习对话。学到这里,提问是:
「使用这种旋转的位置编码,似乎只保留了相对位置,缺少了绝对位置,这样效果是 ok 的吗。是实验证明的吗。还是有理论?」
这个问题值得单独一课:岔路课:RoPE 丢了绝对位置吗?LLM 的设计是证明出来的吗?