Prhub

#1889 fix qwen3.6 hf config validation bug

原始 PR 作者 zhuzilin 合并时间 2026-05-06 13:22 文件变更 1 提交数 1 评论 0 代码增减 +38 / -0

执行摘要

修复 Qwen3.6 HF 配置校验 MoE bug

原有的 HF 配置校验逻辑默认所有模型都包含 intermediate_size 字段,但 Qwen3.6 使用 MoE 架构,其 HuggingFace 配置中不暴露该字段,导致校验失败(AssertionError)。本 PR 旨在统一 MoE 和 Dense 模型的校验逻辑,避免因模型架构差异触发误报。

建议精读本 PR,理解 MoE / dense 混合模型的配置校验设计。重点关注 _has_dense_moe_layers 的逻辑,以及它在 _hf_validate_args 中的语义——它控制是否跳过 dense FFN 尺寸校验。可以考虑以后补充单元测试。

讨论亮点

无 review 讨论。

实现拆解

  1. 新增 _is_moe_config 函数(第31-40行):通过检测 HuggingFace 配置中是否存在 moe_intermediate_sizenum_expertsn_routed_expertsnum_local_experts 等属性来判断模型是否为 MoE 架构。
  2. 新增 _has_dense_moe_layers 函数(第14-28行):解析 moe_layer_freq 参数,判断当前配置是否包含 dense 层(值为0的层为 dense);如果全为 MoE 层则返回 False。
  3. 条件跳过 dense FFN 校验(第96-97行):在 _hf_validate_args 的校验循环中,若 hf_config_name == "intermediate_size"validate_dense_ffn 为 False,则跳过该项对比。其中 validate_dense_ffn = not _is_moe_config(hf_config) or _has_dense_moe_layers(args)
  4. 新增 MoE 配置项校验(第90-91行):在循环中增加 ("moe_intermediate_size", "moe_ffn_hidden_size", equal)("shared_expert_intermediate_size", "moe_shared_expert_intermediate_size", equal) 对比条目,确保 MoE 模型的专家维度得到验证。
  5. 依赖调整:新增 import ast 以支持字符串形式的 moe_layer_freq 解析。
文件 模块 状态 重要度
slime/backends/megatron_utils/arguments.py 参数校验 modified 7.44

关键符号

_has_dense_moe_layers _is_moe_config _hf_validate_args

关键源码片段

slime/backends/megatron_utils/arguments.py dependency-wiring

唯一修改的文件,包含所有核心变更:新增两个辅助函数、修改校验循环、新增 MoE 配置项对比。

import ast
import logging
# ...def _has_dense_moe_layers(args):
    """判断配置中是否包含 dense MoE 层(即 moe_layer_freq 中存在 0)"""
    moe_layer_freq = getattr(args, "moe_layer_freq", None)
    if moe_layer_freq is None:
        return True # 默认认为有 dense 层
​
    if isinstance(moe_layer_freq, str):
        try:
            moe_layer_freq = ast.literal_eval(moe_layer_freq) # 例如 "[0,1]"
        except (SyntaxError, ValueError):
            return "0" in moe_layer_freq # 兜底:检查字符串是否包含 "0"
​
    try:
        return any(int(layer_freq) == 0 for layer_freq in moe_layer_freq)
    except TypeError:
        return int(moe_layer_freq) == 0 # 单个整数
​
​
def _is_moe_config(hf_config):
    """通过 HuggingFace 配置属性判断是否为 MoE 模型"""
    return any(
        hasattr(hf_config, attr)
        for attr in (
            "moe_intermediate_size",
            "num_experts",
            "n_routed_experts",
            "num_local_experts",
        )
    )def _hf_validate_args(args, hf_config):
    # ... 原有逻辑 ...
​
    # 决定是否验证 dense FFN 的 intermediate_size
    validate_dense_ffn = not _is_moe_config(hf_config) or _has_dense_moe_layers(args)
​
    for hf_config_name, megatron_config_name, compare_fn in [
        # ... 原有对比项 ...
        ("intermediate_size", "ffn_hidden_size", equal),
        # MoE 特定项
        ("moe_intermediate_size", "moe_ffn_hidden_size", equal),
        ("shared_expert_intermediate_size", "moe_shared_expert_intermediate_size", equal),
        # ... 其余项 ...
    ]:
        if hf_config_name == "intermediate_size" and not validate_dense_ffn:
            continue # 对纯 MoE 模型跳过 dense 尺寸校验
​
        if hasattr(hf_config, hf_config_name) and hasattr(args, megatron_config_name):
            if not compare_fn(getattr(hf_config, hf_config_name), getattr(args, megatron_config_name)):
                errors.append(...)
    # ... 后续逻辑 ...

评论区精华

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

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

风险与影响

  • 回归风险:修改了 _hf_validate_args 的核心校验循环,如果没有 MoE 模型测试覆盖,可能引入回归;需确保非 MoE 模型(如 Qwen2.5、GLM4)的校验行为不变。
  • 配置边界_has_dense_moe_layersmoe_layer_freq 字符串解析依赖 ast.literal_eval,若用户配置格式不规范可能解析异常,代码有 fallback 但逻辑较脆弱。
  • 缺少单元测试_has_dense_moe_layers_is_moe_config 没有直接对应的测试文件,后续依赖此功能的模型若配置变化可能未被及时发现。
  • 用户影响:解决 Qwen3.6 等 MoE 模型在 slime 框架下运行时的配置校验阻断问题,提升 MoE 模型兼容性。
  • 系统影响:仅修改 slime/backends/megatron_utils/arguments.py 一个文件,影响面小,但校验逻辑变更可能影响所有通过 _hf_validate_args 的模型初始化。
  • 团队影响:为 MoE 配置校验提供了通用模式,便于后续新增 MoE 模型时复用。
缺少测试覆盖 配置解析脆弱

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论