fix(megatron): pass delegation flags on the presharded train path - #3859
Open
rohitrango wants to merge 1 commit into
Open
fix(megatron): pass delegation flags on the presharded train path#3859rohitrango wants to merge 1 commit into
rohitrango wants to merge 1 commit into
Conversation
`_train_microbatch_body` called `get_microbatch_iterator` without
`delegate_pack_to_model`, `delegate_mtp_loss_mask_to_model`, or
`model_slices_context_parallel_inputs`. The other three call sites in this
file (logprob and non-presharded train) all pass them. They default to
False, so on the presharded path a model that declares
`model_slices_context_parallel_inputs=True` had that silently ignored.
For a model that slices its own CP inputs (Nemotron Omni) with CP>1 the
effect was:
`_prepare_prepacked_batch_for_megatron` handed the model the CP-local
slice (65536/4 = 16384 tokens) while `PackedSeqParams.cu_seqlens_q_padded`
stayed global at 65536. The model, which slices its own CP inputs after
media insertion, then sliced again. `tex.thd_get_partitioned_indices`
built indices into a 65536 stream against a 16384 tensor, so
`index_select` ran off the end:
Assertion `idx_dim >= 0 && idx_dim < index_size &&
"scatter gather kernel index out of bounds"` failed.
CUDA reports that asynchronously, so it surfaced in an unrelated later
kernel (mamba in_proj RMSNorm), which made it look like a model bug.
Any recipe that goes through the presharded/TQ train path was affected, so
CP>1 was unusable there for such models. Note TQ itself is not involved in
the sharding: `tq_policy.py` marks context_parallel as a replicated axis.
Verified on a Nemotron Omni blend, 2 nodes x 8 GPU, TP4 x CP4, seq 65536.
Before: 0 optimizer steps, 1001 scatter/gather asserts.
After: cu_seqlens[-1] == total_tokens == 65536, per-rank indices numel=16384
in bounds, training runs (grad_norm 2.2-3.6 over 4+ steps).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: rohitrango <rohit.rango@gmail.com>
|
Auto-sync is disabled for ready for review pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
Contributor
Author
|
/ok to test e7c5fad |
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 this fixes
MegatronPolicyWorkerImpl._train_microbatch_body(the presharded / TQ train path) callsget_microbatch_iteratorwithout the three delegation flags:delegate_pack_to_modeldelegate_mtp_loss_mask_to_modelmodel_slices_context_parallel_inputsThe other three
get_microbatch_iteratorcall sites in the same file (logprob and the non-presharded train path) all pass them. All three default toFalse, so on the presharded path a model that declaresmodel_slices_context_parallel_inputs = Truehad that declaration silently ignored.Failure mode
For a model that slices its own CP inputs (e.g. Nemotron Omni) with CP>1:
_prepare_prepacked_batch_for_megatronhanded the model the CP-local slice (65536/4 = 16384 tokens) whilePackedSeqParams.cu_seqlens_q_paddedstayed global at 65536. The model, which slices its own CP inputs after media insertion, then sliced again.tex.thd_get_partitioned_indicesbuilt indices into a 65536-token stream against a 16384-token tensor, soindex_selectran off the end:CUDA reports that asynchronously, so it surfaced in an unrelated later kernel (mamba
in_projRMSNorm), which made it look like a model bug rather than a batch-prep bug.Net effect: CP>1 was unusable on the presharded train path for any model that slices its own CP inputs. Note TQ itself is not involved in the sharding —
tq_policy.pymarkscontext_parallelas a replicated axis.The fix
Pass the same three flags that the other call sites already pass. Three added lines, no behaviour change for models where the flags are
False(which is every model that does not opt in).Verification
Run on a Nemotron Omni blend, 2 nodes x 8 GPU, TP4 x CP4, seq 65536:
cu_seqlens[-1] == total_tokens == 65536, per-rank indicesnumel == 16384and in bounds, training runs cleanly (grad_norm 2.2–3.6 over 4+ steps).🤖 Generated with Claude Code