推动 vLLM WideEP 和大规模服务在 Blackwell 架构上的成熟(第一部分)
简介
继我们先前的工作在 WideEP 下实现了 2.2k tok/s/H200 的解码吞吐量后,vLLM 团队持续针对 NVIDIA GB200 平台进行性能优化。本博客详细介绍了使 vLLM 能够在 GB200 上实现 26.2K 预填充 TPGS(每 GPU 每秒 Token 数)和 10.1K 解码 TPGS 的关键优化,负载为 2K 输入 Token 和 2K 输出 Token,适用于包括 DeepSeek R1/V3/V3.1 在内的 DeepSeek 风格 MoE 模型。上述数据是通过包含 4 个预填充实例(每个实例 2 个 GB200)和 1 个解码实例(8 个 GB200)的部署环境收集的,全部使用了数据并行 (DP) 和专家并行 (EP) 的组合。
这些提升源于一系列新优化的结合
新优化
- 低精度运算(NVFP4 GEMM、FP8 GEMM、NVFP4 MoE 调度)
- 算子融合(RoPE+量化+Q 写入、RoPE+量化、Concat K)
- 通过权重卸载缩减预填充规模
- 最小化分块开销
先前讨论过的特性
- 异步调度
- 预填充/解码分离式服务
GB200 增强的计算能力与这些针对性优化相结合,使得吞吐量较 H200 部署有了显著提升。
结果
以下基准测试比较了 vLLM 在 GB200 与 H200 上针对 DeepSeek-V3/R1 工作负载(固定 2K 输入和 2K 输出 Token)的性能。详细部署设置见下表。

| 部署设置 | H200 | GB200 |
|---|---|---|
| 预填充 | 16 个 GPU | 8 个 GPU(4 个实例 x 2 个 GPU) |
| 解码 | 32 个 GPU | 8 个 GPU(1 个实例 x 8 个 GPU) |
GB200 增加的内存带宽(8 TB/s 对比 4.8 TB/s)、通过 FP4 实现的更高计算吞吐量以及 CPU 和 GPU 之间的 NVLink-C2C 互联,都为这些提升做出了贡献。我们通过应用下述优化最大限度地发挥了这一潜力。
我们还在 GB200 上针对一系列标准工作负载对 DeepSeek-V3/R1 解码吞吐量进行了基准测试,在保持并行设置不变的同时,改变了能够充分利用 GPU 内存的解码 Batch Size。
复现所有基准测试结果的说明可以在这里找到。

关键优化
低精度运算
与 H200 相比,GB200 为 FP4 和 FP8 运算带来了显著更高的吞吐量。vLLM 通过多项精度优化利用了这些功能。
NVFP4 GEMM (MoE GEMMs, O-proj)
DeepSeek-V3/R1 模型可以量化为 FP4 精度用于 MoE 专家权重和输出投影层。vLLM 集成了 FlashInfer 的 TRTLLM-Gen GEMM 算子,这些算子专门针对 GB200 的 FP4 Tensor Core 进行了优化。
FP4 检查点格式以打包的 4-bit 表示法存储权重,并带有分组缩放因子。在运行时,TRTLLM-Gen 算子在 Tensor Core 内部即时反量化,在保持模型质量的同时实现了接近原生的 FP4 吞吐量。
关键实现细节
- FP4 权重,带有存储在打包格式中的 FP8 或 FP16 缩放因子
- 针对 GB200 Tensor Core 调度优化的 FlashInfer TRTLLM-Gen 算子
- 应用于 MoE 专家 GEMM 和注意力输出投影 (O-proj)
MLA 的 FP8 GEMM
对于 DeepSeek 的多头潜在注意力 (MLA),查询上投影(从潜在空间到全查询维度)受益于 FP8 量化。与 FP4 提供最佳吞吐量/精度权衡的 MoE 层不同,注意力投影对量化更为敏感,精度的提升得益于 FP8 更高的分辨率。
vLLM 为这些投影使用了优化的 FP8 GEMM 算子,在保持注意力质量的同时,实现了相对于 FP16 的显著加速。
NVFP4 MoE 调度 (Dispatch)
除了专家 GEMM 本身,将 Token 路由到指定专家的 MoE 调度操作也可以从低精度中获益。vLLM 实现了 NVFP4 调度,在执行全对全 (all-to-all) 通信之前将 Token 激活值量化为 FP4。
这使得全对全通信量比 FP16 调度减少了 4 倍,显著降低了 EP 部署中的 GPU 间通信延迟。量化开销被通信节省所抵消,从而带来了净吞吐量的提升。
算子融合 (Kernel Fusion)
有几种算子融合策略通过将多个操作组合成单个 GPU 算子,减少了内存带宽消耗和算子启动开销。
RoPE + 量化 + Q 写入(解码阶段)
在解码期间,查询投影需要
- 应用 RoPE(旋转位置嵌入)
- 为后续 GEMM 进行量化
- 写入查询缓冲区
vLLM 将这三个操作融合为一个算子,消除了两次中间内存往返。

RoPE + 量化(预填充阶段)
同样,对于预填充,RoPE 应用和量化也被融合。预填充路径处理更大的 Token 批次,使得融合带来的内存带宽节省更具影响力。
Concat K 优化
对于 MLA 键投影,vLLM 使用 FlashInfer 的 concat_mla_k 算子实现了优化的拼接操作。在 DeepSeek 的 MLA 架构中,键张量由两部分组成:非位置嵌入部分(k_nope,每个头)和旋转位置嵌入部分(k_rope,所有头共享)。必须将它们拼接起来以形成完整的键张量。
朴素方法需要复制 k_nope 并在所有 128 个头上广播 k_rope,这导致了大量的内存带宽消耗。FlashInfer 的 concat_mla_k 算子实现了多项优化
- 基于 Warp 的处理:每个 Warp 处理一对(token, head_chunk),一次处理 16 个头
- 向量化内存访问:使用 8 字节向量加载 nope 数据,使用 4 字节加载 rope 数据,最大化内存吞吐量
- 带有 L2 预取的软件流水线:在处理当前行的同时预取下一行,隐藏内存延迟
- Rope 值的寄存器复用:由于 rope 在所有头上共享,它被一次性加载到寄存器中并写入 chunk 中的所有 16 个头,避免了冗余的内存加载
缩减预填充 (Prefill) 规模
为何缩减规模是合理的
在考虑面向吞吐量的推理服务 GPU 数量时,我们通常会进行横向扩展,要么是为了容纳模型,要么是为了分片内存(专家、上下文)以增加 Batch Size。然而,对于已经是计算受限的预填充工作负载,减少 GPU 数量实际上可以通过降低通信开销来提高吞吐量。
我们的微基准测试表明,当 Batch Size 从 16K 增加到 64K Token 时,MLA 后端吞吐量性能开始趋于平稳。超过 64K Token 后,MoE 吞吐量的提升也可以忽略不计。这意味着我们可以在适合 2-GPU 服务设置的 Batch Size 下使计算利用率达到饱和。


通过将 GPU 数量从 4 个减少到 2 个,我们将用于 EP 通信的 NCCL 集合通信(all_gather 和 reduce_scatter)减半,从而显著降低了通信开销。


权重卸载 (Weight Offloading) v2
为了在保持性能的同时减少 GPU 内存占用,vLLM 实现了带有异步预取的权重卸载 v2。这一 v2 实现受到 SGLang 预填充中卸载方法的启发,现已适配以在 vLLM 内实现与 torch.compile 和 CUDA Graph 的额外兼容性。
在 vLLM 权重卸载 v1 中,卸载的权重保留在 CPU 上,并通过统一虚拟寻址 (UVA) 进行访问,这会产生缓慢的 PCIe 传输延迟。这旨在作为在 GPU 资源受限的情况下运行模型的最后手段。
权重卸载 v2 采取了不同的方法:它预先将权重显式复制(加载)到 GPU。关键的创新是在单独的 CUDA 流上异步加载下一层的权重。通过仔细将权重加载与算子执行重叠,加载延迟可以被完全隐藏。

group_size:将每 N 层分为一组num_in_group:每组卸载这么多层(每组的最后 N 层)prefetch_step:提前预取的层数
对于 DeepSeek-R1 预填充服务,我们每两个 MoE GEMM 权重卸载一个,在保持全吞吐量的同时实现了显著的内存节省。

