
一次 LLM 推理的完整旅程从你按下回车到最后一个字吐出你给大模型发了一段 2000 token 的 prompt它回复了 500 token。这中间服务端到底发生了什么为什么第一个字要等一会儿后面却像打字机一样往外蹦为什么输出 token 比输入 token 贵好几倍为什么缓存命中的输入又便宜一个数量级这些问题的答案全部藏在推理过程的两个阶段里Prefill和Decode。理解了这两个阶段的本质区别API 计费规则、延迟表现、各种推理优化技术就全部通了。一、总览一次推理的四个步骤假设你发送了一段 2000 token 的 prompt模型回复 500 token。服务端实际发生的事情可以分成四步Tokenize分词文本切成 token 序列转成 ID 数组Prefill预填充并行处理全部输入 token生成 KV Cache 和第一个输出 tokenDecode解码自回归循环一次一个 token吐出剩下的 499 个终止与释放碰到停止符或达到max_tokens结束并释放资源。其中 Prefill 和 Decode 是两种性质截然不同的负载——一个吃算力一个吃内存带宽。下面逐个展开。二、Tokenize文本变数字模型不认识文字只认识数字。Tokenizer 把你的文本按词表切成 token 序列再映射成整数 ID 数组今天天气不错 → [今天, 天气, 不, 错] → [45012, 8823, 191, 7756]英文大约 4 个字符对应 1 个 token中文大约 1~2 个汉字对应 1 个 token取决于词表。这一步是纯 CPU 上的字符串处理耗时通常在毫秒级开销可以忽略。但它决定了后面所有环节的计量单位——你账单上的每一分钱、上下文窗口的每一格容量都是按 token 数的。三、Prefill并行吞下整个 prompt算力受限模型对这 2000 个输入 token 做一次并行的前向计算。关键在于输入是已知的。第 1500 个 token 是什么不需要等第 1499 个算完才知道——它们本来就在你的 prompt 里。因此这 2000 个 token 可以同时通过整个网络Transformer 每一层的注意力和 MLP 都是大规模矩阵乘法GPU 的算力单元被吃得很满。这个阶段是**算力受限compute-bound**的瓶颈在于 GPU 每秒能做多少次浮点运算而不是数据搬运。Prefill 产出两样东西KV Cache全部 2000 个输入 token 在每一层注意力中的 Key/Value 向量被写入显存缓存。这是后续 Decode 阶段的记忆——没有它每生成一个新 token 都要把整个上下文重算一遍KV Cache 的详细原理可以单独展开成一篇这里只需要知道它把重复计算换成了显存占用。第一个输出 token最后一个输入 token 位置上的概率分布采样出第一个回复 token。你感受到的首字延迟TTFT, Time To First Token基本就是 prefill 的耗时。prompt 越长prefill 要算的矩阵越大首字越慢——这就是为什么塞了几万 token 上下文的请求第一个字要等好几秒。四、Decode一次一个 token 的自回归循环带宽受限从第二个输出 token 开始进入完全不同的模式。每一步循环只做一件事处理一个token——读取全部模型权重 已积累的 KV Cache做一次前向计算对最后一层输出的概率分布采样出下一个 token把这个新 token 的 K/V 追加进 Cache进入下一步。循环 500 次就是你看到的 500 个字逐个蹦出来的打字机效果。为什么 Decode 慢——GPU 在等数据这个阶段每步的计算量极小只有一个 token 的矩阵乘但每步都要把全部模型权重从显存搬到计算单元。算一笔账就明白了一个 70B 参数模型FP16 精度下权重约140 GB一张 A100 的显存带宽约2 TB/s每生成一个 token 至少要完整读一遍权重140 GB ÷ 2 TB/s ≈70 ms/token也就是说单条请求不做任何优化理论上限只有14 token/s左右——而此时 GPU 的算力单元利用率可能不到 1%。这就是内存带宽受限memory-bound瓶颈不是算得不够快而是数据喂不过来GPU 大部分时间在等权重从显存搬运过来。这也解释了为什么推理芯片的竞争核心指标是显存带宽HBM以及为什么权重量化INT8/INT4能直接提升 decode 速度——权重体积减半搬运时间就减半。采样概率分布如何变成具体的字前向计算的输出不是一个 token而是整个词表上的概率分布。怎么从分布里挑出下一个字由采样参数控制temperature温度越低分布越尖锐趋向确定性输出越高越随机top-p / top-k:只在概率最高的候选集合里采样砍掉长尾greedytemperature0永远取概率最高的那个。这就是为什么同一个 prompt 每次回答不完全一样——decode 的每一步都在掷骰子。五、终止与释放Decode 循环在两种情况下结束采样到停止符EOS token或你指定的 stop sequence——模型自己说完了达到max_tokens上限——被强行截断这就是回答说到一半戛然而止的原因。结束后这个请求占用的 KV Cache 被释放显存归还给调度器分配给其他请求。或者——按缓存策略保留一段时间如果几秒后同一个对话又来了下一轮前缀的 KV Cache 还在就能跳过大部分 prefill。这就是Prefix Caching前缀缓存的原理也是 API 厂商prompt caching 命中的输入 token 便宜 10 倍的技术来源命中的部分根本不用重新计算只是从显存/内存里读出来。六、生产环境的真相Continuous Batching以上是单条请求的视角。真实的推理服务上一张 GPU 同时挂着几十上百个请求各自处于完全不同的阶段有的刚进来在 prefill有的在 decode 第 300 步有的马上要结束。老式的做法是静态批处理凑一批请求一起跑全部生成完才接下一批。问题很明显——批里有人生成 50 个 token 就完了有人要生成 2000 个先完成的只能干等着GPU 利用率被最慢的请求拖垮。现代推理引擎vLLM、TensorRT-LLM、SGLang 等用的是Continuous Batching连续批处理调度以步为粒度——每一步动态决定这一批算谁。谁生成完谁立刻退出、腾出位置新请求随时插入prefill 和 decode 的请求可以拼在同一批里跑。这样把 decode 阶段每步都要搬全部权重的固定成本摊到几十个请求头上反正权重都要读一遍多算几十个 token 几乎不增加时间。批处理是 decode 吞吐的第一杠杆。配套的关键技术还有PagedAttentionKV Cache 像操作系统内存分页一样管理按小块分配而不是预留整段连续显存消灭碎片同一张卡能塞下多好几倍的并发请求vLLM 的成名作Chunked Prefill把一个超长 prompt 的 prefill 切成小块和其他请求的 decode 步交错执行避免一个大 prefill 把整张卡霸占几百毫秒、让所有正在 decode 的用户卡顿Prefill/Decode 分离部署更激进的架构——既然两种负载性质完全不同干脆用两组机器分别跑 prefill 和 decodeKV Cache 通过高速互联传输各自按最优配置调度。七、更快的 Decode投机解码与注意力变体除了批处理还有两类正交的优化在攻击 decode 的单步成本投机解码Speculative Decoding用一个小模型或模型自带的轻量预测头快速猜出后面 4~8 个 token再让大模型一次前向并行验证这串猜测。猜对了就一步等于多步猜错了从错的位置重来正确性完全无损数学上等价于大模型自己逐个生成。本质是把 decode 的串行搬运成本换成了一次类似 prefill 的并行验证——用便宜的算力换昂贵的带宽。注意力头共享MQA / GQA / MLA标准多头注意力里每个头都有独立的 K/VKV Cache 巨大。Multi-Query Attention 让所有头共享一组 K/VGrouped-Query Attention 折中分组共享Llama 系采用DeepSeek 的 MLA 则把 KV 压缩成低秩隐向量。KV Cache 小了每步搬运的数据少了能塞的并发也多了。八、关键结论计费规则的物理解释现在回到最初的问题。把两个阶段的性质放在一起看Prefill输入 tokenDecode输出 token计算方式全部 token 一次并行一次一个串行循环瓶颈算力compute-bound显存带宽memory-boundGPU 利用率高低靠 batching 拯救单 token 成本低高数倍用户感知首字延迟 TTFT逐字生成速度 TPOTPrefill 吞吐高、按 token 算便宜Decode 慢、每个 token 都要读一遍全模型单位成本高得多。于是 API 价格表上的一切都有了物理解释输出 token 比输入贵 3~5 倍——不是定价策略是 decode 的真实成本就是高缓存命中的输入再便宜一个数量级——命中前缀的 KV Cache 连 prefill 都省了几乎零计算长 prompt 首字慢——prefill 计算量随输入长度增长注意力部分还是平方增长长对话越聊越慢、越聊越贵——每轮都携带全部历史KV Cache 线性膨胀每一步 decode 要读的缓存也越来越大。对开发者的直接启示也是这四条的镜像能缓存的前缀system prompt、few-shot 例子、文档放在 prompt 开头且保持逐字节稳定让 prefix caching 命中能省的输出就省要 JSON 别要散文设置合理的 max_tokens对延迟敏感就用流式输出让用户在 TTFT 之后立刻开始阅读感知延迟骤降。一句话总结输入是批发输出是零售——记住这一点大模型推理的性能、成本和一切优化技术就都在同一张地图上了。