大模型推理基础:Transformer架构回顾、自回归生成原理、KV Cache机制、预填充与解码阶段

在深入vLLM的部署与调优之前,必须建立对大模型推理底层机制的清晰认知。当前主流的大语言模型(如、LLaMA、Qwen等)均基于Transformer解码器架构,其推理过程并非一次性生成完整文本,而是通过逐自回归的方式展开。理解这一过程中的计算特征、内存瓶颈与阶段划分,是后续掌握vLLM连续批处理、PagedAttention、投机采样等高级优化的前提。本章将系统梳理Transformer架构的核心组件、自回归生成的内在逻辑、KV Cache的引入动机与代价,以及预填充(Prefill)与解码(Decode)两个阶段的本质差异。

Transformer解码器推理链路与KV Cache机制 Transformer 解码器层 Masked Multi-Head Attention Add & LayerNorm Feed-Forward Network Add & LayerNorm Embedding + Positional Encoding t₁ t₂ t₃ … KV Cache(显存占用核心) K Cache 形状: [L, H, D] 存储历史Key 每层独立维护 V Cache 形状: [L, H, D] 存储历史Value 每层独立维护 显存占用 = 2 × L × H × D × 2bytes (以FP16存储,L为层数,H为头数,D为头维度) 解码阶段:持续追加新的KV 自回归生成过程 Step 1: 输入 "今天天气" Step 2: 预测 P(下一个) Step 3: 采样得到 "真" Step 4: 拼接后继续预测下一个 两个推理阶段 预填充 并行计算 解码 串行逐 预填充:计算密集型 | 解码:访存密集型 写入 输出logits 读取 预填充阶段:处理整个输入序列,并行计算所有的注意力,生成初始KV Cache 解码阶段:每步仅计算1个新,利用KV Cache避免重复计算历史

上图展示了Transformer解码器推理的核心链路。左侧为解码器层的基本结构,中间为KV Cache的存储形态,右侧为自回归生成与两个阶段的划分。下面我们将逐一拆解每个环节的数学本质与工程含义。

3.1 Transformer架构核心组件回顾

现代大语言模型几乎全部采用仅解码器(Decoder-only)架构,其核心是堆叠的Transformer解码器层。每一层包含两个主要子层:掩码多头自注意力(Masked Multi-Head Attention)和前馈神经网络(Feed-Forward Network, FFN),每个子层后都跟随残差连接与层归一化(LayerNorm)。

在推理场景中,我们最需要关注的是自注意力机制的计算过程。对于输入序列中的第 \( i \) 个,其隐藏状态 \( h_i \) 会通过三个可学习的权重矩阵 \( W_Q, W_K, W_V \) 分别映射为查询向量 \( q_i \)、键向量 \( k_i \) 和值向量 \( v_i \):

q_i = h_i · W_Q
k_i = h_i · W_K
v_i = h_i · W_V

随后,注意力分数通过查询与所有键的点积计算,并经过缩放与Softmax归一化:

Attention(Q, K, V) = softmax(Q · K^T / √d_k) · V

其中 \( d_k \) 为键向量的维度。在解码器中,由于使用掩码机制,每个位置只能关注其之前(包括自身)的位置,这保证了自回归生成的因果性。

工程视角:在推理时,我们并不需要重新计算所有历史的注意力。对于已经生成的前 \( t-1 \) 个,它们的 \( K \) 和 \( V \) 向量在之前的计算中已经得到。如果每次生成新时都重新计算全部历史的 \( K, V \),计算复杂度将从 \( O(t) \) 退化为 \( O(t^2) \),导致推理速度随序列长度急剧下降。这正是引入KV Cache的根本原因。

3.2 自回归生成原理与概率分布

自回归(Autoregressive)生成是指模型将已生成的序列作为上下文,逐步预测下一个的概率分布。形式化地,对于目标序列 \( x_1, x_2, ..., x_T \),模型在每一步 \( t \) 计算条件概率:

