Prhub

#50801 [CPU] Refine CPU kernel dispatch

原始 PR 作者 bigPYJ1151 合并时间 2026-08-03 17:42 文件变更 6 提交数 5 评论 4 代码增减 +47 / -30

执行摘要

CPU 内核调度重构,移除 SGL 实验开关并修复选择条件

作者在 PR body 中给出的核心动机是:benchmark 表明 SGL 派生 AMX 内核在其既有适格窗口(对称 INT8 W8A8、形状对齐、AMX x86)内没有性能副作用,没必要继续藏在实验开关后;同时审计发现 check_cpu_sgl_kernel 的 dtype 门控漏掉 torch.float16,而 vendored 内核全部通过 AT_DISPATCH_REDUCED_FLOATING_TYPES 分发,同时覆盖 BFloat16Half——导致 FP16 权重被路由到更慢的 oneDNN 路径。另外,CPUExpertsFp8/CPUExpertsMxfp4/CPUExpertsInt4_supports_current_device() 只查 is_cpu()CPUExpertsInt8 只查 x86 不查 AMX,而它们调用的 fused_experts_cputorch.ops._C.convert_weight_packed 只编译进 AMX 档位扩展,非 AMX x86 或 ARM 上选择这些类会直接 AttributeError 崩溃,而不是由 oracle 在加载前干净拒绝。

值得精读,尤其适合 CPU 后端维护者和关注 kernel oracle 机制的人。可学习的点:① 用 vendored 内核源码逐条验证选择条件,而不是靠文档假设;② 把「不支持」的判断前置到 is_supported_config,避免加载期/运行期才崩溃;③ 实验性开关在 benchmark 无副作用且范围收窄后做默认化的完整决策流程。注意其遗留的形状门控问题可作为后续 PR 的切入点。

讨论亮点

该 PR 来自 fork 分支,claude[bot] 自动 review 被禁用;维护者 jikunshang 直接 APPROVED,未留下技术评论。实际的技术讨论沉淀在 PR body 中:作者主动标注了遗留问题——CPUExpertsFp8/CPUExpertsMxfp4/CPUExpertsInt4 仍缺形状对齐门控,原因是 convert_weight_packed 对 mxfp4/int4 字节打包的 IC 计账会翻倍,且 moe_fp8.cpp/moe_int4.cpp 没有运行时 TORCH_CHECK 可交叉验证,贸然加模数判断可能误拒合法配置,因此留作后续而非猜测。

实现拆解

  1. 删除实验开关vllm/envs.pydocs/getting_started/installation/cpu.md):从 EnvVars 类和解析字典移除 VLLM_CPU_SGL_KERNEL 声明与 lambda,文档同步删除对应条目。由于 #50133 已先删掉未量化 MoE 的 SGL 分支,flag 唯一剩余使用点是 INT8 W8A8 线性路径,而该路径在本 PR 中已改为无条件,因此可以整体移除。
  2. 线性层与未量化 GEMM 调度调整vllm/model_executor/kernels/linear/scaled_mm/cpu.pyvllm/model_executor/layers/utils.py):CPUInt8ScaledMMLinearKernel.process_weights_after_loading 删除 envs.VLLM_CPU_SGL_KERNEL 条件,适格时直接 _apply_weights_sgldispatch_cpu_unquantized_gemm 删除 SGL 分支(未量化 GEMM 继续仅用 oneDNN),并顺带清理不再需要的 N, K, dtype 提前取值;check_cpu_sgl_kernel 的 dtype 集合加入 torch.float16
  3. 量化 MoE 专家类选择条件修复vllm/model_executor/layers/fused_moe/experts/cpu_moe.py):四个量化专家类的 _supports_current_device() 统一为 is_cpu() + x86 + AMX 三重检查;CPUExpertsInt8 新增 is_supported_config 重写,提前拒绝 hidden_dimintermediate_size_per_partition 不是 32 倍数的配置。
  4. 依赖升级cmake/cpu_extension.cmake):x86 oneDNN FetchContentv3.10 升到 v3.13,ARM 保持独立 pin。
  5. 测试与基准(未新增测试文件):作者在 AMX 主机跑通 8 个 CPU 相关测试文件(651 过 / 289 跳 / 0 失败),并用 vllm bench serve 分别对比 oneDNN 版本与 SGL 开关移除前后的 serving 指标。本 PR 没有为新增的 is_supported_config 添加正式单测,仅靠手工单元检查验证拒绝路径,是本次变更的薄弱点。
文件 模块 状态 重要度
vllm/model_executor/layers/fused_moe/experts/cpu_moe.py 专家内核 modified 7.32
vllm/model_executor/layers/utils.py 内核调度 modified 6.38
vllm/model_executor/kernels/linear/scaled_mm/cpu.py 量化线性 modified 5.1
vllm/envs.py 环境配置 modified 4.59
cmake/cpu_extension.cmake 构建配置 modified 2.54
docs/getting_started/installation/cpu.md 文档说明 modified 1.58

关键符号

CPUExpertsInt8.is_supported_config CPUExpertsInt8._supports_current_device CPUExpertsFp8._supports_current_device CPUExpertsMxfp4._supports_current_device CPUExpertsInt4._supports_current_device check_cpu_sgl_kernel dispatch_cpu_unquantized_gemm CPUInt8ScaledMMLinearKernel.process_weights_after_loading

