mirror of
https://github.com/Comfy-Org/comfy-kitchen.git
synced 2026-11-04 23:37:42 +00:00
[PR #174] Optimize HIP WMMA INT8 GEMM staging, epilogue, and deep-K tiling #194
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/comfy-kitchen#194
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/comfy-kitchen/pull/174
Author: @qweqweewqe7-create
Created: 9/13/2026
Status: 🔄 Open
Base:
main← Head:optimize-hip-int8-wmma-gemm📝 Commits (5)
6f26009Optimize HIP WMMA INT8 GEMM4711125Preserve signed zero without INT8 bias2ab6a7cUse the 128x256 BKB=128 INT8 WMMA tile on gfx12 at every K21c422dKeep the cached INT8 epilogue scale order exact06c5ee1Keep gfx12 INT8 linear on the row-major route📊 Changes
4 files changed (+218 additions, -14 deletions)
View changed files
📝
comfy_kitchen/backends/hip/__init__.py(+8 -0)📝
comfy_kitchen/backends/hip/epilogue.h(+25 -0)📝
comfy_kitchen/backends/hip/gemm_wmma.h(+164 -14)📝
tests/test_hip_wmma.py(+21 -0)📄 Description
Summary
GroupM=4for existing instantiations128x256, 2x4-wave,TM4xTN4,GroupM=8INT8 tile on gfx12, withBKB=128, used at every K (see the update below; it wasBKB=64and K >= 4096 only)The new tile is selected with a cached host-side HIP device property query. The generated
COMFY_MMA_GFX12macro is intentionally not used in the launcher because the__gfx*__conditions that define it are device-pass-only. If the runtime architecture query fails, or the current device is not gfx12, selection falls back to the existing cross-architecture tile policy.FP8 and INT4 tile selection is unchanged. The common staging optimization and defaulted
GROUP_Mtemplate parameter are shared infrastructure.Performance
Raw HIP event timing on an RX 9070 XT (
gfx1201), PyTorch2.15.0a0+rocm10.1.0a20260822, HIP7.16.26332, BF16 output,M=30000, N=21504, K=5376. Each ABBA run used 5 warmups and 15 measured iterations with deterministic inputs.The mean of the two run medians improves from 39.3435 ms to 33.052 ms, a cumulative 19.04% speedup (176.3 to 209.9 TOPS). This comparison is the complete stack in this PR against current upstream, not the isolated effect of the new geometry.
With the other optimizations held constant, the new tile was also validated across QKV M sweeps with no observed regression: about 3.0-3.5% over the previous canonical tile on gfx1201 and 5.08% at M=30000 on gfx1200. The
GroupM=8ablation contributed 1.59% at gfx1201 QKV M=30000 and was neutral-to-positive across the tested projection shapes.Static resource inspection of the winning specialization on gfx1200 and gfx1201 reported 23 SGPRs, 221 VGPRs, 27,648 bytes LDS, zero scratch, and no spills.
Validation
gfx1200;gfx1201fat HIP extensiontests/test_hip_wmma.py tests/test_hip_dispatch.py tests/test_gemm_bias_contract.py: 452 passed, 11 skipped on each GPUgfx1100;gfx1151git diff --checkUpdate: rebased onto v0.2.38, BKB=128 at every K
Rebased onto current
main(42081bf, v0.2.38) without conflicts, plus one commit, Use the 128x256 BKB=128 INT8 WMMA tile on gfx12 at every K. The gfx12 INT8 tile now usesBKB=128, which halves the K-loop barriers, and covers shallow K too. Before this commit,K < 4096used the cross-architecture 128x128x64 tile. Outputs are bit-identical (int32 accumulation).RX 9070 XT (gfx1201), PyTorch
2.16.0a0+rocm10.2.0a20261015, HIP event timing,int8_linearwith ConvRot (activation quant included). "Before" is this PR's previous tile policy.MOSS-Image 1024x1536 DiT projections, M=6304:
The deep-K GEMM alone at 8192 -> 3072 goes from about 2.5 ms (
BKB=64) to about 1.5 ms (212 TOPS). The full MOSS-Image DiT forward goes from 535 to 508 ms.M sweep (256 to 4096), speedup of
int8_linear: K=3072/N=3072 1.01-1.07x, K=3072/N=9216 1.00-1.09x, K=8192/N=3072 1.03-2.02x, K=4096/N=4096 1.07-1.36x. M=128 stays below the WGP threshold and keeps the existing small tile.H3 projections (already on the previous deep-K tile), M=15000/30000, alternating runs:
That is +1.0-1.8% across the H3 shapes, and the same at M=15000.
Resources of the new specialization (bf16, fp16 and fp32 outputs alike, gfx1200 and gfx1201): 256 VGPRs, 3 VGPRs spilled (16 bytes/lane of scratch), 52,224 bytes LDS, occupancy 4 waves/SIMD. Unlike the previous
BKB=64tile, this one spills a little. It is still the fastest of the tiles swept here (15 configurations) at every shape above, and the numbers above include the spill.Re-validation after the rebase, on RX 9070 XT (gfx1201) and RX 9060 XT (gfx1200),
gfx1200;gfx1201build:tests/test_int8*.py tests/test_hip_wmma.py tests/test_hip_dispatch.py tests/test_w4a8_requant.py tests/test_convrot_unpacked_quantization.py tests/test_adaln.py tests/test_rms_rope.py tests/test_hip_convrot_perf.py tests/test_gemm_bias_contract.pygive the same results as unmodifiedmain(1176 passed). The only failures, 18 triton cases andtest_int8_linear_correctness[hip], fail identically onmain.Update: rebased onto v0.2.40 (#259)
Rebased onto
main(f8b7e97, v0.2.40). The conflict with #259 ingemm_wmma.his resolved by keeping both sides:GROUP_Mnow follows #259'sCOALESCED_STAGINGandTILED_Atemplate parameters.TileStager::loaduses the same chunk index asstore, so it is also correct for coalesced staging.Two commits are added:
acc * (sa * sb). That rounds differently from(acc * sa) * sbin rare bf16 cases (1-26 of 0.6M-5.9M outputs), and the newtest_gfx12_int8_gemm_is_exactcaught it.apply_cachednow pins the association, and the test passes.int8_linearthrough the tiled-A producer andint8_gemm_a_tiled128. With this PR's 128x256 BKB=128 tile, the row-major route is faster at every MOSS-Image/H3 projection, and its outputs are bit-identical to the tiled-A route. gfx117 keeps tiled-A, andCOMFY_KITCHEN_INT8_TILED_A=1selects it on gfx12.RX 9070 XT (gfx1201) and RX 9060 XT (gfx1200), PyTorch
2.16.0a0+rocm10.3.0a20261023, HIP 7.17.26423. Timings are wall-clock medians over windows of calls, averaged over two alternating runs.int8_linearwith ConvRot, bf16 out:With
COMFY_KITCHEN_INT8_TILED_A=1, the PR build matchesmainwithin about 1%. The gain therefore comes from the row-major tile.On the 9070 XT, the raw
int8_gemm(no activation quant) goes from 4.09 to 3.14 ms at MOSS qkv and from 68.6 to 55.0 ms at H3 fc1. Its outputs are identical tomain.Tests on both GPUs (
test_hip_wmma,test_hip_dispatch,test_gemm_bias_contract,test_int8*,test_adaln,test_rms_rope,test_int8_attention,test_sol_attn,test_convrot_unpacked_quantization,test_w4a8_mma,test_w6a8):main's 2400 plus the signed-zero test added here.main: 18 triton rope cases andtest_int8_linear_correctness[hip].🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.