P(x_t | x_1, x_2, ..., x_{t-1})

整个序列的联合概率为各步条件概率的乘积:

P(x_1, ..., x_T) = ∏ P(x_t | x_1, ..., x_{t-1})

在工程实现中,模型最后一层会输出一个维度为词表大小 \( V \) 的logits向量,经过Softmax后得到概率分布。随后通过采样策略(如贪心搜索、Top-k采样、Top-p采样或温度缩放)从分布中选取下一个。

自回归生成的关键特性是串行依赖:第 \( t \) 个的生成必须等待前 \( t-1 \) 个全部生成完毕。这意味着即使GPU具备强大的并行计算能力,解码阶段也无法通过简单的数据并行来加速单个序列的生成。这一特性直接导致了解码阶段成为推理延迟的主要瓶颈。

采样策略 原理 适用场景 风险
贪心搜索 每步选择概率最高的 确定性要求高的任务(如代码生成) 容易陷入重复、缺乏多样性
Top-k采样 从概率最高的k个中采样 通用对话、文本创作 k值固定,可能截断合理候选
Top-p采样 从累积概率超过p的最小集合中采样 需要动态调整候选集的任务 p值过小可能导致生成过于保守
温度缩放 将logits除以温度T后再Softmax 控制生成随机性(T>1更随机,T<1更确定) T过高导致输出无意义

3.3 KV Cache机制:原理、代价与显存计算

KV Cache的核心思想是空间换时间:在预填充阶段计算并缓存所有历史的 \( K \) 和 \( V \) 向量,在解码阶段仅计算当前新的 \( q, k, v \),然后与缓存的 \( K, V \) 进行注意力计算。这样,每一步解码的计算量从 \( O(t^2) \) 降为 \( O(t) \),大幅提升了推理速度。

然而,KV Cache带来了显著的显存开销。对于一个具有 \( L \) 层、\( H \) 个注意力头、每个头维度为 \( D \) 的模型,在生成序列长度为 \( S \) 时,KV Cache的总显存占用为:

显存占用 = 2(K和V) × L × H × D × S × 每个元素字节数

以LLaMA-7B模型为例(\( L=32, H=32, D=128 \)),使用FP16存储(2字节),当序列长度达到2048时:

KV Cache大小 = 2 × 32 × 32 × 128 × 2048 × 2 bytes
            = 2 × 32 × 32 × 128 × 2048 × 2 / (1024^3) GB
            ≈ 1.0 GB

这意味着仅KV Cache一项就占用了约1GB显存,且随着序列长度线性增长。对于长文本生成(如32K上下文),KV Cache将膨胀至16GB以上,远超模型权重本身(约14GB FP16)。

显存瓶颈警示:在推理服务中,KV Cache往往是显存占用的最大头。当并发请求增多时,KV Cache的总量会成倍增长。vLLM的核心创新——PagedAttention,正是为了解决KV Cache的碎片化与动态增长问题,通过分页管理将显存利用率提升至接近90%以上。

3.4 预填充阶段与解码阶段的本质差异

推理过程被清晰地划分为两个阶段,它们在计算特征、时间占比和优化策略上截然不同。

预填充阶段(Prefill):当用户输入一段提示词(Prompt)时,模型需要一次性处理整个输入序列。此阶段所有的 \( K, V \) 向量被并行计算并写入缓存。由于输入序列通常包含数百到数千个,预填充阶段属于计算密集型任务,GPU的算力利用率较高。其耗时主要取决于输入序列长度和模型规模。

解码阶段(Decode):在生成第一个输出后,模型进入逐生成的循环。每一步仅处理1个新,计算量极小,但需要从KV Cache中读取全部历史的 \( K, V \) 向量。此时,访存带宽成为主要瓶颈,GPU算力利用率通常不足10%。解码阶段的总耗时与生成数量成正比,是用户感知延迟的主要来源。

