Bonus-4 · LLM 上下文长度原理全景手册
讲透 "LLM 为什么会有 context length 上限"。从 attention 数学根因,到位置编码,到 KV cache 显存账,再到长文档训练数据稀缺,把四层约束串成一条完整逻辑链。配套 [[Bonus3-Inference-Optimization]](推理优化)和 [[Training-v2]](训练栈)一起读。
0. 一句话先讲清
上下文长度的 "限制" = Attention 的 O(N²) 算力 + KV cache 的线性显存 + 位置编码的训练上限 + 长文档训练数据稀缺,四个独立硬约束的 "短板效应"。
厂商喊的 "1M context" 是工程极限,生产可用 context 通常 = 训练长度 × (1.5 ~ 4)。
长上下文不是放大 max_pos 那么简单,它是一个跨架构/训练/推理/数据的系统工程问题。
1. 第一层根因:Attention 的 O(N²)
1.1 Transformer 核心算式
Q = X · W_q # X: [N, d_model], W_q: [d_model, d_k] → Q: [N, d_k]
K = X · W_k # K: [N, d_k]
V = X · W_v # V: [N, d_v]
Attention(Q, K, V) = softmax( Q · Kᵀ / √d_k ) · V
↑
[N, N] ← 这就是命门
每多一个 token,attention matrix 从 N² → (N+1)²,计算量平方增长,显存也平方增长。
1.2 显存账(单层单 head,FP16)
attention_matrix_bytes = N × N × 2
| seq_len N | 矩阵元素数 | 显存(FP16) |
|---|---|---|
| 2 K | 4 M | 8 MB |
| 8 K | 64 M | 128 MB |
| 32 K | 1 G | 2 GB |
| 128 K | 16 G | 32 GB ← 单层单 head 就吃掉整张 A100 |
| 1 M | 1000 G | 2 TB ← 物理上不可能 |
注意:这只是单层单 head。Llama-3.1-70B 有 80 层、64 heads → 5120 倍。128K context 朴素跑要 16 万 GB attention matrix,任何硬件都装不下。
1.3 算力账
每个 attention matrix 元素需要 2·d_k FLOPs(一次点积),再加 softmax(O(N²))和最后乘 V(N²·d_v)。总 FLOPs ≈ 4 · N² · d。
N=2K d=4096 → 64 GFLOPs/layer;N=128K d=4096 → 256 TFLOPs/layer(放大 4096 倍而非 64 倍);80 层 → 20 PFLOPs / 一次 forward。A100 BF16 312 TFLOPS,128K 单次 forward 理论下限约 65 秒,这就是 128K context 推理 TTFT 动辄分钟级的根因。
1.4 Flash Attention 救场(救显存不救算力)
Flash Attention 用 IO-aware 分块算法,把 attention matrix 不显式落 HBM,只在 SRAM 里小块计算并即时累加 softmax:
传统: Q · Kᵀ → 写 HBM (N² 显存) → softmax → 写 HBM → · V
Flash: 把 N 切成 block,每 block 算完局部 softmax 累加到 V,全程 SRAM
效果:显存 从 O(N²) → O(N)(Flash Attention 核心贡献),算力 仍然 O(N²)(骗不了)。Flash Attention 2/3 进一步优化 GPU warp 调度和 H100 TMA / async copy,接近理论峰值。Gemini 1.5 / Claude 能 1M context 但 latency 飞天 —— 显存解决了,算力账没法躲。
2. 第二层根因:位置编码 —— 训练时 "见过的最长" 是上限
2.1 为什么需要位置编码
Transformer 的 attention 是对称的、置换不变的:打乱 token 顺序,attention 结果一样(忽略 mask)。这意味着 "A 在 B 前面" vs "B 在 A 前面" 在模型看来无区别。
→ 必须把位置信息注入。注入方式决定了模型对位置的"理解上限"。
2.2 主流位置编码及其上限来源
A. Sinusoidal 绝对位置编码(原始 Transformer)
PE(pos, 2i) = sin(pos / 10000^(2i/d))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d))
数学上对任意 pos 都有定义,理论无上限;但模型从未训练过 pos > train_len 的样本,行为完全未定义。实践上几乎不用了(BERT/GPT-1/2 时代)。
B. Learned Absolute Position Embedding(BERT/GPT-3)
self.pos_emb = nn.Embedding(max_pos, d_model) # max_pos 写死
训练时给每个 position 一个独立 embedding 向量;超过 max_pos 就索引越界,直接 crash。BERT max_pos=512,GPT-3 max_pos=2048,这就是早期 LLM "硬上限" 的来源。
C. RoPE(Rotary Position Embedding)—— Llama/Qwen/DeepSeek/Mistral 全家桶
把位置变成 "旋转矩阵" 乘到 Q/K 上:
θ_i = 10000^(-2i/d) # 第 i 维的频率
RoPE(x, pos) = [
x_0 · cos(pos·θ_0) - x_1 · sin(pos·θ_0),
x_0 · sin(pos·θ_0) + x_1 · cos(pos·θ_0),
...
]
直观理解:位置 pos 把向量在每个 2D 子空间旋转 pos·θ_i 弧度。两个 token 做 attention 时,相对位置体现为旋转角度差。数学上外推到任意 pos 都有定义;数据上训练时 pos ≤ train_len,模型从未学过更大角度差的语义,外推质量退化。频率分布:θ_0=1(高频对应局部位置感),θ_{d/2}=1/10000(低频对应全局位置感)。
D. ALiBi(Attention with Linear Biases)
attention_score(i, j) -= m · |i - j|
直接在 attention score 上加距离 bias。外推性最强,但表达力不如 RoPE。MPT、BLOOM 用过,现在主流已弃。
2.3 RoPE 外推的根本问题
Llama-3.1-8B 训练 max_position_embeddings=8192。直接推理 100K tokens:跑得动(RoPE 数学 OK),但 perplexity 在约 16K 之后飙升,长距离 retrieval 准确率断崖式下降。根因:高频 θ_i 在 pos > train_len 后采样不足,模型未学过的 "旋转角度组合",注意力分数失真。
2.4 Long Context 扩展方法演进史
| 方法 | 年代 | 核心思想 | 工程代价 |
|---|---|---|---|
| Position Interpolation (PI) | 2023.6, Meta | 把推理位置压缩:pos' = pos / scaling | 需要约 1B token continued pretrain |
| NTK-aware scaling | 2023.6, kaiokendev | 高频不动,低频按 NTK 拉伸,zero-shot 即可 | 0,可直接配置文件改 |
| YaRN | 2023.10, EleutherAI | NTK 的精细版,分频段差异化 scaling + temperature scaling | 配合约 100M token finetune 效果最优 |
| Dynamic NTK | 2023.7 | 推理时按实际 seq_len 动态调 scaling | 0,但每个请求重算 |
| LongRoPE | 2024.2, Microsoft | 进化算法搜 RoPE 频率最优 rescaling | 一次性搜索,推理 0 代价 |
| Context Parallel (CP) | 2024+ | 把 seq 维度切分到多 GPU(类似 sequence parallel) | 需要多卡 |
| Ring Attention | 2023.10, Berkeley | sequence 切片在 GPU ring 上传 K/V,P2P 通信 | 训练时 OK,推理慢 |
2.5 配置文件实操(Qwen2.5 例)
// config.json — Qwen2.5-7B-Instruct
{
"max_position_embeddings": 32768, // 训练时
"rope_theta": 1000000.0, // base θ_0(大幅放大,等于天然支持长距离)
"rope_scaling": {
"type": "yarn",
"factor": 4.0, // 推理时扩到 128K
"original_max_position_embeddings": 32768
}
}
LLaMA-Factory yaml 里对应字段:
rope_scaling: dynamic # linear / dynamic / yarn / longrope / null
2.6 Qwen2.5 从 32K → 128K 的完整工程链
① 训练时 rope_theta=1000000 而非默认 10000,预先把长距离的频率"打稀疏";② 32K 全长 pretrain;③ 1B token 长文档 continued pretrain @ 32K;④ YaRN scaling factor=4,推理时窗口扩到 128K;⑤ needle-in-haystack 测试通过 → 发布。直接调 LLaMA-Factory yaml 的 rope_scaling: yarn 而不做 CPT,效果远不及官方 long 版本。
3. 第三层根因:KV Cache —— 推理时的 "隐形显存怪兽"
3.1 为什么需要 KV cache
LLM 推理是 autoregressive 的:生成第 N+1 个 token 时,需要前 N 个 token 的 attention。如果每次都从头算:
Token N+1 生成成本 = O((N+1)² · d)
生成 N tokens 总成本 = ∑ O(i²·d) = O(N³·d)
→ 推 1K tokens 比训练一次 forward 还贵,完全不可用。
KV cache 救场:每层把 K, V 算一次缓存下来,后续 token 只算自己的 Q,跟整段历史 K 做 attention。
推理第 t 步:
q_t = x_t · W_q
k_t = x_t · W_k → 追加到 K_cache
v_t = x_t · W_v → 追加到 V_cache
out_t = softmax(q_t · K_cacheᵀ / √d) · V_cache # O(N·d)
→ 单步成本 O(N·d), N 步总成本 O(N²·d),回到可接受范围。
3.2 KV cache 显存公式
KV_cache_bytes = 2 # K + V
× num_layers
× num_kv_heads
× head_dim
× seq_len
× bytes_per_elem
× batch_size
例:Llama-3.1-70B 全程展开
| 维度 | 值 |
|---|---|
| num_layers | 80 |
| num_kv_heads (GQA) | 8 |
| head_dim | 128 |
| bytes_per_elem (BF16) | 2 |
| batch=1, seq_len=128K |
KV_cache = 2 × 80 × 8 × 128 × 131072 × 2 × 1 / 1024³
≈ 40 GB
模型权重 140 GB(BF16)+ KV cache 40 GB,batch=1 就 180 GB。这就是为什么 long context 推理的瓶颈不是算力是显存。
3.3 KV cache 的 "乘法效应"
显存预算 = base_model + KV_cache × batch_size × seq_len
↑ ↑
固定 随并发和长度线性放大
| 场景 | KV cache 占比 |
|---|---|
| 7B model, 2K seq, batch=1 | 5% |
| 7B model, 32K seq, batch=8 | 60% |
| 70B model, 128K seq, batch=4 | >50% |
| 70B model, 1M seq, batch=1 | 约 150%(显存爆) |
这就是为什么 long context + 高并发几乎是矛盾的。
3.4 KV cache 优化技术栈
| 技术 | 原理 | 显存节省 | 配套 |
|---|---|---|---|
| MQA (Multi-Query Attention) | 所有 head 共享同一对 K/V | num_heads × | PaLM 用过,质量损失大,已被 GQA 替代 |
| GQA (Grouped Query Attention) | 把 heads 分组,每组共享一对 K/V | (num_q_heads/num_kv_heads)× | Llama-3 / Qwen2.5 标配 |
| MLA (Multi-head Latent Attention) | 把 K/V 压缩到低维 latent 再恢复 | 约 10x | DeepSeek-V2/V3 创新 |
| PagedAttention | KV cache 分页存储,消除碎片 | 1.5–3× | vLLM 核心 |
| Prefix Caching / RadixAttention | 共享相同 prefix 的 KV cache | system prompt 完全免费 | SGLang 自动,vLLM 手动开 |
| FP8 KV Cache | KV 用 FP8 存储 | 50% | H100/H200, --kv-cache-dtype fp8 |
| Quantized KV Cache (INT4) | 进一步量化 | 75% | 还在实验,质量损失明显 |
| Sliding Window | 只保留最近 N 个 token 的 KV | 固定 = window | Mistral 早期用,丢长程信息 |
| KV Cache Offload | 不活跃 sequence 的 KV swap 到 CPU | 临时救急 | vLLM --swap-space N |
| Cross-Layer KV Share | 多层共享同一份 KV cache | num_layers / share_group × | YOCO/CLA,2024+ 研究 |
3.5 GQA 实测节省(Qwen2.5-7B vs Llama-2-7B)
| 模型 | num_q_heads | num_kv_heads | KV 节省 |
|---|---|---|---|
| Llama-2-7B (MHA) | 32 | 32 | 1× (baseline) |
| Llama-3-8B (GQA) | 32 | 8 | 4× |
| Qwen2.5-7B (GQA) | 28 | 4 | 7× |
| DeepSeek-V3 (MLA) | 128 | latent dim 512 | >10× |
同样 8B 级模型,Llama-3 长上下文能力比 Llama-2 强一截 —— 不是算法变了,是 GQA 让 KV cache 显存腾出来支持更长 seq。
4. 第四层根因:训练数据 —— "见过" 的长度才是真上限
4.1 长文档天然稀缺
互联网公开数据中,token 数分布:
| 文档类型 | 典型长度 | 数据占比 |
|---|---|---|
| 网页(Common Crawl) | 500 - 2K | 70%+ |
| 论坛/Reddit 单条 | 100 - 500 | 10%+ |
| 维基百科文章 | 1K - 8K | 5% |
| 论文(arXiv) | 5K - 20K | <2% |
| 长篇小说 | 50K - 500K | <0.1% |
| 完整代码库(单 repo) | 100K - 10M | <0.01% |
模型训练时 99% 样本是 < 8K 的,即使开了 max_seq_len=128K,绝大多数样本被 pad 掉,根本学不到长距离依赖。
4.2 三种 long-context 数据策略
A. Document Packing(LLaMA-Factory yaml packing: true)
原始: [doc1(500 tok)] [doc2(800 tok)] [doc3(300 tok)] ...
packing: [doc1, doc2, doc3, doc4, ...] 拼成 8K, 4K, 6K ...
提高 GPU 利用率(没 padding),但 attention mask 默认跨文档会 "看到" 别的文档,学到错误依赖。解法 neat_packing: true,加 attention mask 隔离。
B. Long Document Curation
专门收集长文档:arXiv 全文、GitHub 完整 repo(代码 + README + tests)、长篇小说(Project Gutenberg)、法律/医学文档、多轮对话拼接。Qwen2.5-7B-128K 训练用了约 40B token 长文档。
C. Synthetic Long Context
RAG-style 把 retrieval 结果(top-50)拼成训练样本;Question-rewriting 让 LLM 生成需要跨长上下文回答的合成 QA;DeepSeek R1 用了大量长 reasoning trace 训练。
4.3 Lost in the Middle —— 真实困境
Lost in the Middle (Liu et al., 2023) 实验:把答案放在 200K context 不同位置,模型召回准确率:
位置: 前 10% 前 30% 中间 后 30% 后 10%
召回准确率(GPT-4): 75% 50% 25% 50% 80%
典型 "U 型曲线":首尾保留,中段丢失。这是所有 long-context 模型的通病,包括 Claude 3.5 / Gemini 1.5 / GPT-4o。
根因:训练时 attention head 倾向关注两端(开头通常是 system prompt + 任务说明,结尾是当前生成),中段 attention 权重小。
4.4 Needle in a Haystack —— 业界 benchmark 实情
| Claude 3.5 Sonnet | GPT-4o | Qwen2.5-72B | DeepSeek-V3 | |
|---|---|---|---|---|
| 128K context | 99% | 100% | 100% | 100% |
| 200K context | 95% | (不支持) | (RoPE 拉伸后约 85%) | 95% |
| 1M context (Gemini) | (不支持) | (不支持) | (不支持) | (不支持) |
但这是单针单线,真实 multi-hop reasoning at long context 准确率普遍掉到 30–60%,RULER / LongBench 等更难的 benchmark 才反映真实水平。
5. Long Context 的工程扩展手段汇总
5.1 训练侧
| 手段 | 适用 | 注意事项 |
|---|---|---|
| Sparse Attention(Longformer/BigBird) | 早期 long-context 方案 | 已被 dense + Flash Attention 替代 |
| Sliding Window Attention | Mistral 7B v0.1 | 牺牲长程,换显存 |
| Flash Attention 2/3 | 现代 default | 必开,无副作用 |
| Sequence Parallel | Megatron-LM | 把序列维度切到多卡 |
| Context Parallel | Megatron 0.7+ | 跨节点切 sequence,需 InfiniBand |
| Ring Attention | 研究阶段 | 1M context 训练用 |
| RoPE base 提前调大 | Qwen2.5 / Llama 3 | rope_theta=1000000 而非 10000 |
| 长文档 CPT | 必须 | 真正学到长程依赖 |
5.2 推理侧
| 手段 | 工具 | 效果 |
|---|---|---|
| PagedAttention | vLLM | KV cache 显存碎片 60% → 4% |
| Prefix Caching / RadixAttention | vLLM (manual) / SGLang (auto) | system prompt 完全免费 |
| FP8 KV Cache | vLLM --kv-cache-dtype fp8_e5m2 | KV 显存减半 |
| Chunked Prefill | vLLM --enable-chunked-prefill | 长 prefill 不卡死调度 |
| Continuous Batching | vLLM / SGLang / TGI | 多请求并发摊薄成本 |
| RoPE Scaling 推理时配置 | config.json rope_scaling | zero-shot 拉长 |
5.3 应用层
| 手段 | 何时用 |
|---|---|
| RAG | 几乎总是优先于纯 long-context |
| Hierarchical summarization | 100K+ 文档 → 先 chunk + summary → 喂 summary |
| Map-Reduce QA | 长文档分段并行 QA,最后汇总 |
| Late Chunking | 先全文 embed,再切分,保留全局上下文 |
| Context Compression | LongLLMLingua 等,把 prompt 压到 1/5 |
6. Context Length 容量推算速查表
6.1 训练阶段容量
单卡 BF16 训练上限(粗算):
max_seq_len ≈ √(GPU_memory_GB · 1e9 / (num_layers · 12))
例:A800-40GB, Llama-7B (32 层)
max_seq_len ≈ √(40e9 / (32·12)) ≈ 32K(不开 FlashAttn)
开 FlashAttn 后约 128K(显存 O(N²) → O(N))
实际还要扣 weights + grad + optimizer + activation。A800 单卡训 7B at 128K 真实需要 grad ckpt + ZeRO-1。
6.2 推理阶段容量
推理显存 ≈ model_weight + KV_cache_per_seq · batch_size + activations
KV_cache_per_seq = 2 · num_layers · num_kv_heads · head_dim · seq_len · bytes
例:Qwen2.5-7B GQA, A800-40GB, BF16
weights = 14 GB
KV_per_seq @ 32K = 2·28·4·128·32768·2 / 1e9 ≈ 1.5 GB
→ batch 16 时 KV = 24 GB → 总 38 GB,刚好打满
6.3 选型决策
| 需求 | 推荐 |
|---|---|
| 2–4 K context,高并发 chatbot | Qwen2.5-7B-Instruct(默认 32K window 用前一段) |
| 8–32 K,单文档 QA | Qwen2.5-7B-Instruct 直接用 |
| 32–128 K,多文档总结 | Qwen2.5-7B-Instruct-128K(YaRN-extended)或 Llama-3.1-8B-128K |
| > 128 K,重要任务 | 强烈考虑 RAG 替代 —— 20 个 5K chunk 通常优于 200K 直接塞 |
| > 1 M,没法避开 | Gemini 1.5 / Claude Sonnet —— 心理准备 latency 几分钟 |
| 单 GPU 跑 70B + 32K | 必须 AWQ 量化 + GQA + Flash Attention |
7. 与 RAG 的对决:何时该 long-context,何时该 RAG
7.1 性能曲线
准确率
│
1 │ ●━━━━━━━●━━━━━━━━━━━━●━━━━━━● <- RAG (top-K=10, K 不变)
│ ●
│ ●
│ ●━━━━━━●━━●━━● <- Long Context(单 prompt)
│ ●
│ ●
│ ●
└──────────────────────────────────→ 输入 token
2K 8K 32K 128K 512K 1M
实测规律:< 32K Long context 略优(retrieval 可能漏关键信息);32K – 128K 平手或 RAG 略优;> 128K RAG 显著优于 long-context(retrieval 命中 + 5K context 准确率 > 128K 直接塞);> 1M RAG 完全碾压,long-context 工程成本不可行。
7.2 成本对比
| 输入大小 | RAG 成本 | Long Context 成本 | 比值 |
|---|---|---|---|
| 5K(retrieval result) | 1× | 1× | 1:1 |
| 32K | 1×(top-10 = 5K) | 6.4×(32K prompt) | 1:6 |
| 128K | 1× | 25.6× | 1:26 |
| 1M | 1× | 200× | 1:200 |
(假设 prefill cost 与 seq_len 正比)
7.3 结论
2026 年的工程实情:RAG 没死,反而是 long-context 把 "准确率天花板" 暴露后,RAG 重新成为大多数生产应用的首选。Bonus-2 RAG 章节即使在 1M context 时代仍然是 LLM 应用工程的主菜。
8. 一句话总结(对应章节序号)
| # | 命题 |
|---|---|
| 1 | Attention 是 O(N²),Flash Attention 救显存不救算力 |
| 2 | 位置编码上限 = 训练时见过的最长 seq_len,RoPE 也不例外 |
| 3 | KV cache 推理时随 seq_len 线性吃显存,是长上下文真正的瓶颈 |
| 4 | 训练数据中长文档稀缺,Lost in the Middle 是所有 long-context 模型的通病 |
| 5 | Long context 是跨架构/训练/推理的系统工程,不是配置一行 |
| 6 | 显存预算 = weights + KV_cache(batch, seq_len),量化和 GQA/MLA 是关键 |
| 7 | RAG > long-context 在 > 32K 的几乎所有场景,1:200 成本比逼着做 RAG |
附录 A:常用配置/参数速查
A.1 vLLM long-context 启动
vllm serve Qwen/Qwen2.5-7B-Instruct \
--max-model-len 131072 \ # 推理 max seq
--rope-scaling '{"type":"yarn","factor":4.0,"original_max_position_embeddings":32768}' \
--enable-prefix-caching \ # 必开
--enable-chunked-prefill \ # 必开
--kv-cache-dtype fp8_e5m2 \ # H100/H200 可开
--gpu-memory-utilization 0.92 \
--swap-space 16 # CPU swap 救急
A.2 LLaMA-Factory yaml long-context 训练
model_name_or_path: Qwen/Qwen2.5-7B-Instruct
template: qwen
flash_attn: fa2 # 必开
rope_scaling: dynamic # linear / dynamic / yarn / longrope
shift_attn: false # LongLoRA shift short attention(可选)
stage: sft
finetuning_type: lora
cutoff_len: 32768 # 训练时 seq 长度
per_device_train_batch_size: 1
gradient_accumulation_steps: 16
gradient_checkpointing: true # 长 seq 必开
packing: true # 提高利用率
neat_packing: true # 跨文档 attention mask 隔离
deepspeed: examples/deepspeed/ds_z3_offload_config.json # ZeRO-3 + CPU offload
A.3 Megatron long-context
python pretrain_gpt.py \
--seq-length 32768 \
--sequence-parallel \
--context-parallel-size 8 \ # Megatron 0.7+
--use-flash-attn \
--use-distributed-optimizer \
--recompute-granularity selective \
--recompute-method uniform
附录 B:延伸阅读(经典论文)
Attention Is All You Need (2017) Transformer 原始;RoFormer (2021) RoPE;Train Short, Test Long: ALiBi (2022);Flash Attention (2022) / Flash Attention 2 (2023);Lost in the Middle (2023) U 型曲线;Position Interpolation (2023) / YaRN (2023) / LongRoPE (2024) RoPE 扩展;Ring Attention (2023) 分布式 attention;MLA (DeepSeek-V2, 2024) Multi-head Latent Attention;Cross-Layer Attention (2024) 跨层 KV 复用。
附录 C:与其他文档交叉引用
- [[bonus-LLM-training]] —— 训练栈视角
- [[bonus2-RAG-Agent]] —— 替代 long-context 的工程方案
- [[bonus3-inference-optimization]] —— KV cache 优化、PagedAttention 实测
- [[Training-v2]] —— LoRA/DeepSpeed/Megatron yaml 字段
面试常见题
Q1:long-context 模型为什么能扩到 1M?RoPE/ALiBi 外推机制?
核心是位置编码外推 + 训练数据补充。RoPE 把位置 pos 转成 2D 子空间旋转角度 pos·θ_i,数学上对任意 pos 都有定义,但模型只学过 pos ≤ train_len 的角度组合,超出后注意力分数失真。扩展手段:① PI(pos' = pos / s 压缩);② NTK-aware(高频不动、低频拉伸);③ YaRN(分频段差异化 + temperature scaling,配合 100M token CPT);④ LongRoPE(进化算法搜频率)。ALiBi 在 attention score 上加 -m·|i-j| 距离 bias,外推性最强但表达力差,已被主流弃用。1M context 还需要 Ring Attention / Context Parallel 的训练侧支持,单纯改 rope_scaling 配置只能 zero-shot 拉伸,质量退化明显。
Q2:KV cache 显存随 context 增长的公式?为什么 long context 推理瓶颈是显存?
公式:KV_bytes = 2 · num_layers · num_kv_heads · head_dim · seq_len · bytes · batch。Llama-3.1-70B @ 128K, batch=1, BF16 → 约 40 GB;权重 140 GB + KV 40 GB = 180 GB。算力是 O(N²) 但 Flash Attention 在 SRAM tile 计算不落 HBM,对 latency 是问题不阻塞;显存是硬约束,OOM 直接挂。所以 long context 优化核心是 KV cache:GQA / MLA 压 num_kv_heads,FP8 KV 砍 bytes,PagedAttention 消碎片,Prefix Caching 共享 system prompt。Long context + 高并发矛盾,因为 KV_cache 随 batch × seq_len 双线性放大。
Q3:Lost in the Middle 现象是什么?怎么缓解?
答案放在长 context 不同位置,召回准确率呈 U 型:首尾 75–80%,中段 25%。根因是训练数据里 system prompt 在开头、生成在结尾,attention head 被训练成关注两端。Claude 3.5 / GPT-4o / Gemini 1.5 都有。缓解:① RAG,retrieval chunk 放 prompt 开头或结尾;② 关键信息开头结尾各说一遍;③ Hierarchical summarization 先 chunk + summary;④ 训练时用答案位置随机化的数据增强。Needle in a Haystack 单针满分,multi-hop reasoning at long context 只有 30–60%,看 RULER / LongBench 更接近真实。
Q4:long-context vs RAG 怎么选型?
按长度分档:① < 32K long-context 略优;② 32K–128K 平手或 RAG 略优;③ > 128K RAG 显著优,retrieval 命中后 5K context 准确率超过 200K 直接塞;④ > 1M RAG 碾压。成本比 1:200(1M 塞 vs RAG 5K)。其他维度:数据更新频繁用 RAG,跨文档 reasoning long-context 仍有优势(GraphRAG 才接近),严格 citation 要求用 RAG。2026 实情:RAG 没死,long-context 把 "准确率天花板" 暴露后 RAG 重新成为生产首选。
Q5:context 超过模型上限时的 truncation / compression 策略?
① Sliding Window:只保留最近 N token KV,丢历史(Mistral 7B v0.1);② Recursive Summarization:每 K 轮压缩成 summary,summary 再被压(LangChain ConversationSummaryBufferMemory);③ Hierarchical Summarization:先 chunk + summary 再二级 retrieval;④ Map-Reduce QA:分段独立 QA 后汇总(Anthropic Cookbook 标准);⑤ Context Compression:LongLLMLingua / LLMLingua-2 用小模型压 prompt 到 1/5;⑥ Late Chunking:先全文 embed 再切分,保留全局上下文;⑦ Selective Context:基于 self-information 删冗余 token。生产里 Recursive Summarization + RAG 最常见。