Prhub

#52502 [Hardware][NVIDIA] Add GB10 fused-MoE fp8 tuning configs (E=256, E=512)

原始 PR 作者 pavelzak 合并时间 2026-08-17 11:04 文件变更 2 提交数 1 评论 3 代码增减 +294 / -0

执行摘要

新增 GB10 E=256/512 的 fused-MoE fp8 调优配置

PR body 明确指出:"Without device-specific configs, GB10 falls back to heuristic defaults",即 GB10 上 DeepSeek 系 MoE 层(fp8_w8a8、block_shape=[128,128]、N=512)缺少设备特定配置,只能使用启发式默认参数,性能未达最优。同时作者预先澄清了重复性质疑:现有 #52192(E=512,N=2688,Nemotron-3-Super)与 #45949(Qwen3-Coder-Next 形状)覆盖的是其他形状,"No open or merged config covers device_name=NVIDIA_GB10 with N=512"。

值得快速浏览而非精读:价值在于理解 vLLM fused-MoE tuning 配置的命名约定、分桶粒度与参数规律(小 M 用小 GROUP_SIZE_M、大 M 提升 BLOCK_SIZE_M 与 GROUP_SIZE_M、num_stages 做流水线/寄存器折中),以及"真机 sweep + E2E 验证"的配置提交流程。对计划为其他设备或形状提交调优配置的贡献者,该 PR 是很好的模板。

讨论亮点

该 PR 的 review 几乎没有技术交锋:claude[bot] 因 PR 来自 fork 而跳过自动审查(提示维护者可用 @claude review 触发一次性审查);维护者 jeejeelee 直接批准并通过 /ci run 触发 Buildkite CI #84081;随后由 WoosukKwon 合并。真正有价值的"讨论"发生在 PR body 中——作者预先回应了最可能被质疑的重复提交问题,逐条列出 #52192 与 #45949 覆盖的形状差异,这是此类纯配置 PR 最核心的评审关注点。

