Repository navigation
Fix runtime CP group handling in attention for hybrid CP - #6821
Conversation
Two fixes for models built with context_parallel_size == 1 that bind a CP group per microbatch at runtime (hybrid/dynamic context parallelism): 1. TEDotProductAttention only allocates its auxiliary CP CUDA stream in the constructor when static CP > 1, so the runtime branch passed cp_stream=None into TE and AttnFuncWithCPAndKVP2P crashed with AttributeError: 'NoneType' object has no attribute 'wait_event'. Create the stream lazily when a runtime CP group is bound. 2. apply_rotary_pos_emb derives (cp_size, cp_rank) for the fused THD RoPE kernel from its cp_group argument, but attention always passed the static pg_collection.cp group. Under hybrid CP each rank holds only its runtime group's zigzag slice while cu_seqlens describe the full sequence, so the kernel indexed positions past the tensor: illegal memory accesses on short sub-samples, and wrong positions, NaN gradients and a softmax-lse device assert on long ones. Prefer packed_seq_params.cp_group when the runtime path binds one. Unit tests cover both: RoPE must receive the runtime group (and the static group when none is bound), and the CP stream must be created lazily and passed to TE. Validated end to end on 4x GB200 (8B GPT, 100k-token THD profile, mixed CP1/2/4 groups, finite losses and grad norms). Signed-off-by: Tom Long <tolong@nvidia.com>
Review follow-up: instead of a RoPE-local variable, re-assign pg_collection.cp to the runtime CP group so every CP consumer in the forward benefits. Because hybrid CP binds a different group per microbatch and local_cp_size == 1 sub-samples carry no group, the build-time group (captured at construction) is restored whenever no runtime group is bound - otherwise a CP1 microbatch following a CP2 one would inherit the stale larger group and recreate the wrong-positions bug. The unit test now also asserts the bind and the restore on the collection itself. Signed-off-by: Tom Long <tolong@nvidia.com>
|
Done — took @parthmannan's suggestion and went one step further: the runtime group is now bound on |
Keeps the tests consistent with the runtime-CP contract (local_cp_size == 1 sub-samples carry no cp_group) that NVIDIA#6825 asserts. Signed-off-by: Tom Long <tolong@nvidia.com>
|
Verified and audited, per the question above:
|
|
/ok to test 9493661 |
|
/ok to test 14a19cc |
The repo black config skips magic trailing commas; apply exactly the hunks the lint job suggests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: ilml <tolong@nvidia.com>
|
🔄 Merge queue validation started! You can track the progress here: https://github.com/NVIDIA/Megatron-LM/actions/runs/33934670269 |
What does this PR do?
Two fixes for runtime (hybrid/dynamic) CP in the attention stack, where a
model built with static
context_parallel_size == 1binds a CP group permicrobatch via
PackedSeqParams.cp_group:TEDotProductAttention.cp_streamwhen static CP > 1, so the runtime branchpassed
cp_stream=Noneinto TE andAttnFuncWithCPAndKVP2Pcrashed withAttributeError: 'NoneType' object has no attribute 'wait_event'.apply_rotary_pos_embderives(cp_size, cp_rank)for the fused THD RoPE kernel from itscp_groupargument, but attention always passed the static
pg_collection.cp. Underruntime CP each rank holds only its group's zigzag slice while
cu_seqlensdescribe the full sequence, so the kernel indexed positions past the
tensor: illegal memory accesses on short sub-samples (caught with
CUDA_LAUNCH_BLOCKING=1infused_rope_forward), and wrong positions,NaN gradients, then a softmax-lse device assert on long ones. This is the
dangerous one: with different luck it trains-but-wrong.
Test
New unit tests assert (a) RoPE receives the runtime group when
packed_seq_params.cp_groupis bound and the static group otherwise, and(b) the CP stream is lazily created and handed to TE's
set_context_parallel_group.Validation
End to end on 4x GB200: 8B GPT, 100k-token THD workload, mixed CP1/2/4
groups, finite losses/grad norms. One of three independent fixes required to
make hybrid CP runnable (siblings: schema-bridge and rerun-iterator PRs);
supersedes the combined draft #6816.