LLM 推理 · Prefill 与 Decode

大模型服务 Prefill 和 Decode 是什么:
一次推理的两个阶段,为什么一个「等得久」、一个「出字慢」

Prefill 是读题,Decode 是写答案;读题靠算力,写答案靠带宽

大模型生成一段文字,本质是先读完全部输入(Prefill),再一个字一个字地往外吐(Decode)。这两个阶段在 GPU 上的表现截然相反:

一句话:Prefill 是「读题」,Decode 是「写答案」;读题靠算力,写答案靠带宽。读题越短、越能复用(前缀缓存),第一个字就来得越快;写答案的字速,则被显存带宽死死卡住——这也正是后面一切优化(前缀缓存、KV 量化、投机解码、PD 分离)的出发点。

两阶段总览

一、先把整个推理过程摆出来:为什么分两个阶段

1. 大模型是「逐字生成」的

现在的 LLM 是自回归(Autoregressive)模型:预测第 n 个 token 时,输入是「Prompt + 已经生成的 n-1 个 token」,输出是下一个 token 的概率分布。生成是串行的——第 n 个字没算完,第 n+1 个字就没法开始。

于是任何一次请求都被天然切成两半:

一次请求的完整生命周期
─────────────────────────────────────────────
[ Prefill ]  一次性并行处理整个 Prompt
              ├─ 算出第 1 个输出 token
              └─ 把每个 token 的 K/V 张量写入 KV Cache
─────────────────────────────────────────────
[ Decode ]   循环 N 次,每次只生成 1 个 token
              ├─ 读取(全部历史)KV Cache
              └─ 增量算出一个新 token,再追加进 KV Cache
─────────────────────────────────────────────

2. 为什么 Prefill 能并行、Decode 不能?

Prefill 阶段

二、Prefill 阶段:算力拉满,决定「第一个字等多久」

1. 它在干什么

用户输入 Prompt 后,模型先把文本分词(Tokenization)成 token 序列,然后对所有 token 一次性做 Transformer 前向计算:每一层的 Self-Attention 都要把当前 token 与前面所有 token 做交互,形成各自的 Key/Value 向量,写入 KV Cache,并最终算出第一个输出 token。

2. 关键指标:TTFT(Time To First Token,首 token 延迟)

用户感知到的「第一个字多久出现」,就是 TTFT。它包含:

TTFT ≈ 排队时间 + Prefill 计算时间

3. 它的 GPU 特征:计算密集型(Compute-bound)

特征说明
计算强度一次处理整个输入序列,矩阵乘巨大,Tensor Core / TFLOPS 利用率高
并行度天然可并行,批量(batch)越大效率越高
瓶颈算力(GPU FLOPs),而非带宽
优化手段FlashAttention 类高效注意力、多卡并行、chunked prefill 分段计算、前缀缓存跳过重复前缀
Decode 阶段

三、Decode 阶段:带宽受限,决定「每秒钟出几个字」

1. 它在干什么

从第一个输出 token 开始,模型进入自回归循环:把「已生成的 token」作为新输入,预测下一个 token;每步只算一个 token,却要把全部历史 KV Cache 从显存读出来做注意力,然后把新 token 的 KV 追加进去。

2. 关键指标:TPOT / ITL / 吞吐

3. 它的 GPU 特征:访存密集型(Memory-bound)

特征说明
计算强度一次只算一个 token,矩阵很小,算力严重欠饱和
带宽压力每步都要把全部历史 KV 从显存搬到计算单元,瓶颈是 HBM 带宽
直观比喻像写文章:写一个字,要把已写满的整本稿纸从头翻一遍
优化手段KV Cache 量化压缩、GQA/MQA 减少 KV 头数、投机解码(一次猜多个 token)、连续批处理(Continuous Batching)摊薄带宽

一个关键数字关系:Decode 的吞吐 ≈ 显存带宽 ÷ 每 token 要读的 KV 字节数。KV 越小、带宽越大,出字越快——这也是为什么 KV Cache 量化、GQA 这些技术效果显著。

KV Cache 纽带

四、KV Cache:连接两个阶段的纽带

Prefill 负责「写」,Decode 负责「读」,写和读的都是同一份 KV Cache:

有了这个纽带,两个阶段的优化可以互相借力——尤其是前缀缓存:如果两个请求的输入前缀相同,第二个请求可以直接复用第一个请求算好的前缀 KV,把 Prefill 几乎整个跳过,TTFT 骤降。这是「跨请求」维度的大优化,另文详述。

两阶段冲突

五、两个阶段混在一起跑,为什么「互相拖累」

同一张 GPU 上同时有 Prefill 请求和 Decode 请求时,矛盾就来了:

这正是 PD 分离(Prefill-Decode Disaggregation) 架构出现的原因:把 Prefill 和 Decode 拆到两个独立的 GPU 集群,A 集群全是高算力卡专门「读题」,B 集群全是高带宽大显存卡专门「吐字」,KV Cache 通过网络在两者之间传递。业界数据:Splitwise 论文实现 4.48x 加速比、DistServe 实现 1.4x 加速比和 2.35x 更高吞吐,DeepSeek、Mooncake、NVIDIA Dynamo 都在用。完整原理见本站《大模型服务 PD 分离部署原理与架构详解》。

优化手段

六、工程上怎么分别优化两个阶段

1. 优化 Prefill(让「第一个字」更快)

2. 优化 Decode(让「出字」更快)

3. 指标对照速查表

