vLLM Continuous Batching 和KVCache
目录
vLLM 的 Continuous Batching(连续批处理) 是其相较于传统 LLM Serving 框架(如 HuggingFace TGI、早期 Triton 推理方案)最核心、也是最有工程价值的优化点之一。下面从问题背景 → 核心思想 → 关键实现机制 → 性能收益 → 与传统 batching 的对比几个层次,系统性说明其优化原理。
一、背景问题:为什么“传统 batching”在 LLM 推理中失效
1. Prefill 与 Decode 阶段差异巨大
LLM 推理天然分为两段:
| 阶段 | 特点 |
|---|---|
| Prefill | 输入长、一次性计算、算力密集 |
| Decode | 每步只生成 1 token,但需要频繁迭代 |
传统 batching 假设:
所有请求 同步开始、同步结束
但现实是:
- 用户 prompt 长度不同
- 输出 token 数不同
- 有的请求已经进入 decode,有的还在 prefill
→ 批次中最慢的请求拖累所有请求
2. Padding 浪费极其严重
传统 batching 需要对齐:
- 输入长度
- KV Cache 长度
结果:
- 短请求被 padding 到最长请求
- GPU 做了大量无效计算
二、vLLM 的核心思想:把“批”变成“流”
一句话总结:
Continuous Batching = 请求级动态调度 + Token 级执行对齐
不是“等一批请求齐了再算”,而是:
- GPU 每一步 decode 都在干活
- 请求可以 随时加入 / 随时退出
- 不再存在固定 batch 生命周期
三、Continuous Batching 的工作机制(关键原理)
1. Token-Level 执行对齐(最关键)
在 decode 阶段:
- 每个请求 每一步只需要 1 个 token
- vLLM 将不同请求的 下一 token 生成 拼成一个 batch
例如:
| 请求 | 当前状态 |
|---|---|
| Req A | decode step 12 |
| Req B | decode step 5 |
| Req C | decode step 20 |
vLLM 做的是:
Step t:
[A 的第13个 token]
[B 的第6个 token]
[C 的第21个 token]
→ 合并成一个 GPU batch
这意味着:
- 不要求请求“同一时间开始”
- 只要求“同一时间生成下一个 token”
2. 动态 Batch Size(随时变化)
传统:
batch_size = 固定
vLLM:
batch_size(t) = 当前所有 active 请求数
- 新请求 → 立即加入 batch
- 完成请求 → 立即移出 batch
GPU 利用率始终维持在高位。
3. Prefill / Decode 混合调度
vLLM 并不会强行区分:
- “现在只能 prefill”
- “现在只能 decode”
而是:
- Prefill 请求作为 一次性大算子
- Decode 请求作为 持续小算子
- 通过调度器交错执行
调度目标:
- 避免 decode starvation
- 避免 prefill 阻塞整体吞吐
4. PagedAttention(为 Continuous Batching 服务)
Continuous Batching 能成立,PagedAttention 是前提条件。
传统 KV Cache:
- 每个请求一块连续显存
- 长度变化 → 内存碎片 / 重分配
PagedAttention:
- KV Cache 切成固定大小的 block(页)
- 类似虚拟内存页表
好处:
- 请求加入 / 退出时 不搬内存
- 不同长度请求共存
- 支撑高频 batch 变化
Continuous Batching 解决算力利用率问题
PagedAttention 解决显存管理问题
两者是强耦合设计。
四、与传统 Batching 的本质对比
| 维度 | 传统 Static Batching | vLLM Continuous Batching |
|---|---|---|
| Batch 生命周期 | 请求级 | Token 级 |
| 请求加入时机 | 批次开始前 | 任意时刻 |
| Batch Size | 固定 | 动态 |
| Padding | 严重 | 基本无 |
| GPU 利用率 | 波动大 | 稳定高 |
| 尾延迟(P99) | 高 | 显著降低 |
五、性能收益从哪里来(量化直觉)
典型收益来源:
- Decode 阶段 GPU 不再空转
- Prefill 不再阻塞 Decode
- KV Cache 不重排、不复制
- 更高并发下仍可稳定吞吐
实际线上常见效果:
- 吞吐 ↑ 2–4 倍
- P99 延迟 ↓ 30%–70%
(具体与 prompt 长度分布强相关)
六、为什么 Triton / 传统 Serving 很难做到?
核心障碍:
- 静态 batch 假设写死在推理图中
- KV Cache 以连续内存组织
- 调度粒度在 request 而非 token
vLLM 是:
- 推理引擎
- 调度器
- 显存管理器
三位一体设计
这也是为什么:
Triton + HF Model ≠ vLLM
七、一句话总结(面试/评审级)
vLLM Continuous Batching 的本质是:
以 token 为最小调度单位,在 PagedAttention 的支撑下,实现请求级动态加入/退出,从而在高度异构的 LLM 推理负载下维持 GPU 的持续满载。
如果你愿意,我可以进一步:
- 拆解 vLLM Scheduler 的内部队列设计
- 画一个 prefill/decode 混合调度时间线
- 对比 Continuous Batching 与 Speculative Decoding 的协同关系

浙公网安备 33010602011771号