ARTICLE / ai

长上下文技术栈:从 512 到 10M Token 的位置编码演进与工程实践

大语言模型的上下文窗口(Context Window)是其理解与生成能力的物理边界——它决定了模型在单次推理中能"看到"多少信息。2017 年原始 Transformer 的上下文长度仅为 512 个 Token,而到了 2025 年,Google Gemini 2.5 Pro 已支持 100 万 Token,Meta Llama 4 Scout 更是达到了惊人的 1000 万 Token。这一跨越四个数量级的扩展,不仅是"数字变大"那么简单,而是位置编码、注意力机制和系统工程三个维度协同演进的结果。

长上下文并非万能药。 即使拥有百万级 Token 窗口,模型在利用中间位置信息时仍然表现出显著的性能衰减——这就是著名的 “Lost in the Middle” 问题。理解从位置编码到底层注意力优化的完整技术栈,是做出正确模型选型和架构设计的前提。

本文将从位置编码的数学原理出发,系统梳理 RoPE 及其扩展方法族(PI、NTK-Aware、YaRN、LongRoPE),深入分析 FlashAttention 等注意力加速技术,剖析长上下文的工程挑战与最佳实践,并对比当前主流模型的长上下文能力。


1. 上下文窗口的演进:从 512 到 10M+ Token

1.1 历史脉络

上下文窗口的扩展历程可以划分为四个阶段:

┌───────────────────────────────────────────────────────────────────────────┐
│                    Context Window 演进时间线                               │
├──────────────┬────────────────────────────────────────────────────────────┤
│ 2017         │ Transformer: 512 tokens(原始 Self-Attention)             │
│ 2020-2022    │ GPT-3: 2K → PaLM: 8K → GPT-4: 8K-32K                    │
│ 2023-2024    │ Claude: 200K → Gemini 1.5: 1M → Llama 3: 128K            │
│ 2025-2026    │ Gemini 2.5 Pro: 1M → Llama 4 Scout: 10M → Qwen Long: 10M │
└──────────────┴────────────────────────────────────────────────────────────┘

1.2 当前主流模型上下文窗口对比

模型厂商上下文窗口最大输出定价(Input/Output per 1M tokens)
GPT-5.4OpenAI1.05M128K$1.25 / $10(>272K 2x)
Gemini 2.5 ProGoogle1M64K$1.25 / $10
Claude Opus 4.6Anthropic1M(GA)128K$5 / $25(无长上下文加价)
Claude Sonnet 4.6Anthropic1M(GA)64K$3 / $15
Llama 4 ScoutMeta10M32K开源免费
Qwen LongAlibaba10M-$0.07 / $0.29
DeepSeek V3.2DeepSeek128K32K$0.27 / $1.10
GPT-4oOpenAI128K16K$2.50 / $10

关键洞察:Claude Opus 4.6 和 Sonnet 4.6 在 2026 年 3 月实现了 1M 上下文窗口的 GA(正式发布),且不收取长上下文加价——一个 90 万 Token 的请求与 9000 Token 的请求单价完全相同。而 OpenAI 的 GPT-5.4 在超过 272K Token 后会触发 2x 加价,这意味着长上下文场景的成本策略差异巨大。

1.3 为什么长上下文如此重要?

长上下文窗口解锁了几个关键应用场景:

  • 全代码库理解:单次输入完整的代码仓库(10K+ LOC ≈ 114K Token),无需分块
  • 长文档分析:一次性处理数百页法律合同、财务报告或研究论文
  • Agent 会话记忆:在多步 Agent 工作流中保持完整的工具调用历史
  • In-Context Learning:在 Prompt 中放入更多 Few-Shot 示例,直接提升任务表现

但窗口越大,计算成本越高——Self-Attention 的复杂度是 O(n²),这意味着 1M Token 的注意力计算量是 128K Token 的约 60 倍。这就引出了本文的核心技术主题:如何在保持模型质量的同时,高效地扩展上下文窗口。


2. 位置编码:Transformer 的"GPS 导航系统"

2.1 为什么需要位置编码?

