把 RoPE 直接用到训练长度之外会崩,但只要重新分配旋转频率、不重训模型,就能把 4k 的模型推到 128k 乃至百万 token——PI、NTK-aware、YaRN、LongRoPE 是同一条思路的四次迭代。
为什么直接外推会崩
旋转位置编码(RoPE) 的相对位置性质对任意 都成立,数学上没有长度上限。崩溃来自训练分布,不是公式:
- 高频维度失去区分度: 中 小的维度波长 只覆盖几个 token。位置越界后 已绕转成百上千圈,模型从未见过这些相位组合,相邻位置在高频维上的差异变成噪声。
- 注意力熵异常:越界相位把 query-key 点积推出训练时的数值范围,softmax 或被少数离群 token 独占、或摊平成近似均匀分布。实测 PPL 在约 训练长度处陡升。
- 数值精度:bf16 下求 的三角函数,相位截断误差被放大。
与之对照,ALiBi 用单调衰减偏置天然压制远距离影响,外推平滑却牺牲长程检索能力。RoPE 路线的选择是保留全部位置信息,事后重排频率——这正是下面全部方法的公共前提。
PI:线性位置插值
最直接的做法(arXiv:2306.15595):把位置索引整体压回训练区间。扩展倍率 ,
等价于把每个维度的旋转步长同比缩小 倍,所有位置都落在模型见过的相位范围内。
代价是高频维度被过度压缩。原本用 2–3 个 token 区分邻近位置的维度,压缩后邻词相位差不足,局部语序信息受损。PI 因此通常需要千步量级的微调来恢复。
NTK-aware:改 base 而非改索引
核心洞察来自 NTK 视角——神经网络学高频函数本就困难,线性插值偏偏把高频压得最狠。改法是不动位置索引,只放大 base:
由于 对 指数衰减,放大 base 对各维度的影响天然不均: 的高频维几乎不变, 的低频维被压缩约 倍。局部分辨率保住了,长程外推交给低频维承担,因此免微调即可用。
缺点是高频维仍在小幅外推,倍率大时误差累积。
Dynamic NTK:按实际长度动态缩放
固定 的静态方案有个浪费:序列只有 2k 时,模型也在按 128k 的倍率压缩相位,短序列性能反而不如原版。Dynamic NTK 在推理时逐步计算
未越界就等同原始 RoPE,越界后才按需压缩,且随 KV cache 增长平滑抬升。这是目前多数推理框架的默认选项。
YaRN:分频段插值 + 注意力温度
arXiv:2309.00071 把前面的思路推到显式分段,两个改动叠加:
NTK-by-parts。以波长与上下文长度之比 判断每个维度的角色,按区间分治:
| 维度类型 | 判据 | 处理 |
|---|---|---|
| 高频 | (波长远短于上下文) | 不插值,完整保留局部分辨率 |
| 低频 | (波长超过上下文,从未转满一圈) | 按 线性插值 |
| 中频 | ramp 函数在两者间平滑过渡 |
LLaMA 系常用 。
注意力温度修正。插值压缩相位后 query-key 点积幅度整体缩小,softmax 变平、注意力熵偏高。YaRN 给 logits 乘上常数 把分布锐化回来,经验公式
实现上直接把系数折进预计算的 表,零额外开销。效果是免微调即可达 64k,少量微调达 128k,成为事实标准。
LongRoPE:搜索每维系数
YaRN 的分段仍是人工设计的三段式。LongRoPE 改用进化搜索,以 PPL 为适应度,为每个维度独立搜索插值系数,再配合渐进式扩展(先搜 256k → 微调 → 重搜)突破百万 token。代价是搜索成本高、系数与具体模型绑定。
工业实践
| 模型 | 做法 |
|---|---|
| LLaMA-3 | 8k 预训练,分阶段长上下文继续训练 + YaRN 类缩放至 128k |
| ChatGLM | 仅对部分维度应用 RoPE,留出维度承载非位置信息 |
| Qwen 系 | config 中声明 rope_scaling,推理端开启 YaRN |
{
"rope_scaling": {
"type": "yarn",
"factor": 4.0,
"original_max_position_embeddings": 32768
}
}注意 YaRN 一旦静态启用就作用于全部序列,短输入上会有轻微损失——这也是 Dynamic 变体存在的理由。视频场景的 3D RoPE 则要对时间轴单独选倍率,空间轴通常不动。
外推能力总结
| 场景 | 无限外推 | 说明 |
|---|---|---|
| 理论机制 | ✅ | 旋转连续性 + 正交性 |
| 未优化模型 | ❌ | 长度 > 2×训练范围时性能崩溃 |
| 优化后模型 | ⚠️ 有限 | 可扩展至训练长度的 10–100 倍 |
整个方法谱系的位置见 位置编码。