Prhub

#47410 support GLM-5.2 gate use FP32

原始 PR 作者 zRzRzRzRzRzRzR 合并时间 2026-07-02 22:45 文件变更 2 提交数 1 评论 0 代码增减 +19 / -0

执行摘要

GLM-5.2 MoE 门控强制使用 FP32 路由

GLM-5.2 模型配置(glm_moe_dsa)没有暴露 moe_router_dtype,但其 MoE 路由需要 FP32 计算。原作者在 PR body 中说明“support GLM-5.2 gate use FP32”,直接点明动机。

推荐精读。这是一个小而精的适配性修复,展示了在 vLLM 中如何优雅地处理模型变体的特殊配置。关键设计点:

  • 集中路由类型判断逻辑到一个函数 _get_moe_router_dtype,易于扩展。
  • 利用 force_fp32_compute 统一处理 fallback,而不需要改动下游 kernel 选择逻辑。
  • allow_dsv3_router_gemm 的条件修复也值得关注,说明谨慎的 kernel 路径前置检查是必要的。
讨论亮点

无 review 评论。PR 被 ywang96 直接 approve,表明改动简单明确。claude[bot] 的自动回复仅说明 fork PR 需人工审核。

实现拆解

  1. 新增 _get_moe_router_dtype 函数 (文件 deepseek_v2.py):根据 config 的 model_type 是否为 glm_moe_dsamoe_router_dtype 是否为 "float32",决定返回 torch.float32None。这个函数作为集中决策点,避免了在多个地方重复判断。

  2. 修改 DeepseekV2MoE.__init__ (同上):调用 _get_moe_router_dtype,并将结果作为 params_dtypeout_dtypeforce_fp32_compute 传给 GateLinear 构造器。当 router_dtypetorch.float32 时,force_fp32_compute=True 会触发 GateLinear 内部的 FP32 fallback(若没有专用 kernel)。

  3. 补充条件守卫 self.gate.out_dtype is None (同上):在 ROCm Aiter MoE 融合路径中,若 out_dtype 已被外部设置(如本 PR),则跳过 set_out_dtype,避免重复覆盖。

  4. 修复 GateLinear.__init__allow_dsv3_router_gemm 的条件 (文件 gate_linear.py):增加 self.weight.dtype == torch.bfloat16 检查,确保只有 BF16 权重才会启用 DSV3 专用 kernel,避免 FP32 权重错误使用该 kernel 路径。

  5. 无测试/配置/部署配套变更:本次改动完全属于源码适配,未引入新测试或配置项。

文件 模块 状态 重要度
vllm/model_executor/models/deepseek_v2.py 模型加载 modified 7.0
vllm/model_executor/layers/fused_moe/router/gate_linear.py MoE 内核 modified 4.79

关键符号

_get_moe_router_dtype

关键源码片段

vllm/model_executor/models/deepseek_v2.py data-contract

核心修改:新增 `_get_moe_router_dtype` 函数,修改 `DeepseekV2MoE.__init__` 传递路由精度参数给 `GateLinear`。

# vllm/model_executor/models/deepseek_v2.py# ... (imports 省略 )def _get_moe_router_dtype(
    config: DeepseekV2Config | DeepseekV3Config,
) -> torch.dtype | None:
    """根据模型配置决定 MoE 路由器权重和计算的精度。    GLM-5.2 (`glm_moe_dsa`) 强制使用 FP32,
    其他模型若配置了 `moe_router_dtype="float32"` 也返回 FP32,
    其余情况返回 `None`(使用默认精度)。
    """
    router_dtype = getattr(config, "moe_router_dtype", None)
    if getattr(config, "model_type", None) == "glm_moe_dsa":
        # Older GLM-5/5.2 configs require fp32 routing but do not expose
        # moe_router_dtype yet.
        return torch.float32
    if router_dtype == "float32":
        return torch.float32
    return Noneclass DeepseekV2MoE(nn.Module):
    def __init__(self, config, parallel_config, quant_config=None, prefix=""):
        # ... 其他初始化代码 ...
​
        # 获取路由精度,None 表示用默认精度(通常是 BF16)
        self.router_dtype = _get_moe_router_dtype(config)
​
        self.gate = GateLinear(
            config.hidden_size,
            config.n_routed_experts,
            params_dtype=self.router_dtype, # 权重精度
            out_dtype=self.router_dtype, # 输出精度
            force_fp32_compute=self.router_dtype == torch.float32, # 强制 FP32 计算
            prefix=f"{prefix}.gate",
        )
        # ... 后续代码 ...
​
        if (
            self.is_rocm_aiter_moe_enabled
            and self.gate.e_score_correction_bias is not None
            and self.gate.out_dtype is None # 新增:若 out_dtype 已设定,不覆盖
        ):
            # Accumulates in fp32; avoids bf16->fp32 cast.
            self.gate.set_out_dtype(self.gate.weight.dtype)
vllm/model_executor/layers/fused_moe/router/gate_linear.py data-contract

修复 `allow_dsv3_router_gemm` 条件,增加 `weight.dtype == torch.bfloat16` 检查,防止 FP32 权重误用 DSV3 专用 kernel。

# vllm/model_executor/layers/fused_moe/router/gate_linear.pyclass GateLinear(ReplicatedLinear):
    # ... 类定义 ...
​
    def __init__(self, ..., force_fp32_compute=False, ...):
        # ... 前置代码 ...
​
        self.allow_dsv3_router_gemm = (
            self.allow_specialized_router_gemm
            and self.weight.dtype == torch.bfloat16 # 新增:只有 BF16 权重才能用此 kernel
            and output_size in self.DSV3_SUPPORTED_NUM_EXPERTS
            and input_size in self.DSV3_SUPPORTED_HIDDEN_SIZES
            and (input_size, output_size) not in self.DSV3_UNSUPPORTED_SHAPES
        )
        # ... 后续代码 ...

评论区精华

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

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

风险与影响

低风险。改动仅影响 glm_moe_dsa 类型模型的路由器行为,且修改都是条件性添加:

  • 回归风险:对于非 glm_moe_dsa 模型,_get_moe_router_dtype 返回 None,行为与之前完全一致。
  • 性能风险:FP32 计算可能略慢,但这是正确性前提,且只有 GLM-5.2 模型会走此路径。
    • 无安全/兼容性问题

仅影响 GLM-5.2(glm_moe_dsa 模型类型)用户。他们现在可以正确加载并使用该模型,MoE 路由不再因精度问题导致数值错误。对其他模型和系统无影响。

低风险 无测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论