2026年4月19日

系统优化

KV Cache 大小与序列长度**线性增长**:

知识库大模型推理与系统inferenceoptimizationmemory

系统优化

1. 长上下文与显存瓶颈

KV Cache 的线性增长

KV Cache 大小与序列长度线性增长

KV Cacheseq_len\text{KV Cache} \propto \text{seq\_len}

显存需求示例

以 LLaMA-3-8B 为例(GQA, 8 KV heads, 32 layers, FP16):

序列长度 KV Cache/请求 总显存需求 (Batch=32)
4K 0.5 GB 16 GB
8K 1.0 GB 32 GB
32K 4.0 GB 128 GB
128K 16.0 GB 512 GB
1M 128.0 GB 不可行

核心矛盾:长上下文推理需要海量 KV Cache 存储,远超单 GPU 容量。

QUESTION 面试高频:大模型训练和推理时显存分别花在哪里?

训练阶段(以 7B 模型 BF16 为例):

组件 显存占用 说明
模型参数 14 GB 7B x 2 bytes
梯度 14 GB 与参数同大小
优化器状态 (Adam) 56 GB momentum + variance (FP32)
激活值 8-16 GB 取决于 batch size 和序列长度
总计 ~100 GB 单卡放不下

推理阶段(以 7B 模型 BF16 为例):

组件 显存占用 说明
模型参数 14 GB 7B x 2 bytes
KV Cache 变化大 与序列长度和 batch 正比
激活值 2-4 GB 较小
框架开销 1-2 GB 固定

关键差异:训练显存约为推理的 4-6 倍。训练主要消耗在优化器状态和梯度,推理主要消耗在 KV Cache。

显存优化公式

模型参数显存:

参数显存=参数量×字节数/参数\text{参数显存} = \text{参数量} \times \text{字节数/参数}

Adam 优化器显存:

优化器显存=2×参数显存(momentum+variance, FP32)\text{优化器显存} = 2 \times \text{参数显存} \quad (\text{momentum} + \text{variance, FP32})

训练总显存估算:

总显存(4+4+12)×参数量(bytes)=20×参数量\text{总显存} \approx (4 + 4 + 12) \times \text{参数量(bytes)} = 20 \times \text{参数量}

(参数 FP16 + 梯度 FP16 + 优化器 FP32 + 激活值)

2. GPU 显存分配详解

推理场景的显存分配

GPU 显存 (80 GB A100)
├── 模型权重: 16 GB (8B FP16)
├── KV Cache: 60+ GB (长上下文)
├── 激活值: 2-4 GB
└── 框架开销: 1-2 GB

对于长上下文,KV Cache 成为绝对主导的内存消费者。

显存优化策略总览

优化方向 方法 节省效果 精度影响
模型量化 FP16→INT4 模型体积减少 75% 小(1-3%)
KV Cache 量化 FP16→FP8 KV Cache 体积减少 50% 极小
GQA 减少 KV 头数 KV Cache 减少 4-32× 极小
PagedAttention 分页管理 利用率 20-40%→>95%
CPU Offloading KV Cache 换出到 CPU GPU 显存需求大幅降低 无(延迟略增)
滑动窗口 固定 KV Cache 大小 与序列长度无关 有(丢失长距离信息)

QUESTION 面试题:推理服务显存不足怎么办? 按优先级排序的优化策略:

  1. 量化:FP16→INT4/INT8,最快见效(模型体积减半至 1/4)
  2. PagedAttention:消除 KV Cache 碎片,利用率翻倍以上
  3. KV Cache 量化:FP16→FP8,KV Cache 减半
  4. 降低并发/序列长度:直接减少 KV Cache 需求
  5. CPU Offloading:不活跃的 KV Cache 换出到 CPU
  6. 多 GPU(TP):模型和 KV Cache 分布到多张卡

通常组合使用:量化 + PagedAttention + KV Cache 量化 可以在单卡上获得最佳性价比。

3. Attention 计算瓶颈

标准注意力的计算复杂度为 O(N2)O(N^2)

序列长度 Attention FLOPs (相对) 注意力矩阵大小
4K 1x 16M
32K 64x 1B
128K 1024x 16B
1M 65536x 1T

128K 序列的注意力计算量是 4K 的 1024 倍

4. 长上下文优化技术

4.1 算法层面优化

Flash Attention(IO 感知的分块注意力)

  • 避免存储完整 N×NN \times N 注意力矩阵
  • 分块计算,减少 HBM 访问次数
  • 使长序列训练和推理在计算层面可行
  • 详见 推理加速

滑动窗口注意力(Sliding Window Attention)

只关注最近 WW 个 Token + 少量"锚点" Token:

Token:    [1] [2] [3] ... [N-W] [N-W+1] ... [N-1] [N]
窗口:                        |<-- 滑动窗口 -->|
锚点:      ↑                          ↑
         Attention Sink              Attention Sink
  • 固定 KV Cache 大小O(W)O(W) 而非 O(N)O(N)
  • StreamingLLM:保留初始几个 Token(Attention Sink)+ 滑动窗口
  • 代表模型:Mistral(W=4096)、Gemma

