feat(megatron): handle zero-token no-signal steps in the shared trainer - #285
Open
xcosmosbox wants to merge 4 commits into
Open
feat(megatron): handle zero-token no-signal steps in the shared trainer#285xcosmosbox wants to merge 4 commits into
xcosmosbox wants to merge 4 commits into
Conversation
xcosmosbox
requested review from
NINGBENZHE,
Yangruipis and
yxyOo
as code owners
August 19, 2026 08:49
xcosmosbox
marked this pull request as draft
August 20, 2026 02:58
…ection The original implementation unconditionally broadcast the zero-token decision over the pipeline-model-parallel group, but that group does not contain global rank 0 in PP=1 topologies, causing a collective mismatch deadlock (rank 0 ValueError + other ranks stuck in optimizer all-reduce) that tripped the global restart path. With PP=1 every rank is the last pipeline stage and joins the same DP+CP all-reduce, so the local count is already consistent and no broadcast is needed. Add regression tests for PP=1 (no broadcast) and PP>1 (last stage broadcasts, non-last stages join).
xcosmosbox
marked this pull request as ready for review
August 20, 2026 03:08
Contributor
Author
|
All changes are ready, awaiting your review to merge @NINGBENZHE |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
为共享 Megatron 训练器增加 zero-token no-signal step 的完整处理:空/全 mask response 的 token 计数口径(CP=1 与 CP>1 一致)、全 batch 无有效 loss token 时的指标归零与 fail-fast,以及全局零 token step 跳过 optimizer 与 LR scheduler 更新。
这是此前在 #205 中实现、后按 review 意见回退的 shared 基础设施改动,现按要求建议独立成 PR,方便内部做全量算法 CE 验证。
Why
当前共享训练路径对"空/全 mask response"存在两处语义不一致与一个数值风险:
get_cp_local_num_tokens()在 CP=1 时对每个样本使用历史 per-sampleclamp_min(loss_mask.sum(), 1)(空 response 计 1 个 token),而 CP>1 路径按真实 unmasked token 计数(空 response 计 0)。同一份数据在 CP=1 与 CP>1 下会得到不同的 loss denominator,从而产生不同的 loss/gradient。0 * logits.sum()零连接,梯度恒为 0;但 optimizer.step() 仍会通过 Adam momentum / weight decay 移动参数,并推进 LR scheduler,在没有任何训练信号的情况下改变模型状态。这些是共享 Megatron 基础设施问题,不限于 RLOO 算法;本 PR 将其作为独立基础设施改动处理。
How
relax/backends/megatron/cp_utils.py):get_cp_local_num_tokens()在 CP=1 时改为按真实loss_mask.sum()计数,空/全 mask response 贡献0,与 CP>1 的 global valid-token denominator 语义一致。relax/backends/megatron/loss.py、model.py):normalize_reduced_loss_metrics():denominator 为 0 且所有 numerator 为 0 时按 no-signal step 报告全零指标;denominator 为 0 但存在非零 numerator 时 fail-fast(提示 reducer 不一致),不再静默除零。relax/backends/megatron/model.py):_is_global_zero_token_step():在 pipeline last stage 上对 DP+CP 组 all-reduce 全 batch 有效 token 总数;PP=1 时所有 rank 均为 last stage、归约结果本地一致,直接本地判定;PP>1 时 last stage 沿 pipeline 组 broadcast 决策、非 last stage 加入 broadcast 完成 collective。各 rank 一致决定跳过 optimizer 与 LR scheduler 更新;跳过时grad_norm=0.0上报,不改变正常 step 路径的任何行为。get_pipeline_model_parallel_group()在 PP=1 拓扑下不含 global rank 0(relax 既有代码hf_weight_iterator_direct.py同样以pp_size > 1保护后才使用该组),无条件广播会导致 rank 0ValueError+ 其余 rank 卡在 optimizer all-reduce 的 collective 失配死锁(真实双卡训练首个 step 即复现,已修复并由回归测试锁定)。relax/backends/megatron/loss.py):get_responses()对response_length == 0返回空切片(logits[0:0]/tokens[0:0]),避免tokens[-0:]取到完整 prompt 的边界错误。Testing
pre-commit runpasses(本次修改文件:ruff、ruff-format、docformatter、check-conflict-markers 等全部通过)验证摘要(本地,基于最新 main):
65 passed。_is_global_zero_token_step纯函数:全零 vs 非零 token 的判定(monkeypatch 分布式原语)。_is_global_zero_token_step分布式契约回归:PP=1 断言 broadcast 零调用(all-reduce 后本地判定);PP>1 断言 last stage 广播(src=pp_size-1)、非 last stage 加入广播。_is_global_zero_token_step(PP=1 路径),无 collective 失配;正常数据未误触发 zero-token 跳过(无zero effective loss tokens警告)。train_one_step集成:全局零 token step 断言 optimizer.step 与 LR scheduler 均未被调用、grad_norm == 0.0。response_length == 0的最终 scalar loss / gradient oracle,覆盖生产loss_function()的 reducer 与 Megatron token normalizer。get_responses()CP=1 空 response 返回匹配的空 chunks。Type of Change
Risk & Rollback
get_cp_local_num_tokens()是共享函数,CP=1 下空/全 mask response 的计数从1变为0,会影响所有算法在"存在空 response"时的 loss denominator;正常(非空)训练路径数值完全不变。Training step %d has zero effective loss tokens globally观测。Checklist