对比维度 预填充阶段 解码阶段
输入规模 整个Prompt(数百至数千) 单
计算特征 计算密集型(矩阵乘法为主) 访存密集型(KV Cache读取为主)
GPU利用率 较高(可达50%-80%) 较低(通常低于10%)
KV Cache操作 写入全部历史的K/V 读取全部历史K/V,写入新的K/V
延迟特征 与Prompt长度近似线性 每延迟相对稳定,但总延迟与生成长度线性相关
优化重点 减少冗余计算、并行处理多个请求 减少访存开销、提高批处理大小

3.5 实战场景:从KV Cache视角理解推理性能问题

假设我们使用一个13B参数的模型(\( L=40, H=40, D=128 \))部署推理服务,配置为单张A100-80GB GPU。模型权重以FP16存储,占用约26GB显存。我们分析一个实际请求:用户输入500 的Prompt,期望生成1000 的回答。

显存预算分析:

模型权重:26 GB
KV Cache(预填充后):2 × 40 × 40 × 128 × 500 × 2 / 1024^3 ≈ 0.38 GB
KV Cache(生成完成后):2 × 40 × 40 × 128 × 1500 × 2 / 1024^3 ≈ 1.15 GB
剩余可用显存:80 - 26 - 1.15 ≈ 52.85 GB

表面上看,单请求的显存占用并不高。但在实际生产环境中,我们需要同时处理多个并发请求。假设每个请求的输入输出长度相近,那么并发数 \( N \) 受限于:

N × 1.15 GB + 26 GB ≤ 80 GB
N ≤ (80 - 26) / 1.15 ≈ 46.9

理论上可支持约46个并发请求。然而,传统推理框架(如FasterTransformer的静态批处理)会为每个请求预留最大可能长度的KV Cache空间,导致显存浪费严重。例如,若预留最大长度4096,则每个请求的KV Cache占用为:

2 × 40 × 40 × 128 × 4096 × 2 / 1024^3 ≈ 3.13 GB
N ≤ (80 - 26) / 3.13 ≈ 17.2

并发数骤降至17,显存利用率不足40%。vLLM通过PagedAttention按需分配KV Cache页,将显存利用率提升至90%以上,从而显著提高并发处理能力。

性能调优启示:在实际部署中,应优先关注KV Cache的显存管理策略。对于长上下文场景,考虑使用量化技术(如FP8、INT8)压缩KV Cache;对于短文本场景,则需优化批处理调度,避免因单个长请求阻塞其他短请求。

3.6 常见误区与总结复盘

在理解大模型推理基础时,开发者常陷入以下误区:

  • 误区一:认为模型权重是显存占用的主要部分。实际上,在长序列或高并发场景下,KV Cache的显存占用远超模型权重。以LLaMA-65B为例,模型权重约130GB(FP16),而32K上下文的KV Cache可达数百GB。
  • 误区二:将预填充和解码阶段混为一谈。两个阶段的计算特征截然不同,优化手段也完全不同。预填充阶段适合通过增大batch size提升吞吐,解码阶段则需要通过连续批处理(Continuous Batching)减少等待时间。
  • 误区三:忽略KV Cache的访问模式。解码阶段对KV Cache的访问是顺序读取全部历史数据,这对GPU的访存带宽提出了极高要求。使用更高带宽的HBM(如H100的3.35TB/s)能显著降低解码延迟。
  • 误区四:认为自回归生成无法并行。虽然单个序列的生成是串行的,但不同请求之间的解码可以并行。vLLM的连续批处理正是利用了这一特性,在每一步解码时动态调度多个请求,最大化GPU利用率。

本章总结:Transformer解码器架构决定了推理的串行本质,KV Cache是平衡计算与显存的关键机制,预填充与解码阶段的分治优化是提升推理性能的基石。理解这些基础概念后,我们才能深入掌握vLLM如何通过PagedAttention、连续批处理和投机采样等技术,将理论性能转化为实际吞吐的提升。