简介:本文系统讲解大语言模型推理中Prefill与Decode两个核心阶段的原理、差异与工程实践,帮助开发者理解计算密集型与访存密集型的本质区别,掌握KV Cache机制、批处理策略与性能优化方法,从而更高效地完成推理服务的部署、调优与问题排查。
本教程旨在帮助读者系统理解大语言模型(LLM)推理过程中 Prefill(预填充) 与 Decode(解码) 两个核心阶段的工作原理、计算特征与工程差异。通过本教程,读者将能够:
本教程适合大模型应用开发者、推理服务运维人员、技术负责人以及对 LLM 底层机制感兴趣的工程师阅读。阅读前建议具备 Transformer 注意力机制、矩阵乘法、GPU 并行计算等基础知识。
理解 Prefill 与 Decode 的差异,在以下场景中尤为关键:
在深入阶段细节之前,需要明确以下前置概念与条件:
若上述概念尚不熟悉,建议先补充相关知识再阅读本教程,效果更佳。
大语言模型生成文本采用自回归方式:每次根据已有的 Token 序列预测下一个 Token,然后将新 Token 追加到序列中,继续预测,直到遇到结束符或达到最大长度。
这个流程天然分为两段:
第一段对应 Prefill,第二段对应 Decode。理解这一划分,是理解后续所有差异的前提。
在 Prefill 阶段,模型一次性接收长度为 n 的输入序列,需要为每个位置计算 Query、Key、Value 向量,并完成注意力计算:
Q = X · W_qK = X · W_kV = X · W_vAttention = softmax(Q · Kᵀ / √d_k) · V
其中 Q · Kᵀ 是一个 n × n 的注意力分数矩阵。当 n 较大时,这个矩阵乘法的规模非常可观。同时,各层的线性变换(如 X · W_q)也是大规模矩阵乘法。
关键结论:Prefill 阶段包含大量可以并行执行的矩阵运算,GPU 的众多计算核心能够被充分调度,因此它属于计算密集型(Compute-bound)任务。计算单元利用率高,显存带宽往往不是瓶颈。
工程含义:Prefill 阶段的耗时与输入长度呈近似平方或线性增长关系,长提示词会显著拉高首 Token 延迟。
进入 Decode 阶段后,假设模型已经处理到第 t-1 个 Token,现在需要处理第 t 个 Token。此时模型只需要计算当前 Token 的 q_t、k_t、v_t,并与之前保存的 KV Cache 结合,完成注意力计算:
h_t = softmax(q_t · [K_cache; k_t]ᵀ / √d_k) · [V_cache; v_t]
其中:
K_cache、V_cache:保存了前 t-1 个 Token 的 Key 和 Value;k_t、v_t:当前 Token 新计算得到的 Key 和 Value;[K_cache; k_t] 表示在序列维度上的拼接。关键结论:Decode 阶段每次只处理一个 Token,矩阵乘法的维度极小(例如 1 × d 与 d × d 相乘),无法填满 GPU 的大量计算核心。但每一步都需要读取整个 KV Cache 以及模型权重,数据搬运量远大于计算量。因此它属于访存密集型(Memory-bound)任务,瓶颈在显存带宽而非算力。
工程含义:Decode 阶段单步延迟受显存带宽限制明显,且随上下文长度增长而增加,因为需要读取更长的 KV Cache。
| 维度 | Prefill | Decode |
|---|---|---|
| 处理 Token 数 | 一次处理 n 个 | 一次处理 1 个 |
| 矩阵规模 | 大矩阵乘法 | 小矩阵向量乘 |
| 瓶颈类型 | 计算密集型 | 访存密集型 |
| GPU 利用率 | 高 | 低,算力闲置 |
| 主要延迟指标 | 首 Token 延迟(TTFT) | 单 Token 输出延迟(TPOT) |
| 对上下文敏感度 | 输入长度影响大 | 上下文长度影响缓存读取 |
| 优化重点 | 并行度、算子融合 | 显存带宽、批处理、缓存管理 |
理解这张对比表,是后续做推理优化和容量规划的基础。
KV Cache 是 Decode 阶段能够高效运行的关键机制。若没有缓存,每生成一个新 Token 都要重新计算全部历史 Token 的 K、V,计算量将随序列长度线性增长,完全不可接受。
KV Cache 的核心逻辑:
k_t、v_t,追加到缓存,然后与全部历史 K、V 做注意力;显存估算思路(通用公式):
KV Cache 显存 ≈ 2 × 层数 × 头数 × 头维度 × 序列长度 × 批大小 × 数据类型字节数
在实际部署中,需要根据模型规模、上下文长度上限和并发数,合理预留显存,避免 OOM。
针对 Prefill 的优化方向:
n × n 矩阵的内存占用与计算量;针对 Decode 的优化方向:
通用优化建议:
部署或调优后,可通过以下方式验证效果:
问题一:首 Token 延迟过高。
原因通常是 Prefill 阶段计算量大,尤其是长提示词。排查方向:确认输入长度分布,是否可做提示词压缩、前缀缓存复用;检查是否启用了高效注意力算子。
问题二:输出阶段每 Token 延迟随上下文增长明显。
原因是 Decode 阶段需读取更长的 KV Cache。排查方向:确认缓存是否量化、是否存在重复读取;评估是否可通过滑动窗口注意力或缓存淘汰策略控制长度。
问题三:显存溢出(OOM)。
通常是 KV Cache 占用过大,常见于长上下文或高并发。排查方向:估算缓存显存公式,检查批大小与最大长度配置,考虑缓存量化或分页管理。
问题四:GPU 利用率忽高忽低。
Prefill 阶段利用率高,Decode 阶段利用率低,属于正常现象。若整体利用率持续偏低,可能是批处理策略未优化,考虑启用连续批处理。
问题五:吞吐上不去。
若 Decode 是瓶颈,通常是批大小不足或访存受限;若 Prefill 是瓶颈,可能是算子效率低或并行度不够。需分阶段测量后再决定优化方向。
本教程围绕大语言模型推理的两个核心阶段展开:
两者在计算特征、瓶颈类型和优化手段上差异显著。理解这些差异,是进行推理服务部署、性能调优、容量规划与问题排查的基础。后续可继续关注连续批处理、缓存压缩、投机解码等方向,进一步提升推理效率与资源利用率。