Decode原理
目录
下面我用工程视角 + 一个完整、可计算的例子,把 Decode 彻底展开。看完你会清楚三件事:
- Decode 每一步 GPU 在算什么
- KV Cache 在 Decode 中如何被使用和增长
- Decode 为什么是吞吐和尾延迟的核心瓶颈
一、先给一句“严格定义”
Decode 是:在 Prefill 已完成、KV Cache 已建立的前提下,模型按步(step-by-step)生成新 token 的过程。
每一步只输入 1 个 token,但要和“全部历史 KV Cache”做 attention。
二、用一个具体输入完整跑一遍
输入 Prompt(用户发给 API)
“北京是中国的首都,上海是”
1️⃣ Tokenizer 后(示意)
[token1, token2, token3, token4, token5, token6, token7]
三、Prefill(回顾,用一句带过)
Prefill 做完后:
- 已计算 token1 ~ token7 的 attention
- KV Cache 中已经存了 7 个 token 的 K / V
- 模型状态:“已读完整 prompt”
接下来,才进入 Decode。
四、Decode 的逐步展开(关键部分)
Decode Step 1(生成第 1 个新 token)
输入给模型的是什么?
输入 token:token7(prompt 的最后一个 token)
KV Cache:token1 ~ token7
模型内部做什么?
-
用 token7 的 embedding
-
在每一层 Transformer:
- 生成 token7 的 Q
- 用 Q 去和 KV Cache(token1~7)的 K/V 做 attention
-
得到 logits
-
选出下一个 token(如 greedy / sampling)
假设输出:
token8 = “中国”
KV Cache 变化
原来:token1 ~ token7
新增:token8 的 K / V
Decode Step 2(生成第 2 个 token)
输入
输入 token:token8
KV Cache:token1 ~ token8
输出(示意)
token9 = “的”
KV Cache 继续增长:
token1 ~ token9
Decode Step 3
token10 = “经济”
KV Cache:
token1 ~ token10
Decode Step 4
token11 = “中心”
Decode Step 5(遇到 EOS 或 max_tokens)
token12 = <EOS>
Decode 结束。
五、Decode 的几个“非常反直觉”的点
1️⃣ Decode 不是把全部 token 再算一遍
-
Prefill 已经算过 prompt
-
Decode 只算:
- 新 token 的 Q
- 和历史 KV 的 attention
否则计算量会爆炸。
2️⃣ Decode 每一步是 串行的
这点非常关键:
- token8 必须算完
- 才能算 token9
- 无法并行展开
这也是:
tokens/s 有上限的根本原因
3️⃣ Decode 的 attention 复杂度
每一步:
O(当前 token 数)
随着生成越长:
- KV Cache 越大
- 单步 Decode 稍微变慢
六、为什么 Decode 是“吞吐瓶颈”
Prefill vs Decode 的对比(核心)
| 维度 | Prefill | Decode |
|---|---|---|
| 并行度 | 高 | 低(串行) |
| 主要影响 | TTFT | tokens/s |
| 优化方式 | prefix caching / FA | batching / scheduling |
七、vLLM 如何“救 Decode”
1️⃣ Continuous Batching(最重要)
vLLM 做的不是:
请求A:step1 → step2 → step3
请求B:等 A 全结束
而是:
step1:A B C D 一起算
step2:A B C
step3:A B
→ GPU 每一步都在“并行算多个请求的 1 个 token”
2️⃣ max-num-seqs / max-num-batched-tokens 的意义
-
限制每个 Decode step 中参与的序列数
-
防止:
- KV Cache 爆显存
- step latency 过大
八、Decode 和你关心的指标如何对应
| 指标 | Decode 的关系 |
|---|---|
| tokens/s | 几乎完全由 Decode 决定 |
| P95 latency | Decode 尾部 token |
| GPU SM 利用率 | Decode batching |
| TTFT | Prefill + 第 1 个 Decode |
九、工程级一句话总结(你可以直接记)
Decode 是模型“一个 token 一个 token 往外吐字”的过程。
每一步只能串行,但 vLLM 通过把“多个请求的同一步”并行化,最大化 GPU 利用率。
吞吐调优,调的本质就是 Decode 阶段的 batch 质量。
如果你愿意,下一步我可以继续把下面之一彻底拆开:
- 4090 上一次 Decode step 大概耗时多少,怎么算 tokens/s
- 为什么 max-num-batched-tokens 比 max-num-seqs 更重要
- Decode 阶段 P95 延迟是怎么被“长文本请求”拖垮的
你选一个,我继续。

浙公网安备 33010602011771号