第 6 章 · 位置编码(RoPE)

解释 RoPE 如何通过逐对旋转把 token 顺序注入注意力,而无需可学习的位置嵌入。

自注意力是置换不变的——没有位置信号,模型无法区分 'cat sat on mat' 和 'mat sat on cat'。

8 分钟
前向传播分词嵌入查表× 24 层最终 RMSNormLM head采样
术语表 · 6 个术语
RoPE
旋转位置嵌入(Rotary positional embedding)。在点积之前,把 Q 和 K 的每个 (x_2i, x_2i+1) 维度对旋转 m * theta_i 的角度。
pair frequency (theta_i)
每个维度对的旋转速率:theta_i = base^(-2i / rope_dims)。i 小转得快,i 大转得慢。
rope_theta (base)
频率指数的底数。Qwen3.5 用 1e7,远高于最初的 1e4——把频谱拉长以支持长上下文。
partial rotary factor
RoPE 旋转每个头维度的比例。Qwen3.5 用 0.25,所以 256 个头维度中只有 64 个被旋转;其余原样通过。
relative-position property
RoPE(q,m) 与 RoPE(k,n) 的点积只取决于 m-n,所以模型只需要学习相对偏移。
unitary rotation
旋转保持向量范数不变——RoPE 改变向量指向的方向,从不改变它们的大小。

位置编码:模型如何知道 token 的顺序

自注意力有一个奇怪的性质:它是置换不变(permutation-invariant)的。如果把输入 token 打乱,每个 token 的注意力输出也会跟着一起被打乱,但注意力层计算出的关系本身不会变。没有外力帮助,Transformer 真的分不清 "the cat sat on the mat""mat the on sat cat the"。必须有什么东西把顺序重新注入进来。

先亲眼看看。下面是一个由三个 token 组成的玩具集合,没有附带任何位置信息——随意重新排列它们,注意力权重纹丝不动:

朴素的注意力看不见顺序
重新排列这袋 token——权重纹丝不动
当前顺序 · cat · sat · mat
cat 对每个 token 的注意力 · softmax(content · content)
cat0.46
sat0.36
mat0.17
权重相同,只是位置重新贴了标签。打乱顺序,再看 cat 的每根条——每个 token 的数值原封不动:上面的槽位换了,数字没有动。

朴素的注意力只看见哪些 token 在场,看不见它们的顺序——换个顺序,每个权重都保持不变。这种对顺序的失明,正是 RoPE 通过按位置旋转 Q 和 K 所填补的空缺。

仅作示意——三个固定 token,使用手挑的 2 维内容向量,没有任何位置信号。一个 token 对另一个 token 的权重,是二者内容向量点积的 softmax,只取决于这两个 token 本身,与槽位无关——所以在任何排序下都相同。真实模型有更多维度、可学习的 Q/K 投影,以及恰好打破这种对称性的 RoPE 旋转。

两个更早的想法

  • 可学习的位置嵌入。早期的 GPT、BERT 等模型给 0..N-1 的每个位置都配一个可学习的向量,并把它到 token 嵌入上。简单,但模型无法外推到训练中从未见过的位置,而且必须事先定死最大长度。
  • 正弦位置嵌入。2017 年最初的 Transformer 用不同频率的固定正弦波,同样加到 token 嵌入上。理论上可以外推,但实践中超过训练窗口后质量会退化。

RoPE 的想法:旋转,而不是相加

旋转位置嵌入(Rotary Positional Embedding,RoPE)不去动嵌入本身,而是把位置直接烘焙进注意力的数学里。诀窍是在点积计算之前,把 query 和 key 向量按一个取决于 token 位置的角度旋转

具体来说,RoPE 把相邻的特征维度配成对——(x_0, x_1)(x_2, x_3)、… ——并把每一对当作 2D 平面上的一个点。对维度对序号 i旋转维度 d(RoPE 实际旋转的特征数——不一定是完整的头维度;下文马上细说),频率是:

用文字读这个式子:随着维度对序号 i 增大,指数 −2i/d 越来越负,所以 越来越小。低序号的对转得快(追踪精细的局部位置);高序号的对转得慢(追踪粗粒度的长程位置)。

在 token 位置 m,这一对被旋转 的角度:

旋转矩阵做的事就是把一个 2-D 点——想象一根钟表指针——旋转角度 ;下面的四个三角函数项只是计算旋转后落点的配方。再往下的钟面表盘展示的正是这种旋转。这里的角度用弧度(radian)度量——在这个单位里一整圈是 ,所以“1 rad/token” 的速率大约是每步六分之一圈。

亲手把这个矩阵算一遍,就用 pair 0——它的频率恰好是 θ₀ = base⁰ = 1 弧度/token,所以 pair 0 每步转 1 rad。取位置 m = 2 处的 (1, 0):它旋转 2 rad,落在 (cos 2, sin 2) ≈ (−0.42, 0.91)。长度不变,方向变了——而这正是你将在下方表盘 0(高频钟面)上看到的旋转。

这里为了直观把维度画成相邻配对(x_0x_1);Qwen3.5 实际如何排列它们是一个实现细节,第一遍阅读可以跳过(见下方进阶)。

进阶:维度对实际是怎么排列的(rotate-half) · 可选,给好奇的读者