Transformer 的 Self-Attention 机制本质上是一个集合操作(Set Operation)——如果不提供位置信息,模型无法区分 “猫追狗” 和 “狗追猫”。位置编码(Positional Encoding)就是为每个 Token 注入"你在序列中的哪个位置"这一信息。

2.2 绝对位置编码(APE)

原始 Transformer 使用正弦/余弦函数生成绝对位置编码:

PE(pos, 2i)   = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

其中 pos 是位置索引,i 是维度索引,d_model 是模型维度。

APE 的致命缺陷:它将位置编码直接加到输入嵌入上,模型只能看到绝对位置。一旦推理时遇到训练时未见过的位置(如位置 4097 对于只训练到 4096 的模型),输出质量会急剧下降。APE 无法外推(Extrapolation)到训练长度之外。

2.3 旋转位置编码(RoPE)

2021 年,苏剑林在论文 “RoFormer” 中提出了 Rotary Position Embedding(RoPE),彻底改变了位置编码的设计范式。RoPE 的核心思想极其优雅:

将位置信息编码为旋转矩阵,作用在 Query 和 Key 向量上。

┌──────────────────────────────────────────────────────────────┐
│                    RoPE 核心操作                               │
│                                                              │
│  输入: Q, K 向量 (位置 m 和 n)                                │
│                                                              │
│  步骤 1: 将 Q, K 的每一对维度视为一个二维平面                   │
│          q̃ = R(m) · q,  k̃ = R(n) · k                       │
│                                                              │
│  步骤 2: R(θ) 是旋转矩阵:                                    │
│          ┌ cos(θ)  -sin(θ) ┐                                 │
│          └ sin(θ)   cos(θ) ┘                                 │
│                                                              │
│  步骤 3: q̃ᵀ · k̃ 仅依赖于相对距离 (m-n)                      │
│                                                              │
│  结果: 自然捕获相对位置关系,且旋转角度由频率参数 θ_d 控制      │
└──────────────────────────────────────────────────────────────┘

RoPE 的频率参数定义为:

θ_d = base^(-2d / D)

其中 base 通常取 10000,D 是维度数,d 是当前维度索引。

RoPE 的三大优势

  1. 天然的相对位置编码:Q 和 K 的点积自然只依赖相对距离,无需额外的相对位置偏置
  2. 远程衰减性:距离越远的 Token 对,注意力分数自然越低
  3. 灵活的外推潜力:通过调整频率参数,RoPE 可以被扩展到更长的上下文

形象比喻:如果 APE 是给每个人发一张写有"我是第 N 个人"的胸牌,那么 RoPE 就是给每个人发一个旋转角度不同的陀螺——两个人交流时,只需要知道彼此陀螺的角度差,就能理解相对位置关系。

2.4 ALiBi:另一种思路

2021 年,Press et al. 提出了 ALiBi(Attention with Linear Biases),采用了一种更简洁的方案:直接对注意力分数加上与距离成正比的线性偏置。ALiBi 的优势在于无需训练即可做有限的外推(约 2x),但外推能力有限,且在非常长的上下文中表现不如 RoPE 系方法。


3. Context Window 扩展核心技术

3.1 问题定义:外推失败

当模型在长度 L 的序列上训练后,试图在长度 L’ > L 的序列上推理时,会发生什么?

直接外推(Direct Extrapolation):保持位置索引不变,让新位置使用超出训练范围的值。结果是灾难性的——模型的困惑度(Perplexity)会暴涨,输出变得不可用。

原因在于:RoPE 中高频维度的旋转角度超出了训练时见过的范围,模型完全无法理解这些"陌生"的位置信息。

3.2 Position Interpolation(PI)

Google 的 Chen et al.(2023)和 Meta 的 kaiokendev 几乎同时提出了一种简单而有效的解决方案:位置插值

核心思想:将新的位置索引线性压缩到训练范围内,而不是让模型去理解训练范围外的位置。

