Repository navigation
[ROCm][diffusion] Enable fused qk norm and rope on ROCm - #35573
Merged
yichiche merged 14 commits intoSep 18, 2026
Merged
Conversation
Enable fused qk norm and rope paths for double and single transformer blocks. Add .contiguous() to query/key unflattens in single transformer block so the in-place fused kernel receives real views instead of implicit copies.
gurpreet-dhami
marked this pull request as ready for review
August 19, 2026 22:02
gurpreet-dhami
requested review from
AgainstEntropy,
BBuf,
HaiShaw,
mickqian,
ping1jing2 and
yichiche
as code owners
August 19, 2026 22:02
|
|
||
| query = query.unflatten(-1, (self.local_heads, -1)) | ||
| key = key.unflatten(-1, (self.local_heads, -1)) | ||
| query = query.unflatten(-1, (self.local_heads, -1)).contiguous() |
sushildubey171
suggested changes
Aug 20, 2026
Plumb allow_strided_qk through apply_qk_norm_with_optional_rope and enable it in the single transformer block so the fused kernel handles strided packed-QKV views natively without forcing contiguous copies.
gurpreet-dhami
force-pushed
the
flux2-sglang-fused-qknorm-rope
branch
from
August 20, 2026 18:39
edcff7e to
12f4816
Compare
gurpreet-dhami
commented
Aug 21, 2026
gurpreet-dhami
left a comment
Contributor
Author
There was a problem hiding this comment.
Added requested changes.
This was referenced Aug 22, 2026
Contributor
Author
|
@sushildubey171 @HaiShaw : Can you please review this PR. |
sushildubey171
approved these changes
Aug 26, 2026
yichiche
requested changes
Sep 17, 2026
Co-Authored-By: Claude <noreply@anthropic.com>
yichiche
self-requested a review
September 18, 2026 08:23
This was referenced Sep 19, 2026
This was referenced Sep 21, 2026
Open
This was referenced Sep 22, 2026
This was referenced Sep 29, 2026
This was referenced Oct 8, 2026
4 of 5 tasks
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.
Motivation
The fused QK-norm + RoPE and fused LayerNorm + modulate kernels were previously gated to CUDA only. This PR enables these fused paths on ROCm, giving FLUX.2 the same eager-mode optimizations on AMD GPUs that already exist on NVIDIA.
Additionally, the single transformer block's packed-QKV unflatten produced strided views that the in-place fused kernel couldn't consume without implicit copies. Instead of forcing
.contiguous()copies, we plumballow_strided_qk=Trueso the kernel handles strided views natively.Modifications
_is_cuda or _is_rocminstead of_is_cudaalone inapply_qk_normandapply_qk_norm_rope(layernorm.py)._flux2_norm_modulatehelper (already platform-agnostic via.is_cudatensor check) now runs on ROCm for both double and single transformer blocks (flux_2.py).allow_strided_qkparameter toapply_qk_norm_with_optional_ropeand passallow_strided_qk=TrueinFlux2ParallelSelfAttentionandFlux2SingleTransformerBlock, avoiding unnecessary.contiguous()copies.Results
Benchmarked on MI350 (ROCm) with FLUX.2 at two resolutions for TP=1, ULLYSSES=8. Times are per-step per-layer GPU kernel time in microseconds. Estimated E2E uplift is extrapolated from per-layer kernel savings; measured E2E is in Accuracy Tests below.
Kernel microbenchmarks — 1024×1024 (~10% estimated E2E uplift)
[1, 64, 48, 128][1, 512, 48, 128][1, 576, 48, 128]Kernel microbenchmarks — 2048×2048 (~6% estimated E2E uplift)
[1, 64, 48, 128][1, 2048, 48, 128][1, 2112, 48, 128]Accuracy tests
Verified that the fused ROCm paths (QK-norm + RoPE, LayerNorm + modulate, strided QKV) produce identical accuracy to the unfused baseline on AMD MI350X using SGLang's built-in diffusion consistency test suite (
test_server_1_gpu.py -k flux_2_image_t2i).Setup: FLUX.2-dev, 1 GPU, 1024×1024, 50 denoising steps, seed=42, prompt: "Doraemon is eating dorayaki"
Results
CI States
Latest PR Test (Base): ✅ Run #35280442691
Latest PR Test (Extra): ❌ Run #35280442529
Latest PR Test (AMD ROCm 10): ❌ Run #35280442520