Prhub

#49982 Fix MLA padding and grouped topk routing in the Transformers modelling backend

原始 PR 作者 hmellor 合并时间 2026-07-28 02:32 文件变更 5 提交数 6 评论 0 代码增减 +227 / -39

执行摘要

修复 MLA padding 和分组 topk 路由,扩展 Transformers 后端模型兼容性

Transformers 建模后端旨在支持原生 Hugging Face 模型进入 vLLM 的高性能执行路径,但当前实现存在若干错误导致多个流行 MoE 模型无法正常加载与推理。具体问题包括:MLA 架构中 value 投影头大小与 query/key 不同(如 DeepSeek-V2 的 128 vs 192),未 padding 时注意力计算错误;分组 topk 路由(如 DeepSeek-V3)因路由搜索锚点定位到错误的 topk 节点而被误判为非 router;use_grouped_topk 始终为 False 导致分组路由块被排除融合;缺少 routed_scaling_factor 的支持导致共享专家输出缩放异常。本 PR 目标就是修正这些问题,使主流 MoE 模型能够在 Transformers 后端中正确运行。

该 PR 值得业务开发者仔细阅读,特别是对 Transformers 后端或 MoE 融合感兴趣的同学。关键设计决策包括:使用 FX 图分析推断路由器精度、锚定最后一个 topk 节点以支持分组路由、以及通过 GateLinear 复用专用路由内核。这些方法对扩展 vLLM 模型支持很有借鉴意义。建议合并后关注相关模型的回归测试。

讨论亮点

该 PR 的 review 主要由 automation bot 和单一 reviewer 完成,无深入公开讨论。Isotr0py 在 review 中批准(Approved)该 PR,没有提出进一步修改要求。所有代码变更均来自作者 hmellor 的独立提交。

实现拆解

  1. 路由匹配改进:在 vllm/model_executor/models/transformers/fusers/moe.py 中,_match_router 方法现在接受包含 e_score_correction_bias 缓冲区的门控状态,并返回 (scoring_func, router_dtype) 元组。路由搜索锚定到图中最后一个 topk 节点,而不是第一个,从而正确识别先分组后路由的 DeepSeek 模式。新添 _forced_dtype 函数从 FX 图中读取显式类型转换,用于推断路由器计算精度。

  2. 融合参数传递:在 vllm/model_executor/models/transformers/moe.py 的 recursive_replace 中,现在读取 text_config 的 moe_router_dtype、routed_scaling_factor、n_group、topk_group 等字段,并构建 routed_scaling_factor_kwargs 和 grouped_topk_routing_kwargs 字典传入 FusedMoE。对于共享专家,将下投影层收集并交由 FusedMoE 进行规约,而非在共享专家内部独自规约。

  3. Gate 重建为 GateLinear:融合后,门控模块被重建为 GateLinear(若支持则使用专用路由 GEMM 内核),并设置 router_logits_dtype 以匹配原始模型精度。FusedMoE 的 router_logits_dtype 参数优先级为:moe_router_dtype → 从图中推断的 _forced_dtype → 激活数据类型。

  4. MLA 注意力 Padding:在 vllm/model_executor/models/transformers/__init__.py 的 vllm_attention_forward 中,检测 value 的最后一维是否小于 query/key 的头大小,若是则将 value 填充到 head_dim_qk,注意力计算后再切片回原始大小。这使得 MLA 模型(如 DeepSeek-V2)在禁用 MLA 专用实现(VLLM_MLA_DISABLE=1)时能够作为全注意力正常运行。

  5. 代码整理与告警:将 named_state 函数从 fusers/moe.py 迁移到 transformers/utils.py 作为通用工具。当 fp16 模型含有 routed_scaling_factor 与共享专家且未融合时,输出警告,提示用户该路径可能出错,避免了静默 fallback。

  6. 测试用例扩展:在 tests/models/transformers/fusers/test_moe.py 中新增 ScaledRouter、Fp32Router、GroupedRouter 等模拟路由器类,以及对应的测试函数验证缩放路由、分组路由、偏置校正路由、路由器精度推断等场景。CorrectionRouter 的预期行为从“拒绝”改为“匹配”,因为 e_score_correction_bias 现在被允许。

文件 模块 状态 重要度
vllm/model_executor/models/transformers/fusers/moe.py 路由融合 modified 8.65
vllm/model_executor/models/transformers/__init__.py 注意力 modified 6.66
vllm/model_executor/models/transformers/moe.py MoE 后端 modified 7.3
tests/models/transformers/fusers/test_moe.py 测试 modified 7.07
vllm/model_executor/models/transformers/utils.py 工具 modified 5.45

关键符号

_match_router _forced_dtype vllm_attention_forward recursive_replace named_state TransformersMoERunner.forward MoEBlockFuser.match

关键源码片段

vllm/model_executor/models/transformers/__init__.py core-logic

注意力前向函数增加 value padding,实现 MLA 兼容。

def vllm_attention_forward(
    module: 'torch.nn.Module',
    query: 'torch.Tensor',
    key: 'torch.Tensor',
    value: 'torch.Tensor',
    attention_mask: 'torch.Tensor',
    scaling: float | None = None,
    attention_instances: dict[int, 'Attention'] | None = None,
    **kwargs,
):
    self_attn = attention_instances[module.layer_idx]
    if scaling is not None:
        self_attn.impl.scale = float(scaling)
    hidden = query.shape[-2]
    head_dim_qk = query.shape[-1]
    head_dim_v = value.shape[-1]
    # MLA 兼容:value 头尺寸不足时补零
    query, key, value = (x.transpose(1, 2) for x in (query, key, value))
    query, key, value = (x.reshape(hidden, -1) for x in (query, key, value))
    if head_dim_v != head_dim_qk:
        value = F.pad(value.view(-1, head_dim_v), (0, head_dim_qk - head_dim_v))
        value = value.reshape(hidden, -1)
    attn_output = self_attn.forward(query, key, value)
    if head_dim_v != head_dim_qk:
        attn_output = attn_output.view(-1, head_dim_qk)[..., :head_dim_v]
        attn_output = attn_output.reshape(hidden, -1)
    return attn_output, None

评论区精华

无公开讨论 other

该 PR 无 review 评论,仅由 bot 自动回复和 reviewer 批准。

结论:PR 按时合并 · 已解决

风险与影响

主要技术风险包括:① 回归风险:_match_router 的锚点逻辑修改可能使某些非标准路由器被误判为 router。新增的状态白名单 {"weight", "e_score_correction_bias"} 覆盖了 DeepSeek 场景,但其他自定义 gate 可能被拒绝或错误匹配。② 性能风险:MLA padding 引入了额外的 F.pad 和 slice 操作,但影响较小(仅当 head_dim_v != head_dim_qk 时)。③ 数值精度风险:通过 FX 图推断 router_dtype 依赖于模式匹配,可能在某些复杂网关中失效,导致回退到默认精度,影响模型输出。④ 未融合告警:新增的 warning 可能产生噪声,但有助于发现问题。总体风险中等偏低,测试已覆盖主要场景。

对用户:启用 Transformers 后端(通过环境变量或配置文件)的用户现在可以加载和推理 DeepSeek-V2/V3、GLM-4.5、Qwen2.5-MoE 等 MoE 模型,大大扩展了该后端的模型支持范围。对系统:新增了参数传递和逻辑分支,但不会影响原生 MoE 后端路径。对团队:维护了更清晰的路由匹配逻辑和参数传递方式,降低了后续添加新模型的门槛。

FX 图分析脆弱性 MLA padding 引入新路径 未覆盖的分组配置 警告可能含噪声

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论