Overlap experimental FSDP communication with compute#5719
Open
wujingyue wants to merge 2 commits into
Open
Conversation
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
356bf43 to
2d43993
Compare
2d43993 to
700c4f0
Compare
700c4f0 to
68aa5a2
Compare
wujingyue
commented
Jul 9, 2026
| with torch.cuda.device(device): | ||
| self.allgather_stream = torch.cuda.Stream() | ||
|
|
||
| def next_of(self, module: "FsdpModule") -> "FsdpModule | None": |
Contributor
Author
There was a problem hiding this comment.
Consider a linked hashmap.
Comment on lines
+140
to
+141
| # named_modules() yields units in registration order, which is the static | ||
| # forward execution order used to prefetch the next unit's all-gather. |
Contributor
Author
There was a problem hiding this comment.
This is a fragile assumption. Fine for the prototype.
9045a0d to
4d2f7de
Compare
In pre_forward, issue the next FSDP unit's all-gather on the comm stream
(static module-tree order) so AG_{i+1} launches before F_i finishes, instead
of relying on delayed releases for overlap.
Since prefetch now drives overlap, the delayed-release deque is dropped: each
unit frees its own unsharded storage on the all-gather stream right after its
own compute (event-gated on a compute-stream consumer event so the free never
races the consuming kernels), rather than queuing releases. This bounds peak
in-flight memory to the current unit plus the prefetched next.
Each unit tracks its own materialized state via FsdpModule._is_unsharded, so
pre_forward can skip a unit an earlier unit already prefetched -- no central
id-keyed set or per-forward reset.
Applied on top of the FSDP all-gather overlap work (NVIDIA#5513). Verified against the
mfsdp_v2 unit tests: no new failures vs the base, and forward-peak-memory-bounds
now passes (it failed with the deque). resting-forward (32 MB) and flaky-overlap
fail on the base too. Profiling: prefetch raises concurrent AG/compute overlap
but not forward wall-clock because the SM-based all-gather contends with the
persistent full-occupancy GEMM; the real lever is SM-free (CTA-zero) comm.
Static module order assumes forward order == registration order.
Signed-off-by: Jingyue Wu <jingyuew@nvidia.com>
Reuse the recorded forward order in reverse during backward to prefetch each upcoming FSDP unit's parameters on the all-gather stream. Wait only for the current unit before compute so later all-gathers can overlap backward GEMMs. Split gradient reduction into allocation, packing, and reduce-scatter stages, and launch each reduction immediately on a dedicated stream. Register an autograd-final callback from the root backward pre-hook to order optimizer work after communication while preserving mixed-dtype accumulation and symmetric-memory averaging. Extend the profiler test to require the expected all-gather and reduce-scatter overlap counts and verify that communication and compute use distinct streams. Signed-off-by: Jingyue Wu <jingyuew@nvidia.com>
4d2f7de to
29f3f1f
Compare
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.
Summary
This implements the “explicit prefetching” approach used in MFSDP v1 for experimental Megatron-FSDP (
mfsdp_v2). The current implementation assumes that the static module registration order matches the execution order.Each module’s pre-forward hook prefetches the next module’s parameter all-gather. During backward, the same order is traversed in reverse: each pre-backward hook prefetches the preceding module’s all-gather, which is the next one needed in backward.
An example trace from the added unit test:
Implementation
Forward prefetch
After materializing the current FSDP unit's parameters,
pre_forwardissues the next unit's all-gather on the shared all-gather stream. Each unit releases its own unsharded storage in stream order after its compute consumer completes, bounding the live parameter storage to the current unit and its prefetched successor.Backward overlap
The shared FSDP context reuses its static
forward_orderin reverse. Each backward pre-hook:Gradient reduction is split into allocation, packing, and communication stages. Once a module's gradients are packed, its reduce-scatter is launched immediately on a separate reduce-scatter stream, allowing it to overlap subsequent backward GEMMs and all-gathers. Existing symmetric-memory scaling, mixed gradient dtypes, first-backward assignment, and microbatch accumulation semantics are preserved.
An autograd-end callback registered by the root makes the caller's current stream wait for the reduce-scatter stream before
backward()returns. This cannot rely on the root module's own post-backward hook: that hook tracks gradients for parameters owned by the root and may run before descendants finish, or may not run at all when the root owns no trainable parameters.Verification