大模型推理基础:Transformer架构、自回归生成与KV Cache原理
要理解 vLLM 与 TensorRT-LLM 在吞吐调优上的差异,首先必须回到大模型推理的底层运行机制。吞吐量的瓶颈并非单纯来自 GPU 的浮点算力,而是由 Transformer 的解码方式、自回归生成顺序以及 KV Cache 的内存增长模式共同决定。本节将拆解这三个核心概念,并揭示它们如何直接制约推理引擎的调度策略。
2.1 Transformer 架构:从 Encoder 到 Decoder 的推理差异
现代大语言模型(如 GPT、LLaMA、Qwen)几乎都采用 Decoder-only 架构。与早期 Transformer 的 Encoder-Decoder 结构不同,Decoder-only 模型在推理时没有独立的编码阶段,而是直接对输入序列进行自回归处理。其核心组件包括:
- 多头自注意力(Multi-Head Attention):每个 Token 都要与序列中所有之前的 Token 计算相关性,生成 Query、Key、Value 向量。
- 前馈网络(FFN):对注意力输出进行非线性变换,通常占据模型约 2/3 的参数。
- 层归一化与残差连接:稳定深层网络训练与推理的数值流。
在推理阶段,Decoder-only 模型存在两种典型模式:
| 模式 | 触发场景 | 计算特征 |
|---|---|---|
| Prefill(预填充) | 用户输入提示词(Prompt) | 并行处理所有输入 Token,计算密集,GPU 利用率高 |
| Decode(解码) | 逐个生成输出 Token | 串行处理单个 Token,访存密集,GPU 利用率低 |
吞吐调优的核心矛盾在于:Prefill 阶段需要高算力,Decode 阶段需要高带宽。vLLM 与 TensorRT-LLM 的调度器本质上都在解决这两种阶段混合时的资源分配问题。
2.2 自回归生成:串行依赖与条件概率
自回归(Autoregressive)生成是指模型将 已生成的 Token 序列作为下一步预测的输入。数学上表示为:
P(y₁, y₂, ..., yₙ | x) = Π P(yₜ | x, y₁, ..., yₜ₋₁)
这意味着第 t 个 Token 的生成必须等待前 t-1 个 Token 全部完成。这种串行依赖导致两个重要推论:
- 无法并行生成同一序列内的 Token——即使 GPU 有数千个核心,单请求的 Decode 步骤也只能一次推进一个 Token。
- 序列长度动态增长——每个请求的最终长度未知,导致显存分配无法预先精确规划。
为了提升吞吐,推理引擎采用 连续批处理(Continuous Batching):不再等待整个批次全部完成,而是当批次中某个请求生成完毕(如遇到 EOS 或达到 max_tokens)时,立即插入新请求。这要求引擎能够动态管理每个请求的中间状态。
2.3 KV Cache:推理吞吐的显存瓶颈
KV Cache 是 Transformer 推理中最关键也最容易被忽视的机制。在 Decode 阶段,每个新 Token 的注意力计算需要与历史所有 Token 的 Key 和 Value 向量做点积。若不缓存,则每次都要重新计算历史 Token 的 K/V,计算量随序列长度平方增长,完全不可接受。
KV Cache 的显存占用公式为:
KV Cache 显存 = 2 (K 和 V) × 层数 × 注意力头数 × 头维度 × 序列长度 × 批大小 × 每个元素字节数
以 LLaMA-7B 为例(32 层,32 头,头维度 128,FP16):
每 Token 每请求的 KV Cache = 2 × 32 × 32 × 128 × 2 字节 = 512 KB
当批大小为 64、平均序列长度为 1024 时,仅 KV Cache 就占用:
512 KB × 1024 × 64 = 32 GB
这已经超过许多单张 GPU 的显存容量。因此,KV Cache 的管理方式直接决定了推理引擎能否支持更大的并发批处理。
2.4 可视化:Transformer 推理数据流与 KV Cache 增长
下图展示了 Decoder-only 模型在 Prefill 与 Decode 阶段的数据流差异,以及 KV Cache 如何随生成过程动态增长。左侧为 Prefill 阶段并行处理输入 Token,右侧为 Decode 阶段逐个生成并持续追加 KV Cache。
图中清晰展示了两个阶段的本质区别:Prefill 阶段一次性处理所有输入 Token,计算完成后生成 KV Cache 的初始版本;Decode 阶段则每次只处理一个 Token,但需要从 KV Cache 中读取历史信息,并将新 Token 的 K/V 追加到缓存中。随着生成推进,KV Cache 的显存占用呈线性增长,这直接限制了批处理大小。
2.5 吞吐调优的核心矛盾与误区复盘
基于上述原理,可以总结吞吐调优的三大核心矛盾:
- 算力 vs. 带宽:Prefill 需要算力,Decode 需要带宽。混合批处理时,引擎必须决定 GPU 资源在两种计算模式间的分配比例。
- 批大小 vs. KV Cache 容量:增大批大小能提升吞吐,但 KV Cache 占用随之线性增长,显存不足时只能降低批大小或使用更小的模型。
- 动态长度 vs. 静态分配:请求的最终长度未知,若按最大长度预分配显存,将造成巨大浪费;若动态分配,则面临碎片化问题。