Skip to content

07 · Prefill 与 Decode:两条不同的执行路径

07 · Prefill 与 Decode:两条不同的执行路径

同一个 Transformer,两种工作负载

Prefill 处理 prompt 中尚未缓存的多个 token,目的是一次性建立这些 token 的 KV Cache。它通常拥有较大的 token 维度,矩阵乘法并行度高,偏计算密集。

Decode 每个活跃 Sequence 每轮通常只输入最新一个 token,却要读取整个历史 KV Cache。它的矩阵尺寸较小,容易被内存带宽、kernel launch 和调度开销影响。

nano-vLLM 如何区分

Scheduler 返回 (seqs, is_prefill)。ModelRunner 据此进入不同输入准备路径:

  • Prefill:拼接多条 Sequence 的 token,构建累计序列长度 cu_seqlens,支持 variable-length FlashAttention。
  • Decode:每条 Sequence 提供最后一个 token、当前 context length、block table 和 slot mapping。

为什么不能把两者当成同一批

它们需要的元数据不同,Attention 调用不同,理想 batch 策略也不同。把 Prefill 与 Decode 混在一个简单 kernel 中会增加实现复杂度,并可能让两个阶段都得不到最佳效率。

常见性能指标

指标更受哪个阶段影响用户感受
TTFT(首 token 时间)排队 + Prefill点发送后多久看到第一个字
TPOT(每输出 token 时间)Decode后续文字流动速度
总吞吐 tokens/s两者与 batch系统整体容量

只报告总 tokens/s 可能掩盖交互体验。一个吞吐很高的配置,仍可能因为等待聚批而拥有很差的 TTFT。

观察张量,不要只看函数名

调试时打印 input_ids.shapepositions.shapeslot_mapping.shapeblock_tables.shape。当你能从形状判断当前是 Prefill 还是 Decode,就真正理解了两条路径。

HTML INTERACTIVE LAB07 · Prefill 与 Decode:两条不同的执行路径
单独打开 ↗
课后习题等待完成

Decode 阶段为什么常比 Prefill 更容易受内存带宽影响?

动手任务

为 8 个并发请求、prompt 长度 64、输出长度 20,分别写出 Prefill 需要处理的初始 token 工作量和 Decode 需要循环的 step 数。

下一节:Attention

社区教程,与 nano-vLLM 上游项目无官方隶属关系。