LLM 推理过程本质上分为两个截然不同的计算阶段:Prefill(预填充/上下文处理)和 Decode(解码/自回归生成)。Prefill 阶段接收完整的输入 prompt token 序列,通过一次前向传播计算所有 prompt token 的 KV Cache,同时生成第一个输出 token。Decode 阶段则进入自回归循环,每次只处理一个新 token,利用已缓存的 KV Cache 逐 token 生成后续输出 [S1][S2]。
Prefill 阶段具有以下核心特征:
per_token_kv_size = 2 * L * H * D * dtype_size
其中 2 表示 Key 和 Value 两组张量,dtype_size 为数据类型字节数(FP16 为 2 字节,FP8 为 1 字节)。
Decode 阶段具有以下核心特征:
| 指标 | 公式 | 说明 |
|---|---|---|
| TTFT | t_first_token_output - t_request_received | 从请求到第一个输出 token 的时间,主要由 Prefill 决定 |
| TPOT | Total decode time / (Output tokens - 1) | 每个输出 token 的平均时间,反映 Decode 速度 |
| ITL | t_{i+1} - t_i | 相邻 token 间隔,反映生成平滑度 |
| E2E Latency | TTFT + (Output length - 1) * TPOT | 端到端总延迟 |
| Prefill FLOPs | approx 2 * B * n² * d | Batch size B,序列长度 n,模型维度 d |
| Decode FLOPs/token | approx 2 * B * n * d | 每生成一个 token 的计算量 |
Prefill 是 Decode 的前置条件:没有 Prefill 阶段计算的 KV Cache,Decode 阶段无法开始。在传统系统中,当一个长 prompt 请求进入时,它会在一个 step 中独占整个 GPU 执行 Prefill,期间所有正在 Decode 的请求必须等待,导致它们的 ITL 急剧增加。这是 Chunked Prefill(模块二)和 Disaggregated Serving(模块四)等技术要解决的核心问题。
资源需求矛盾:Prefill 需要强算力、大 batch(摊薄开销);Decode 需要高内存带宽、低延迟、持续调度。当两者混合在同一 GPU 上时,Prefill 会抢占 Decode 的计算资源,导致 Decode token 延迟剧增。
KV Cache(Key-Value Cache)是 LLM 推理中的核心优化技术。在 Transformer 的自回归生成过程中,每个新 token 的 Attention 计算需要与之前所有 token 的 Key 和 Value 进行交互。如果每次都重新计算所有历史 token 的 K 和 V,将产生大量的重复计算。KV Cache 技术将之前计算过的 Key 和 Value 张量缓存起来,在后续步骤中直接复用,从而将每步的计算复杂度从 O(n²) 降低到 O(n)(n 为序列长度)[S1]。
对于单个请求,KV Cache 的总大小为:
KV_Cache_Size = 2 * L * S * H * D * dtype_size
其中:
示例:LLaMA3-70B(FP16)每 token 的 KV Cache:
2 * 80 * 1 * 8 * 128 * 2 = 327,680 bytes approx 320 KB
对于 4K context,KV Cache approx 1.28 GB;对于 128K context,KV Cache approx 40 GB。
在 PagedAttention 出现之前,主流推理系统为每个请求预分配一块连续的 GPU 内存,容量按该请求的最大可能序列长度计算。这种方案的内存浪费来源包括 [S1][S29]:
vLLM 论文报告的实验数据显示,在 OPT-13B 模型和 Alpaca trace 上,传统方案的 KV Cache 内存利用率通常只有 20-40%,而 PagedAttention 可将利用率提升至 95% 以上。
KV Cache 是 PagedAttention 的管理对象。PagedAttention 本质上是一种 KV Cache 的内存管理方案,它将 KV Cache 分为固定大小的 block,通过 Block Table 实现逻辑到物理的非连续映射。没有 KV Cache 的概念,PagedAttention 就失去了管理目标;没有 PagedAttention,KV Cache 的内存利用效率极低。
Attention Mechanism(注意力机制)是 Transformer 架构的核心组件,它允许模型在处理序列时动态地关注输入的不同部分。Self-Attention(自注意力)是 Attention 的一种特殊形式,其中 Query、Key、Value 都来源于同一个输入序列,使模型能够捕捉序列内部任意两个位置之间的依赖关系 [S1]。
对于输入序列 X ∈ R^{n × d_model},Self-Attention 的计算步骤如下:
Step 1: Q/K/V 投影
Q = X WQ, K = X WK, V = X WV其中 WQ, WK, WV ∈ R^{d_model × d_k} 是可学习的投影矩阵。
Step 2: 缩放点积
scorei,j = (qi · kj) / √(dk)除以 √(d_k) 的缩放因子是为了防止当 d_k 较大时点积数值过大,导致 softmax 进入梯度饱和区。
Step 3: Softmax 归一化
αi,j = softmax( (qi · kj) / √(dk) )j = exp( (qi · kj) / √(dk) ) / Σl=1n exp( (qi · kl) / √(dk) )在 Decoder 的自注意力中,还需要应用因果掩码(Causal Mask)M:
αi,j = softmax( (qi · kj) / √(dk) + Mi,j )其中 Mi,j = 0 如果 j ≤ i,否则 Mi,j = -∞。
Step 4: 加权聚合
Attention(Q, K, V) = softmax( Q KT / √(dk) ) VMulti-Head Attention 通过并行运行多组独立的注意力机制,让模型同时从多个表示子空间中捕捉不同类型的关系:
headi = Attention(Q WiQ, K WiK, V WiV)
MultiHead(Q, K, V) = Concat(head1, head2, ..., headh) WO其中 WO ∈ R^{h d_v × d_model} 是最终的输出投影矩阵。
| 特性 | MHA(Multi-Head Attention) | MQA(Multi-Query Attention) | GQA(Grouped-Query Attention) |
|---|---|---|---|
| 定义 | 每个头有独立的 Q/K/V 投影 | 所有头共享同一组 K/V | K/V head 数介于 MHA 和 MQA 之间 |
| KV Cache 大小 | O(n · h · d) | O(n · 1 · d) | O(n · g · d) |
| 内存效率 | 低 | 高 | 中等 |
| 质量损失 | 无(基线) | 可能有轻微损失 | 损失较小 |
| 代表模型 | 原始 Transformer | PaLM | LLaMA-2/3, Mistral |
| 适用场景 | 追求质量优先 | 极致内存压缩 | 质量与效率平衡 |
GQA 的具体机制:将 h 个 Query head 分成 g 组(g < h),每组共享一组 K/V。例如 LLaMA-2 有 32 个 Q head 和 8 个 KV head(g = 8),即每 4 个 Q head 共享 1 个 KV head。这减少了 KV Cache 到 1/4,同时质量损失远小于 MQA。
Attention 的计算依赖 KV Cache:在 Decode 阶段,Attention 的计算公式变为:
Attention(qt, K≤t, V≤t) = softmax( qt K≤tT / √(dk) ) V≤t其中 K≤t 和 V≤t 就是 KV Cache 中存储的历史 Key 和 Value。没有 KV Cache,每次 Decode 都需要重新计算所有历史 token 的 K 和 V,计算量从 O(n) 暴涨到 O(n²)。
PagedAttention 要求 Attention Kernel 支持非连续 KV Cache 访问。传统 Attention Kernel 假设 K 和 V 是连续的内存块,而 PagedAttention 的 K 和 V 存储在分散的物理 block 中。因此,FlashAttention、FlashInfer 等后端需要接收 block table(物理块 ID 列表)和 slot mapping(每个 token 对应的物理块内偏移),而非连续的内存指针 [S12]。