现在很多 ai 平台都会提供类似这样的能力:
在 gpu 服务器上搭建 llm api,通过多级缓存、pd 分离、连续批处理等技术实现降本增效。
第一次看到这句话,容易感觉每个词都认识,但连起来不知道到底在做什么。
用一句白话概括:
把大模型部署成 api,然后让昂贵的 gpu 少做重复工作、减少空闲、合理分工,用同样的硬件处理更多请求。
这篇文章不讨论复杂的数学原理,只从实际工程场景出发,理解这三种技术分别解决什么问题。
模型能提供 api,只是第一步
假设一台 gpu 服务器上部署了 qwen,并通过 vllm、sglang 或 tensorrt-llm 对外提供接口:
POST /v1/chat/completions
请求流程并不复杂:
用户请求
↓
llm api
↓
gpu 推理
↓
返回结果
到这里已经完成了最基本的模型服务化,但模型能跑起来,不代表服务适合生产环境。
用户增多以后,真正的问题变成了:
如何让同样数量的 gpu 处理更多请求,同时控制首个 token 延迟和后续生成速度?
如果没有做好推理优化,gpu 时间可能消耗在重复计算、等待其他请求、显存碎片以及不同计算阶段的相互干扰上。多级缓存、pd 分离和连续批处理,就是从不同方向减少这些浪费。
多级缓存:算过的内容尽量不要重算
假设企业智能助手的每个请求都带着一段很长的 system prompt:
你是公司的 ai 助手。
只能根据内部知识库回答问题。
回答必须准确、简洁……
用户的问题不同,但前面的系统指令、知识库上下文或多轮对话前缀可能完全相同。如果每个请求都从头计算一遍,会浪费大量 gpu 算力。
缓存的核心不是简单地“存数据”,而是:
保存已经完成的计算或结果,在满足复用条件时避免重复计算。
推理服务里常见的缓存并不只有一种:
| 缓存 | 保存什么 | 适合的场景 |
|---|---|---|
| 结果缓存 | 完整请求对应的回答 | 输入完全相同、结果允许复用 |
| prefix cache | 公共前缀对应的 kv 状态 | system prompt、固定模板或公共上下文相同 |
| kv cache | 当前序列已经计算过的注意力状态 | 生成下一个 token 时复用历史上下文 |
例如两个请求都以同一段系统指令开头,prefix cache 命中后,后一个请求可以从已计算的公共前缀继续,而不是重新处理整段内容。
整个过程可以理解为:
缓存命中
↓
减少重复计算
↓
降低 gpu 工作量
↓
提高吞吐量并降低单次请求成本
缓存也不是免费的。它会占用内存或显存,还需要处理淘汰、隔离和一致性问题。如果请求之间没有可复用内容,缓存命中率很低,收益也会随之下降。
pd 分离:把“读题”和“答题”分开
大模型推理可以粗略分成两个阶段:
| 阶段 | 白话解释 | 典型特点 |
|---|---|---|
| prefill | 读题 | 一次处理大量输入 token,计算密集 |
| decode | 答题 | 逐步生成 token,频繁读取 kv cache |
假设用户提交了一篇很长的技术文档,让模型进行总结。模型首先需要处理整段输入,这就是 prefill;完成以后,再一个 token 一个 token 地生成回答,这就是 decode。
两个阶段的计算特点不同。把它们混合运行在同一组 gpu 上,长 prompt 的 prefill 可能影响正在进行的 decode,导致其他用户等待下一个 token 的时间变长。
pd 分离的做法,是让不同的资源分别负责 prefill 和 decode:
用户请求
↓
调度器
↓
┌─────────┴─────────┐
↓ ↓
prefill 实例 decode 实例
读题 答题
└────传递 kv 状态────→
可以把它想象成饭店里的分工:备菜组负责洗菜、切菜,炒菜组负责烹饪。两类工作可以独立调度、扩容和优化。
例如平台主要处理 rag、长文档和长 prompt,可以增加 prefill 资源;如果主要生成代码、报告等长回答,则可以重点调整 decode 资源。
不过,pd 分离并不是把 gpu 分成两组就一定更快。prefill 产生的 kv 状态需要传给 decode 实例,这会增加网络传输和调度开销。请求规模较小、输入较短,或者网络条件不合适时,分离后的收益可能抵不过额外成本。
连续批处理:有空位就接收新请求
gpu 擅长并行计算,因此推理框架通常会把多个请求组成一个 batch。但用户生成的内容长短不同:
用户 a:生成 100 个 token
用户 b:生成 500 个 token
用户 c:生成 1000 个 token
如果必须等整个 batch 全部结束后才能接收下一批请求,那么 a 和 b 完成以后,对应的计算位置会一直空着,直到 c 也完成。
连续批处理会在每轮生成过程中动态调整 batch:
时间 →
a a a 完
d d d d d
b b b b 完
e e e e e
c c c c c c c c c
谁先完成,就尽快把等待中的新请求补进来,不必等同一批里的所有请求结束。
这很像医院叫号:一个人看完以后马上叫下一位,而不是等当前这一组人全部看完再叫下一组。它的目标是减少 gpu 空转,让计算资源持续处理有效请求。
连续批处理提高吞吐量的同时,也需要调度器控制 batch 大小、显存占用和请求优先级。塞入太多请求可能增加单个请求的延迟,所以生产环境通常需要在吞吐量和延迟之间做取舍。
三种技术解决的是三类浪费
把它们放在一起看,会更容易理解:
| 技术 | 主要解决的问题 | 白话理解 |
|---|---|---|
| 多级缓存 | 重复计算 | 算过的尽量不要再算 |
| pd 分离 | prefill 和 decode 相互干扰 | 读题和答题分开处理 |
| 连续批处理 | batch 中途出现空闲 | 有空位就安排新请求 |
组合后的推理链路可以粗略表示为:
用户请求
↓
api gateway / router
↓
缓存检查
├─ 命中 → 复用结果或计算状态
└─ 未命中
↓
prefill 实例
↓
kv 状态传输
↓
decode 实例
↓
连续批处理
↓
返回结果
实际生产环境还会涉及模型并行、量化、推测解码、显存管理、限流、监控和自动扩缩容等问题,但刚开始学习 llm 推理时,可以先记住这三个方向:
少做重复工作
+
让不同阶段合理分工
+
减少计算资源空闲
对 ai 平台意味着什么
如果一个 ai 平台只能完成:
选择模型
↓
分配 gpu
↓
启动 pod
↓
暴露 api
它解决的是“模型如何运行并提供服务”。真正面向生产的推理平台,还需要继续回答这些问题:
- 请求如何排队和调度?
- kv cache 如何管理和复用?
- prefill 和 decode 如何分配资源?
- 多个推理实例之间如何负载均衡?
- 如何衡量吞吐量、首个 token 延迟和后续生成速度?
- gpu 利用率低时,应该调整模型、缓存、batch,还是资源配置?
因此,平台能力通常是逐步演进的:
模型能够运行
↓
模型能够提供 api
↓
多人并发调用
↓
gpu 高效利用
↓
生产级推理服务
多级缓存、pd 分离和连续批处理,正是从“模型能提供 api”走向“高性能推理服务”过程中很典型的三种技术。
总结
以后再看到“通过多级缓存、pd 分离和连续批处理实现降本增效”,可以直接翻译成:
让 gpu 少做重复工作,让读题和答题按各自特点分工,并在有可用资源时尽快接收新请求。
最终目标只有一个:
用同样数量的 gpu,稳定地服务更多请求,降低每次推理的平均成本。