3、核心概念:LLM推理原理、KV Cache、PagedAttention、连续批处理(Continuous Batching)机制
要真正驾驭 vLLM 的离线批处理与在线服务双模式,必须先穿透其底层引擎的设计逻辑。vLLM 之所以能在吞吐量和显存效率上显著优于传统推理框架,核心在于它对 Transformer 解码过程的深刻理解与三项关键技术的工程化落地:KV Cache 的动态管理、PagedAttention 的非连续显存分配,以及 Continuous Batching 的微观调度。本节将逐一拆解这些概念,并揭示它们如何协同工作,为后续的实战操作打下坚实的认知基础。
上图清晰地展示了 vLLM 引擎内部三大核心机制的协同关系。下面我们将逐一深入剖析每个环节的原理与工程实现。
3.1 LLM 推理原理:从概率分布到 Token 生成
核心原理:自回归解码
当前主流的大语言模型(如 GPT、LLaMA、Qwen 等)均基于 Transformer 的解码器(Decoder)架构,其推理过程本质上是自回归(Autoregressive)的。这意味着模型在生成第 N 个 Token 时,会将前 N-1 个 Token(即 Prompt 和已生成的 Token)全部作为输入,通过模型计算得到下一个 Token 的概率分布,然后根据采样策略(如贪心搜索、温度采样、Top-p 采样)选出最终的 Token。这个过程会一直循环,直到生成结束符(EOS Token)或达到最大长度限制。
以一个简单的例子说明:假设 Prompt 为“中国的首都是”,模型第一步会计算整个序列的概率分布,选出“北”字;第二步会将“中国的首都是北”作为输入,再选出“京”字;第三步输入“中国的首都是北京”,选出“。”。每一步都依赖完整的输入序列。
判断方法:如何识别推理阶段的性能瓶颈
在实际部署中,我们可以通过以下指标判断推理是否高效:
- 首 Token 延迟(TTFT, Time To First Token):从请求发出到收到第一个 Token 的时间。该指标主要受 Prompt 长度和模型计算速度影响,与 KV Cache 的预填充(Prefill)阶段直接相关。
- 单 Token 生成延迟(TPOT, Time Per Output Token):生成后续每个 Token 的平均耗时。该指标主要受显存带宽和 KV Cache 读取速度影响。
- 吞吐量(Throughput):单位时间内模型能处理的 Token 总数或请求总数。这是衡量系统整体效率的核心指标。
如果 TPOT 过高,往往意味着 KV Cache 的读取成为了瓶颈,或者显存带宽不足;如果 TTFT 过高,则可能是 Prompt 过长导致 Prefill 计算量过大。
案例拆解:一个简单的生成过程
假设我们使用 vLLM 离线批处理接口,输入两个请求:
请求1: "给我讲一个关于AI的笑话"
请求2: "用一句话解释什么是量子计算"
在未使用 KV Cache 的朴素实现中,生成“笑话”这个词时,模型需要重新计算“给我讲一个关于AI的”这 8 个 Token 的 Key 和 Value 矩阵。而使用 KV Cache 后,这 8 个 Token 的 KV 值在第一次计算后就被缓存,后续生成“笑话”时只需计算新 Token 的 KV 值,并与缓存的历史 KV 值做 Attention 计算即可。这极大地减少了重复计算,将计算复杂度从 O(N²) 降为 O(N)。
常见误区与总结
总结:LLM 推理的核心是自回归解码,KV Cache 是消除重复计算、降低单 Token 生成延迟的必备手段,但它的引入也带来了新的显存管理挑战。
3.2 KV Cache 与 PagedAttention:显存管理的革命
核心原理:为什么需要 PagedAttention
传统推理框架(如 HuggingFace Transformers)在管理 KV Cache 时,会为每个请求预先分配一块连续且固定大小的显存。这种方式的弊端非常明显:
- 预分配浪费:我们无法预知请求最终会生成多少 Token,因此只能按最大序列长度(如 2048)来分配。但实际请求可能只生成了 50 个 Token 就结束了,导致大量显存被闲置浪费。
- 内部碎片化:即使我们动态扩容,由于显存分配是连续的,当多个请求的 KV Cache 大小不一且频繁申请/释放时,会产生大量无法利用的显存碎片。
- 无法共享:在并行采样(如 Beam Search)或前缀共享场景下,传统方式无法让多个序列共享相同的 KV Cache 块。
vLLM 借鉴了操作系统中虚拟内存分页(Paging)的思想,提出了 PagedAttention。它将 KV Cache 划分为固定大小的“块”(Block,通常大小为 16 或 32 个 Token)。每个请求的逻辑 KV Cache 由一个或多个块组成,但这些块在物理显存中可以是非连续的。vLLM 维护一张“块表”(Block Table),记录逻辑块到物理块的映射关系。
| 对比维度 | 传统连续显存管理 | PagedAttention 非连续管理 |
|---|---|---|
| 分配方式 | 一次性预分配最大长度 | 按需分配,动态增长 |
| 显存利用率 | 低(存在大量内部碎片) | 高(接近物理极限) |
| 序列长度限制 | 受限于预分配大小 | 仅受物理显存总量限制 |
| 并行采样支持 | 不支持 KV 共享 | 支持块级共享,节省显存 |
| 调度灵活性 | 低(无法应对突发请求) | 高(支持 Continuous Batching) |
操作流程:PagedAttention 如何工作
在 vLLM 的 Prefill(预填充)阶段,系统会计算 Prompt 中所有 Token 的 KV 值,并将它们写入分配的物理块中。在 Decode(解码)阶段,每生成一个新 Token,系统会计算其 KV 值,并写入当前块的末尾。如果当前块已满,则通过块表分配一个新的物理块。Attention 计算时,GPU Kernel 会通过块表间接寻址,读取非连续的 KV 数据。
案例拆解:显存利用率对比
假设一块 80GB 的 A100 显卡,模型权重占用 20GB,剩余 60GB 用于 KV Cache。传统方式下,若每个请求预分配 2048 Token 的 KV Cache(约 0.2GB),则最多支持 300 个并发请求。但实际上,这些请求的平均生成长度可能只有 200 Token,实际 KV Cache 占用仅为 0.02GB。这意味着 90% 以上的显存被浪费。使用 PagedAttention 后,系统可以按需分配,实际支持的并发请求数可能提升 5-10 倍,达到 1500-3000 个。
常见误区与总结
总结:PagedAttention 是 vLLM 的核心创新之一,它通过非连续显存管理,将 KV Cache 的利用率提升至接近物理极限,为高并发推理扫清了显存障碍。
3.3 连续批处理(Continuous Batching)机制
核心原理:从静态批处理到迭代级调度
传统的静态批处理(Static Batching)方式下,推理框架会等待一批请求全部到达后,再统一进行前向传播。这一批请求必须全部生成完毕后,才能释放显存并接收下一批请求。这种方式存在严重的“木桶效应”:整个批次的生成速度受限于最慢的那个请求。如果某个请求生成了很长的序列,其他已经完成的请求所占据的 GPU 资源也无法被释放,导致 GPU 利用率大幅波动。
Continuous Batching(连续批处理),也称为迭代级调度(Iteration-level Scheduling),打破了这种“批”的界限。它在每一个解码步骤(Iteration)结束后,都会检查当前批次中是否有请求已经完成。如果有,则立即将其从批次中移除,并释放其占用的 KV Cache 物理块;同时,如果有新的请求等待,则立即将其加入当前批次,参与下一轮的解码计算。这样,GPU 始终在处理“活跃”的请求,不会因为等待慢请求而空闲。
判断方法:如何评估 Batching 策略的优劣
我们可以通过观察 GPU 利用率曲线来判断。静态批处理的利用率曲线是锯齿状的,波峰和波谷差距很大;而 Continuous Batching 的利用率曲线则相对平稳,长期保持在高位。此外,平均请求延迟(Average Latency)和P99 延迟也是关键指标。Continuous Batching 能显著降低 P99 延迟,因为它避免了慢请求阻塞快请求的情况。
案例拆解:一个动态调度的完整闭环
假设我们有一个在线服务,当前批次中有 3 个请求(A、B、C)。
- 初始状态:A 需要生成 100 Token,B 需要生成 10 Token,C 需要生成 50 Token。
- 静态批处理:系统必须等待 A 生成完 100 Token 后,才能释放 B 和 C 的资源。B 和 C 虽然早已生成完毕,但只能空等,导致 GPU 算力浪费。
- Continuous Batching:
- 第 10 步迭代后,B 生成完毕。系统立即将 B 移出批次,释放其 KV Cache 块,并加入新请求 D。
- 第 50 步迭代后,C 生成完毕。系统将 C 移出,加入新请求 E。
- 第 100 步迭代后,A 生成完毕。此时 D 和 E 可能仍在生成中,系统继续调度。
通过这种方式,GPU 在整个过程中始终在处理 3 个请求(A+B+C → A+C+D → A+D+E → D+E...),计算资源被充分利用。整体吞吐量相比静态批处理可提升 2-3 倍。
常见误区与总结
总结:Continuous Batching 是 vLLM 实现高吞吐的关键调度策略。它与 PagedAttention 紧密配合——PagedAttention 提供了快速分配/释放 KV Cache 的能力,而 Continuous Batching 则利用这一能力实现了请求的即时插拔。理解这三者的关系,是掌握 vLLM 性能调优的前提。