执行摘要
- 一句话:LoRA 桥接路径透传 attention-backend
- 推荐动作:值得快速浏览,无需精读。这是一次教科书式的参数透传遗漏修复:通过对比 model_provider.py 与 bridge 路径的差异定位根因,并同步修正了 CI 中不可能成功的参数请求。可关注的设计点是"一行修复 + 测试语义对齐"的最小 diff 实践,以及作者自我 review 移除注释保持提交简洁的做法。若团队有类似"批量复制参数到 provider"的代码,建议考虑加参数透传完整性校验或对照测试。
功能与动机
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。
实现拆解
- 变更入口:
miles/backends/megatron_utils/bridge_lora_helpers.py 的 _setup_lora_model_via_bridge,该函数集中把 args 上的并行度、重计算、激活显存等配置复制到 Megatron Bridge 返回的 provider 对象上,最后调用 provider.finalize()。
- 核心变更:在
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 路径上真正生效。
- 测试配套:
tests/e2e/megatron/model_scripts/test_gpt_oss_20b_moe_lora_ci.py 的 misc_args 中把 --attention-backend fused 改为 --attention-backend auto。这是请求与 TE 实际能力对齐的必要修正,否则该 E2E 在 --softmax-type learnable 下永远不可能成功。
- diff 演进:最初提交还带了三行解释性注释,作者在 review 中自我要求移除(
remove the comments),最终提交只保留单行赋值,形成最小 diff。本 PR 无新增 CLI 参数、无 schema 或构建配套改动,因为 args.attention_backend 早已存在。
关键文件:
miles/backends/megatron_utils/bridge_lora_helpers.py(模块 LoRA 桥接;类别 source;类型 core-logic;符号 _setup_lora_model_via_bridge): 核心修复文件:在 _setup_lora_model_via_bridge 的 provider 配置块中补上 attention_backend 透传,与 model_provider.py 对齐,修复 LoRA 路径静默忽略 --attention-backend 的问题。
tests/e2e/megatron/model_scripts/test_gpt_oss_20b_moe_lora_ci.py(模块 E2E 测试;类别 test;类型 test-coverage;符号 execute): 测试配套:把 gpt-oss 20B MoE LoRA CI 的 --attention-backend 从 fused 改为 auto,与 TE 2.17 + learnable softmax 下无 fused kernel 的实际能力对齐。
关键符号:_setup_lora_model_via_bridge, execute
关键源码片段
miles/backends/megatron_utils/bridge_lora_helpers.py
核心修复文件:在 _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()
评论区精华
作者 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 评审因请求者配额耗尽未能生效,实际审查由作者自查与两位维护者人工完成。
- 移除随行注释,保持最小 diff (style): 最终提交只保留单行赋值 provider.attention_backend = args.attention_backend,注释全部移除。
- 等待 CI 通过后合入 (other): CI 通过后合入,guapisolo 与 Zhichenzzz 均 APPROVED,PR 已合并。
- Copilot 评审未生效 (other): 无评审输出,审查由作者自查与两位维护者人工完成。
风险与影响
- 风险:行为变更: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 字段存在
关联脉络
- PR #1794 feat(multi-lora): enable and validate MoE expert adapters: 改动了同一文件 miles/backends/megatron_utils/bridge_lora_helpers.py,同属 LoRA bridge 功能线;本 PR 补上了该路径参数透传的遗漏。
- PR #1928 [fix] DSA indexer on Blackwell: send the DSA indexer wk unquantized: 同为 Megatron 后端注意力路径修复,与本 PR 中 dsa_attention_backend 分支相邻,体现对注意力后端配置一致性的持续修补。
参与讨论