原始: 位置 0, 1, 2, 3, ..., L-1     (L 个位置)
扩展: 位置 0, 1/s, 2/s, ..., (L'-1)/s  (L' 个位置, s = L'/L)
方案外推比例微调数据需求困惑度变化
直接外推1x灾难性暴涨
PI8x少量长文本数据轻微退化后恢复
PI + 微调16x+0.1% 预训练数据几乎无损

PI 的问题:对所有维度施加均匀的线性插值会丢失高频信息。根据 Neural Tangent Kernel(NTK)理论,深度神经网络学习高频信息的能力与输入维度的频率分布密切相关。PI 将所有频率等比压缩,导致模型难以区分近距离但语义相似的 Token。

3.3 NTK-Aware Interpolation

Reddit 用户 bloc97 在 2023 年提出了 NTK-Aware Interpolation,核心洞察是:不应该对所有 RoPE 维度施加相同的插值比例。

┌─────────────────────────────────────────────────────────────────┐
│            PI vs NTK-Aware 的关键区别                           │
│                                                                 │
│  PI:        所有维度都乘以 1/s(均匀压缩)                       │
│             θ_d' = θ_d / s                                      │
│                                                                 │
│  NTK-Aware: 高频维度保持不变,低频维度进行插值                    │
│             通过调整 base 值实现非均匀缩放                        │
│             base' = base × s^(D/(D-2))                         │
│                                                                 │
│  效果:  高频信息(局部位置细节)得以保留                          │
│         低频信息(全局位置关系)被平滑插值                        │
└─────────────────────────────────────────────────────────────────┘

Code Llama 正是采用了 NTK-Aware 方法来扩展其上下文窗口。但 NTK-Aware 的一个缺点是:由于部分维度略微外推到"超出界限"的值,微调效果不如纯 PI。

3.4 Dynamic NTK Scaling

Dynamic NTK 进一步改进:不再使用固定的缩放因子,而是根据当前输入序列的实际长度动态调整缩放比例。

def dynamic_ntk_scaling(seq_len, base=10000, d_model=128, max_seq_len=8192):
    if seq_len <= max_seq_len:
        return base
    scale = seq_len / max_seq_len
    new_base = base * (scale ** (d_model / (d_model - 2)))
    return new_base

Dynamic NTK 的优势在于无需微调即可使用——Qwen 7B 正是采用了这种方法。它的缺点是扩展比例有限(约 4x),且在无微调场景下的表现不如微调后的方案。

3.5 YaRN:集大成者

2023 年 8 月,Peng et al. 提出了 YaRN(Yet another RoPE extensioN method),被 ICLR 2024 接收为 Poster。YaRN 结合了前述所有方法的精华:

┌─────────────────────────────────────────────────────────────────────┐
│                       YaRN 方法论全景                                │
│                                                                     │
│  ┌──────────────┐    ┌──────────────────┐    ┌──────────────────┐   │
│  │ NTK-by-parts │    │  Attention 温度  │    │  Dynamic Scaling │   │
│  │   插值       │ +  │  缩放 (t)        │ +  │   推理时自适应    │   │
│  └──────────────┘    └──────────────────┘    └──────────────────┘   │
│                                                                     │
│  核心创新:                                                          │
│  1. NTK-by-parts: 将 RoPE 维度分为三组,分别处理                     │
│     - 低频维度 (r < α): 线性插值 (避免外推)                         │
│     - 高频维度 (r > β): 不插值 (保留局部细节)                       │
│     - 中间维度: 过渡处理                                            │
│                                                                     │
│  2. Attention 温度缩放:                                             │
│     - 线性插值导致 attention logits 的"温度"升高                     │
│     - 引入温度因子 t 补偿,保持注意力分布的合理熵                     │
│                                                                     │
│  3. 效率: 仅需 0.1% 原始预训练数据微调,即可扩展至 128K             │
│     训练步数比前代方法减少 2.5x,Token 需求减少 10x                  │
└─────────────────────────────────────────────────────────────────────┘

YaRN 的通用公式可以统一表示为:

f'_W(x_m, m, θ_d) = f_W(x_m, g(m), h(θ_d))

其中 g(m) 控制位置索引的变换(如插值比例),h(θ_d) 控制频率参数的变换(如 base 调整)。所有 RoPE 变体本质上都是在调整这两个函数。

实践提示:从 Qwen2.5 到 DeepSeek V3,YaRN 已经成为各家 LLM 做长文本外推的标配组件。相比 Pretrain 的巨大资源消耗,YaRN 仅需极小代价就能获得至少 16 倍的长度外推能力。

3.6 LongRoPE:突破 2M Token

Microsoft Research 在 2024 年 2 月提出了 LongRoPE,首次将 LLM 的上下文窗口扩展到 2048K(2M)Token

LongRoPE 的三大创新:

  1. 非均匀位置插值搜索:通过进化搜索(Evolutionary Search)为每个 RoPE 维度找到最优的插值因子,而非使用人工设定的分组规则
  2. 渐进式扩展策略:先将模型扩展到 256K(微调 1K 步),再进行第二次位置插值扩展到 2048K
  3. 短上下文性能恢复:在 8K 长度上重新调整 RoPE,确保扩展后的模型不会在短上下文中退化

4. 注意力机制优化:从 O(n²) 到实际可用

4.1 计算瓶颈:Self-Attention 的二次复杂度

标准 Self-Attention 需要计算一个 n × n 的注意力矩阵,对于 1M Token 的序列,这需要存储和处理 1 万亿个浮点数。仅注意力矩阵就需要约 4TB 显存(FP32),远超当前任何单卡 GPU 的容量。

4.2 FlashAttention:IO 感知的精确注意力

2022 年,Tri Dao 等人提出了 FlashAttention,核心思想是让注意力算法感知 GPU 的内存层次结构

┌───────────────────────────────────────────────────────────────────┐
│              FlashAttention 内存访问优化                            │
│                                                                   │
│  标准 Attention:                                                   │
│  HBM ← Q,K  → 计算 S=QKᵀ → HBM ← S → 计算 P=softmax(S)          │
│       → HBM ← P → 计算 O=PV → HBM ← O                           │
│  问题: n×n 矩阵频繁读写 HBM,IO 成为瓶颈                          │
│                                                                   │
│  FlashAttention:                                                  │
│  分块(Tiling): 将 Q,K,V 切分为小块                                 │
│  在 SRAM 中完成 softmax 和输出计算,避免 n×n 矩阵落盘              │
│  使用 online softmax 算法,单次扫描完成计算                        │
│                                                                   │
│  效果: 内存复杂度从 O(n²) 降至 O(n),计算完全等价                   │
│  加速: 2-4x wall-clock speedup,5-10x 内存节省                     │
└───────────────────────────────────────────────────────────────────┘

FlashAttention 的关键特性:

  • 精确计算:不是近似算法,数学上与标准 Attention 完全等价
  • IO 复杂度最优:HBM 访问次数在给定 SRAM 大小下达到理论下界
  • Block-Sparse 扩展:支持块稀疏注意力,可进一步跳过不相关的 Token 块

4.3 FlashAttention-2 与 FlashAttention-3

版本年份核心改进H100 利用率
FlashAttention2022Tiling + Online Softmax~30%
FlashAttention-22023序列维度并行 + 优化工作分配~35%
FlashAttention-32024Warp 专用化 + FP8 低精度 + 异步计算~85%

FlashAttention-3 在 NVIDIA H100 上实现了惊人的 840 TFLOPS/s(BF16)1.3 PFLOPS/s(FP8),接近硬件理论峰值。

4.4 Ring Attention:分布式长上下文

当单机显存无法容纳超长上下文的 KV Cache 时,Ring Attention 提供了跨设备并行计算的方案:

┌──────────────────────────────────────────────────────────────┐
│                  Ring Attention 原理                          │
│                                                              │
│  Device 0    Device 1    Device 2    Device 3                 │
│  ┌──────┐   ┌──────┐   ┌──────┐   ┌──────┐                 │
│  │Q₀K₀V₀│ → │Q₀K₁V₁│ → │Q₀K₂V₂│ → │Q₀K₃V₃│ → 计算完成    │
│  └──────┘   └──────┘   └──────┘   └──────┘                 │
│     ↓          ↓          ↓          ↓                       │
│  KV 块在设备间以环形拓扑传递,每个设备只需存储 1/n 的 KV Cache │
│                                                              │
│  效果:  n 个设备可以处理 n 倍长度的上下文                      │
│         内存需求均匀分布,通信与计算重叠                        │
└──────────────────────────────────────────────────────────────┘

4.5 稀疏注意力与混合注意力

除了 FlashAttention 系列,研究者还发展了多种降低注意力复杂度的方案:

方法原理复杂度适用场景
稀疏注意力只计算部分 Token 对的注意力O(n√n)局部模式明确的任务
局部注意力每个 Token 只关注邻近窗口O(nw)流式/增量推理
线性注意力用核函数近似 softmaxO(n)长序列但精度要求不高
混合局部-全局注意力交替使用局部层和全局层O(n²) 但常数小当前主流长上下文模型

DeepSeek V3 采用的 Multi-Head Latent Attention(MLA) 是另一种高效方案——通过对 KV Cache 进行低秩压缩,显著减少显存占用,同时保持模型质量。


5. “Lost in the Middle”:长上下文的阿喀琉斯之踵

5.1 问题发现

2023 年,Liu et al. 在 TACL 上发表了里程碑式的论文 “Lost in the Middle”,揭示了一个令人不安的事实:

即使模型拥有足够大的上下文窗口,它在利用中间位置信息时仍然表现糟糕。

┌──────────────────────────────────────────────────────────────────┐
│              "Lost in the Middle" 性能分布                        │
│                                                                  │
│  检索准确率                                                       │
│     ▲                                                            │
│  高 │ ██                                              ██         │
│     │ ████                                          ████         │
│     │ ██████                                      ██████         │
│     │ ████████                                  ████████         │
│  低 │ ██████████████████████████████████████████████████         │
│     └────────────────────────────────────────────────────→       │
│       开头          上下文位置           结尾                      │
│                                                                  │
│  典型的 U 型曲线:开头和结尾表现好,中间显著退化                    │
└──────────────────────────────────────────────────────────────────┘

5.2 核心发现

  • 在多文档问答任务中,将相关文档放在输入的开头或结尾时,模型表现最好;放在中间时,性能显著下降
  • 这一现象在 GPT-3.5、GPT-4 等专门声称支持长上下文的模型中同样存在
  • 即使是 200K 窗口的模型,在处理 100K+ Token 的输入时仍会表现出明显的 U 型注意力偏好

5.3 Needle in a Haystack 测试

“Needle in a Haystack” 测试是验证长上下文能力的经典方法:在长文档的随机位置插入一条关键信息(“针”),然后测试模型能否准确检索。

2025 年 Bianchi et al. 的进一步研究 “Lost in the Haystack” 发现:

  • 针越小(信息越简短),模型越难找到
  • 金色上下文(Gold Context)的长度对检索性能有显著影响
  • 这一问题在 7 个不同的 SOTA 模型上都存在

5.4 工程应对策略

面对 “Lost in the Middle” 问题,工程层面有以下应对策略:

1. 策略性信息排列(Position Engineering)

将最重要的信息放在 Prompt 的开头结尾,避免放在中间位置。对于 RAG 场景,按相关性排序后,将最相关的文档放在首尾。

2. 上下文压缩与重排序

使用 Reranker 模型对检索结果重排序,确保最相关的内容位于注意力敏感区域。结合 Prompt Compression 技术(如 LLMLingua)减少噪声。

3. 分块处理与聚合

将长输入拆分为多个块(Chunk),分别处理后聚合结果。避免一次性塞入过多信息。

4. 选择支持长上下文的模型

2025 年以来的新型模型(如 Gemini 2.5 Pro、Claude Opus 4.6)在长上下文利用效率上已有显著提升。选择模型时,不仅要看窗口大小,更要关注实际的长上下文基准测试表现。


6. 长上下文工程实践指南

6.1 模型选型决策矩阵

场景推荐模型理由
全代码库分析(>100K Token)Gemini 2.5 Pro / Claude Sonnet 4.61M 窗口,长上下文无加价
多轮 Agent 对话Claude Opus 4.61M GA,无加价,强推理能力
超长文档摘要(>500K Token)Gemini 2.5 Pro1M 窗口 + 低成本
预算敏感的长上下文Qwen Long / Gemini Flash极低 Token 单价
自部署/隐私优先Llama 4 Scout10M 窗口,开源免费

6.2 成本优化策略

# 策略 1: 动态模型选择
def select_model_for_context(input_tokens: int) -> str:
    if input_tokens < 32_000:
        return "gpt-4o-mini"          # $0.15/$0.60 per 1M tokens
    elif input_tokens < 128_000:
        return "gpt-4o"               # $2.50/$10
    elif input_tokens < 200_000:
        return "claude-sonnet-4.6"     # $3/$15, 无长上下文加价
    else:
        return "gemini-2.5-pro"        # $1.25/$10, 1M 窗口

# 策略 2: 上下文压缩
def compress_context(documents: list[str], max_tokens: int) -> str:
    from llmlingua import PromptCompressor
    compressor = PromptCompressor(
        model_name="microsoft/llmlingua-2-xlm-roberta-large-meetingbank",
        device_map="cpu"
    )
    compressed = compressor.compress_prompt(
        "\n\n".join(documents),
        rate=0.5,  # 压缩 50%
        force_tokens=["\n", "?", "!"]
    )
    return compressed["reduced_prompt"]

6.3 评估长上下文能力的基准

在选择模型时,不要仅看上下文窗口大小,还需关注以下评测指标:

评测基准测试内容关键发现
RULER多跳检索、聚合、推理部分声称支持长上下文的模型实际得分很低
Needle in a Haystack单点信息检索Gemini 和 Claude 表现最稳定
∞Bench100K+ Token 长文本理解真正的"超长上下文"能力差异显著
SCROLLS长文档摘要和问答商业模型普遍优于开源模型

警告:不要被"支持 128K 上下文"这样的营销宣传所迷惑。窗口大小 ≠ 实际利用能力。很多模型虽然理论上支持长上下文,但在实际使用中的有效利用长度远小于标称值。


7. 未来趋势与展望

7.1 技术趋势

  1. YaRN 成为标配:从 Qwen2.5 到 DeepSeek V3,YaRN 已经成为开源 LLM 扩展上下文的标准组件,只需极小代价即可获得 16x+ 的长度外推能力

  2. 10M+ Token 窗口普及:Llama 4 Scout(10M)和 Qwen Long(10M)将超长上下文从实验室推向了生产环境

  3. 注意力机制的硬件协同优化:FlashAttention-3 在 H100 上实现了 85% 的利用率,Blackwell 架构的 FP4 支持将进一步释放算力

  4. RAG 与长上下文的融合:长上下文并不取代 RAG,而是改变了 RAG 的设计——更少的分块、更少的重排序,但仍然需要检索来获取最新的外部知识

7.2 架构创新方向

  • 混合注意力架构:交替使用局部注意力层和全局注意力层,在效率和全局理解间取得平衡
  • 无限上下文的 Memory 机制:如 RWKV、Mamba 等线性复杂度架构,结合外部记忆实现真正意义上的无限上下文
  • 推理时上下文优化:在推理阶段动态决定哪些 Token 需要完整的注意力计算,哪些可以使用近似方法

8. 总结

本文系统梳理了长上下文技术栈的完整图景。核心要点:

  • 位置编码是上下文扩展的基础:从 APE 到 RoPE 是范式跃迁,RoPE 的旋转矩阵设计天然支持相对位置编码,为后续所有扩展方法(PI → NTK-Aware → YaRN → LongRoPE)奠定了基础

  • YaRN 是当前的事实标准:通过 NTK-by-parts 插值 + 温度缩放 + 动态 Scaling 的组合,以极低的微调代价实现 16x+ 的上下文扩展,已被 Qwen、DeepSeek、LLaMA 等主流模型采用

  • FlashAttention 解决了计算瓶颈:通过 IO 感知的分块计算,将注意力的内存复杂度从 O(n²) 降至 O(n),FlashAttention-3 在 H100 上达到了 85% 的硬件利用率

  • 窗口大小 ≠ 实际能力:“Lost in the Middle” 问题提醒我们,模型对长上下文的利用效率比窗口大小更重要。工程实践中需要结合信息排列、压缩和重排序等策略

  • 长上下文改变了 RAG 的设计:更长的上下文窗口减少了分块和检索的必要性,但检索在获取实时信息和降低幻觉方面仍然不可替代

参考资源