2. Transformer基础

要理解vLLM为何能实现长序列推理加速,首先必须回到Transformer架构的三个核心机制:注意力机制决定了模型如何关联上下文,自回归生成决定了推理的基本范式,而KV Cache则是针对自回归生成中重复计算问题的关键优化。这三者环环相扣,构成了长序列推理性能优化的底层逻辑。

2.1 注意力机制:从全局关联到缩放点积

注意力机制(Attention)让模型在生成每个token时,能够动态地“回看”输入序列中的所有位置,并赋予不同位置不同的权重。Transformer使用的是缩放点积注意力(Scaled Dot-Product Attention),其计算过程可以拆解为四个步骤:

  1. 生成Q、K、V:将输入向量分别乘以三个权重矩阵 \(W_Q\)、\(W_K\)、\(W_V\),得到查询(Query)、键(Key)、值(Value)三个向量。
  2. 计算相似度:用当前token的Query与序列中所有token的Key做点积,得到注意力分数,表示当前token对每个历史位置的关注程度。
  3. 缩放与归一化:将分数除以 \(\sqrt{d_k}\)(\(d_k\) 为Key向量的维度),防止点积过大导致梯度消失,再通过Softmax归一化为概率分布。
  4. 加权求和:用归一化后的概率对Value向量进行加权求和,得到当前token的输出向量。

这一机制的计算复杂度为 \(O(n^2)\),其中 \(n\) 为序列长度。当序列从2K增长到32K时,注意力计算量将增长256倍,这是长序列推理面临的首要瓶颈。

关键公式:
Attention(Q, K, V) = softmax(QK^T / √d_k) · V

下图展示了单头注意力在生成第5个token时的完整数据流,以及KV Cache如何避免重复计算:

自回归生成第5个token时的注意力计算与KV Cache复用 输入序列 我 爱 大 模 型 推理 K/V 投影(仅首次计算) W_K, W_V 权重矩阵 KV Cache(内存中) 存储所有历史token的K、V向量 形状: [4, d_k] + [4, d_v] Q投影 W_Q 读取 注意力计算 Q · K^T / √d_k → Softmax → 加权求和 仅计算当前token的行 输出token "型" 的下一个词 新token的K、V 追加到KV Cache ❌ 无KV Cache时(每次重新计算) 每个新token都要重新计算所有历史token的K、V 计算量: O(n²) · d 延迟随序列长度线性恶化 ✅ 有KV Cache时 只需计算当前token的Q,读取缓存的K、V 计算量: O(n) · d 延迟与序列长度近似线性关系

2.2 自回归生成:逐token的迭代范式

大语言模型的推理本质上是自回归生成(Autoregressive Generation):模型每次只生成一个token,然后将新生成的token拼接到输入序列末尾,作为下一次预测的上下文。这个过程持续进行,直到遇到结束符或达到最大长度限制。

自回归生成有两个重要特征:

  • 串行依赖:第 \(t+1\) 个token的生成必须等待前 \(t\) 个token全部生成完毕,无法并行化。
  • 上下文累积:每生成一个新token,输入序列就变长一位,模型需要“重新审视”全部历史信息。

这种范式直接导致了推理时的计算模式:Prefill阶段(处理初始提示词)和Decode阶段(逐token生成)。Prefill阶段可以并行处理所有输入token,而Decode阶段则只能串行执行,且每个token的生成都需要与全部历史token进行注意力计算。

2.3 KV Cache:消除重复计算的利器

观察自回归生成过程,我们会发现一个严重的计算浪费:在生成第 \(t+1\) 个token时,前 \(t\) 个token的Key和Value向量其实已经计算过了。如果没有缓存,模型会重新计算所有历史token的K、V向量,导致计算量随序列长度呈平方级增长。

KV Cache的核心思想:将历史token的Key和Value向量缓存在GPU显存中,后续生成新token时直接复用,只计算当前token的Query向量,以及当前token自己的K、V向量(用于更新缓存)。

KV Cache的显存占用公式:
显存占用 = 2(K和V) × 层数 × 序列长度 × 隐藏维度 × 精度字节数

示例:7B模型,隐藏维度4096,32层,FP16(2字节)
序列长度 2048:2 × 32 × 2048 × 4096 × 2 = 1.07 GB
序列长度 32768:2 × 32 × 32768 × 4096 × 2 = 17.18 GB

从上表可以看出,KV Cache的显存占用随序列长度线性增长,但基数很大。在长序列场景下(如32K、128K),KV Cache会成为显存的主要消耗者,甚至超过模型权重本身。这也是vLLM引入PagedAttention(分页注意力)的核心动机——通过类似操作系统虚拟内存的分页管理,解决KV Cache的显存碎片化和浪费问题。

2.4 案例:从2K到32K序列的显存变化

让我们通过一个具体案例来感受KV Cache的影响。假设使用一个13B参数的模型(隐藏维度5120,40层,FP16精度),对比不同序列长度下的显存占用:

序列长度 模型权重 KV Cache 总显存 KV Cache占比
2,048 26 GB 1.68 GB 27.68 GB 6.1%
8,192 26 GB 6.71 GB 32.71 GB 20.5%
32,768 26 GB 26.84 GB 52.84 GB 50.8%
131,072 26 GB 107.4 GB 133.4 GB 80.5%

当序列长度达到131K时,KV Cache的显存占用已经超过模型权重的4倍。这意味着在长序列推理场景下,KV Cache的管理效率直接决定了系统的吞吐量和并发能力。如果KV Cache管理不当(如显存碎片化、预分配浪费),即使有足够的显存总量,也可能无法同时处理多个并发请求。

2.5 常见误区与复盘

误区一:认为KV Cache是“缓存”所以不重要
KV Cache不是可选的性能优化,而是Transformer自回归推理的必需组件。没有KV Cache,模型依然能工作,但计算量会从O(n)退化为O(n²),导致长序列推理几乎不可用。
误区二:忽略KV Cache的显存管理
很多初学者只关注模型权重的显存占用,却忽略了KV Cache。实际上,在长序列场景下,KV Cache才是显存的主要消费者。vLLM的核心创新之一就是针对KV Cache的显存管理进行优化。
复盘要点:
  • 注意力机制是Transformer的“大脑”,但O(n²)复杂度是长序列的天然瓶颈。
  • 自回归生成决定了推理的串行特性,Decode阶段无法并行。
  • KV Cache将历史K、V向量缓存,将单步计算从O(n²)降为O(n),但引入了显存线性增长的新问题。
  • 理解KV Cache的显存占用公式,是预估推理资源需求的基础。
  • vLLM的PagedAttention正是为了解决KV Cache的显存碎片化问题而设计。