Support HSDP deferred DP-outer gradient reduction#5743
Conversation
Signed-off-by: Achyuthan Sivasankar <achyuthan.sivasankar@gmail.com>
|
This PR has been automatically converted to draft because all PRs must start as drafts. When you are ready for review, click Ready for Review to begin the review process. This will:
See the contribution guide for more details. |
There was a problem hiding this comment.
Pull request overview
This PR extends the experimental Megatron-FSDP (“MFSDP v2”) path to support HSDP-style deferred DP-outer gradient synchronization, using the microbatch context to delay DP-outer reduction until the last microbatch.
Changes:
- Allow
main_gradto differ frommain_weightplacements in the HSDP-compatible case (gradPartialwhere weightReplicate) and introduce deferred DP-outer gradient reduction logic. - Thread
is_last_microbatchthroughpost_backwardto gate the final DP-outer reduction and installation of sharded parameter grads. - Add a 2-D device-mesh parity test validating HSDP loss equivalence to single-rank SGD across multiple microbatch counts.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
tests/unit_tests/distributed/mfsdp_v2/test_fully_shard.py |
Adds an HSDP parity test on a 2-D DP mesh and introduces HSDP placement definitions. |
megatron/core/distributed/fsdp/src/megatron_fsdp/experimental/parameter_group.py |
Implements deferred DP-outer gradient reduction/accumulation and relaxes gradient/weight placement constraints. |
megatron/core/distributed/fsdp/src/megatron_fsdp/experimental/module.py |
Passes context.is_last_microbatch into gradient reduction to enable last-microbatch gating. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if len(grad_placements) != len(weight_placements): | ||
| return False | ||
| for grad_placement, weight_placement in zip(grad_placements, weight_placements): | ||
| if grad_placement == weight_placement: | ||
| continue | ||
| if isinstance(grad_placement, Partial) and isinstance(weight_placement, Replicate): | ||
| continue | ||
| return False | ||
| return True |
There was a problem hiding this comment.
Restricted _grad_placements_reduce_to_weight to at most one deferred (Partial→Replicate) axis, matching the single-axis redistribute. Multi-axis deferral is a follow-up.
| if self._defers_grad_reduction: | ||
| self._accumulate_deferred_grad(partial_grad, partial_op, is_last_microbatch) | ||
| for parameter in self.unsharded_parameters: | ||
| parameter.grad = None | ||
| return |
There was a problem hiding this comment.
_reduced_grad is now cleared at the first microbatch of each step, so the previous step's buffer is released after zero_grad().
…ad buffer Signed-off-by: Achyuthan Sivasankar <achyuthan.sivasankar@gmail.com>
Signed-off-by: Achyuthan Sivasankar <achyuthan.sivasankar@gmail.com>
Anytime @wujingyue , you can always tag me in the future for any other issues , I find them very interesting and love solving them . |
Rest main_grad at main_weight placements so it backs .grad and reuses the zero_grad/set_to_none reset; reduce-scatter the sharded axes every backward and all-reduce the replicated DP-outer axis in place only on the last microbatch. Drop the per-group state and multi-axis reduction helper; cover both set_to_none modes in the HSDP parity test. Signed-off-by: Achyuthan Sivasankar <achyuthan.sivasankar@gmail.com>
main_grad rests at its DP-outer-Partial gradient placement between microbatches and is all-reduced to main_weight's placements on the last microbatch, per HSDP semantics. Extend DBuffer.get_dtensor to represent Partial so main_grad backs .grad throughout, reusing the existing zero_grad/set_to_none accumulation. Cover both set_to_none modes in the HSDP parity test. Signed-off-by: Achyuthan Sivasankar <achyuthan.sivasankar@gmail.com>
|
/ok to test |
@wujingyue, there was an error processing your request: See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/1/ |
|
/claude fix |
Signed-off-by: svcnvidia-nemo-ci <svcnvidia-nemo-ci@nvidia.com>
|
🛠️ Claude fix commit
What changed Files changed by Claude
Why DCO Sanitized and posted by |
|
/ok to test 434a4d9 |
|
/ok to test c7c7183 |
Filter on activity_type == 'kernel' so the profiler's gpu_user_annotation duplicates aren't double-counted, and format the boolean (per @wujingyue's suggestion). Signed-off-by: Achyuthan Sivasankar <achyuthan.sivasankar@gmail.com>
Head branch was pushed to by a user without write access
c7c7183 to
96764cd
Compare
|
@wujingyue @ericharper Signed off and black-formatted the activity_type change in 96764cd — DCO is green now. The force-push cleared CI authorization and disabled auto-merge, so it needs one more /ok to test 96764cd and auto-merge re-enabled (or a manual merge once green). Thanks! |
|
/claude fix |
Signed-off-by: svcnvidia-nemo-ci <svcnvidia-nemo-ci@nvidia.com>
|
🛠️ Claude fix commit
What changed Files changed by Claude
Why DCO Sanitized and posted by |
|
/ok to test 89b5296 |
|
❌ Claude fix stopped because exact-SHA CI did not complete in time. View exact-SHA CI. |
|
/claude fix |
Signed-off-by: svcnvidia-nemo-ci <svcnvidia-nemo-ci@nvidia.com>
|
🛠️ Claude fix commit
What changed Files changed by Claude
Why DCO Sanitized and posted by |
|
/ok to test 66b592a |
|
❌ Claude fix stopped because exact-SHA CI did not complete in time. View exact-SHA CI. |
|
/ok to test 66b592a |
|
🔄 Merge queue validation started! You can track the progress here: https://github.com/NVIDIA/Megatron-LM/actions/runs/29783738040 |
Summary
Adds HSDP DP-outer gradient synchronization to the experimental Megatron-FSDP path, building on the microbatch context from #5652. Partially addresses #5616.
main_grad/main_weightplacement guard somain_gradmay rest at a DP-outer-Partialaccumulation state (Partialon an axis wheremain_weightisReplicate).is_last_microbatch: reduce-scatter DP-inner and accumulate intomain_gradevery backward; reduce DP-outer and install the sharded parameter gradients only on the last microbatch.is_last_microbatchfrom the FSDP context throughpost_backward.microbatch(...).Scope and design notes (draft — feedback welcome)
[Replicate, Flat]); gradients rest[Partial, Flat]. HFSDP (optimizer sharded across DP-outer) is a follow-up.Partialreduce op must match the collective op (AVG). Symmetric-memory reduction across more than one axis is not yet supported (raisesNotImplementedError).Testing
Run on a 2×2 mesh (4 ranks):
python -m torch.distributed.run --standalone --nproc-per-node 4 -m pytest -q
tests/unit_tests/distributed/mfsdp_v2/test_fully_shard.py
Covers HSDP parity against single-rank SGD for
num_microbatchesin {1, 3}; the existing 1-D FSDP path is unchanged.cc @wujingyue @ahmadki