关键源码片段

vllm/model_executor/layers/fused_moe/experts/cpu_moe.py data-contract

核心修复所在:四个量化 MoE 专家类补 x86/AMX 设备检查,`CPUExpertsInt8` 新增 oracle 阶段形状对齐门控,防止非 AMX 硬件运行时 `AttributeError` 崩溃。

    @staticmethod
    def _supports_current_device() -> bool:
        # SGL 派生的 fused_experts_cpu / convert_weight_packed 只编译进
        # AMX 档位的 _C 扩展,非 AMX x86 与 ARM 上直接调用会 AttributeError,
        # 因此必须在 oracle 选择阶段就拒绝。
        return (
            current_platform.is_cpu()
            and current_platform.get_cpu_architecture() == CpuArchEnum.X86
            and torch.cpu._is_amx_tile_supported()
        )
​
    @staticmethod
    def is_supported_config(
        cls: type[mk.FusedMoEExperts],
        moe_config: FusedMoEConfig,
        weight_key: QuantKey | None,
        activation_key: QuantKey | None,
        activation_format: mk.FusedMoEActivationFormat,
    ) -> tuple[bool, str | None]:
        supported, reason = mk.FusedMoEExperts.is_supported_config(
            cls, moe_config, weight_key, activation_key, activation_format
        )
        if not supported:
            return supported, reason
        # convert_weight_packed(四个量化专家共用的 VNNI 预打包)要求
        # OC % TILE_N(16) == 0 且 IC % TILE_K(32) == 0;moe_int8.cpp 的
        # w1 门控核还要求中间维本身(非 2x)是 32 的倍数,综合起来
        # hidden_dim 与 intermediate_size_per_partition 都必须是 32 的倍数。
        if moe_config.hidden_dim % 32 != 0:
            return False, "kernel requires hidden dim divisible by 32"
        if moe_config.intermediate_size_per_partition % 32 != 0:
            return False, "kernel requires intermediate dim divisible by 32"
        return True, None
vllm/model_executor/layers/utils.py data-contract

删除未量化 GEMM dispatch 中的 SGL 分支(未量化 GEMM 本就只用 oneDNN),并在 `check_cpu_sgl_kernel` 的 dtype 门控中加入 `torch.float16`。

def check_cpu_sgl_kernel(n: int, k: int, dtype: torch.dtype) -> bool:
    # 底层 SGL 内核(weight_packed_linear、int8_scaled_mm_with_quant、
    # fused_experts_cpu)统一走 AT_DISPATCH_REDUCED_FLOATING_TYPES,
    # 同时覆盖 BFloat16 与 Half,因此 FP16 也具备适格性,
    # 此前漏掉 torch.float16 会把 FP16 模型错误地路由到 oneDNN。
    return (
        torch.cpu._is_amx_tile_supported()
        and (dtype in (torch.bfloat16, torch.float16, torch.int8))
        and k % 32 == 0
        and n % 16 == 0
    )

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. 配置静默失效(breaking change):设置过 VLLM_CPU_SGL_KERNEL=0 的用户升级后开关被忽略,适格条件下会自动启用 SGL 路径,可能带来精度/性能的意外变化。
  2. FP16 行为变化check_cpu_sgl_kernel 新增 FP16 适格性后,FP16 模型在对称 + 对齐 + AMX 下会从 oneDNN 切到 SGL 内核;作者未提供 FP16 的专项基准对比。
  3. oneDNN v3.13 数值差异:body 报告 gemma-7b 有一个 prompt 输出与 v3.10 发散(BF16 舍入顺序敏感);对依赖字节级稳定输出的用户需要关注。
  4. 遗留形状门控:FP8/MXFP4/INT4 专家类仍可能误选/误拒非常规形状配置,未来模型若出现非 32 倍数的中间维度可能重新触发崩溃。
  5. 依赖 vendored 内核细节:选择条件与 csrc/cpu/sgl-kernels/ 内部约束(TILE_N=16、TILE_K=32、moe_int8 的 32 倍数)耦合,上游 sglang 更新或 vendored 变更时需同步审计。

对用户:AMX x86 上的 INT8 W8A8 在线服务自动获得 SGL 内核提速(body 基准:mean TTFT 4136.7→3721.5 ms,total tok/s 359.8→385.1);非 AMX/ARM 用户从潜在运行时崩溃变为 oracle 干净拒绝;BF16 模型在 oneDNN v3.13 下 TPOT/吞吐提升约 2-3%(6-prompt 样本)。对系统:删除一个实验开关,减少 envs 与文档维护成本;CPU MoE 内核选择逻辑更接近自解释。对团队:与 #50133 形成 CPU MoE 调度从「全局 flag + 特判」到「oracle 按设备/形状/量化自述能力」的连续演进,后续可继续补齐 FP8/MXFP4/INT4 的形状门控。

实验开关静默移除 oneDNN 升级数值差异 FP16 新增 SGL 路径 FP8/MXFP4/INT4 形状门控遗留 依赖 vendored 内核约束

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论