StreamingLLM 详解

StreamingLLM 是一种使 LLM 拥有无限长生成能力的推理技术。

核心发现:Transformer 模型中存在 Attention Sink 现象 —— 大量注意力分数集中在序列开头的几个 Token 上,即使这些 Token 语义上不重要。

StreamingLLM 策略

保留 Token:  [Sink Tokens (前 4 个)] ... [最近的 W 个 Token]
             ├─ 固定保留 ──┤          ├─ 滑动窗口 ──┤
  1. 保留 Attention Sink:始终保留序列开头的几个 Token(通常 4 个)
  2. 滑动窗口:只缓存最近 WW 个 Token 的 KV Cache
  3. 滚动更新:新生成的 Token 追加到窗口,超出窗口的 Token 被淘汰

优势

  • KV Cache 固定为 O(W+sink_size)O(W + \text{sink\_size}),不随序列长度增长
  • 无需微调或修改模型
  • 可以无限长度生成(已验证 400 万+ Token)

局限

  • 丢失长距离依赖信息(超出窗口的 Token 信息丢失)
  • 对需要全文理解的场景不适用(如文档摘要)

QUESTION 面试题:什么是 Attention Sink?StreamingLLM 如何利用它? Attention Sink 是指 Transformer 中大量注意力集中在序列开头几个 Token 上的现象。研究发现,即使这些 Token 是无意义的填充 Token,模型也会将大量注意力分配给它们。

原因分析:Softmax 需要所有注意力权重之和为 1,当模型不确定关注哪些 Token 时,倾向于将"多余的"注意力分配给开头的 Token 作为"Sink"。

StreamingLLM 利用这个发现:

  • 始终保留开头的 Sink Token(通常 4 个),防止注意力崩溃
  • 配合滑动窗口,只缓存最近 WW 个 Token
  • 实现 O(W)O(W) 固定大小的 KV Cache,支持无限长度生成

去掉 Sink Token 会导致模型输出质量急剧下降(注意力机制失效)。

稀疏注意力(Sparse Attention)

只计算部分 Token 对之间的注意力:

  • 局部注意力:只关注邻近 Token
  • 全局 Token:少数 Token 与所有 Token 做注意力
  • 随机注意力:随机选择部分远距离 Token
  • 混合模式:局部 + 全局 + 随机

GQA / MQA

减少 KV 头数以降低 KV Cache 大小:

方法 KV 头数 KV Cache 压缩比
MHA 32 1x
GQA-8 8 4x
GQA-4 4 8x
MQA 1 32x

4.2 KV Cache 管理优化

KV Cache 量化

精度 大小 精度影响 适用场景
FP16 2 bytes 基准 通用
FP8 1 byte 极小 推荐
INT4 0.5 bytes 可接受 极致压缩
KIVI (2-bit) 0.25 bytes 有损失 研究

KV Cache 淘汰(Token Eviction)

  • H2O (Heavy-Hitter Oracle):保留注意力分数累积最高的 Token
  • Scissorhands:保留"关键"Token,移除冗余 Token
  • CacheGen:基于信息论的压缩
# H2O 伪代码
def evict_tokens(kv_cache, attention_scores, budget):
    # 计算每个 Token 的累积注意力分数
    scores = attention_scores.sum(dim=0)
    # 保留分数最高的 budget 个 Token
    top_k = scores.topk(budget)
    return kv_cache[:, top_k.indices]

跨层 KV 共享

某些架构(如 MiniCPM、Adaptive-Layer KV)共享相邻层的 KV Cache:

  • 减少总 KV 存储量
  • 适用于层间 KV 差异小的模型

4.3 分布式推理优化

Ring Attention

将序列分块分布到多个 GPU,以环形拓扑传递 KV Block:

GPU 0: 处理 Block 0 → 传递 KV Block 0 给 GPU 1
GPU 1: 处理 Block 1 → 传递 KV Block 1 给 GPU 2
...
GPU N: 处理 Block N → 传递 KV Block N 给 GPU 0

每轮传递一个 KV Block,N 轮后所有 GPU 都有完整的 KV 序列
计算与通信重叠(overlap)
  • 支持接近无限长的上下文(100M+ Token)
  • 计算与通信完全重叠
  • 关键:Block 大小需足够大以隐藏通信延迟

4.4 位置编码扩展

RoPE 扩展方法

训练时使用较短上下文,推理时扩展到更长上下文。

方法 原理 是否需要微调 效果
直接外推 不做任何修改 差(长序列性能急剧下降)
Position Interpolation 缩放位置索引 否/少量 中等
NTK-aware Scaling 调整 RoPE 基频 良好
YaRN 混合缩放策略 优秀
ALiBi 线性注意力偏置 良好

YaRN (Yet another RoPE extensioN method)

