Repository navigation
[Perf] diffusion: Keep same-device copies out of the pipelined Ulysses exchange - #46145
Merged
mickqian merged 2 commits intoOct 24, 2026
Merged
Conversation
…s exchange A same-device copy (cuMemcpy2DAsync D2D or copy_) runs on the SMs, so it waits out the attention kernel that is running. The head-group pipeline copied this rank's own rows into its receive slots on the copy stream, between the peer sends: each group's own copy waited for the previous group's attention and held the peer sends queued behind it. The output merges (own rows and the peers' blocks into the merged output) were same-device copies too, and all ran after the last group. - This rank's rows of every group go into its slots in one Triton pass (copy_head_groups) on the main stream before the first group attends; the copy stream carries only peer sends. - When the backend writes through a strided output (forward_into; FA4), each group attends straight into a token-major buffer of every row and head. This rank's rows are the result, the peers' rows are sent from there, and the peers' blocks come back in one pass per peer. Outputs are bit-identical: the same kernels see the same values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mickqian
requested review from
AgainstEntropy,
BBuf,
HaiShaw,
kevin-mii,
niehen6174,
ping1jing2,
yichiche and
yingluosanqian
as code owners
October 23, 2026 18:27
Collaborator
Author
|
/tag-and-rerun-ci |
…n_backend.py The forward_into tests (FA4 writing through a strided out, and the default declining) move from their own file into the existing CUDA attention backend tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mickqian
deleted the
mick/diffusion-ulysses-pipeline-same-device-copies
branch
October 24, 2026 13:36
This was referenced Oct 24, 2026
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.
Branch: mick/diffusion-ulysses-pipeline-same-device-copies (on main efd2ce8), commit 2aec3e1
Motivation
The head-group pipeline (
IpcA2AMultiState.pipelined_attention) overlaps the Ulysses exchange with attention: group g's peer copies run on the copy engine while group g-1 attends. Two parts of it were same-device copies, and a same-devicecuMemcpy2DAsync(orcopy_) runs on the SMs, so it waits out whatever attention kernel is running:A microbenchmark on B300 (FA4 or cuDNN attention on one stream, six 38.7 MB pitched copies issued on another): D2D copies finish 0.2 ms after the attention ends; P2P copies finish 0.4 ms after they start.
Modifications
kernels/ops/diffusion/layout/head_group_copy_triton.py:copy_head_groups(src, dst)copies[group, batch, rows, width]views with arbitrary strides (last dim contiguous) in one Triton pass.ipc_a2a_multi.pipelined_attention:copy_head_groupspass per part on the main stream, before the first group; the copy stream carries only peer sends;attend_into(q, k, v, out): when the backend can write through a strided output, each group attends straight into a token-major[batch, world * s_local, heads, head_dim]buffer. This rank's rows of it are the returned output; the peers' rows are sent from it on the copy engine; the peers' blocks come back in onecopy_head_groupspass per peer. No own merge, one gather per peer.AttentionImpl.forward_into(q, k, v, out, attn_metadata) -> bool(default False).FlashAttentionImplserves it on FA4 (same call asforward, without=);DynamicCudnnSDPAImpldelegates when it would take FA4 for those inputs.out=Noneonly asks.USPAttention's dense Ulysses path passesattend_into.Masked, replicated-row, fill (MiniMax-H3) and cuDNN-served calls keep the previous output path.
Accuracy Tests
The pipeline checks itself against the sequential exchange on first sight and keeps it only on byte equality; with this change it still passes on Wan2.2 (no "differs from the sequential exchange" in the log). Decoded videos are byte-identical (mp4 md5) to the run without the change for the same requests.
test_usp_pipelined_attention_multi_gpu.py: every Ulysses layout, FA and cuDNN backends, pipelined vs sequential, bitwise, 2 and 4 ranks: passes (the FA4 cases now takeattend_into).test_ipc_a2a_multi_gpu.py: passes (2 and 4 ranks, expandable segments without pidfd_getfd).test_layout.py::test_copy_head_groups_*: both directions vs per-group copies, bitwise; input validation.test_cuda_attention_backend.py(forward_into cases): FA4forward_intointo one head group of a wider buffer equalsforwardbitwise and writes nothing else; backends without it decline.Speed Tests and Profiling
Wan2.2 T2V A14B 720p, 81 frames, 40 steps, 4xB300, CFG 2 x Ulysses 2, eager, FA4 attention (needs "Prefer FA4 over cuDNN SDPA for long self-attention on B300" for the default backend).
Per transformer block (torch profiler, rank 0):
E2E, harness single_e2e (client latency, two measured requests per fresh server, two interleaved rounds), on top of the other B300 Wan changes: without
attend_into90.820 / 90.797 s, with it 90.683 / 90.680 s (-0.13 s). The own-rows half was measured together with the FA4 selection change (92.72 -> 91.34 s median, probe client, six requests each).All four GPUs sit at the 1100 W power cap through the denoise, so idle gaps cost less than their length: removing them raises power and the clocks drop. The e2e gain is smaller than the timeline gain.
🤖 Generated with Claude Code
CI States
Latest PR Test (Base): ✅ Run #40062976150
Latest PR Test (Extra): ❌ Run #40062976164
Latest PR Test (AMD ROCm 10): ⏳ Run #40062976135