这里为了直观把维度画成相邻配对(x_0x_1),但 Qwen3.5——和大多数 Llama/HF 风格的模型一样——用的是数学上等价的 rotate-half 布局:维度 i 与旋转块后一半中的对应维度 i + d/2 配对。同样的角度、同样的频率、同样的相对位置性质;不同的只是两个维度共享一次旋转。

旋转是酉变换(unitary)——它保持向量范数不变——所以 RoPE 不改变 Q 和 K 的大小,只改变它们指向的方向。位置信息骑在角度上,而不是大小上。

宽广的频率范围

低序号的维度对(i 小)拿到最高的频率、转得最快——几个 token 就转完一整圈。高序号的维度对频率小到几乎为零,即使跨越数万个 token 也几乎不动。直觉是:高频对编码精细的局部位置(“我离邻居是不是 3 个 token?”),低频对编码粗粒度的全局位置(“我在文档的前半部分还是后半部分?”)。

Qwen3.5 的头维度是 256,部分旋转因子(partial rotary factor)是 0.25(所以每个头只有前 64 个特征被旋转——其余原样通过),RoPE 底数则大得不寻常:1e7。大底数把频谱拉长,使最低频的维度对在模型 262,144 token 的上下文窗口内几乎不旋转——这是长上下文外推的关键配料之一。

为什么只旋转头的四分之一?因为未被旋转的那 192 个维度完全不携带位置——它们做纯粹的内容匹配(“这个 key 的含义是不是我的 query 正在找的?”)。位置只需要骑在向量的一部分上;其余部分可以只关心语义本身。

还有一个 Qwen3.5 混合架构特有的细节:这个 RoPE 旋转只施加在 6 个全量注意力层上(如上所述,这些层旋转 256 个头维度中的前 64 个)。其余 18 层是线性(GatedDeltaNet)层,通过循环再加一段短因果卷积来隐式地编码位置——完全不用 RoPE。

相对位置性质

这是让 RoPE 真正“通”的部分。取 RoPE(q, m)RoPE(k, n) 的点积,结果只取决于差值 m - n,与 mn 各自的取值无关。模型永远不需要学习“位置 1,427”是什么意思——它只需要学习注意力在相对偏移上应该如何表现,而这天然地泛化到它从未见过的长度。

右侧第三个面板把这一点变得具体。把 query 位置固定在 m = 50、变动 key 位置 n,旋转后的点积在 n - m = 0 处出现尖锐峰值,并随着距离拉远向两侧(带着涟漪地)衰减。这种衰减正是让注意力天然“偏爱”近处 token 胜过远处 token 的归纳偏置——而且完全不需要逐位置的参数。

你可以直接感受这种只依赖偏移量的性质。把两个位置一起平移,分数纹丝不动:

q·k 只取决于偏移 m − n
同时移动两个位置——分数纹丝不动
基向量 (pos 0)k · n=2q · m=6
两个位置一起移动(Δ 不变)——看两支箭头一起扫过,而 q·k 保持不动
偏移 Δ
4
相对旋转
Δ·ω = 2.00 rad
q·k
-0.42
逐渐背离 · q·k = cos(Δ·ω) = cos(2.00) = -0.42
结论:分数 q·k = cos(Δ·ω) 只取决于偏移 m − n——两个位置一起移动,它纹丝不动。

两支箭头都从同一个基向量出发;RoPE 把 query 旋转 m·ω,把 key 旋转 n·ω,所以 query 的相对旋转恰好是 Δ·ω = (m − n)·ω,且 q·k = cos((m − n)·ω)。让 mn 一起增大,整幅图都会旋转,但夹角——以及分数——冻结不动。只动其中一个,夹角就会张开或闭合:让它们对齐(Δ → 0),q·k → 1

仅作示意——这里只用了一个代表性频率(ω = 0.5 rad/token),并把内容向量简化为共享的基向量,以便单独观察位置部分。随着位置增大,相对旋转 Δ·ω 可能超过一整圈,但余弦每圈重复一次,所以分数仍然只取决于偏移 Δ。真实模型会把它与真正的 query/key 内容结合,在许多速度各异的频率对上同时进行(见下方的频率谱)。

本章直接可视化 RoPE 的数学——不需要任何模型推理。想看看它在真实注意力分数上的效果?打开自注意力(第 4 章),观察分数图如何偏向对角线。

工程要点
  • RoPE 把位置编码成旋转而不是加法——向量大小保持恒定,只有角度携带位置信号。
  • 低序号的维度对是高频的(精细的局部位置);高序号的维度对是低频的(粗粒度的全局位置)。
  • RoPE 之后的点积只取决于 m - n,这正是带 RoPE 的模型能外推到训练中从未见过的长度的原因。
动手练习

把 'Token position m' 滑块从 0 拖到 100。对比高频旋转面板(pair 0)和低频面板(pair 28)。哪一个先转完一整圈?当 m=100 时,另一个转了多少?

随堂测验
1. RoPE 解决了纯自注意力解决不了的什么问题?
2. 在 RoPE 下,最终编码“粗粒度全局位置”的是哪些维度对?
3. 它为什么被称为相对位置性质?

动手试试

互动演示加载中……