Skip to content

[AMD][Diffusion] Route unquantized linears through aiter tgemm on gfx1250 - #41988

Merged
yichiche merged 1 commit into
sgl-project:mainfrom
sogalin:amd-opt-wan2.2
Oct 15, 2026
Merged

yichiche merged 1 commit into
sgl-project:mainfrom
sogalin:amd-opt-wan2.2

Conversation

@sogalin

@sogalin sogalin commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

On ROCm, diffusion DiT linears call F.linear, which goes to hipBLASLt. On gfx1250 that is about 3x slower than aiter's tuned Triton GEMM for the large Wan2.2 projections.

Modifications

  • Add SGLANG_USE_ROCM_AITER_TGEMM (default off).
  • When it is enabled on ROCm, apply_unquantized_linear sends bf16/fp16 linears to aiter.tuned_gemm.tgemm.mm, which picks the backend for each (M, N, K) from aiter's tuned CSVs. Calls with mixed dtypes still use F.linear.
    Tuned configs for Wan2.2 on gfx1250 are in the companion aiter PR#6032.

Accuracy Tests

The output video is bit-identical (same mp4 md5) with the flag on and off. tgemm matches F.linear exactly on all Wan2.2 GEMM shapes.

Speed Tests and Profiling

Wan2.2-T2V-A14B, 720x1280, 33 frames, 8 steps, 1x gfx1250, median of 3 interleaved runs:

Stage hipBLASLt aiter tgemm Speedup
Text encoding 1.01 s 0.96 s 1.05x
Denoising 228.74 s 64.41 s 3.55x
Decoding 7.37 s 7.00 s 1.05x
Total 237.39 s 72.64 s 3.27x

Scaling with --num-frames (single run each; 193-frame tuned run is estimated):

Frames Denoising (hipBLASLt → tgemm) Decoding Total (hipBLASLt → tgemm) Total speedup GEMM share of a tuned step
33 228.7 → 64.4 s 7.4 s 237.4 → 72.6 s 3.27x 31%
81 644.5 → 260.9 s 16 s 661.8 → 278.7 s 2.37x 15%
129 1191.7 → 602.4 s 24 s 1217.4 → 629.3 s 1.93x 11%
193 2094.0 → 1680.5 s 36 s 2131.8 → 1719.3 s 1.24x* 8%

* At 193 frames, the two FFN GEMMs exceed 2^31 elements and stay on F.linear. Only the 5120x5120 projections use tgemm.
Time saved per step grows with frame count (20.6 s at 33 frames to 75.3 s at 129 frames). The overall speedup still drops, because attention grows quadratically with token count and becomes the main bottleneck. Text encoding (~1 s) and decoding are unaffected. No new GEMM shapes appear between 33 and 193 frames (only M changes), so the aiter configs need no retuning.
To reproduce, add SGLANG_USE_ROCM_AITER_TGEMM=1 to the sglang generate command.
These numbers were measured on the original local branch, which has the same diff as this PR. The rebased branch has only passed py_compile.

Checklist

Review and Merge Process

  1. Ping Merge Oncalls to start the process. See the PR Merge Process.
  2. Get approvals from CODEOWNERS and other reviewers.
  3. Trigger CI tests with comments or contact authorized users to do so.
    • Common commands include /tag-and-rerun-ci, /tag-run-ci-label, /rerun-failed-ci
  4. After green CI and required approvals, ask Merge Oncalls or people with Write permission to merge the PR.

CI States

Latest PR Test (Base): ✅ Run #36875285583
Latest PR Test (Extra): ❌ Run #36875284125
Latest PR Test (AMD ROCm 10): ❌ Run #36875285745

@github-actions github-actions Bot added the diffusion SGLang Diffusion label Oct 1, 2026
@sogalin
sogalin marked this pull request as ready for review October 1, 2026 10:15
@sogalin sogalin added amd run-ci CI: run the baseline test suite on this PR labels Oct 1, 2026
Add SGLANG_USE_ROCM_AITER_TGEMM (default off). When set on ROCm,
apply_unquantized_linear sends bf16/fp16 linears to aiter's tgemm.mm,
which picks the backend (torch/hipBLASLt or Triton) per (M, N, K) from
aiter's bf16_tuned_gemm CSVs. Mixed-dtype calls keep using F.linear.

This covers every DiT linear in Wan (QKV/out projections, FFN, text and
time embedders), which all reach ColumnParallelLinear/RowParallelLinear.

Wan2.2-T2V-A14B, 720x1280, 33 frames, 8 steps, 1x gfx1250, median of 3
interleaved runs, with the companion aiter Wan2.2 gfx1250 configs:

  | Stage    | hipBLASLt | aiter tgemm | Speedup |
  | Encoding |    1.01 s |      0.96 s |   1.05x |
  | Denoise  |  228.74 s |     64.41 s |   3.55x |
  | Decoding |    7.37 s |      7.00 s |   1.05x |
  | Total    |  237.39 s |     72.64 s |   3.27x |

Output video is bit-identical (same mp4 md5) to the F.linear path.
@sogalin sogalin added the bypass-fail-fast CI: a failing job no longer aborts its siblings (lint still gates) label Oct 2, 2026
@sogalin sogalin changed the title [AMD][Diffusion] Route unquantized linears through aiter tgemm on ROCm [AMD][Diffusion] Route unquantized linears through aiter tgemm on gfx1250 Oct 2, 2026

if (
_USE_AITER_TGEMM
and x.dtype in (torch.bfloat16, torch.float16)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should add x.ndim >= 2 and x.is_contiguous() to avoid unsuported and copy call ?

@yichiche

Copy link
Copy Markdown
Collaborator

In #44379, aiter has been upgrade. This PR is ready to merge.

@yichiche
yichiche merged commit 2092160 into sgl-project:main Oct 15, 2026
216 of 234 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

amd bypass-fail-fast CI: a failing job no longer aborts its siblings (lint still gates) diffusion SGLang Diffusion run-ci CI: run the baseline test suite on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants