长上下文专题
从 4K 到 128K 甚至 1M token,长上下文是大模型的重要竞争维度。「怎么把上下文做长、做长之后有什么坑」是综合性很强的高频考点,串联了位置编码、注意力、KV Cache 多个知识点。
长上下文难在哪?
把上下文窗口做大,要同时解决四个问题:
| 挑战 | 说明 |
|---|---|
| 位置外推 | 训练时只见过短序列,推理时遇到更长位置会「没见过」而性能崩塌 |
| KV Cache 显存 | KV Cache 随序列长度线性增长,长上下文下成为显存瓶颈 |
| 注意力 O(n²) | 自注意力计算量随长度平方增长,长序列又慢又贵 |
| 有效利用 | 「大海捞针」——能放进去 ≠ 能用好,中间信息易被忽略(lost in the middle) |
一、位置外推
让训练在短上下文的模型适配更长位置,主流方案基于 RoPE(详见 位置编码):
- 位置插值(PI):把超长位置「压缩」回训练范围,需少量微调。
- NTK-aware Scaling:调整 RoPE 频率基(base),高频少缩放、低频多缩放,几乎免微调。
- YaRN:结合 NTK 与温度调整,是目前效果较好的扩展方法之一。
- ALiBi:用线性距离惩罚替代位置向量,天生外推能力强(BLOOM、MPT)。
二、高效注意力(降 O(n²))
- 滑动窗口注意力(Sliding Window):每个 token 只关注最近 W 个 token(如 Mistral W=4096)。多层叠加后,靠「感受野扩张」间接获得更长的有效上下文。
- 稀疏注意力(Sparse):只计算部分注意力对(局部 + 少量全局),如 Longformer、BigBird。
- StreamingLLM / Attention Sink:发现序列**最开头的几个 token(注意力汇聚点)**对稳定性极其重要。保留这几个「sink」+ 最近窗口的 KV,就能稳定处理近乎无限长的流式输入(但不等于真的记住了全部历史)。
- 线性注意力 / 状态空间模型(Mamba 等):用 O(n) 复杂度的机制替代 softmax 注意力,是长序列的另一条技术路线。
三、KV Cache 优化(降显存)
- GQA / MQA / MLA:共享或压缩 KV 头,直接减小 KV Cache,详见 Attention 与变体。
- KV Cache 量化:把缓存的 K、V 量化到 INT8/INT4。
- KV 驱逐 / 压缩:只保留「重要」的 token KV(如 H2O 按累积注意力分数保留重要 token),丢弃不重要的。
- PagedAttention:分页管理 KV,减少碎片、提升并发,详见 推理优化。
四、长上下文 vs RAG
二者都是「给模型更多信息」,但思路不同,常被对比:
| 维度 | 长上下文 | RAG |
|---|---|---|
| 做法 | 把全部资料塞进 prompt | 先检索相关片段再喂少量 |
| 成本 | 输入 token 多、贵、慢 | 只喂相关内容,省 token |
| 信息量 | 受窗口上限约束 | 知识库可无限大 |
| 精度 | 易受无关信息干扰、lost in middle | 检索质量决定上限 |
| 可溯源 | 弱 | 强(能给出处) |
结论:不是二选一。海量/动态/需溯源的知识用 RAG;单文档深度理解、跨段推理用长上下文;二者可结合(RAG 召回 + 长上下文容纳更多候选)。
高频追问
Q:为什么上下文不是越长越好? 三个代价:KV Cache 显存线性增长、注意力 O(n²) 变慢变贵、以及「lost in the middle」导致中间信息利用率低。能放进去不代表能用好,有效利用比单纯堆长度更重要。
Q:什么是「lost in the middle」?怎么缓解? 模型对上下文首尾的信息利用好,中间的容易忽略,呈 U 形。缓解:把最关键内容放在 prompt 首尾、用 Rerank 把最相关片段提前、减少无关内容、必要时多次检索。
Q:滑动窗口注意力为什么还能「看到」窗口外的信息? 单层只看最近 W 个,但多层叠加后感受野逐层扩大——第 k 层能间接聚合到约 k×W 范围的信息,类似 CNN 堆叠卷积扩大感受野。
Q:StreamingLLM 的 attention sink 是什么? 实验发现序列开头的少数 token 会吸引大量注意力(充当「稳定锚点」)。即使内容不重要,丢掉它们也会让模型崩溃。保留这几个 sink token + 最近窗口的 KV,就能稳定处理超长流式输入。注意它是「保持流畅」而非「记住全部历史」。
Q:长上下文和 RAG 怎么选? 知识海量/频繁更新/需要溯源 → RAG;单篇长文档的深度理解、需要跨大段落综合推理 → 长上下文;两者可结合使用。本质是「成本、信息量、精度、可溯源」之间的权衡。
Q:1M 上下文是怎么做到的? 综合多项技术叠加:高效位置外推(YaRN 等)+ 高效注意力(稀疏/滑窗)+ KV Cache 压缩与量化 + 工程上的分布式 KV 管理,再配合长上下文数据做继续训练/微调。单靠某一项做不到。