跳转至

三十四:Long Context~YaRN 与 LongRoPE

来源:http://mp.weixin.qq.com/s?__biz=MzYyNTk3Njg1NA==&mid=2247484410&idx=1&sn=3bc0142061881d32a298bf8b51c703bd&chksm=f01eb083c7693995cf82dd641f521bf5d0045d816a137dd75b5c5c6f623b8c7c9dc9d74beb9f#rd

1. 学习范围

本日主题是 RoPE 长上下文扩展中更细粒度的插值方法,重点是 YaRN 插值。Day 33 已经讲了直接外推、线性 Position Interpolation 和 NTK-aware scaling;Day 34 进一步讨论为什么统一缩放仍然不够,以及 YaRN、LongRoPE 如何在不同频率维度和不同位置区域上做更细的设计。 需要掌握: - 线性 PI 和 NTK-aware 的局限。

  • NTK-by-parts 的分段频率缩放思想。

  • 动态插值的动机。

  • YaRN 的核心目标、频率分段和 attention scaling。

  • LongRoPE 的非均匀插值和渐进扩展直觉。

  • 这些方法在工程中如何配置、评估和排错。

2. 参考资料

  • YaRN 论文:https://arxiv.org/abs/2309.00071

  • LongRoPE 论文:https://arxiv.org/abs/2402.13753

  • Position Interpolation 论文:https://arxiv.org/abs/2306.15595

  • 从 RoPE 到 YaRN 的公式推导:https://zhuanlan.zhihu.com/p/15311461897

  • 从 ALiBi、PI、NTK-aware 到 YaRN、S2-Attention:https://blog.csdn.net/v_JULY_v/article/details/135072211

  • Hugging Face RoPE utilities:https://github.com/huggingface/transformers/blob/main/src/transformers/modeling_rope_utils.py

3. 为什么还需要 YaRN

线性 PI 的问题:

position m -> m / s
所有维度、所有距离都被统一压缩。它稳定,但局部位置分辨率下降。 NTK-aware 的问题:

base -> base_new
它通过改变频率分布保留更多局部能力,但仍是一个相对统一的频率重标定。不同频率维度承担不同位置尺度,统一规则未必最优。 YaRN 的出发点是:

不同 RoPE 维度对应不同波长。
短波长维度更重要于局部顺序,不应强行插值。
长波长维度用于远距离建模,更需要扩展。
中间维度可以平滑过渡。
因此 YaRN 更像一种“按频率分段的 RoPE 插值方案”。

4. 波长视角

RoPE 的第 i 个频率:

inv_freq_i = 1 / base^(2i / d)
对应波长可以粗略理解为:

wavelength_i = 2π / inv_freq_i
波长短: - 相位绕圈快。

  • 对局部位置很敏感。

  • 训练长度内已经多次变化。

  • 不适合强插值,否则局部能力受损。

波长长: - 相位变化慢。

  • 更适合表达长距离。

  • 扩展上下文时需要拉长覆盖范围。

YaRN 利用这个波长视角,判断哪些维度应该保留外推,哪些维度应该插值,哪些维度处于过渡区。

5. NTK-by-parts

NTK-by-parts 可以理解为“分段 NTK scaling”。它不像普通 NTK-aware 那样对所有频率用同一个 base 缩放,而是按维度分成几段:

短波长维度:
  更偏向不插值或少插值,保留局部能力。

中间波长维度:
  使用平滑权重,在外推和插值之间过渡。

长波长维度:
  更偏向插值或更强缩放,覆盖长距离。
抽象写法:

inv_freq_new_i =
  ramp_i * inv_freq_interp_i + (1 - ramp_i) * inv_freq_extra_i
其中: - inv_freq_extra_i 原始未缩放RoPE频率,即外推频率。

  • inv_freq_interp_i 线性插值后的频率,更擅长超长距离。

  • ramp_i斜坡权重,是按维度变化的平滑权重。

  • 短波 → ramp=0 → 100% 原始外推;

  • 长波 → ramp=1 → 100% 插值缩放;

  • 中间波段 → ramp 线性从 0 升到 1,平滑混合两种频率。

这个思想是 YaRN 的关键直觉之一。

6. YaRN 的核心机制

YaRN 的全称常被理解为 Yet another RoPE extensioN。它的目标是高效扩展上下文窗口,同时减少训练 token 和训练步数需求。 YaRN 主要做三件事: - 按频率维度区分外推、插值和过渡区域。

  • 使用平滑 ramp 避免频率突变。

  • 引入 attention scaling,补偿长上下文下 attention score 分布变化。(序列拉很长后,RoPE 会让 Q・K 的内积(attention score)整体变小、挤在一起,softmax 分不清主次;Attention Scaling 就是乘一个放大系数,把分数拉开,恢复长短文本一致的注意力分布。)

高层流程:

输入:
  原始 base / inv_freq
  原训练长度 L_train
  目标长度 L_target
  扩展倍率 factor
  beta_fast / beta_slow 等超参

步骤:
  1. 根据波长或旋转次数,找到需要过渡的维度范围。
  2. 生成 ramp mask。
  3. 对不同维度混合外推频率和插值频率。
  4. 生成 cos/sin cache。
  5. 对 attention score 或 cos/sin 应用 magnitude scaling。

7. beta_fast 与 beta_slow 的直觉

YaRN 中常见两个超参:

beta_fast
beta_slow
它们用于决定哪些频率维度属于快速旋转、哪些属于慢速旋转,以及中间过渡区在哪里。 直觉: - beta_fast 关注快速变化、高频、短波长维度。

  • beta_slow 关注慢速变化、低频、长波长维度。

  • 二者之间用平滑 ramp 过渡,而不是硬切一刀。

面试不必死背具体实现函数,但要能说清:

YaRN 不是所有维度统一插值,而是根据不同维度的旋转频率决定插值强度。

8. Attention Scaling

长上下文扩展后,attention score 的统计分布可能变化。原因包括: - 可见 token 数量变多。

  • 位置相位被重新缩放。

  • QK 内积的尺度和 softmax 分布发生变化。

YaRN 引入 attention scaling 或 magnitude scaling,对 RoPE 后的 attention 计算做幅度校正。不同实现中可能体现为对 cos/sin 或 attention logits 的缩放。 直觉:

长上下文不仅是位置坐标变长,attention 的数值分布也会改变。
YaRN 不只改频率,还补偿 score magnitude。
工程中要注意:如果模型配置里已有 attention_factorrope_scaling 等字段,不要随意省略,否则可能出现长度扩展后 perplexity 或生成质量异常。

9. 动态插值

固定插值按目标最大长度设置缩放:

s = L_target / L_train
即使当前输入只有 2k,也可能使用为 32k 设计的缩放。这会影响短上下文。 动态插值根据实际输入长度设置缩放:

if seq_len <= L_train:
    s = 1
else:
    s = seq_len / L_train
优点: - 短输入保持原模型行为。

  • 中等长度不会被过度压缩。

  • 更适合长度分布变化大的线上服务。

风险: - KV cache 中生成过程长度持续增长,缩放参数不能随意中途变化。

  • 批内不同样本长度不同时,实现要明确使用统一缩放还是逐样本缩放。

  • 与训练时固定 scaling 不一致可能影响效果。

10. LongRoPE 的核心直觉

LongRoPE 进一步提出非均匀位置插值和渐进式扩展。它认为:

不同频率维度需要不同插值因子。
不同位置区间也可能需要不同插值策略。
极长上下文扩展不应只靠一个统一 factor。

img

LongRoPE 的高层思路: - 搜索或设计每个维度的非均匀缩放因子。

  • 对短上下文和长上下文使用不同策略以保留原能力。

  • 通过渐进式扩展,把上下文窗口从较短长度逐步扩到更长长度。

  • 配合少量长上下文微调或继续训练。

与 YaRN 的关系: - YaRN 重点是频率分段和平滑缩放。

  • LongRoPE 更强调非均匀搜索和超长上下文渐进扩展。

11. 方法对比

方法 核心修改 优点 风险 / 缺点 线性 PI(线性插值) 位置映射 m→m/s,全局统一压缩所有维度频率 实现极简、推理稳定、无额外超参 全局压缩低频,短文本位置分辨率大幅下降,短输入 PPL 飙升 NTK-aware 抬高 RoPE 基底 base,低频直接外推、高频插值 局部细粒度位置信息保留优于线性插值,中等扩展效果好 base 参数敏感;超长外推性能衰减明显;无平滑过渡,维度边界突变 NTK-by-parts 高低频维度分段做差异化频率缩放 贴合 RoPE 维度天然快慢特性,比统一 NTK 效果更好 手动划分区间逻辑,代码实现复杂;无平滑 ramp,边界存在频率跳变 Dynamic scaling(动态缩放) 根据输入实际长度动态计算缩放因子 短输入完全使用原生 RoPE,不损失短文本精度 需动态重建 cos/sin 缓存,缓存管理、框架适配逻辑复杂 YaRN 1. beta 快慢阈值分段频率2. 平滑 ramp 过渡3. Attention 幅值缩放补偿 长短文本兼顾;微调步数少、训练成本低;工业 32K/128K 主流方案 beta、缩放因子超参必须匹配配置;漏配 scaling 会导致长文本生成崩坏 LongRoPE 1. 进化搜索维度 / 位置双层非均匀插值2. 渐进阶梯式拉长上下文窗口 支持百万 token 极长上下文,长距离依赖效果最优 需要进化搜索、多阶段渐进微调,训练、验证、部署成本极高

12. 工程配置要点

部署或微调模型时,通常会在配置中看到类似字段:

{
  "rope_theta": 10000,
  "max_position_embeddings": 4096,
  "rope_scaling": {
    "rope_type": "yarn",
    "factor": 8,
    "original_max_position_embeddings": 4096,
    "beta_fast": 32,
    "beta_slow": 1,
    "attention_factor": 0.1
  }
}
字段名和默认值因框架而异。重点不是背 JSON,而是检查: - 原训练长度是否正确。

  • 目标扩展倍率是否正确。

  • rope_type 是否和模型训练/微调时一致。

  • 是否使用了正确的 rope_theta

  • 是否包含 attention scaling。

  • 推理框架是否支持该 rope type。

13. 评估与排错

评估维度: - 短上下文 PPL 和常规任务。

  • 长上下文 PPL 曲线。

  • Needle-in-a-haystack。

  • 长文档问答和引用定位。

  • 多跳长距离任务。

  • 代码长文件理解。

  • 推理延迟、显存、KV cache。

排错优先级:

1. rope_scaling 配置是否被推理框架识别。
2. original_max_position_embeddings 是否正确。
3. factor 是否和训练/微调一致。
4. attention_factor 是否遗漏。
5. position_ids 和 KV cache offset 是否正确。
6. 是否只改了推理,没有做必要微调。
7. 长上下文输入是否被服务层截断。

14. 面试表达模板

可以这样回答 YaRN:

YaRN 是一种 RoPE 长上下文扩展方法。它的核心不是把所有 position 统一除以一个 factor,而是根据 RoPE 不同频率维度的波长来决定插值强度。短波长高频维度更影响局部顺序,尽量保留外推;长波长低频维度更适合长距离,需要更强插值;中间维度用 ramp 平滑过渡。除此之外,YaRN 还考虑长上下文下 attention score 分布变化,引入 attention scaling。

所以 YaRN 可以看作 NTK-by-parts 加平滑过渡和幅度校正。工程上要保证 rope_type、factor、original_max_position_embeddings、rope_theta 和 attention_factor 与训练配置一致,并同时评估短上下文和长上下文。

15. 紧凑总结

  • 统一线性插值会损失局部位置分辨率。

  • NTK-aware 调整 base,但仍较统一。

  • NTK-by-parts 按频率维度分段处理。

  • YaRN 的关键词是:频率分段、ramp 平滑、attention scaling。

  • 动态插值按实际长度调整,但要小心 KV cache。

  • LongRoPE 强调非均匀插值和渐进式超长扩展。

  • 上线前必须确认推理框架真正支持对应 rope scaling。

            预览时标签不可点
    

    <div class="