结合三种缩放策略:

  1. 温度缩放:调整注意力温度
  2. NTK-aware 缩放:修改 RoPE 基频
  3. 混合缩放:对近程和远程 Token 使用不同策略
近距离 Token → 原始位置编码(保持精度)
中距离 Token → 线性插值
远距离 Token → NTK-aware 缩放(保持泛化)
  • 零训练:不需要额外微调
  • 低开销:推理时即可生效
  • 广泛应用:LLaMA-3、Qwen-2.5 等均使用类似方法

4.5 系统层面优化

Chunked Prefill

将长 Prompt 分块处理,避免单个长 Prefill 阻塞所有请求:

标准 Prefill:
[████████████████████████████] 200ms (阻塞)

Chunked Prefill:
[████][████][████][████] 每块 50ms
  ↑     ↑     ↑     ↑
  可以穿插其他请求的 Decode

好处:

  • 长请求不会阻塞短请求
  • Prefill 和 Decode 可以交替执行
  • 降低 P99 TTFT

分页 KV Cache + 前缀缓存

  • PagedAttention 管理不连续的 KV Block(详见 vLLM
  • 多请求共享 System Prompt 的 KV Cache

CPU Offloading

将不活跃的 KV Cache 暂存到 CPU 内存:

GPU: 当前活跃请求的 KV Cache
CPU: 不活跃请求的 KV Cache
需要时从 CPU 加载到 GPU

5. 长上下文推理架构

典型部署方案

场景: 128K 上下文, 8B 模型

方案 1: 单 GPU (80GB A100) + FP8 KV Cache
  KV Cache: ~8 GB/请求 → 支持 ~6 个并发

方案 2: 2 GPU (TP=2) + FP16 KV Cache
  KV Cache: ~16 GB/请求 → 支持 ~8 个并发

方案 3: 单 GPU + 滑动窗口 (W=8K)
  KV Cache: ~1 GB/请求 → 支持 ~60 个并发
  但丢失长距离依赖信息

方案 4: 4 GPU + Ring Attention
  KV Cache 分布在 4 GPU → 支持 1M+ 上下文

方案选择决策

需要长上下文推理?
    │
    ├─ 否(短文本)──→ 标准部署 + PagedAttention
    │
    ├─ 是 ──────────┐
    │                ├─ 可接受丢失长距离信息 ──→ 滑动窗口 / StreamingLLM
    │                ├─ 需要完整上下文 ──┐
    │                │                  ├─ 单卡够 ──→ FP8 KV Cache + Chunked Prefill
    │                │                  └─ 不够 ──→ TP + Ring Attention
    │                └─ 极致吞吐 ──→ 量化 + Continuous Batching + Prefix Caching

QUESTION 面试题:如何为一个 128K 长上下文的在线服务设计部署方案? 需要权衡并发量、延迟和成本:

  1. 单卡方案(80GB A100):FP8 KV Cache,8B 模型每请求 ~8 GB,支持 ~6 并发。成本最低但并发有限
  2. 双卡方案(TP=2):FP16 KV Cache,16 GB/请求,8 并发。推荐方案
  3. 多卡 + Ring Attention:4+ 卡,支持 1M+ 上下文。成本最高
  4. 量化 + 滑动窗口:如果可接受丢失长距离信息,可用滑动窗口大幅提升并发

关键技术组合:GQA + PagedAttention + FP8 KV Cache + Chunked Prefill + Continuous Batching

6. 系统优化技术全景

推理加速技术分类

层级 技术 效果 适用阶段
算法层 FlashAttention 2-4× 加速 Prefill + Decode
算法层 投机解码 1.5-3× 加速 Decode
算法层 GQA/MQA KV Cache 减少 4-32× Decode
算法层 滑动窗口 固定 KV Cache Decode(长序列)
模型层 量化 (INT4/INT8) 模型体积减 75-50% 全阶段
模型层 KV Cache 量化 KV 体积减 50-75% Decode
系统层 Continuous Batching 吞吐 2-4× 在线服务
系统层 PagedAttention KV 利用率 >95% 在线服务
系统层 Chunked Prefill 减少 TTFT 阻塞 长上下文
系统层 Prefix Caching 避免重复计算 System Prompt
硬件层 Tensor Parallelism 线性加速 大模型
硬件层 CPU Offloading 扩展显存 显存不足

7. 2025 年趋势

  1. 原生长上下文模型:Gemini 2.0 (1-2M Token)、Claude (200K)、GPT-4 (128K)
  2. 混合注意力架构:Mamba + Attention 混合模型(Jamba 等)
  3. KV Cache 压缩成为标配:FP8 KV Cache 在主流推理引擎中默认支持
  4. 分块 Prefill 与 Chunked Attention:长 Prompt 不再阻塞短请求
  5. Ring Attention 的工程化:从研究走向生产部署
  6. Context Distillation:将长上下文压缩为短表示,用于后续推理
  7. 推理框架大一统:vLLM、SGLang、TensorRT-LLM 功能趋同,差异化在性能优化深度