指标全称反映什么主要受谁影响
TTFTTime To First Token第一个字等多久Prefill + 排队
TPOTTime Per Output Token平均每字耗时Decode
ITLInter-Token Latency流式出字间隔Decode
Throughputtokens/s每秒出多少字Decode + 批处理
Hit/Miss前缀缓存命中prefill 能否跳过输入前缀相似度
FAQ 速答

FAQ

Q1:为什么首字总是等很久,后面的字反而流畅?
首字之前要跑完整个 Prefill(全量计算整个 Prompt),而后续每字只是 Decode 的增量计算,所以「第一个字最慢」是推理阶段的固有特征。

Q2:Decode 为什么不能像 Prefill 一样并行?
自回归生成里每个新 token 依赖前一个 token,必须串行;而且每步要读取全部历史 KV,GPU 更多时间花在搬数据上,算力本身用不满。

Q3:TTFT 和 TPOT 哪个更能代表「用户体验」?
聊天/客服类场景(等第一个字)看 TTFT;长文生成/内容创作类场景(等完稿速度)看 TPOT 和吞吐。两个指标都要监控。

Q4:为什么上下文越长越慢?
Prefill 随输入长度增长;Decode 每步要读的 KV Cache 也随历史长度线性增长——长上下文下 KV 读取量巨大,带宽瓶颈更明显。

Q5:前缀缓存对 Prefill 有用,对 Decode 有用吗?
主要作用于 Prefill:跳过相同前缀的重复计算,让 TTFT 大幅下降。Decode 阶段的提速要靠 KV 量化、GQA、投机解码等手段。

Q6:PD 分离是什么?我需要吗?
PD 分离是把 Prefill 和 Decode 拆到不同 GPU 集群,适合并发高、首字延迟要求严的场景。自建推理的早期或小规模部署可以先不拆,用前缀缓存 + 批处理优化即可。

Q7:服务商 API 里我怎么感知这两个阶段?
你感知不到 Prefill 的名字,但能看到它的效果:流式输出的首包延迟、每字速度、以及账单上的 token 消耗。API 侧能做的,就是优化你的 Prompt(复用固定前缀)和选择合适的模型档位。

一句话总结:Prefill 决定「首字多快」,Decode 决定「出字多快」,中间用 KV Cache 连接,上游用前缀缓存跳过重复,下游用 PD 分离解耦资源。

关于向量云
向量云(南京)科技有限公司

面向大模型应用落地的技术服务型企业,依托字节跳动火山方舟能力,为合作方提供低折扣模型 Token、可独立部署的运营支撑平台及全链路运营支持。

火山方舟官方授权 官方 API Key 独享接入点 缓存隔离降本 低折扣 Token 即用即扣 · 不设账期

常见问题(FAQ)

火山方舟官方 API 与官方 Key 直连 · 向量云 · 大模型推理两阶段

Q1. 为什么首字总是等很久,后面的字反而流畅?

A. 首字之前要跑完整个 Prefill——一次性并行计算整个 Prompt,生成 KV Cache 并产出第一个输出 token,用户必须等它跑完;后续每个字只是 Decode 的增量计算,一步只算一个 token。所以「第一个字最慢」是大模型推理阶段的固有特征,也是 TTFT 指标存在的意义。

Q2. Decode 为什么不能像 Prefill 一样并行?

A. 自回归生成里每个新 token 依赖前一个 token 的输出,生成是串行的,无法并行;而且每步都要把全部历史 KV Cache 从显存读一遍,GPU 更多时间花在搬数据上,算力本身用不满。这就是 Decode 访存密集型(Memory-bound)的根源。

Q3. TTFT 和 TPOT 哪个更能代表「用户体验」?

A. 看场景:聊天/客服类场景用户等的是「第一个字」,看 TTFT(首 token 延迟);长文生成/内容创作类场景用户等的是「完稿速度」,看 TPOT(每字耗时)与吞吐。两者都要监控——TTFT 恶化往往是 Prefill 排队或输入过长,TPOT 恶化往往是带宽瓶颈或 KV 过大。

Q4. 为什么上下文越长越慢?

A. 两个阶段都受影响:Prefill 的计算量随输入长度增长,TTFT 变大;Decode 每步要读的 KV Cache 也随历史长度线性增长,长上下文下 KV 读取量巨大,带宽瓶颈更明显。KV 占用公式:显存 ≈ token 数 × 层数 × 注意力头数 × 每头维度 × 字节数 × 2(K+V)。

Q5. 前缀缓存对 Prefill 有用,对 Decode 有用吗?

A. 前缀缓存主要作用于 Prefill:两个请求输入前缀相同即可复用已算好的前缀 KV,直接跳过重复 prefill,TTFT 大幅下降。Decode 阶段的提速要靠另一组手段——KV Cache 量化、GQA/MQA 减头、投机解码、连续批处理等。

Q6. PD 分离是什么?我需要吗?

A. PD 分离(Prefill-Decode Disaggregation)把 Prefill 和 Decode 拆到不同 GPU 集群:高算力卡集群读题、高带宽大显存卡集群吐字,KV Cache 通过网络传递。适合并发高、首字延迟要求严的场景(DeepSeek、Mooncake、NVIDIA Dynamo 等均采用)。自建推理早期或小规模部署可以先不拆,用前缀缓存 + 批处理优化即可。

Q7. 服务商 API 里我怎么感知这两个阶段?

A. 你感知不到 Prefill 的名字,但能看到它的效果:流式输出的首包延迟、每字速度、以及账单上的 token 消耗。API 侧能做的,就是优化你的 Prompt(复用固定前缀)和选择合适的模型档位;追求更快首字与更稳吞吐,可选缓存命中率高的服务与独享接入点。