12. 长上下文能力通常受哪些因素影响?

整理长上下文能力的关键影响因素与工程瓶颈。

简单回答

长上下文能力受四方面影响:位置编码的外推能力(如 RoPE 及其插值方案)、注意力机制的计算复杂度(标准 Attention 是 O(n²))、训练时是否见过足够的长序列数据、以及推理时 KV Cache 的显存瓶颈。四个环节任何一个有短板,长上下文就不好用。

详细解释

位置编码的外推能力

这是最核心的因素。如果模型训练时最长只见过 4K 的序列,推理时给它 32K,位置编码能不能正常工作?原始的 learned positional embedding 完全不行,训练多长就只能用多长。RoPE 有一定外推基础,但直接外推效果也会衰减。所以出现了一系列位置插值方法:线性插值(Position Interpolation)把长序列的位置"压缩"回训练范围内;NTK-aware scaling 调整 RoPE 的频率基数;YaRN 在此基础上进一步改进,对不同频率分量做不同程度的缩放。这些方法让模型可以在较短训练长度的基础上外推到更长的上下文。

注意力机制的计算复杂度

标准 self-attention 的计算和显存复杂度是 O(n²),当序列长度从 4K 扩展到 128K,计算量增长了 1024 倍。FlashAttention 通过 tiling 优化了显存访问模式,解决了显存问题但计算量没变。还有一些稀疏注意力方案(如 Sliding Window Attention、Longformer 的局部+全局注意力),通过限制 attention 的范围来降低复杂度。Mistral 就用了 Sliding Window Attention。

训练数据中的长序列

即使架构上支持长上下文,如果训练时没有足够的长文本数据,模型也学不会利用长距离信息。很多模型的做法是:先在短序列上做大规模预训练,然后用少量长序列数据做继续预训练(通常叫 long context extension 阶段)。数据中需要包含真正需要长程依赖的任务,否则模型可能只学会了"能处理长输入",但并没有学会"利用远处的信息"。

推理时的 KV Cache 显存

每一层的每个 token 都需要缓存 K 和 V。以 70B 模型为例,128K 上下文的 KV Cache 可能需要几十 GB 显存。GQA(Grouped Query Attention)能显著压缩 KV Cache 大小,这也是为什么支持长上下文的模型几乎都用 GQA。另外 KV Cache 量化、PagedAttention 等技术也在帮助缓解这个瓶颈。

"能放进去"和"真正能用"是两回事

这是一个很关键的认知。很多模型声称支持 128K 甚至 1M 的上下文,但实际测试中(如 Needle in a Haystack 测试)在长距离上的信息检索能力会显著下降,尤其是在上下文中间位置的信息容易被"遗忘"(lost in the middle 现象)。

面试时可以这样答

长上下文能力我一般从四个维度来分析。

第一是位置编码。模型训练时见过的最长序列决定了它的基础上下文能力,要扩展就得靠位置编码的外推方案。RoPE 配合 YaRN 或 NTK-aware scaling 是目前最主流的做法,本质是对旋转频率做插值或缩放,让模型能处理训练时没见过的位置。

第二是注意力计算的复杂度。标准 attention 是 O(n²),从 4K 扩展到 128K 计算量增长巨大。FlashAttention 优化了显存访问但计算量没变。Sliding Window Attention 这类稀疏方案可以降低复杂度,但会牺牲一些全局信息。

第三是训练数据。架构上能处理长序列不代表模型真的会用长距离信息,必须在训练数据中包含足够的长文本和需要长程依赖的任务。常见做法是先短序列预训练,再用长序列做 extension。

第四是推理时的 KV Cache 显存。128K 上下文的 KV Cache 开销非常大,所以 GQA、KV Cache 量化、PagedAttention 这些技术都是为了解决这个问题。

还有一点值得提,"能放进去"和"真正用好"是两回事。很多模型声称支持很长的上下文,但实际测试中存在 lost in the middle 现象,中间位置的信息容易被忽略。

常见追问

  1. Needle in a Haystack 测试的原理是什么?你怎么看它作为长上下文评测的局限性?
  2. YaRN 和线性位置插值的核心区别在哪?
  3. 如果你要把一个 8K 模型扩展到 128K,具体怎么做?需要多少数据和训练量?