Prhub

#43770 [Bugfix] fix wrong partial_rotary_factor calculation for bailing_moe model.

原始 PR 作者 zzt93 合并时间 2026-06-01 17:42 文件变更 1 提交数 3 评论 9 代码增减 +6 / -1

执行摘要

修复 Bailing MoE 模型中 partial_rotary_factor 计算错误

Ling-flash-2.0 和 AntAngelMed 等模型的 config 中只有 partial_rotary_factor=0.5 而没有 rotary_dim,旧代码直接回退到 head_dim 并计算出 partial_rotary_factor=1,导致 Ascend NPU(vllm-ascend)上 _cos_sin_cache 初始化尺寸错误,引发异常。详见 PR body 中的配置链接和异常截图。

值得精读,以了解模型配置优先级处理的常见模式。关注点是:优先使用显式字段(rotary_dim),其次使用派生字段(partial_rotary_factor),最后使用默认回退(head_dim)。该模式可推广到其他模型实现。

讨论亮点

xianbaoqian 在 review 中指出第 137 行的 if rotary_dim is None: 检查是死代码(因为上一行 int(self.head_dim * partial_rotary_factor) 不会产生 None),作者 zzt93 回应这是防御性代码以防 config 未来变化导致异常,并同意必要时可删除。最终保留该行,但未产生实际影响。

实现拆解

  1. 修改回退优先级:在 vllm/model_executor/models/bailing_moe.py__init__ 中,将 rotary_dim = getattr(config, "rotary_dim", self.head_dim) 改为先尝试读取 rotary_dim,若为 None 则从 config.partial_rotary_factor 计算 rotary_dim
  2. 保留防御性回退:即使上述计算后 rotary_dim 仍为 None,则回退到 self.head_dim,确保极端配置下的鲁棒性。
  3. 更新 rope_parameters:无论哪种路径,最后仍按 rotary_dim / self.head_dim 设置 config.rope_parameters['partial_rotary_factor'],保持与下游 get_rope 的接口一致。
  4. 无其他文件变更:本次修改仅涉及单文件 6 行新增、1 行删除,没有测试、配置或部署配套改动。
文件 模块 状态 重要度
vllm/model_executor/models/bailing_moe.py 模型执行器 modified 6.01

关键源码片段

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

修复了 rotary_dim 计算逻辑,是本次变更的唯一文件。

# 位于 __init__ 方法中,构建 rotary embedding 之前
# 原逻辑 : rotary_dim = getattr(config, "rotary_dim", self.head_dim)
# 导致当 config 没有 rotary_dim 时,partial_rotary_factor 总是被设为 1.0# 新逻辑:优先使用 config 中的 rotary_dim
rotary_dim = getattr(config, "rotary_dim", None)# 如果 config 没有 rotary_dim,则从 partial_rotary_factor 计算
if rotary_dim is None:
    partial_rotary_factor = getattr(config, "partial_rotary_factor", 1.0)
    rotary_dim = int(self.head_dim * partial_rotary_factor)# 防御性回退:如果仍未定义,则默认使用 head_dim
if rotary_dim is None:
    rotary_dim = self.head_dim# 更新 rope_parameters,与下游 get_rope 接口保持一致
config.rope_parameters["partial_rotary_factor"] = rotary_dim / self.head_dimself.rotary_emb = get_rope(
    self.head_dim,
    max_position=config.max_position_embeddings,
    rope_parameters=config.rope_parameters,
    is_neox_style=True,
)

评论区精华

死代码检查 正确性

xianbaoqian 指出第 137 行 `if rotary_dim is None` 在当前的逻辑下不会触发,因为是死代码。作者 zzt93 回应这是防御性代码,以防未来 config 变化,且同意可删除。

结论:保留该防御性代码,但实际不会被执行。 · 已解决

风险与影响

风险极低:改动仅影响 rotary_dim 的计算逻辑,且优先读取 config 中明确设置的字段,兼容原有配置(如 Ring-1T 同时设置了 rotary_dim)。防御性回退保证了极端情况不会崩溃。但缺少测试覆盖可能让未来重构时忽略此行为。

直接影响:修复了 Ling-flash-2.0 和 AntAngelMed 等模型在 Ascend NPU 上的启动失败。影响范围限于 Bailing MoE 模型,不影响其他模型或通用路径。对已有配置的 Ring-1T 等模型无副作用。

缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论