Repository navigation
[Bugfix][Distributed] Preserve symmetric collective outputs #58154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d8a8bc6
cfaf005
6d30c7b
03d6f44
4532149
ce072b3
cfd1205
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the PR's description: “does not repeat allocation” should refer specifically to symmetric scratch allocation.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the PR description to clarify that cached symmetric scratch and window registration are reused, while each |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -636,11 +636,10 @@ def _get_symm_scratch( | |
| geometric growth bounds their total capacity to less than twice the | ||
| current allocation. | ||
|
|
||
| Safe across serial MoE layers and eager sequence parallelism: the | ||
| producer and collective are ordered on the same stream before the next | ||
| same-role operation reuses the buffer. DBO microbatches use distinct | ||
| cache entries. Any future cross-layer communication overlap must also | ||
| use distinct roles. | ||
| These buffers are internal scratch. Returning one would let a later | ||
| collective with the same cache key overwrite an earlier live result. | ||
| MoE combines may reuse scratch when the producer and collective are | ||
| ordered on the same stream. DBO microbatches use distinct cache entries. | ||
| """ | ||
| from vllm.distributed.device_communicators.pynccl_allocator import ( | ||
| nccl_symm_mem_context, | ||
|
|
@@ -698,12 +697,13 @@ def _reduce_scatter_symm_mem( | |
| ) | ||
| symm_input.copy_(input_tensor) | ||
|
|
||
| scratch_output = output is None | ||
| if output is None: | ||
| output = self._get_symm_scratch( | ||
| "rs_out", output_shape, input_tensor.dtype, input_tensor.device | ||
| ) | ||
| pynccl_comm.reduce_scatter(output, symm_input) | ||
| return output | ||
| return output.clone() if scratch_output else output | ||
|
|
||
| def get_symmetric_memory_buffer( | ||
| self, | ||
|
|
@@ -921,7 +921,7 @@ def _all_gather_symm_mem(self, input_: torch.Tensor) -> torch.Tensor: | |
| "ag_out", out_size, input_.dtype, input_.device | ||
| ) | ||
| pynccl_comm.all_gather(symm_output, input_) | ||
| return symm_output | ||
| return symm_output.clone() | ||
|
Comment on lines
923
to
+924
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for catching the issue. However this means we will lose the zero copy behavior. To allow different use cases, let's add
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @GirasoleY, thanks. My concern with adding Could we keep this PR focused on the ownership fix and pursue the copy cost separately?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah ideally we want to either allocate different buffers or be smart about the buffer regions so collective that can race each other do not overlap their symm buffer region. |
||
|
|
||
| def _all_gather_batched_symm_mem( | ||
| self, inputs: list[torch.Tensor] | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add CUDA-graph coverage for both operations? Capture two same-key calls, retain both outputs, then replay with changed inputs and verify both results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added CUDA graph coverage in
cfaf005: both AllGather and ReduceScatter capture two same-key calls, retain both outputs, and verify them after two replays with changed inputs. The exact PR head passed both tests on 2xGB200 with no skips. NCCL logs confirmed the symmetric paths.