Prhub

#26710 Fix MoE LoRA wrapper exposing moe_runner_config

原始 PR 作者 huangtingwei9988 合并时间 2026-05-30 16:59 文件变更 1 提交数 1 评论 1 代码增减 +1 / -0

执行摘要

修复 MoE LoRA 缺少 moe_runner_config 属性导致崩溃

PR #25379 为 DeepSeek/Kimi MoE 前向路径引入了 self.mlp.experts.moe_runner_config.inplace 的直接访问,目的是复用前一层输出作为 FP4 routed MoE 的 symm_output 以减少内存分配。然而当 MoE LoRA 启用时,self.mlp.expertsFusedMoEWithLoRA 包装,该包装器未定义 moe_runner_config 属性,导致在 CUDA graph 捕获阶段抛出 AttributeError。作者在 PR body 中提供了错误截图,并明确说明是 #25379 引入的回归。

作为关键回归修复,建议合并并同步至相关发布分支。该 PR 值得所有使用 MoE LoRA 场景的读者关注,其修复方式也为类似属性透传问题提供了参考模式。

讨论亮点

Review 过程中,gemini-code-assist[bot] 执行了自动化代码审查但未提出具体修改意见。ch-wan 直接批准了该 PR,未留额外评论。整体讨论极少,变更清晰且无争议。

实现拆解

FusedMoEWithLoRA.__init__ 方法的属性初始化部分,于 self.quant_method = base_layer.quant_method 之后新增一行 self.moe_runner_config = base_layer.moe_runner_config。该变更仅 1 行,将底层 FusedMoE 实例的 moe_runner_config 对象直接赋值给包装器实例,使得外部代码(如 deepseek_v2.py 等模型文件)可以通过 self.mlp.experts.moe_runner_config 正常访问配置,例如检查 inplace 标志。

文件 模块 状态 重要度
python/sglang/srt/lora/layers.py LoRA modified 5.15

关键符号

FusedMoEWithLoRA.__init__

关键源码片段

python/sglang/srt/lora/layers.py core-logic

在 `FusedMoEWithLoRA` 类初始化中添加一行属性透传,是修复的核心位置。

class FusedMoEWithLoRA(BaseLayerWithLoRA):
    """Wrapper around FusedMoE that integrates LoRA into the MoE computation."""
​
    def __init__(
        self,
        base_layer: FusedMoE,
        lora_backend: BaseLoRABackend,
    ):
        super().__init__(base_layer, lora_backend)
​
        lora_backend.is_moe_lora = True
​
        self.experts_shared_outer_loras: bool = False
        self.lora_use_virtual_experts: bool = False
        self.quant_method = base_layer.quant_method
        # 将底层 FusedMoE 的 moe_runner_config 透传给包装器
        # 修复 #25379 引入的回归:外部代码直接访问 self.mlp.experts.moe_runner_config
        self.moe_runner_config = base_layer.moe_runner_config
​
        self.tp_size = getattr(base_layer, "moe_tp_size", 1)
        self.tp_rank = getattr(base_layer, "moe_tp_rank", 0)
        self.intermediate_size_per_partition = getattr(
            base_layer, "intermediate_size_per_partition", None
        )
        self._uses_interleaved_gate_up = (
            getattr(base_layer.moe_runner_config, "gemm1_alpha", None) is not None
        )

评论区精华

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

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

风险与影响

风险极低。同一对象引用(base_layer.moe_runner_config)的赋值不会引入数据不一致或性能问题。但不排除未来其他包装器类也需要类似透传,团队应注意保持一致性。

直接影响所有启用 MoE LoRA 的模型(如 DeepSeek-V2/V3、Kimi K2.5),修复其在 CUDA graph 捕获时的崩溃问题,使 LoRA 与 MoE 量化(如 FP4)可以正常共存。

回归修复 单行改动

关联 Issue

#25379 feat(moe): reuse prev-layer output as symm_output for FP4 routed MoE

完整报告

参与讨论