GB200 CPU 和 GPU 之间的 NVLink-C2C 连接使得权重卸载 v2 特别有效,因为与 PCIe 系统相比,加载延迟降到了最低。
最小化分块开销
MoE 模型中的大批量处理需要分块以适应 GPU 内存限制。然而,较小的块会引入重复算子启动和同步带来的开销,造成 GPU 气泡。vLLM 提供了分块大小配置选项,以在保持在内存限制内的同时最大化吞吐量。
MoE DP 分块
在使用数据并行加专家并行 (DP+EP) 时,Token 以协调的块从每个 DP Rank 调度。`VLLM_ENABLE_MOE_DP_CHUNK` 标志(默认启用)启用了此分块行为。
更大的分块大小通过将调度/合并开销分摊到更多 Token 上来减少 GPU 气泡。分块大小由 `VLLM_MOE_DP_CHUNK_SIZE`(默认值:256 Token)控制。增加此值通过降低同步频率来提高吞吐量。
对于 GB200,我们在预填充时禁用 MoE DP 分块 (`VLLM_ENABLE_MOE_DP_CHUNK=0`),并将 `VLLM_MOE_DP_CHUNK_SIZE` 设置为与解码的 Batch Size 相匹配。
MoE 激活值分块
对于大型预填充批次,vLLM 对激活张量进行分块,以通过 MoE 层处理 Token 的子集。`VLLM_ENABLE_FUSED_MOE_ACTIVATION_CHUNKING` 标志控制此行为(默认启用)。
更大的分块大小通过降低启动开销并提供足够的工作量来充分利用 GPU 计算能力,从而提高吞吐量。分块大小由 `VLLM_FUSED_MOE_CHUNK_SIZE`(默认值:16K Token)控制。最佳设置是在可用 GPU 内存内最大化分块大小。
对于 GB200,我们禁用激活分块 (`VLLM_ENABLE_FUSED_MOE_ACTIVATION_CHUNKING=0`) 以最大化吞吐量,因为更大的内存容量可以容纳完整批次而无需分块。
输出处理分块
在 V1 引擎的异步服务路径中,输出处理(Logit 计算、采样、响应生成)是分块进行的。`VLLM_V1_OUTPUT_PROC_CHUNK_SIZE` 控制每次迭代处理的输出数量(默认值:128)。
更大的分块大小通过降低单块开销来提高整体吞吐量。然而,对于流式工作负载,非常大的块可能会增加消息间延迟的变化。对于 GB200 上经过吞吐量优化的解码,我们将分块大小设置为 2048。
未来工作
vLLM 团队正在积极开展针对 GB200 部署的以下改进工作
- 提高负载均衡和扩展 EP:扩展专家负载均衡以处理更大的 EP 程度和更多动态工作负载,并采用改进的重新平衡算法。
- 优化 MoE 调度延迟:通过算子优化和通信调度进一步降低全对全调度操作的延迟。
- 通过计算-通信重叠隐藏通信延迟:通过更激进的重叠策略在通信受限场景下实现更高的 GPU 利用率。
- 在 GB300 上扩展 WideEP 和大规模服务:通过利用 GB300 更出色的 HBM 和计算能力,我们旨在进一步推进我们的 WideEP 和大规模服务工作,目标是以更小的宿主机占用空间实现更高的 TPGS。
获取最新参考,请访问 roadmap.vllm.ai。
总结
- vLLM 为 DeepSeek 风格的 MoE 模型实现了 26.2K 预填充 TPGS 和 10.1K 解码 TPGS,较 H200 提升了 3-5 倍。
- 低精度运算(NVFP4 GEMM、FP8 GEMM、NVFP4 调度)利用了 GB200 增强的 Tensor Core 能力。
- 算子融合降低了内存带宽压力和算子启动开销。
- 通过权重卸载 v2 缩减预填充规模,在保持计算饱和的同时降低了 EP 通信开销。
- 通过环境变量控制的分块优化最大程度地减少了大批量处理的开销。
团队
- Meta:Ming Yang, Xiaozhu Meng, Pengchao Wang, Lucia (Lu) Fang, Bangsheng Tang, Yan Cui, Hongyi Jia, Jinghui Zhang, Zebing Lin, Jason Park, Yejin Lee, Jaewon Lee, Bradley Davis, Jingyi Yang, Adi Gangidi, Ayush Goel, Charlotte (Ye) Qi, Stephen Chen, Raj Ganapathy, Akshay Hegde, Lu Fang
- NVIDIA:Duncan Moss, Cyrus Chang, Andrew Briand, Siyuan Fu, Hanjie Qiu, Jason Li, Pavani Majety, Xin Li, Chirayu Garg, Abhinav Singh, Minseok Lee