旋转位置编码

RoPE (Rotary Position Embedding)

RoPE 旋转位置编码是 LLaMA/GPT-NeoX 等现代模型主流使用的相对位置编码方案:通过对 Query 和 Key 的向量空间进行复数域旋转,把位置信息注入注意力计算中,天然具备长度外推能力。

详细解释

RoPE(Rotary Position Embedding,旋转位置编码) 由 苏剑林(bert4keras 作者)2021 年论文《RoFormer: Enhanced Transformer with Rotary Position Embedding》提出,之后被 LLaMA 家族采用而一战封神。到 2025 年几乎所有新开源大模型(Llama 2/3、Qwen、Mistral、Gemma、DeepSeek、Yi)默认 RoPE,只有最早期的 GPT-2/3 仍用绝对位置正弦编码(Sinusoidal)。

它的核心思想非常优雅:不把”位置 m”当成一个额外向量加给 x_q(加法式绝对编码),而是把位置信息”转进” Q 和 K 的向量方向里。

直观类比(二维复数理解):

  • 把 Query 向量 q(维度为 d 的实数向量) 每两个维度拼起来当作一个复数 一个二维复数对;
  • 对”第 m 个位置的 q”,让它在复平面上旋转角度 m 倍 theta_i 的旋转角(theta_i 旋转角 是不同频率的旋转角,低频的旋转慢,高频的旋转快);
  • Key k 向量 也同样在位置 n 上旋转 n 倍 theta_i 的旋转角;
  • 然后内积 q_m 与 k_n 的内积 = $|q_m|,|k_n||q_m| 乘 |k_n| 再乘 cos((m-n) 乘 theta_i)——神奇的事情发生了!结果只跟 (m-n) 有关,也就是只跟相对距离有关,完美实现了相对位置编码。

所以 RoPE 同时具有:

  1. 相对位置特性:注意力分数只看两个 Token 之间的距离 |m-n|;
  2. 线性外推性:训练到 4K,推理时在 128K 上也能工作(虽然需要配合 NTK-aware Scaling / YaRN 等插值才能不掉分);
  3. 无需额外参数:位置编码是纯函数,不参与训练,省了 d 个参数。

参考:RoFormer 论文YaRN 扩展上下文技术

RoPE 的”上下文拉长四板斧”

原始 RoPE 在训练长度(比如 8K)之外直接推理,效果会崩。业界已经积累了 4 种成熟的外推手段,新模型出厂基本都做过:

方法原理能拉到几倍训练长度效果退化程度
线性插值(Linear Scaling)压缩 theta 角频率:新 theta 等于原 theta 除以外推倍数 k4× 左右小(k 小时)
NTK-aware Scaling高频部分少缩放,低频部分多缩放(按 NTK 理论分频)8× ~ 16×比线性好,已开源 Llama 3 上标配
YaRN动态温度缩放 + 幅度修正,按距离自适应16× ~ 32×(8K → 128K)业界当前 SOTA,掉分最少
Dynamic NTK根据当前实际上下文长度 N 动态选缩放因子按需适合输入长度起伏大的场景

对 API 使用的实际影响

作为调用 API 的用户,RoPE 的存在会表现在:

  1. 同样 128K 上下文价格合理:RoPE + YaRN 让厂商不用重新在 128K 上再训练一遍就能卖长上下文;
  2. 长距离”大海捞针”测试是厂商常考的:常见是在 100K 上下文里随机放一个”魔法数字是 42”,最后问魔法数字是什么——RoPE+YaRN 做得好的模型能稳定答对,差的就错;
  3. 超长度时不要硬撑:即使模型标称 128K,你放在 125K 里也会溢出报错;按文档给定 max_position_embeddings 或 走 唯元智创 网关的”超长切分 + 摘要回并”自动处理。

常见问题

RoPE 和 ALiBi 哪个更好?
ALiBi(Attention with Linear Biases,MosaicML MPT 系列用)是”在注意力分数上加一个与距离成正比的偏置项”,也很优秀。业界目前 RoPE 已经通过生态胜出:Llama 全家桶、Qwen、Mistral、Gemma 都是 RoPE,90% 以上开源权重默认它。效果上两者差距很小,选择基本是跟着你用的基础模型走。
RoPE 的 base 值(theta base=10000/500000)是干什么的?
base 决定了旋转频率的”跨度”。base=10000 是 Llama 1/2 默认;Llama 3、Qwen3 等新模型把 base 拉到 500000 甚至 1000000,让最低频率的旋转更慢,在不做插值的前提下原生就能支持更长上下文。base 越大,越适合长上下文。所以看模型卡时注意 RoPE base 参数经常和 Context 长度一起给。
我在自部署上加载 Llama 3 8K 权重,想推理 32K 文档怎么开 RoPE 缩放?
vLLM 或 HuggingFace 都只要一行参数。vLLM:启动时加 —rope-scaling yarn —rope-factor 4.0 —max-model-len 32768(从 8K 拉到 32K = 4×)。HF Transformers:加载模型后,用字典字面量的方式设置 rope_scaling:键 type“yarn”、键 factor4.0,然后生成时 max_new_tokens 合理即可。