引言
大语言模型(LLM)的推理优化是当前 AI 基础设施领域的核心议题。随着 GPT-4、Claude、DeepSeek 等模型的广泛应用,如何高效、低成本地部署这些庞然大物成为工程团队的首要挑战。
在众多推理优化方案中,vLLM 凭借其核心创新——PagedAttention——异军突起,成为生产环境中最受欢迎的 LLM 服务框架之一。数据显示,vLLM 在 H100 GPU 上的吞吐量比原生 HuggingFace 实现高出 24 倍,已被 LMSYS 等平台采用,日均处理请求超过 3 万次。
本文将深入剖析 vLLM 的架构设计,重点解读 PagedAttention 的技术原理,并探讨其在生产环境中的最佳实践。
一、LLM 推理的两阶段本质
理解 LLM 推理优化的前提,是认识推理过程的两个截然不同的阶段:Prefill 和 Decode。
1.1 Prefill 阶段:计算密集型
Prefill 阶段负责处理所有输入 token,通过大规模矩阵乘法并行计算,构建初始的 KV Cache。这个阶段的特点是:
| 特性 | 说明 |
|---|---|
| 计算模式 | 并行处理,充分利用 GPU 张量核心 |
| 性能瓶颈 | 计算饱和度高 |
| 核心指标 | 决定首 Token 时间(TTFT) |
| 典型耗时 | 10K token 提示词在 H100 上约 200-400ms |
1.2 Decode 阶段:内存带宽密集型
Decode 阶段采用自回归方式,每次只生成一个输出 token,必须读取完整的 KV Cache 和模型权重。这个阶段的特点是:
| 特性 | 说明 |
|---|---|
| 计算模式 | 串行生成,每次只处理一个 token |
| 性能瓶颈 | 内存带宽受限,而非计算能力 |
| 核心指标 | 决定 Token 间延迟(TPOT) |
| 典型速度 | 每请求 30-150 token/s |
1.3 资源竞争问题
核心洞察:Prefill 需要计算资源,Decode 需要内存带宽。这两种操作竞争相同的 GPU 资源,却具有完全相反的计算特征。
这种张力驱动了现代推理服务系统的架构设计。生产级系统(如 Meta 和主要云提供商)现在采用分离式服务(Disaggregated Serving):将 prefill 和 decode 分配到不同的 GPU 池——计算优化型 GPU 处理 prefill,内存带宽优化型 GPU 处理 decode。
二、KV Cache:内存消耗的核心
2.1 KV Cache 的工作原理
在自回归解码过程中,每个 token 都会产生注意力机制所需的 key 和 value 张量。这些张量存储在 GPU 内存中,即 KV Cache。
没有 KV Cache 时,每个输出 token 需要 O(n²) 的计算复杂度;有了 KV Cache,可以降低至 O(n)。但代价是显著的内存开销:
| 模型规模 | 上下文窗口 | KV Cache 内存占用 |
|---|---|---|
| 70B 参数 | 200K token | 40-80 GB |
在 80GB H100 上,KV Cache 几乎占满所有显存,几乎没有空间存放模型权重和激活值。这就是为什么 KV Cache 管理成为推理优化的关键战场。
2.2 传统方法的内存浪费
传统 LLM 服务系统(如 HuggingFace Transformers)对 KV Cache 采用连续预分配策略:为每个序列预先分配最大可能长度的连续内存。这种方法导致两个严重问题:
- 内存碎片化:不同序列长度差异巨大,预分配造成大量空洞
- 过度预留:必须按最大可能长度预留,无法动态调整
研究发现,这种方法浪费了 60%-80% 的 GPU 显存!
三、PagedAttention:操作系统智慧的借鉴
3.1 核心思想
PagedAttention 的灵感来自操作系统的虚拟内存分页机制。它将 KV Cache 内存管理重新设计为类似 OS 管理内存页面的方式:
| OS 概念 | PagedAttention 实现 |
|---|---|
| 存储单元:字节 | Token(令牌) |
| 分页单位:页面(Pages) | 块(Blocks) |
| 进程:独立执行单元 | 序列(Sequence) |
| 连续虚拟地址 | 连续的逻辑块 |
| 非连续物理地址 | 非连续的物理块 |
3.2 Block Table 机制
PagedAttention 将每个序列的 KV Cache 划分为固定大小的 token 块,逻辑上连续,但物理存储可以是非连续的。块表(Block Table)负责维护逻辑块到物理块的映射:
┌─────────────────────────────────────────────────────────┐
│ Block Table (块表) │
├──────────────┬──────────────────────────────────────────┤
│ Logical Block 1 │ → Physical Block #7 │
│ Logical Block 2 │ → Physical Block #3 │
│ Logical Block 3 │ → Physical Block #5 │
│ Logical Block 4 │ → Physical Block #9 │
└─────────────────┴──────────────────────────────────────┘
物理块采用按需分配策略:只有当新 token 生成时才分配新的物理块。这种懒加载方式彻底消除了传统方法的内存浪费。
3.3 内存效率提升
| 方法 | 内存浪费率 | 批处理能力 |
|---|---|---|
| 传统连续分配 | 60%-80% | 受限 |
| PagedAttention | < 4% | 2-4 倍提升 |
内存浪费的唯一来源是序列的最后一个块(不足一整块时产生的碎片),这是不可避免的最小值。
3.4 内存共享:并行采样的优化
PagedAttention 的另一大优势是支持高效的内存共享。在并行采样(从同一 prompt 生成多个不同输出)场景下:
- 不同序列可以共享相同 prompt 对应的物理块
- 通过引用计数跟踪每个物理块的共享数量
- 采用**写时复制(Copy-on-Write)**机制确保安全修改
这种设计带来显著的效率提升:
| 指标 | 提升幅度 |
|---|---|
| 并行采样内存开销 | 减少 55% |
| 复杂采样算法吞吐量 | 提升 2.2 倍 |
四、2026 年 KV Cache 优化新技术
4.1 KV Cache 量化
| 技术 | 说明 | 效果 |
|---|---|---|
| NVFP4 | 4位浮点量化 | 相比 BF16 精度损失 <1%,内存减半,H100/H200 原生支持 |
| ChunkKV | 语义块级别压缩 | 保留语言结构和上下文完整性 |
| Token 驱逐 | 基于注意力分数丢弃低重要性 token | 内存线性减少,最适合结构化输入 |
4.2 前缀缓存(Prefix Caching)
对于 RAG、多轮对话等场景,大量请求共享相同的前缀(如系统提示词、文档片段)。前缀缓存技术将这些共享前缀的 KV Cache 缓存起来,避免重复计算:
- SGLang 的 RadixAttention 自动管理前缀缓存
- 可节省高达 90% 的输入 token 处理成本
五、量化技术:内存与速度的权衡
量化是另一条重要的优化路径,通过降低数值精度换取内存和速度收益。
5.1 主流量化方案对比
| 方法 | 精度 | 内存节省 | 速度影响 | 精度损失 |
|---|---|---|---|---|
| FP8 | 8位浮点 | 2x | H100/H200 上 2x | <0.5% |
| GPTQ | 4位整数 | 4x | Marlin 内核下 2.6x | 1-3% |
| AWQ | 4位整数 | 4x | Marlin 内核下 10.9x | 1-2% |
| GGUF Q4_K_M | 4位混合 | 4x | CPU 友好 | 1-3% |
5.2 关键发现:内核比量化方法更重要
AWQ 无优化内核:68 token/s AWQ + Marlin 内核:741 token/s 相同量化权重,10.9 倍性能差异
这揭示了一个重要事实:量化方法的选择固然重要,但底层计算内核的优化往往带来更大的收益。
5.3 Flash Attention 的演进
| 版本 | 改进 |
|---|---|
| Flash Attention 1 | 基础版本 |
| Flash Attention 2 | 相比原版 2 倍加速 |
| Flash Attention 3 | 利用 H100 TMA(张量内存加速器)单元 |
Flash Attention 重写注意力计算使其 IO 感知,通过融合操作最小化 GPU 高带宽内存的读写。2026 年每个主要推理引擎都默认使用 Flash Attention。
六、连续批处理:GPU 利用率革命
6.1 静态批处理的缺陷
传统静态批处理必须等待批次中所有序列完成后才能接受新请求。这导致:
- GPU 在等待过程中处于空闲状态
- 长序列会阻塞整个批次
- 资源利用率低下
6.2 连续批处理的创新
连续批处理(Continuous Batching,也称迭代级批处理)的核心思想是:当任何序列完成时,立即插入新请求。
┌────────────────────────────────────────────────────────────┐
│ 连续批处理示意 │
├────────────────────────────────────────────────────────────┤
│ Time 0: [Req A] [Req B] [Req C] [Req D] ← 4个请求同时处理│
│ Time 1: [Req A] [Req B___] [Req C] [Req D] ← B还在生成 │
│ Time 2: [Req A] [Req B____] [Req E] [Req F] ← A完成,插入E│
│ Time 3: [Req B_____] [Req C] [Req E] [Req F] ← C完成,插入F│
└────────────────────────────────────────────────────────────┘
这种机制将 GPU 利用率维持在接近 100% 的水平,相比静态批处理可降低 85% 的成本。
七、推理引擎选型指南
7.1 三大主流引擎对比(H100,100并发请求)
| 引擎 | 输出速度 | TTFT (p50) | 冷启动时间 | 最适合场景 |
|---|---|---|---|---|
| TensorRT-LLM | 2,780 tok/s | 680ms | ~28 分钟 | 峰值吞吐量 |
| SGLang | 2,460 tok/s | 710ms | ~58 秒 | 共享前缀工作负载 |
| vLLM | 2,400 tok/s | 740ms | ~62 秒 | 快速迭代、广泛模型支持 |
7.2 各引擎特点
| 引擎 | 优势 | 适用场景 |
|---|---|---|
| vLLM | PagedAttention 首创,60 秒冷启动,广泛模型支持 | 需要模型灵活性和快速部署 |
| TensorRT-LLM | 编译后峰值吞吐量,高并发下比 vLLM 快 13% | 单一模型、长期运行的生产部署 |
| SGLang | 自动前缀缓存(RadixAttention) | 聊天机器人、RAG、多轮对话 |
7.3 优化叠加效果
以下技术组合在 H100 上提供 5-8 倍更好的成本效率:
- FP8 量化
- Flash Attention 3
- 连续批处理
- 投机解码(Speculative Decoding)
最重要的优化不是更快的 GPU,而是减少发送到模型的 token 数量。先压缩,再推理。
八、投机解码:加速生成的新思路
8.1 工作原理
投机解码采用「小模型草稿 + 大模型验证」的策略:
1. 小型草稿模型(1-7B 参数)每次生成 3-12 个候选 token
2. 大型目标模型在单次并行前向传播中验证所有候选
3. 正确预测(特定领域任务正确率 70-90%)→ 多个 token 只需一次目标模型步骤
4. 被拒绝的 token 从目标模型分布重新采样
8.2 核心优势
- 输出质量数学上相同:被拒绝的 token 从目标分布重新采样
- 速度提升:生成密集型工作负载达到 2-3 倍加速
- 零质量损失:验证机制保证最终输出与标准解码一致
九、生产环境最佳实践
9.1 架构设计建议
- 分离式服务:对于高并发场景,考虑将 prefill 和 decode 分离部署
- 量化优先:FP8 是精度与性能的最佳平衡点,AWQ 适合需要极致性能的场景
- 缓存策略:充分利用前缀缓存和 KV Cache 量化
- 监控指标:重点关注 TTFT、TPOT、吞吐量和显存利用率
9.2 成本优化策略
| 策略 | 节省比例 |
|---|---|
| 提示缓存 (Prompt Caching) | 90% |
| 批处理 (Batch Processing) | 85% |
| 批量 API 端点 | 50% |
| 上下文压缩 | 40-95% |
9.3 避免的常见陷阱
- 不要过早优化:先确保服务可用,再追求极致性能
- 不要忽视缓存:对于重复输入,缓存是最有效的优化手段
- 不要迷信单一技术:最优方案往往是多种技术的组合
结语
vLLM 和 PagedAttention 的成功证明了跨领域知识迁移的力量——将操作系统的虚拟内存思想引入 LLM 推理领域,彻底解决了 KV Cache 的内存管理难题。
在 2026 年的今天,LLM 推理优化已形成一套完整的技术体系:PagedAttention 解决了内存效率问题,Flash Attention 优化了注意力计算,连续批处理提升了 GPU 利用率,投机解码加速了 token 生成。这些技术的叠加效应使得 LLM 推理的成本持续下降,为 AI 应用的大规模部署扫清了障碍。
未来的方向已经清晰:更智能的缓存策略、更激进的量化方案、以及更精细的资源调度。作为 AI 工程师,理解这些底层原理,将帮助我们构建更高效、更经济的 AI 系统。
参考资料: