Skip to content

[Diffusion] Fuse Qwen-Image text QKV projections - #36693

Closed
BBuf wants to merge 1 commit into
sgl-project:mainfrom
BBuf:perf/qwen-image-text-qkv
Closed

BBuf wants to merge 1 commit into
sgl-project:mainfrom
BBuf:perf/qwen-image-text-qkv

Conversation

@BBuf

@BBuf BBuf commented Aug 27, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

Qwen-Image projects the short text stream with three separate tensor-parallel Q/K/V GEMMs in every transformer block. vLLM-Omni uses one merged QKV projection. A torch-profiler comparison on 2x H200 showed that merging only the short text branch removes two small split-K launches per block without exposing the large image stream to packed-view materialization costs.

This PR is intentionally separate from the bitwise attention packing optimization because a merged BF16 GEMM changes reduction association.

Modifications

  • Use MergedColumnParallelLinear for the unquantized Qwen-Image added/text QKV projection.
  • Add checkpoint mappings that merge Diffusers add_q_proj, add_k_proj, and add_v_proj weights in Q/K/V order.
  • Preserve the existing unfused layout for other quantization backends; Nunchaku remains on its existing fused path.
  • Add CPU-only wiring and loader-mapping tests.

Accuracy Tests

Validated on the latest main used for this PR (b647ae8) and 2x NVIDIA H200:

  • python3 test/registered/unit/models/test_qwen_image_fused_qkv.py: 3 passed.
  • Five repeated candidate generations were deterministic and byte-identical to each other.
  • Versus the separate-GEMM BF16 baseline: pixel MAE 1.393/255, PSNR 40.55 dB. The difference is expected from GEMM reduction-order reassociation; no model weights or mathematical operation change.

This remains a Draft so maintainers can decide whether that BF16 numerical delta is acceptable for the default speed path.

Speed Tests and Profiling

Environment: 2x H200, TP=2, Qwen/Qwen-Image-2512, 1024x1024, 50 steps, guidance=1, BCG enabled, torch.compile disabled. The incremental A/B used the same CustomAllReduceV2 stack on both sides.

  • Steady denoise baseline: 78.5-78.8 ms/step.
  • Text-QKV candidate: 78.0-78.5 ms/step (78.2 ms median), about 0.4 ms/step / 0.5% faster.
  • Torch trace: removed 1,212 split-K GEMMs (7.606 ms) and 1,212 split-K reductions (3.108 ms); added 403 merged GEMMs (4.797 ms) and the expected packed-slice copies (3.161 ms).
  • Isolated projection microbench, CUDA graph: text seq=64 separate 31 us vs merged 13 us. The large image branch is deliberately left unfused because full-model A/B showed it regressed denoise to about 82 ms/step.

Checklist

  • Format your code according to the contribution guide.
  • Add unit tests according to the contribution guide.
  • Update documentation according to the contribution guide (no user-facing API or flag change).
  • Provide accuracy and speed benchmark results.
  • Follow the SGLang code style guidance.

Background benchmark investigation: BBuf/how-to-optim-algorithm-in-cuda#21


CI States

Latest PR Test (Base): ❌ Run #33069116662
Latest PR Test (Extra): ❌ Run #33069116477
Latest PR Test (AMD ROCm 7.2): ❌ Run #33069116717

@github-actions github-actions Bot added the diffusion SGLang Diffusion label Aug 27, 2026
@BBuf

BBuf commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator Author

Consolidated into #36680 as requested. The full text-QKV commit and its tests are now preserved there.

@BBuf BBuf closed this Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

diffusion SGLang Diffusion

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant