大模型的上下文窗口是如何扩展的?位置插值、NTK、YaRN 是什么?
简化版
大模型在固定长度(如 4K)上训练,直接用到更长序列(如 32K)时,因为位置编码进入没训练过的区域而性能骤降。扩展上下文的主流思路是改造 RoPE 的位置/频率,让长序列「挤」回模型熟悉的范围:
- 位置插值(PI):把位置索引按比例缩小,等比压进训练范围,需少量微调。
- NTK-aware scaling:调整 RoPE 的频率底数,高频(近距离)基本不变、低频(远距离)才插值,可少训练甚至免训练扩中等长度。
- YaRN:结合 NTK 与注意力温度缩放,用更少的微调达到更长、更稳的上下文。
除改位置编码外,还有长文本继续训练、滑动窗口注意力、稀疏/高效注意力、KV 压缩等配套手段。
详细版
问题根源:外推失效
RoPE 用旋转角 m·θ 编码位置 m。模型只在 m ∈ [0, L) 上训练过。当推理位置 m 超过 L,旋转角进入训练时从未见过的区间,注意力模式失真,表现为「困惑度飙升、答非所问、只用到开头信息」。这就是直接外推(extrapolation)会崩的原因。
三种主流扩展法
-
位置插值(Position Interpolation, PI)
- 思路:不外推,而是内插。把位置索引乘以
L/L'(L 是原长,L’ 是目标长),让 [0, L’) 的位置「压缩」到 [0, L) 内。 - 效果:所有位置都落回训练过的范围,稳定。需少量长文本微调恢复精度。
- 代价:位置分辨率变粗(相邻位置的编码差异变小),近距离建模略受损。
- 思路:不外推,而是内插。把位置索引乘以
-
NTK-aware scaling
- 思路:不均匀地缩放——高频维度(管近距离)几乎不动,低频维度(管远距离)才插值。通过调大 RoPE 的 base(θ 的底数)实现。
- 效果:保住了近距离分辨率,中等长度扩展可免微调或极少微调。
- 直觉:近处要看清(别动),远处放宽(插值)。
-
YaRN(Yet another RoPE extensioN)
- 思路:在 NTK 基础上进一步分频段处理,并引入注意力温度缩放(调 softmax 的缩放)补偿长序列下注意力熵的变化。
- 效果:以更少的微调(更省算力)实现更长、更稳的上下文,是当前性价比很高的方案。
配套手段
- 长文本继续预训练/微调:直接在长样本上训,最直接但最贵。
- 滑动窗口注意力:每个 token 只看最近 W 个,降成本(Mistral)。
- 稀疏/高效注意力、KV 压缩:控制长上下文的计算与显存。
完整版教学
记忆钩子:架构题不要只背名字,要沿着「张量怎么变、复杂度怎么变、训练/推理代价怎么变」三步讲。
一、为什么”训 4K、用 32K”会崩
上下文扩展的难点全在位置编码的外推能力。RoPE 把位置信息编成随位置线性增长的旋转角 m·θ_i(不同维度 i 用不同频率 θ_i)。训练时模型见过的旋转角范围对应 m ∈ [0, L)。
当推理位置远超 L:
- 旋转角进入训练分布之外,注意力对「远距离相对位置」的响应没被学过,行为不可控。
- 现象上表现为:困惑度(PPL)急剧上升、模型「注意力涣散」、常常只能有效利用序列开头,丢失中后段信息。
所以扩展的核心目标是:别让长序列的位置编码跑到”没训练过”的区域。要么把位置压回熟悉范围(插值),要么让编码在长距离上变化得更平缓(改频率)。
二、位置插值 PI:把长序列”压”回训练范围
PI 的想法极简:既然模型只熟悉 [0, L),那就把目标长度 L’ 的位置索引线性缩小 L/L' 倍,让它们全部落进 [0, L)。
原始: 位置 m ∈ [0, L'),旋转角 m·θ (超出训练范围)
PI: 位置 m → m·(L/L'),旋转角 m·(L/L')·θ (压回 [0, L) 内)
比如把 4K 扩到 32K,就把每个位置索引除以 8。这样第 32000 个位置的编码,相当于原来第 4000 个位置——完全在模型见过的范围内。
- 优点:稳定可靠,是最早被验证有效的方法。
- 代价:位置「密度」变大、分辨率变粗——原本相邻两个位置的编码差异,现在被压缩了 8 倍,近距离的位置区分度下降,所以需要少量长文本微调让模型适应新的位置尺度。
三、NTK-aware:近处别动,远处才插值
PI 一刀切地压缩所有频率,损害了近距离分辨率。NTK-aware scaling 更聪明:分频段区别对待。
RoPE 的不同维度用不同频率:高频维度旋转快、管近距离的精细区分;低频维度旋转慢、管远距离。NTK 的洞察是:
- 高频(近距离)维度:分辨率宝贵,几乎不缩放,保持精细。
- 低频(远距离)维度:本就变化慢,对它们做插值扩展范围,损失小。
实现上通过调大 RoPE 的 base(θ 的底数) 来达成这种「高频不变、低频插值」的不均匀缩放。好处是在中等扩展倍数下可以免微调或极少微调就工作,因为它没有牺牲近距离精度。这也是很多「无痛扩上下文」技巧的基础。
四、YaRN:更省微调的组合拳
YaRN 在 NTK 的方向上更进一步:
- 分频段精细处理:对不同频率区间采用不同的插值/保留策略(有的维度外推、有的插值、有的过渡),比单一 NTK 更精细。
- 注意力温度缩放:长序列下,注意力要 softmax 的对象变多,注意力分布的「熵」会变化,导致注意力过于平均或过于尖锐。YaRN 引入一个温度因子调节 softmax 的缩放,补偿这种变化,稳住长序列下的注意力质量。
综合下来,YaRN 用远少于「从头长训」的微调量,就能把上下文扩到很长且保持质量,性价比高,被不少开源长上下文模型采用。
五、改位置编码之外,还得配套什么
位置编码扩展解决了「模型能不能理解长位置」,但长上下文还有计算和显存的现实压力(注意力 O(n²)、KV Cache 线性膨胀)。所以工程上通常组合:
- 长文本继续训练:无论用哪种插值,少量长样本微调几乎都能明显提升效果;条件允许时直接在长上下文上继续预训练最稳。
- 滑动窗口注意力:限制每个 token 只看最近 W 个,降低长序列注意力成本(Mistral 的做法)。
- 高效注意力:FlashAttention 降显存/访存,稀疏/线性注意力降复杂度阶。
- KV Cache 优化:GQA/MLA 压缩 KV,缓解长上下文的显存瓶颈。
面试能把「位置编码扩展(PI/NTK/YaRN)」和「计算/显存配套(滑窗、FlashAttention、KV 压缩)」两条线都点到,说明你理解长上下文是系统工程,不止改个位置编码。
六、面试拆解算例
这类题最怕只讲术语,最好把它落成一次资源账。假设模型有 32 层、hidden size 为 4096、序列长度从 2K 增到 16K,标准注意力的相关度矩阵规模会从 2K × 2K 变成 16K × 16K,理论元素数量放大 64 倍。即使具体算子不会真的把所有中间矩阵都落到 HBM,复杂度曲线仍然决定了 prefill 延迟和显存压力会快速上升。
attention_scores_per_head = seq_len * seq_len
2K -> 2,048 * 2,048 ≈ 4.19M
16K -> 16,384 * 16,384 ≈ 268.44M
放大倍数 ≈ 64
| 观察维度 | 面试要说清的问题 | 工程判断 |
|---|---|---|
| 张量形状 | Q/K/V、hidden state 或路由权重怎样变化 | 能否解释实现差异 |
| 复杂度 | 随层数、序列长度、head 数怎样增长 | 谁先成为瓶颈 |
| 质量风险 | 是否改变训练分布或表达能力 | 会不会掉点 |
| 部署代价 | 算子、框架、缓存是否支持 | 能不能稳定上线 |
输入 token -> embedding -> 注意力/FFN/归一化模块 -> hidden state -> logits
| | |
位置/掩码 显存与吞吐 质量与稳定性
所以回答「大模型的上下文窗口是如何扩展的?位置插值、NTK、YaRN 是什么?」时,推荐先讲结构变化,再讲这条变化怎样影响资源曲线,最后补一句质量和部署的边界。这样比单纯背「某某结构更快、更省」更像工程答案。
七、常见误区与追问
- 误区:把上下文调大就行,不用训练。 直接外推会崩;PI 需微调,NTK/YaRN 可少微调,但都不是「零成本随便调」。
- 误区:插值就是简单放大窗口。 是缩小位置索引(把长序列压回训练范围),不是放大。
- 追问:为什么直接外推 RoPE 会失效? 旋转角进入训练时没见过的区间,注意力对远距离相对位置的响应未被学习。
- 追问:NTK 为什么比 PI 好? PI 均匀压缩损害近距离分辨率;NTK 高频不动、低频插值,保住了近处精度,常可少训练。
- 追问:YaRN 多了什么? 分频段处理 + 注意力温度缩放,补偿长序列注意力分布变化,微调更省。
- 追问:只靠位置扩展够吗? 不够,还需长文本训练与计算/显存优化(滑窗、FlashAttention、KV 压缩)配套。
- 追问:上下文长≠用得好? 是的,存在「长上下文但中间信息被忽略(lost in the middle)」问题,需评测真实长程利用能力,而非只看窗口数字。
八、加强记忆
长上下文扩展记一条主线:RoPE 直接外推会崩(位置编码跑出训练范围),所以想办法把长序列”塞回”模型熟悉的区域。 三招递进:PI(位置索引整体缩小、需微调,但近距离分辨率受损)→ NTK(高频不动、低频插值,保近处、少微调)→ YaRN(分频段 + 注意力温度缩放,微调最省、效果最好)。 再挂一句系统视角——扩上下文不只是改位置编码,还要配长文本训练 + 滑窗/FlashAttention/KV 压缩解决 O(n²) 与显存,且要警惕「窗口很长但中间信息用不上」的假长上下文。