第三部分:加速技术的三大家族
第一部分讲清楚了三件事:搬运是瓶颈、Decode 阶段 GPU 95% 闲置、KV Cache 占大量显存。
第二部分把这些做成了可计算的公式。这一部分讲:所有加速技术,都是在解决这三件事中的一件或多件。按"问题家族"分成三类。
家族一:减少搬运
解决的问题:Decode 阶段 GPU 忙着等数据从显存搬过来。
思路:减少要搬的数据量。
量化 (Quantization)
回想第一部分:70B 模型用 FP16 存,每个参数 2 字节,共 140 GB。量化就是用更少的字节存每个参数。
| 精度 | 每个参数 | 70B 模型占多少 | 精度损失 |
|---|---|---|---|
| FP16(baseline) | 2 字节 | 140 GB | 0 |
| FP8 | 1 字节 | 70 GB | <1% |
| INT8 | 1 字节 | 70 GB | 1-2% |
| INT4 (AWQ/GPTQ) | 0.5 字节 | 35 GB | 2-5% |
| FP4(仅某新型卡) | 0.5 字节 | 35 GB | <2% |
为什么量化能加速
两个好处叠加:
- 显存占用变小:FP16 装不下的模型,FP8 能装下
- 搬运量变小:Decode 阶段瓶颈是搬运,搬运减半,Decode 速度几乎翻倍
所以 FP8 量化在某型号卡上是"免费午餐",又省显存又加速。
KV Cache 也能量化
--kv-cache-dtype fp8 这一个参数:
- KV Cache 占用减半
- 意味着同样显存能支持两倍长的上下文,或者两倍的并发用户
跟客户怎么聊量化:"某型号卡上 FP8 是必开的。模型权重 FP8 能省一半显存,KV Cache 也做 FP8 能再翻倍。这不是优化,这是基础配置。INT4 更激进,能再砍一半,但要测精度,建议第一阶段先跑稳 FP8。"
家族二:把闲置的算力用起来
解决的问题:Decode 阶段 GPU 算力闲 95%。
思路:在等数据的时候,让 GPU 顺便多干点活。
三个技术,层层递进。
技术 1: Batching(批处理),让多用户共享一次搬运
核心思想
Decode 阶段,搬运整个模型权重的时间是固定的。但这次搬运能算几个 token 取决于一次喂给 GPU 多少个 token。
类比:卡车从仓库拉一车货到工地。工地上有 1 个工人 vs 32 个工人,消耗的卡车次数是一样的,但 32 个工人能干 32 倍的活。
所以:一次性把 32 个用户的请求合并处理,搬运量不变,但产出 32 倍。GPU 利用率从 1-5% 直接拉到 50-80%。
老做法的问题(Static Batching)
- 凑齐 32 个请求,一起开始 Decode
- 等所有 32 个请求都生成完,再开始下一批
- 一个生成 500 字、另一个只要 50 字,50 字的请求生成完后那个 slot 浪费 450 步
新做法:Continuous Batching
vLLM 2023 年的核心创新,现在是行业标准。
做法:每生成完一个 token,立刻检查,谁结束了?结束的 slot 立刻让新请求顶上来。GPU 永远满载。
效果:吞吐提升 3-10 倍。这是 LLM 从 demo 级走向生产级的关键技术。
技术 2: Speculative Decoding(投机解码),让一次搬运算多个 token
核心思想
batching 是"让多个用户共享一次搬运"。
投机解码是"让一个用户一次搬运算出多个 token"。
利用一个事实:生成下一个 token 大部分是显而易见的。比如你说"今天天气真...",后面接"好"的概率超高。
怎么做
- 小模型先猜:用一个小模型(比如 7B)先生成 5 个候选 token
- 大模型并行验证:大模型一次性看这 5 个 token,判断每个是否同意
- 接受 or 重写:前 3 个 token 大模型也同意,直接接受;第 4 个开始分歧,用大模型的输出替换
为什么有效
不用投机:生成 5 个 token = 5 次搬运 = 5 个 token 时间
用投机:生成 5 个 token = 1 次搬运(验证)+ 小模型成本(很便宜)= 约 1.5 个 token 时间
加速:约 3 倍
关键洞察:因为 Decode 是 memory-bound,让大模型一次验证 5 个 token,和让它验证 1 个 token,搬运成本是一样的。
几个变体(大概知道就行)
- EAGLE / EAGLE-3:不用独立小模型,复用大模型自己的浅层做猜测。命中率最高,2026 年的 SOTA。
- MTP (Multi-Token Prediction):模型架构原生支持一次预测多个 token(DeepSeek-V3 用的)
- Medusa:在大模型上加几个"小脑袋"
- N-gram:用历史文本统计做猜测,零额外成本,代码生成场景特别有效
脱敏说明
本文档对以下敏感内容做了就地替换:
- 卡型号脱敏:H800 替换为"某型号卡"(7 处),B200 替换为"某新型卡"(1 处)。对应带宽、算力等公开硬件规格数字保留原值。
跟客户怎么聊投机解码:"Anthropic 的 Claude Fast Mode 能做到 2.5 倍加速,大概率就是用了更激进的投机解码。我们在 Qwen 上用 EAGLE-3,不需要额外小模型,复用大模型自身的浅层做猜测,命中率 70-80%,端到端能加速 2 倍。这个收益直接转化为单卡多服务用户,是毛利级别的优化。"
技术 3: 编译优化 —— 让每次"忙活"更高效
问题
PyTorch 默认模式下,一次 forward pass 会启动几百次 GPU kernel,每次启动有几微秒"启动开销"。Decode 阶段每生成一个 token 累计开销可观。
解决方案
- CUDA Graphs:把 forward pass 录制成图,反复执行
- torch.compile:PyTorch 2.x 的自动算子融合
- TensorRT-LLM:NVIDIA 官方编译器,单卡峰值吞吐天花板
TensorRT-LLM 特点
- 编译时间长(70B 模型 20-30 分钟)
- 模型架构改了要重编
- 编译后吞吐比 vLLM 高 15-30%
- 适合:模型固定 + 长期稳定 serving
家族三:管好 KV Cache 这个吃显存大户
解决的问题:KV Cache 占大量显存。
思路:要么管理得更聪明(少浪费),要么共享(多用户一起用),要么压到别处(offload)。
技术 1: PagedAttention(KV Cache 分页管理)
问题
老式做法:每个请求最多可能生成 2048 个 token,所以预分配 2048 个 token 的 KV Cache 空间。但实际很多请求只生成 50 个就结束,剩下 1998 个的空间被锁着不能给别人用。结果:60-80% 的显存被浪费。
解决:像操作系统管内存那样管 KV Cache
vLLM 2023 年的另一个核心创新。
- KV Cache 不再是"一个请求一大块连续空间"
- 切成固定大小的"页"(比如每页 16 个 token)
- 每个请求按需申请页,用完释放
- 效果:浪费率从 60-80% 降到 <5%。同一张卡能塞 2-4 倍的请求。
技术 2: Prefix Caching(前缀缓存)
问题
很多请求共享相同的开头。最典型:MaaS 平台上所有客户都用同一个 system prompt"你是一个专业的客服助手..."。每个请求都要重新 Prefill 这个相同前缀,纯浪费。
解决:算过的相同前缀,KV Cache 缓存下来共享
请求1: [相同的system prompt] + [用户A的问题]
请求2: [相同的system prompt] + [用户B的问题]
请求3: [相同的system prompt] + [用户C的问题]
→ system prompt 的 KV Cache 只算一次,三个请求共享
效果
如果 system prompt 很长(1000 个 token)、复用率高(80-90%):
- Prefill 时间减少 80-90%
- 用户感觉到的"首字延迟"大幅降低
SGLang 的 RadixAttention 把这做到极致。vLLM 也支持 prefix caching,但比较基础。SGLang 用一种叫"基数树"的数据结构,能管理任意前缀的复用。多轮对话场景下,每一轮对话都能复用前一轮的全部历史。
这是 SGLang 在 chat/agent 场景比 vLLM 快 30-50% 的根本原因。对 MaaS 场景特别合适。
技术 3: FlashAttention(让 Attention 算得更省内存)
这个技术优化的不是 KV Cache 本身,是 attention 计算过程的中间结果。
问题
Attention 计算时会产生一个 N × N 的注意力矩阵(N 是序列长度)。N = 100K:矩阵占几十 GB。长上下文场景,这个中间矩阵会爆炸。
解决:分块计算,不存完整矩阵
核心思想:把 attention 计算切成小块,每次只在 GPU 的片上小缓存(SRAM)里算一小块,永远不在显存里保存完整的 N×N 矩阵。
- 内存占用从 O(N²) 降到 O(N)
- 速度提升 2-4 倍
- 所有主流引擎默认开启
技术 4: KV Cache Offloading(KV Cache 分层存储)
问题
长上下文(128K+)+ 多用户 → KV Cache 总量超过显存。
解决:把不常用的 KV Cache 挪到便宜的存储
- 活跃用户的 KV Cache → 放 HBM 显存(3 TB/s,贵)
- 沉睡用户的 KV Cache → 放 CPU 内存(100 GB/s,便宜)
- 冷数据 → 放 SSD(更慢更便宜)
关键挑战
如果用户活跃的瞬间才开始从 CPU 内存搬,延迟会暴涨:
- HBM: 3 TB/s
- CPU 内存: 100 GB/s
- PCIe: 64 GB/s
直接同步搬,延迟会增加 50 倍。所以必须异步预取(prefetching):预测下一步要用什么 KV Cache,提前搬过来。
工业实现
- vLLM 0.6+ 的 --cpu-offload-gb
- Mooncake(某公司开源):分布式 KV Cache 池
- NVIDIA Dynamo:原厂支持 KV Cache tiering
第三部分整体回顾
| 家族 | 解决问题 | 核心技术 | 收益 |
|---|---|---|---|
| 减少搬运 | Decode 等数据 | 量化(FP8、INT4、KV 量化) | 速度 ~2x |
| 用闲置算力 | Decode 算力闲 95% | Batching、投机解码、编译 | 吞吐 3-10x,速度 2-3x |
| 管好 KV Cache | KV Cache 吃显存 | PagedAttention、Prefix Caching、FlashAttention、Offloading | 并发 2-4x,prefill 省 80% |
所有技术叠起来能多快
某型号卡上跑 Qwen3.6-27B,从零开始一步步加:
| 步骤 | 配置 | 单卡吞吐 |
|---|---|---|
| Baseline | FP16 装不下,跑不起来 | 0 |
| + FP8 量化 | 模型 27GB 能装下 | 2,000 tokens/s |
| + Continuous Batching + PagedAttention | 并发 32 | 20,000 tokens/s |
| + KV Cache FP8 | 并发 64 | 35,000 tokens/s |
| + Prefix Caching(复用 50%) | 45,000 tokens/s | |
| + Speculative Decoding (EAGLE-3) | 命中率 70% | 60,000 tokens/s |
| + 8 卡 TP + 分离式部署 | 32 卡 pre+de 分离 | 400,000+ tokens/s |
从 0 到这里,有效吞吐提升 20-30 倍。这就是推理加速的真实意义 —— 不是一个 trick,是一整套工程。
修订记录
| 日期 | 改了什么 | 为什么 | 谁 |
|---|---|---|---|
| 2026-08-05 | 从整篇拆成第 4/6 章,正文未改动 | 整篇 44 分钟读不完,拆成每章 20 分钟以内 | 工程 |