3、LLM推理基础:Transformer解码流程、KV Cache原理、预填充与解码阶段
在正式进入 vLLM 的架构与调优之前,我们必须先建立对 LLM 推理底层机制的精确理解。vLLM 的 PagedAttention、Continuous Batching、动态抢占等核心设计,本质上都是为了解决 Transformer 解码过程中“显存碎片化”与“计算利用率低”这两个痛点。本章将深入拆解 Transformer 的解码流程,揭示 KV Cache 的显存占用规律,并严格区分预填充(Prefill)与解码(Decode)两个阶段在计算特征与性能瓶颈上的本质差异。只有透彻理解这些基础,后续的 vLLM 参数配置与性能调优才能做到有的放矢。
上图清晰地展示了 LLM 推理的两个核心阶段及其与 KV Cache 的关系。在预填充阶段,模型并行处理整个输入序列,计算密集但耗时较短;在解码阶段,模型逐 Token 生成输出,访存密集且耗时较长。而 KV Cache 作为贯穿两阶段的“中间状态”,其显存管理方式直接决定了推理系统的吞吐量与延迟表现。接下来,我们将逐一深入这些环节。
3.1 Transformer 解码流程:从输入到输出的逐 Token 生成
现代大语言模型(如 GPT、LLaMA、Qwen 等)均基于 Transformer 的解码器(Decoder)架构。其推理过程并非一次性生成完整回答,而是采用自回归(Autoregressive)方式:每次只预测下一个 Token,并将该 Token 拼接至输入序列末尾,作为下一次预测的输入,循环往复直至生成结束符或达到最大长度。
3.1.1 核心原理:自回归与条件概率
解码过程本质上是计算条件概率分布:
P(y_t | y_1, y_2, ..., y_{t-1}, x)
其中,x 为输入 Prompt,y_1 至 y_{t-1} 为已生成的 Token。模型在每一步输出一个词表大小的概率分布,通过采样策略(如 Top-p、Temperature)选择下一个 Token。这一过程涉及 Transformer 的三大核心子层:
- 掩码自注意力(Masked Self-Attention):确保当前位置只能关注到其左侧的 Token,防止信息泄露。
- 前馈网络(FFN):对注意力输出进行非线性变换,通常包含两层线性映射和激活函数。
- 层归一化与残差连接:稳定训练与推理过程,加速收敛。
3.1.2 操作流程:一次完整的解码步骤
以生成第 t 个 Token 为例,其计算流程如下:
- 输入嵌入:将当前 Token ID 映射为稠密向量,并添加位置编码。
- 逐层计算:经过 L 层 Transformer Block,每层包含自注意力与 FFN。
- 输出投影:最后一层的隐藏状态经 LM Head(词表映射矩阵)转换为词表大小的 logits。
- 采样:对 logits 应用 Softmax 并采样,得到下一个 Token。
关键洞察:在解码阶段,虽然输入只有 1 个 Token,但模型仍需计算所有历史 Token 的注意力权重。若不做优化,计算量将随序列长度平方级增长。KV Cache 正是为了避免重复计算历史 Token 的 Key 和 Value 而引入的缓存机制。
3.2 KV Cache 原理:空间换时间的经典工程实践
KV Cache 是 LLM 推理中最核心的优化手段。其思想朴素而高效:在自注意力计算中,当前 Token 的 Query(Q)需要与所有历史 Token 的 Key(K)做点积,再与 Value(V)加权求和。历史 Token 的 K 和 V 在每一步都是相同的,因此可以缓存下来复用,避免重复计算。
3.2.1 核心原理:缓存什么?如何计算?
对于每一层 Transformer Block,我们需要缓存两个矩阵:
- K Cache:形状为 [Batch_Size, Num_Heads, Seq_Len, Head_Dim]
- V Cache:形状与 K Cache 相同
在预填充阶段,模型一次性计算整个 Prompt 的 K 和 V 并存入缓存;在解码阶段,每生成一个新 Token,仅需计算该 Token 的 K 和 V,并追加至缓存末尾。这样,自注意力的计算量从 O(t²) 降为 O(t),极大提升了推理速度。
3.2.2 显存占用公式与实例
KV Cache 的显存占用是推理部署时必须精确评估的指标。其计算公式如下:
KV_Cache_Memory = 2 (K和V) × Num_Layers × Hidden_Size × Max_Seq_Len × Batch_Size × dtype_size
以 LLaMA-7B 模型(32 层,Hidden Size 4096)为例,假设最大序列长度 2048,Batch Size 8,FP16(2 字节)精度:
Memory = 2 × 32 × 4096 × 2048 × 8 × 2 Bytes
= 2 × 32 × 4096 × 2048 × 8 × 2 / (1024³) GB
≈ 8.59 GB
这意味着,仅 KV Cache 一项就需占用约 8.6 GB 显存,远超模型权重本身(约 14 GB)。若 Batch Size 增至 32,KV Cache 将膨胀至 34 GB,显存压力急剧上升。
| 模型规模 | 层数 | Hidden Size | KV Cache / Token / Batch(FP16) |
|---|---|---|---|
| 7B | 32 | 4096 | 0.5 MB |
| 13B | 40 | 5120 | 0.8 MB |
| 70B | 80 | 8192 | 2.6 MB |
风险提示:KV Cache 的显存占用与 Batch Size 和序列长度呈线性增长,且每个请求的序列长度不可预知。传统静态显存预分配方式会导致大量碎片与浪费,这是 vLLM 引入 PagedAttention 的直接动因。
3.3 预填充与解码阶段:计算特征与性能瓶颈的深度对比
预填充与解码虽同属推理过程,但其计算特征、硬件利用率和性能指标截然不同。理解这些差异是进行 vLLM 参数调优(如 --max-num-seqs、--max-model-len)的前提。
3.3.1 预填充阶段(Prefill)
预填充阶段处理完整的输入 Prompt,属于典型的计算密集型(Compute-Bound)任务。此时,模型并行处理所有输入 Token,矩阵乘法(GEMM)的维度较大,GPU 的算力得以充分发挥。该阶段的性能指标为首 Token 延迟(TTFT, Time To First Token),直接影响用户的感知体验。
3.3.2 解码阶段(Decode)
解码阶段逐 Token 生成输出,属于典型的访存密集型(Memory-Bound)任务。此时,输入仅为 1 个 Token,矩阵乘法退化为矩阵向量乘法(GEMV),GPU 算力利用率极低,瓶颈在于 KV Cache 的显存带宽。该阶段的性能指标为单个 Token 输出延迟(TPOT, Time Per Output Token),以及整体吞吐量(Tokens/s)。
3.3.3 对比总结
| 维度 | 预填充(Prefill) | 解码(Decode) |
|---|---|---|
| 输入规模 | 整个 Prompt(数百至数千 Token) | 1 个 Token |
| 计算类型 | GEMM(矩阵乘法) | GEMV(矩阵向量乘法) |
| 瓶颈 | GPU 算力(FLOPS) | 显存带宽(HBM Bandwidth) |
| GPU 利用率 | 高(>80%) | 低(<20%) |
| 关键指标 | TTFT(首 Token 延迟) | TPOT / 吞吐量 |
| 耗时占比 | 约 30% | 约 70% |
3.4 案例拆解:一个 7B 模型的推理延迟分析
为了将上述理论应用于实践,我们以一个具体的生产环境案例来展示如何分析推理性能瓶颈,并制定优化方向。
场景与约束:某 SaaS 公司部署 LLaMA-7B 模型(FP16)提供聊天服务。GPU 为单张 A10(24 GB 显存,显存带宽 600 GB/s)。业务要求:TTFT < 1.5 秒,TPOT < 100 ms。当前配置下,实测 TTFT 为 1.2 秒,TPOT 为 150 ms,吞吐量仅 6.7 tokens/s,不满足要求。
初始现象与数据:通过 nvidia-smi 观察,GPU 算力利用率(SM Occupancy)在解码阶段仅为 15%,而显存带宽利用率接近 90%。这证实了解码阶段为访存瓶颈。
分析判断过程:
- 计算理论 TPOT:模型权重 14 GB + KV Cache(假设 1 个请求,序列长度 1024)约 0.5 GB,总计约 14.5 GB 需从显存读取。理论最小 TPOT = 14.5 GB / 600 GB/s ≈ 24 ms。实测 150 ms 远高于理论值,说明存在大量额外开销。
- 定位开销来源:通过 profiling 发现,每次解码步骤中,模型需读取全部 14 GB 权重,但仅计算 1 个 Token 的向量乘法。权重读取占据了绝大部分显存带宽,而 KV Cache 的读取占比很小。
- 优化方向:既然权重读取是瓶颈,最直接的手段是增大 Batch Size。当多个请求同时解码时,权重只需从显存读取一次,即可服务多个 Token 的计算,从而摊薄权重读取成本,提升整体吞吐量。
实际操作与结果:将 vLLM 的 --max-num-seqs 从 1 提升至 8。此时,单次解码步骤处理 8 个 Token,权重读取成本被摊薄 8 倍。实测 TPOT 降至 45 ms,吞吐量提升至 22 tokens/s,满足业务要求。代价是显存中 KV Cache 占用增加,但 A10 的 24 GB 显存仍有余量。
风险与代价:增大 Batch Size 会线性增加 KV Cache 显存占用。若请求序列长度较长,可能导致显存溢出(OOM)。vLLM 的 PagedAttention 通过非连续显存管理,允许 KV Cache 存储在碎片化显存中,从而在相同显存容量下支持更大的 Batch Size。
经验复盘:当解码阶段 GPU 利用率低而显存带宽饱和时,优先考虑增大 Batch Size 而非优化单请求延迟。vLLM 的 Continuous Batching 机制正是为了在请求粒度上动态调整 Batch,最大化吞吐量。后续章节将深入讲解其实现原理。
3.5 常见误区与总结复盘
在理解 LLM 推理基础时,工程师常陷入以下误区,导致后续调优方向错误:
- 误区一:认为 KV Cache 是可选优化。实际上,没有 KV Cache 的推理复杂度为 O(t²),对于长序列完全不可用。KV Cache 是推理引擎的必备组件。
- 误区二:混淆 TTFT 与 TPOT 的优化目标。TTFT 受 Prompt 长度和算力影响,TPOT 受 Batch Size 和显存带宽影响。优化手段截然不同。
- 误区三:忽略 KV Cache 的显存增长。在部署时仅考虑模型权重大小,导致实际并发量远低于预期。必须使用公式精确估算。
- 误区四:认为 Batch Size 越大越好。当 Batch Size 增大到一定程度,KV Cache 显存占用将超过可用显存,导致 OOM。vLLM 的 PagedAttention 虽能缓解碎片化,但总容量仍受物理显存限制。
总结:本章揭示了 LLM 推理的本质——预填充阶段的计算密集与解码阶段的访存密集。KV Cache 作为连接两阶段的桥梁,其显存管理是系统设计的核心挑战。vLLM 的所有高级特性,如 PagedAttention、Continuous Batching、动态抢占,均围绕“如何更高效地管理 KV Cache 并提升解码阶段吞吐量”这一命题展开。掌握这些基础,是后续进行 vLLM 性能调优的必备前提。