🧠 图解记忆:静态批处理像公交车等满发车,连续批处理像地铁到站就走——有人下车就有人上车,永不浪费座位。
Continuous Batching(也叫 Iteration-Level Batching 或 In-Flight Batching)是一种 LLM 推理调度技术,以 Token 级别的细粒度动态管理批处理中的请求,而非等到整批请求全部完成后才释放资源。
传统静态批处理的致命缺陷
静态批处理(Static Batching)的工作方式:
┌──────────┬──────────────┬──────────┐
│ Request 1 │ Prefill ──▶ Decode ──▶ Decode ──▶ Decode(结束)│
│ Request 2 │ Prefill ──▶ Decode ──▶ Decode ──▶ Decode ──▶ Decode(结束)│
│ Request 3 │ Prefill ──▶ Decode ──▶ Decode(结束) │
└──────────┴──────────────┴──────────┘
问题:
- 三个请求并行执行,但必须等最慢的请求(Request 2)完成后批次才算结束
- Request 3 提前结束了,但它占用的 GPU 资源不能释放给新请求
- GPU 利用率极低:长请求期间短请求对应的计算单元空闲Continuous Batching 的核心思想
迭代级调度——每个 Token 生成后检查哪些请求完成了:
Step 0: [R1-Prefill] [R2-Prefill] [R3-Prefill]
Step 1: [R1-Dec] [R2-Dec] [R3-Dec] ← 一起生成第一轮
Step 2: [R1-Dec] [R2-Dec] [R3-完成✅] ← R3 完成!
↑ 立刻释放 R3 的资源 → 放入新请求 R4!
Step 3: [R1-Dec] [R2-Dec] [R4-New] ← R4 替换了 R3
Step 4: [R1-Dec] [R2-Dec] [R4-Dec] ← 继续
Step 5: [R1-完成✅] [R2-Dec] [R4-Dec] ← R1 也完成了 → R5 加入
Step 6: [R5-New] [R2-Dec] [R4-Dec] ← 循环往复...Continuous Batching 的关键组件
| 组件 | 作用 |
|---|---|
| 迭代级调度器 | 每个 Token 生成后评估完成状态,决定是否移除/添加请求 |
| PagedAttention | 将 KV Cache 分页管理,支持请求的动态加入/退出(无拷贝、零开销) |
| Chunked Prefill | 长 prompt 拆成 chunks 分批处理,避免 prefill 阶段独占 GPU 太久 |
| Scheduler Policy | 决定等待队列中哪个新请求进入批次(FIFO / Shortest Job First 等) |
与传统 Batch 的性能对比
| 指标 | Static Batching | Continuous Batching | |------|----------------|--------------------|| | 吞吐量化 | 基准 | 23×(vLLM 实测) | | 尾部延迟 (p99) | 高(被最长请求拖垮) | 低(新请求可立即插入) | | GPU 利用率 | 低(长请求拖累批次) | 高(接近 100%) | | 并发请求数 | 受限 | 大幅提高 |
Chunked Prefill(与 Continuous Batching 配合)
问题:一个超长 prompt(比如 100K tokens)预填充需要很长时间
→ 在此期间 GPU 全力服务于 prefill,其他 decode 请求全部阻塞
解法:将 prefill 任务切分为 chunks(如 2048 tokens/chunk),每个 chunk
与其他请求的 decode 交替执行
→ 既保证了 throughput,又控制了 tail latency面试高频追问
- Continuous Batching 和 vLLM 的关系? vLLM 是最早将 Continuous Batching + PagedAttention 结合的开源推理框架,后来 HuggingFace TGI、TensorRT-LLM、SGLang 等也都实现了类似机制
- Prefill 和 Decode 能混在一起算吗? 技术上可以(vLLM 默认会分开调用不同 kernel),但通常 prefill 调 Matmul kernel(计算密集),decode 调 Attention kernel(访存密集),分开调度更优
- 调度策略怎么选? 简单场景用 FIFO;追求吞吐用 SJF(Shortest Job First);生产环境一般用 weighted fair scheduling
面试话术:
"Continuous Batching 解决的是 LLM Serving 中最核心的资源浪费问题。想象一下餐厅厨师炒菜——如果一定要等桌上的客人全部吃完才能上新菜,那厨房产能肯定很低。但如果有人吃完一道就能立刻上桌下一道,厨房产出就会最大化。vLLM 的 Continuous Batching 就是这样做的:每个 request 生成到 EOS 时立刻释放它的 KV Cache 槽位,新请求直接补进来。配合 PagedAttention 的分页管理和 Chunked Prefill 防止长 prompt 独占 GPU,最终可以实现 20 倍以上的吞吐量提升。这套组合拳现在已经成了 LLM Serving 的事实标准。"