实现拆解

  1. 变更入口与命名约定:在 vllm/model_executor/layers/fused_moe/configs/ 目录下新增两个 JSON 文件。文件名本身就是匹配键,编码了 E(专家数)、N(隐藏维)、device_namedtypeblock_shape 五个维度;fused-MoE 内核加载器在运行时按这些维度精确查找配置,命中后打印日志并采用参数,未命中则回退启发式默认。

  2. 配置结构与分桶策略:每个文件顶层以 triton_version: "3.5.0" 作为版本锚点,避免跨 Triton 版本盲目套用;其下按 M(单次内核调用的 token 行数)划分 17 档(1 到 4096)。小 M 档(1-32)统一使用 BLOCK_SIZE_M=16GROUP_SIZE_M=1,以细粒度分块降低小 batch 的跨行同步开销;M 进入 48 后 GROUP_SIZE_M 提升到 16,M>=256 再提升到 32,通过跨 token 行分组提升 A 矩阵访存复用;M>=1024 进入 prefill 长序列区间,BLOCK_SIZE_M 逐步升到 32/64,提高每个线程块的计算密度。BLOCK_SIZE_NBLOCK_SIZE_K 全程固定 128,对应 block_shape=[128,128]num_warps 固定为 4,num_stages 在 3/4 间切换,权衡流水线深度与寄存器占用。

  3. 调优与验证流程:作者用 benchmarks/kernels/benchmark_moe.py 在 DGX Spark(GB10)上对每个 M 档 sweep 参数,随后在 2× DGX Spark、TP=2 的 DeepSeek-V4-Flash-0731 服务上做端到端验证:确认运行日志中配置被选中、服务稳定,decode 吞吐相对回退基线有提升。

  4. 测试与配套:本 PR 没有任何源码、测试或文档改动;CI 由维护者 jeejeelee 的 /ci run 触发(Buildkite #84081)并通过后合并。PR body 声明调优由提交者在 GB10 硬件上完成,AI 仅用于把基于 v0.26.0 的生产分支 rebase 到 main

文件 模块 状态 重要度
vllm/model_executor/layers/fused_moe/configs/E=256,N=512,device_name=NVIDIA_GB10,dtype=fp8_w8a8,block_shape=[128,128].json 内核配置 added 5.68
vllm/model_executor/layers/fused_moe/configs/E=512,N=512,device_name=NVIDIA_GB10,dtype=fp8_w8a8,block_shape=[128,128].json 内核配置 added 5.68

关键源码片段

vllm/model_executor/layers/fused_moe/configs/E=256,N=512,device_name=NVIDIA_GB10,dtype=fp8_w8a8,block_shape=[128,128].json configuration

E=256 专家规模的 DeepSeek 系 MoE 层调优配置,是本 PR 的核心新增之一;文件名即运行时匹配键,编码 E、N、device_name、dtype、block_shape 五个维度,命中后由 fused-MoE 内核加载器采用。

{
    // 版本锚点:fused-MoE 内核加载器只在运行时的 Triton 主版本
    // 与此值一致时才加载本配置,避免跨版本盲目套用导致性能回退
    "triton_version": "3.5.0",    // 分桶键为 M(单次内核调用的 token 行数),覆盖 1 ~ 4096,
    // 每个桶给出该 M 区间实测最优的 Triton launch 参数
    "1": {
        "BLOCK_SIZE_M": 16, // 小 batch 用 16,块粒度细、无效算力少
        "BLOCK_SIZE_N": 128, // 固定为 block_shape 的 N 维 128
        "BLOCK_SIZE_K": 128, // 固定为 block_shape 的 K 维 128
        "GROUP_SIZE_M": 1, // M 很小时按单行分组,避免跨行同步开销
        "num_warps": 4,
        "num_stages": 4 // 流水线深一点,容忍小 M 下的访存延迟
    },
    // 2/4/8/16/24 与 "1" 形状相同,仅 num_stages 降为 3,
    // 用更浅的流水线换取更低寄存器占用(此处省略重复条目)
    "32": {
        "BLOCK_SIZE_M": 16,
        "BLOCK_SIZE_N": 128,
        "BLOCK_SIZE_K": 128,
        "GROUP_SIZE_M": 1,
        "num_warps": 4,
        "num_stages": 4
    },
    // M 进入 48 以后 GROUP_SIZE_M 升为 16:跨多行 token 分组共享
    // A 矩阵分块,提升访存复用率,是中型 batch 的关键收益项
    "48": {
        "BLOCK_SIZE_M": 16,
        "BLOCK_SIZE_N": 128,
        "BLOCK_SIZE_K": 128,
        "GROUP_SIZE_M": 16,
        "num_warps": 4,
        "num_stages": 4
    },
    // 48 ~ 128 区间 GROUP_SIZE_M 统一为 16,num_stages 在 3/4 间微调;
    // 256 起 GROUP_SIZE_M 升到 32,继续放大跨 token 分组
    "256": {
        "BLOCK_SIZE_M": 16,
        "BLOCK_SIZE_N": 128,
        "BLOCK_SIZE_K": 128,
        "GROUP_SIZE_M": 32,
        "num_warps": 4,
        "num_stages": 3
    },
    // 1024 起进入 prefill 长序列区间,BLOCK_SIZE_M 逐步升到 32 / 64:
    // 用更大的 M 块提高每个线程块的计算密度
    "1024": {
        "BLOCK_SIZE_M": 32,
        "BLOCK_SIZE_N": 128,
        "BLOCK_SIZE_K": 128,
        "GROUP_SIZE_M": 16,
        "num_warps": 4,
        "num_stages": 3
    },
    "4096": {
        "BLOCK_SIZE_M": 64, // 4096 行时块内并行度充足,64 为最优
        "BLOCK_SIZE_N": 128,
        "BLOCK_SIZE_K": 128,
        "GROUP_SIZE_M": 32,
        "num_warps": 4,
        "num_stages": 4
    }
    // 1536 / 2048 / 3072 与 4096 形状相同(BLOCK_SIZE_M=64、GROUP_SIZE_M=32、
    // num_stages=4),此处省略重复条目
}

评论区精华

fork PR 自动审查与 CI 触发流程 other

claude[bot] 提示该 PR 来自 fork,自动审查默认关闭,维护者可评论 `@claude review` 触发一次性审查;随后 jeejeelee 评论 `/ci run` 触发 Buildkite CI #84081。PR 无实质技术讨论,亦无 review 评论。

结论:流程性讨论,无遗留问题;jeejeelee 直接批准,PR 由 WoosukKwon 合并。 · 已解决

风险与影响

  • 兼容性风险低:纯 JSON 新增,配置查找机制为现成逻辑,其他设备的代码路径完全不受影响。
  • 静默回退风险:若未来 Triton 升级导致 triton_version=3.5.0 不再命中,或 fused-MoE 内核实现/加载器解析方式变化,GB10 会静默回退到启发式默认,表现为性能回落而非报错,问题难以察觉。
  • 覆盖范围有限:两张表只覆盖 N=512fp8_w8a8block_shape=[128,128] 的 DeepSeek 系形状;同一设备其他形状(如 #52192 的 N=2688)仍需各自的调优配置。
  • 无自动化回归测试:配置有效性依赖提交者的一次性 sweep 与 E2E 验证,后续若内核分组逻辑、算子融合策略变化,这些参数可能不再最优。
  • 用户侧:GB10(DGX Spark)上运行 DeepSeek 系 MoE 模型的用户开箱即得调优参数,MoE 层吞吐与 decode 吞吐相对启发式基线提升;其他设备完全不受影响。
  • 系统侧:改动集中在配置目录内,与 benchmarks/kernels/benchmark_moe.py 的调优工作流衔接,验证了 vLLM 按设备、按形状、按量化方式细分 tuning 配置的机制。
  • 团队侧:为后续 GB10 或其他新硬件的 fused-MoE 调优提交提供了可参照的模板和命名先例,也佐证了当前 GB10 配置族(#52192、#45949)正在逐步补齐不同模型形状的性能基线。
配置与 Triton 版本绑定 失效时静默回退 无自动化回归测试 覆盖形状有限

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论