Prhub

#6626 [megatron] fix: propagate disabled MTP config to bridge providers

原始 PR 作者 Mengyuyang 合并时间 2026-06-10 18:08 文件变更 1 提交数 1 评论 2 代码增减 +13 / -9

执行摘要

修复禁用 MTP 时 bridge provider 重新启用问题

在非标准的 Megatron-Bridge provider 中,模型配置会从 local_path 重载,此时 Hugging Face 配置中的 MTP 字段可能仍然存在,导致 MTP 被重新启用。需要在 check_mtp_config 中强制覆盖 provider 配置。

值得精读,尤其是 check_mtp_config 函数的设计模式。它展示了如何处理多 provider 架构下的配置一致性,以及如何通过 override_transformer_config 强制覆盖下游配置。

讨论亮点

Gemini Code Assist 机器人建议对 engine_config.override_transformer_config 进行防御性初始化,避免其为 None 时引发异常。但该建议未被采纳(评论未解决),可能是由于在实际使用中 override_transformer_config 总是被初始化为字典。

实现拆解

  1. 修复 _set_mtp_num_layers 中的条件逻辑:将 elif 改为 if,确保所有相关的 MTP 字段(num_nextn_predict_layers、mtp_num_hidden_layers 和 text_config.mtp_num_hidden_layers)都被清理,而不是只清理第一个匹配的字段。
  2. 简化 check_mtp_config 的分支逻辑:将原来的 if not enable_mtp and not has_mtp / elif not enable_mtp and has_mtp 两个分支合并为一个 if not enable_mtp 分支,统一处理禁用 MTP 的情况。
  3. 强制覆盖 provider 配置:在禁用 MTP 时,设置 engine_config.override_transformer_config["mtp_num_layers"] = None,并移除 mtp_loss_scaling_factor 键,确保所有 bridge provider 都收到禁用 MTP 的信号。
  4. 启用 MTP 但模型无 MTP 层时抛出异常:保持原有的 ValueError 逻辑。
  5. 启用 MTP 且有 MTP 层时配置 override:保持原有的 mtp_loss_scaling_factor 设置逻辑。
文件 模块 状态 重要度
verl/utils/megatron_utils.py 训练工具 modified 6.0

关键符号

_set_mtp_num_layers check_mtp_config

关键源码片段

verl/utils/megatron_utils.py core-logic

核心变更文件,修改了 MTP 配置检查和清理逻辑,影响所有非标准 Megatron-Bridge provider 的行为

def _set_mtp_num_layers(hf_config, value: int):
    """清理 Hugging Face 配置中的所有 MTP 相关字段。
    注意:使用 `if` 而不是 `elif`,可能同时存在 `num_nextn_predict_layers` 和 `mtp_num_hidden_layers` 字段。"""
    if hasattr(hf_config, "num_nextn_predict_layers"):
        hf_config.num_nextn_predict_layers = value
    # 修复:之前为 elif,导致只有第一个匹配字段被清理
    if hasattr(hf_config, "mtp_num_hidden_layers"):
        hf_config.mtp_num_hidden_layers = value
    if hasattr(hf_config, "text_config") and hasattr(hf_config.text_config, "mtp_num_hidden_layers"):
        hf_config.text_config.mtp_num_hidden_layers = value
​
​
def check_mtp_config(model_config: HFModelConfig, engine_config: McoreEngineConfig):
    hf_config = model_config.hf_config
    mtp_num_layers = _get_mtp_num_layers(hf_config)
    has_mtp = mtp_num_layers > 0
    enable_mtp = model_config.mtp.enable
​
    if not enable_mtp:
        # 无论模型是否有 MTP 层,都清理 HF 配置
        _set_mtp_num_layers(hf_config, 0)
​
        # 强制覆盖 provider 配置,防止非标准 bridge provider
        # 从 local_path 重载配置后重新启用 MTP
        engine_config.override_transformer_config["mtp_num_layers"] = None
        engine_config.override_transformer_config.pop("mtp_loss_scaling_factor", None)
        return
​
    elif enable_mtp and not has_mtp:
        raise ValueError("enable mtp while model has no mtp layer, please use a model with mtp layer")
    elif enable_mtp and has_mtp:
        if "mtp_loss_scaling_factor" not in engine_config.override_transformer_config:
            engine_config.override_transformer_config["mtp_loss_scaling_factor"] = (
                model_config.mtp.mtp_loss_scaling_factor
            )

评论区精华

override_transformer_config 防御性初始化 正确性

Gemini Code Assist 机器人建议在访问 `engine_config.override_transformer_config` 前检查是否为 `None`,并初始化为空字典,以避免潜在的类型错误。

结论:该建议未被最终采纳,可能因为在实际使用中该字段总是被初始化为字典,或者开发者认为不需要额外检查。 · unresolved

风险与影响

主要风险在于 override_transformer_config 可能为 None,导致 engine_config.override_transformer_config["mtp_num_layers"] = None 抛出异常。不过根据上下文,该字段在正常流程中通常已被初始化。此外,禁用 MTP 时强制设置 mtp_num_layers=None 可能会影响其他依赖该字段的代码路径,需要确保所有地方都能正确处理 None 值。

直接影响使用非标准 Megatron-Bridge provider(如第三方桥接实现)的用户,确保禁用 MTP 的配置被正确传播。对标准 Megatron 用户无影响,因为标准路径不会重新从 local_path 加载配置。修复后避免了因 MTP 意外启用导致的训练错误或性能下降。

配置覆盖风险 桥接 provider 兼容性

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论