Prhub

#1915 fix(lora): honor --attention-backend in the bridge LoRA path

原始 PR 作者 yushengsu-thu 合并时间 2026-07-29 07:30 文件变更 2 提交数 1 评论 5 代码增减 +2 / -1

执行摘要

LoRA 桥接路径透传 attention-backend

PR body 明确指出:LoRA runs silently ignore --attention-backend_setup_lora_model_via_bridge never copies it onto the provider,unlike model_provider.py:78。Megatron 会把该字段映射为 NVTE_*_ATTN 环境变量,字段丢失后 TE 会自行选择调用者已经明确排除的后端,这正是 test_lora_qwen2.5_0.5B.py 在 fused-attention backward 上 nightly 崩溃的原因。另外 gpt-oss 使用 --softmax-type learnable,TE 2.17 下 FlashAttention 被禁用且无 fused kernel,只剩 UnfusedDotProductAttention 可用,原 CI 请求 fused 属于无效请求,因此改为 auto

值得快速浏览,无需精读。这是一次教科书式的参数透传遗漏修复:通过对比 model_provider.py 与 bridge 路径的差异定位根因,并同步修正了 CI 中不可能成功的参数请求。可关注的设计点是"一行修复 + 测试语义对齐"的最小 diff 实践,以及作者自我 review 移除注释保持提交简洁的做法。若团队有类似"批量复制参数到 provider"的代码,建议考虑加参数透传完整性校验或对照测试。

讨论亮点

作者 yushengsu-thu 在 diff hunk 上自我 review 留言 remove the comments,随后在回复中说明 Removed in 80df93674 — the PR is now the single assignment line.,将最初的三行解释性注释删除,最终提交只剩单行赋值。guapisolo 评论 let's wait for CI pass and then merge,作者回复 passed 后,guapisolo 给出 LGTM. 并 APPROVED,Zhichenzzz 也 APPROVED。Copilot 评审因请求者配额耗尽未能生效,实际审查由作者自查与两位维护者人工完成。

实现拆解

  1. 变更入口miles/backends/megatron_utils/bridge_lora_helpers.py_setup_lora_model_via_bridge,该函数集中把 args 上的并行度、重计算、激活显存等配置复制到 Megatron Bridge 返回的 provider 对象上,最后调用 provider.finalize()
  2. 核心变更:在 provider.distribute_saved_activations = args.distribute_saved_activations 之后、provider.variable_seq_lengths = True 之前插入一行 provider.attention_backend = args.attention_backend。这样 Megatron 才能把用户显式选择的注意力后端翻译成 NVTE_FLASH_ATTN / NVTE_FUSED_ATTN / NVTE_UNFUSED_ATTN 等开关;不透传时 TE 只能走启发式,本次修复让该参数在 LoRA 路径上真正生效。
  3. 测试配套tests/e2e/megatron/model_scripts/test_gpt_oss_20b_moe_lora_ci.pymisc_args 中把 --attention-backend fused 改为 --attention-backend auto。这是请求与 TE 实际能力对齐的必要修正,否则该 E2E 在 --softmax-type learnable 下永远不可能成功。
  4. diff 演进:最初提交还带了三行解释性注释,作者在 review 中自我要求移除(remove the comments),最终提交只保留单行赋值,形成最小 diff。本 PR 无新增 CLI 参数、无 schema 或构建配套改动,因为 args.attention_backend 早已存在。
文件 模块 状态 重要度
miles/backends/megatron_utils/bridge_lora_helpers.py LoRA 桥接 modified 4.75
tests/e2e/megatron/model_scripts/test_gpt_oss_20b_moe_lora_ci.py E2E 测试 modified 3.46

关键符号

_setup_lora_model_via_bridge execute

关键源码片段

miles/backends/megatron_utils/bridge_lora_helpers.py core-logic

核心修复文件:在 _setup_lora_model_via_bridge 的 provider 配置块中补上 attention_backend 透传,与 model_provider.py 对齐,修复 LoRA 路径静默忽略 --attention-backend 的问题。

# bridge_lora_helpers.py —— LoRA 桥接路径中把训练参数透传给 Megatron provider 的配置块。
# 此处集中复制并行度、重计算等配置;此前漏掉 attention_backend,导致 Megatron 无法生成
# NVTE_FLASH_ATTN / NVTE_FUSED_ATTN 等开关,TE 只能靠启发式自选后端。
provider.tensor_model_parallel_size = args.tensor_model_parallel_size
provider.pipeline_model_parallel_size = args.pipeline_model_parallel_size
provider.expert_model_parallel_size = args.expert_model_parallel_size
provider.sequence_parallel = args.sequence_parallel
provider.context_parallel_size = args.context_parallel_size
provider.gradient_accumulation_fusion = args.gradient_accumulation_fusion
provider.recompute_granularity = args.recompute_granularity
provider.recompute_method = args.recompute_method
provider.recompute_num_layers = args.recompute_num_layers
provider.distribute_saved_activations = args.distribute_saved_activations
# 本次修复新增:与 model_provider.py 对齐,让用户显式选择的注意力后端真正生效。
provider.attention_backend = args.attention_backend
provider.variable_seq_lengths = True
provider.moe_token_dispatcher_type = "alltoall"
provider.moe_router_load_balancing_type = "none"
# DSA 注意力有独立字段,按 args 上的 dsa_attention_backend 单独下发,互不影响。
if hasattr(provider, "dsa_attention_backend"):
    provider.dsa_attention_backend = getattr(args, "dsa_attention_backend", "megatron")
provider.finalize()

评论区精华

移除随行注释,保持最小 diff style

作者 yushengsu-thu 在 diff hunk 上留言 `remove the comments`,随后在回复中说明 `Removed in 80df93674 — the PR is now the single assignment line.`,最初的三行解释性注释被删除。

结论:最终提交只保留单行赋值 provider.attention_backend = args.attention_backend,注释全部移除。 · 已解决

等待 CI 通过后合入 other

guapisolo 评论 `let's wait for CI pass and then merge`,作者回复 `passed`。

结论:CI 通过后合入,guapisolo 与 Zhichenzzz 均 APPROVED,PR 已合并。 · 已解决

Copilot 评审未生效 other

copilot-pull-request-reviewer[bot] 报告 `Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.`

结论:无评审输出,审查由作者自查与两位维护者人工完成。 · 已解决

风险与影响

行为变更:LoRA 训练现在会真实遵循 --attention-backend,原本依赖 TE 启发式选择后端的任务,kernel 选择可能改变,需要留意训练速度与显存表现。兼容性:provider.attention_backend 属性依赖当前 Megatron Bridge 版本,虽然与 model_provider.py 用法一致,但升级 Bridge 后应回归验证。测试盲区:gpt-oss E2E 只覆盖 auto 分支,fused 分支在 TE 2.17 + learnable softmax 下不可用,qwen2.5 等其他模型的 fused LoRA 路径仍依赖 nightly 覆盖兜底。风险整体较低,因为改动是单行赋值且与既有主路径对齐。

影响所有走 bridge LoRA 路径的训练任务:显式指定注意力后端的用户将看到参数真正生效,不再被静默丢弃;对依赖 TE 启发式选择的存量任务,kernel 选择可能发生变化。对团队而言,修复了 main nightly 上一个已知崩溃来源,并让 gpt-oss 20B MoE LoRA CI 的请求与硬件/TE 能力对齐,避免永久性无效请求。改动面极小,风险可控。

TE 后端选择行为变更 E2E 仅覆盖 auto 分支 依赖 Bridge 字段存在

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论