Decode原理


下面我用工程视角 + 一个完整、可计算的例子,把 Decode 彻底展开。看完你会清楚三件事:

  1. Decode 每一步 GPU 在算什么
  2. KV Cache 在 Decode 中如何被使用和增长
  3. 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

模型内部做什么?

  1. 用 token7 的 embedding

  2. 在每一层 Transformer:

    • 生成 token7 的 Q
    • 用 Q 去和 KV Cache(token1~7)的 K/V 做 attention
  3. 得到 logits

  4. 选出下一个 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 质量。


如果你愿意,下一步我可以继续把下面之一彻底拆开:

  1. 4090 上一次 Decode step 大概耗时多少,怎么算 tokens/s
  2. 为什么 max-num-batched-tokens 比 max-num-seqs 更重要
  3. Decode 阶段 P95 延迟是怎么被“长文本请求”拖垮的

你选一个,我继续。

posted @ 2026-01-20 15:30  向着朝阳  阅读(1)  评论(0)    收藏  举报