
问题背景2023 年初LLM 推理服务化还是个混乱地带。FasterTransformer 需要手写 C 组装模型DeepSpeed-MII 勉强能用但社区不温不火HuggingFace 的model.generate()离生产可用差了十万八千里。每家公司都在内部搞一套推理方案——有的基于 ONNX Runtime 手动拼图有的给 PyTorch 套一层 FastAPI 直接上线有的干脆买更多的 GPU 硬抗。这里最核心的矛盾不是一个工程问题而是一个架构问题LLM 推理框架应该如何设计才能让研究者专注模型、让工程师专注部署、让运维专注扩缩容换言之需要有人把 KV Cache 管理、批处理调度、显存分配、量化压缩这些脏活做进一个统一的系统里并给出一个干净的 API 边界。vLLM 就是在这样的背景下出现的。它的目标很明确做 LLM 推理的操作系统而不是另一个推理库。整体架构Centralized Scheduler Block-Level Memory ManagervLLM 的架构可以归结为两层下层的Block-Level KV Cache Manager以 PagedAttention 为核心上层的Centralized Scheduler统一调度器。两层之间的关系就像操作系统的内存管理与进程调度——Manager 管货架Scheduler 管排班。请求入口 ──► Centralized Scheduler ──► Block Manager (KV Cache 分配/回收) │ │ ▼ ▼ Worker Pool GPU Memory (Block Pool) │ ▼ Model Runner (Prefill / Decode)调度器每次迭代的核心流程检查 KV Cache Block 池的空闲状况从等待队列拉入尽可能多的新请求为每个新请求分配 Block新请求的 Prompt 做 Prefill长 Prompt 拆成多个 Chunk分多次迭代完成将所有进行中请求的当前 Token 拼成 Batch执行一次前向采样更新序列状态和 KV Cache已完成请求立即释放 Block回收到空闲池这里的关键是把所有请求的 KV Cache 放在一个全局物理池子里请求来的时候按需分配 Block结束的时候立即归还。没有预留没有批次边界GPU 显存被用到了它能被用到的最满状态。核心创新PagedAttention 的设计逻辑PagedAttention 是 vLLM 最核心的单点贡献它的思路是借用了操作系统的分页机制来解决 KV Cache 的内存碎片问题。问题KV Cache 的内存困境LLM 推理中 KV Cache 是显存占用的主要来源。对于一个 7B 模型每 Token 大约产生 0.5MB 的 KV CacheFP16。问题出在分配策略上静态预分配按 max_seq_len × batch_size 预留大多数空间闲置。一个 2048 个槽位的批次如果请求平均只需要 256 Token 输出就有约 87% 的 KV Cache 空间是在做慈善。动态连续分配按需分配、用完回收但不同请求的 KV Cache 生命周期不同——短请求释放小块空间、长请求需要大块空间——在分配/释放交替中产生外部碎片。某一个时刻总空闲空间够一个新请求用但没有一块连续的够大分配失败。方案页式内存管理PagedAttention 把 KV Cache 逻辑上拆成一个个固定大小的Block例如每个 Block 容纳 16 个 Token 的 KV Cache。一个请求的 KV Cache 不是一个连续大块而是由若干个不连续的 Block 组成通过Block Table做逻辑地址到物理地址的映射请求 A 的 Block Table: [Block₃, Block₇, Block₁₂] 请求 B 的 Block Table: [Block₁, Block₅, Block₉, Block₁₄] ... 空闲 Block 池: [Block₂, Block₄, Block₆, Block₈, ...]每次请求增长一个 Token如果当前的最后一个 Block 还有位置不满 16 个 Token就追加进去如果满了从空闲池里分配一个新的 Block在 Block Table 中追加索引。请求完成整个 Block Table 的所有 Block 归还到空闲池。Attention 计算时Kernel 根据每个请求的 Block Table 读取离散的 Block 数据拼成逻辑上连续的 Key/Value 序列。这里有额外开销——Block Table 查找和跨 Block 拼接——但这个开销远小于碎片整理或显存浪费带来的损失。收益分析零外部碎片所有 Block 大小相同任何空闲 Block 都能分配给任何请求不存在有足够空间但没有足够大的连续块的问题按需增长不需要预估输出长度Token 逐个生成Block 逐个分配即时回收请求完成Block 立刻归还不需要 GC 或整理内存共享这是 PagedAttention 的一个副产品——不同请求的 System Prompt 如果相同它们可以共享同一组物理 Block只读通过 Copy-on-Write 处理后续的分叉。这在多轮对话、Few-shot Prompting 场景下节省的显存非常可观PagedAttention 本质上是把KV Cache 的物理存储与序列的逻辑视图解耦了——操作系统的虚拟内存干了同样的事只不过 OS 管的是 CPU 内存页PagedAttention 管的是 GPU 显存块。为什么成为主流不是技术最强而是架构决策最准vLLM 成为主流推理框架技术上并非每个维度都领先于所有对手但它在几个关键的架构决策上押对了方向。决策一做推理引擎不做推理服务全栈vLLM 的 API 边界画得很克制它提供一个OpenAI-compatible API Server也提供一个Python APILLM类但不试图做负载均衡、模型管理、多节点编排。这些事情留给 Kubernetes、Ray Serve、或者各家的 MLOps 平台去解决。对比 HuggingFace TGI——它试图包揽从调度到路由到鉴权到监控的全栈职责这在大团队里有优势但灵活性被牺牲了。vLLM 选择做好一件事其他交给生态的策略让它在不同部署环境裸机、K8s、云平台中的适配成本极低。决策二优先保证通用性在通用性上追求极致性能很多推理框架的性能优化与特定模型或特定硬件深度耦合——FastTransformer 每个模型手写 KernelTensorRT-LLM 深度依赖 NVIDIA GPU 的软件栈。这种做法在 benchmark 上好看但在一个模型结构每周都在变动的世界里维护成本是指数级的。vLLM 的选择是先适配尽可能多的模型当前已支持 50 种架构然后用系统的架构优势PagedAttention Centralized Scheduler来提升全局吞吐而不是用逐模型的 Kernel 优化来追求单次延迟。它的ModelRunner抽象允许新模型通过相对简单的适配就能接入整套推理流水线而且自动获得 Continuous Batching 和 PagedAttention 的收益。这个决策在 2023-2024 年的模型爆发期被证明是正确的——当 Llama 3、Mistral、Mixtral、Qwen、DeepSeek 接二连三出现时vLLM 的适配速度远超竞品。决策三开源的激进性与社区的飞轮效应vLLM 的开源策略比 TGI 更激进、比 TensorRT-LLM 更开放。Apache 2.0 协议 UC Berkeley 背书吸引了大量贡献者。自 2023 年 6 月发布以来贡献者数量迅速超越 TGI成为 LLM 推理框架中最大的开源社区。这形成了一个正向循环更多用户 → 更多 Issue 和 Feature Request → 更多贡献者 → 支持更多模型和硬件 → 更多用户。在推理框架这个领域支持你的模型往往比比你快 5%更有说服力。决策四显存效率带来的单卡优势PagedAttention 使 vLLM 在相同 GPU 上可以容纳比 TGI早期版本和静态批处理方案多得多的并发请求。对于一个 7B 模型在 A100-80GB 上的部署vLLM 可以同时处理约 2-3 倍于静态批处理的请求量。显存是怎么省出来的不是压缩精度那是量化的活而是避免了静态预分配的浪费和通过 Block 共享消除了相同前缀的冗余存储。在 GPU 按小时计费的云环境中单卡能承载的并发量直接对应了单位推理成本。省显存就是省钱这在商业决策中比任何技术指标都直观。竞品对比各自的选择与取舍HuggingFace TGI全栈优先但包袱太重TGI 是最早支持 Continuous Batching 的推理框架之一比 vLLM 更早。它的优势在于 HuggingFace 生态的原生支持——模型 Hub 到推理服务的链路最短。Transformer 模型下载后可以直接通过 TGI 拉起。但 TGI 的包袱也来自此它的架构必须兼容 HuggingFace Transformers 的全部特性包括大量不常用于推理的代码路径它的后端在 Rust高性能 HTTP 层和 Python模型逻辑之间来回切换引入了通信开销。加之早期 TGI 的 KV Cache 管理不如 PagedAttention 高效同等硬件下的并发能力落后于 vLLM。TGI 的核心用户是已经在 HuggingFace 生态中深度投入的团队对他们来说改一行代码就能上线的价值大于 10% 的吞吐提升。TensorRT-LLM性能天花板通用性的代价TensorRT-LLM简称 TRT-LLM是 NVIDIA 官方的推理方案。它的性能在 NVIDIA GPU 上是天花板级别的——CUDA Graph 消除 CPU-GPU 交互开销、FP8/INT8 KV Cache 量化、Multi-Node TensorPipeline Parallelism 的调度协同每一项都做到了极致。但 TRT-LLM 的代价也很明显模型添加需要手写转换脚本每个新模型架构都需要被映射到 TRT-LLM 的内部表示这不是加一个配置文件的事是需要理解 TRT 内部表示再写适配代码的事构建过程复杂模型需要经过 ONNX → TensorRT Engine 的编译链大型模型编译时间长且在每次更新 TensorRT 版本后都需要重新构建闭源且硬锁定 NVIDIA无法在 AMD、Intel GPU 或 Apple Silicon 上运行TRT-LLM 的定位很清晰追求极致性能的 NVIDIA GPU 用户。如果你的推理服务跑在 NVIDIA H100/H200 集群上并且模型架构相对固定例如只用 LlamaTRT-LLM 意味着最高的吞吐和最低的延迟。但如果你需要快速迭代模型、或者混合使用不同模型它的维护负担会很快超过性能收益。SGLang结构化生成为核调度更为激进SGLang 是 2024 年最值得关注的推理框架之一。它没有试图做一个通用推理引擎而是围绕结构化生成Structured Generation重新设计了推理的编程模型。它的 RadixAttention 机制利用 Radix Tree 来管理 KV Cache 前缀的共享——当多个请求共享相同的 Prompt 前缀例如 System Prompt 多轮对话的历史时这个前缀的 KV Cache 只算一次后续请求直接复用。SGLang 的另一个创新是RadixAttention 的 Prefill 预热在检测到某个前缀被高频命中时将其 KV Cache 保留在显存中不回收让新请求的 Prefill 可以跳过前缀部分。SGLang 的定位和 vLLM 不完全重叠。如果 vLLM 是通用推理的操作系统SGLang 更像是结构化生成场景的专用加速器。但 SGLang 团队正在将 RadixAttention 和 Prefix Cache 的能力泛化到更多场景它与 vLLM 的竞争将集中在 KV Cache 管理的效率上。2024 年底SGLang 已经支持了与 vLLM 相当的模型列表两者的边界正在模糊。LMDeploy国内部署的事实标准LMDeploy 由上海人工智能实验室InternLM 团队开发是国内部署量最大的推理框架之一。它的 TurboMind 引擎在 KV Cache 管理上采用了与 PagedAttention 类似的分块策略但实现上更倾向于连续分配的优化路径——通过减少 Block 粒度开销来追求更高的 Kernel 效率。LMDeploy 的核心优势在于对国产模型InternLM、Qwen、Baichuan 等的原生优化以及对量化方案W4A16、KV Cache INT8/INT4的深度集成。如果 vLLM 的生态优势是在 HuggingFace Hub 上LMDeploy 的优势是在中国云厂商和模型团队的深度绑定上。Ollama / llama.cpp / MLX不是竞品是另一种场景Ollama底层基于 llama.cpp代表的是本地推理和边缘部署的场景——MacBook 上跑 7B 模型、个人工作站上做实验。它们在显存效率通过 MMAP 和量化上做到了极致但不追求高并发下的服务化吞吐。vLLM 的用户从来不是想在本地跑一个 Chatbot 的人而是需要起一个 API Server 给几百个用户提供服务的人。两个世界的设计约束完全不同不是竞争关系。性能关键路径与瓶颈理解 vLLM 的性能需要区分两个场景Prefill 阶段的瓶颈在计算处理一个长 Prompt 时GPU 的 Tensor Core 接近满载显存带宽不是制约因素。vLLM 的 Chunked Prefill 将长 Prompt 的 Prefill 拆入多次迭代目的是不让一次 Prefill 拖慢同一批 Decode 请求的调度。但 Prefill 本身的延迟没有降低——它只是被分期付款了。Decode 阶段的瓶颈在显存带宽Decode 每次只处理一个 Token矩阵乘法维度很小[batch, 1, hidden]Tensor Core 远未吃饱。此时的主要耗时在从显存中读取 KV Cache——几十层的 Attention每层几百个头的 KV都要从全局显存搬到计算单元。Decode 的延迟 KV Cache 的总字节 / 显存带宽。这个特性意味着增大 Batch Size 对 Decode 吞吐的边际收益会快速递减——因为显存带宽是共享资源更多请求意味着更多的 KV Cache 读取带宽更快饱和FlashAttention 对 Decode 的直接加速有限——FlashAttention 主要优化的是 Prefill 阶段的 Attention 计算O(n²) → O(n) 显存读写但 Decode 本身就只算一个 Token显存读写量不大而 Decode 需要加载的 KV Cache 总量FlashAttention 无法消除KV Cache 量化FP8/INT8是 Decode 阶段最有效的优化——它将显存带宽需求直接减半对 Decode 延迟的影响几乎是线性的vLLM 在 Decode 阶段的主要优化手段是通过 PagedAttention Kernel 减少 Block Table 查找的开销以及在可能的情况下做 Batch 内的 Prefix Caching。但这些是减损而非加速——Decode 的物理上限是显存带宽而这一点所有框架都一样。总结vLLM 成为主流不是因为它在每个单项指标上都最强——单卡极限性能不如 TensorRT-LLMHuggingFace 模型即开即用的便利性不如 TGI长前缀复用不如 SGLang 的 RadixAttention 激进。它的决定性问题在于做出了正确的架构选择把推理框架定位为引擎而非平台用 PagedAttention 解决最痛的显存问题以通用性换取生态飞轮。在一个模型架构碎片化、硬件选型多样化、部署环境复杂化的时代架构的灵活性比单点性能优化更有长期价值。vLLM 恰好是这个判断的最好注脚。而从更宏观的角度看推理架构的演进还远未结束。Disaggregated Prefill/Decode 的分离式部署、Multi-LoRA 的细粒度共享、Speculative Decoding 与调度的协同——这些方向正在重新定义推理引擎的职责边界。vLLM 的下一阶段挑战是在保持通用性的同时将这些新技术纳入现有架构而不让系统变成一个臃肿的特性拼盘。参考Kwon, Woosuk, et al. “Efficient Memory Management for Large Language Model Serving with PagedAttention.” SOSP 2023.Zheng, Lianmin, et al. “SGLang: Efficient Execution of Structured Language Model Programs.” NeurIPS 2024.NVIDIA TensorRT-LLM Documentation. https://github.com/NVIDIA/TensorRT-LLMvLLM Documentation. https://docs.vllm.aiHuggingFace Text Generation Inference. https://github.com/huggingface/text-generation-inferenceLMDeploy. https://github.com/InternLM/lmdeploy