mirror of
https://github.com/Comfy-Org/comfy-kitchen.git
synced 2026-11-04 23:37:42 +00:00
[PR #238] [Feat] [RDNA1] Add RDNA1 INT8 Attention backend separate from the existing HIP backend #250
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#250
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/238
Author: @Zakhrov
Created: 10/10/2026
Status: 🔄 Open
Base:
main← Head:rdna1-backend📝 Commits (10+)
5bd4f17Add RDNA1 backend separate from the HIP backend9c485baEnhance README.md for rdna1 backend: clarify separation from HIP and outline unique requirements62d61dcRefactor RDNA1 backend: Remove unneeded WMMA and FP8 structures, update GEMM and quantization kernels7509aabAdd test for small weights to ensure scaled rows remain in fp16 range80b856cAdd new operations for depthwise convolution, direct convolution, GEMV, and packed scaling3c8754bMerge branch 'main' of https://github.com/Comfy-Org/comfy-kitchen into rdna1-backend19b8e11Add Winograd F(2x2, 3x3) convolution implementation for fp16 in rdna1 backendba50e81Add q4_k_linear implementation and related quantization functions for GGUF Q4_K weightse946118Merge branch 'main' of https://github.com/Comfy-Org/comfy-kitchen into rdna1-backenda1e2f74Add support for residual connections and input activation in w4a8_int8_linear📊 Changes
96 files changed (+60819 additions, -103 deletions)
View changed files
📝
MANIFEST.in(+2 -0)📝
README.md(+150 -45)📝
comfy_kitchen/__init__.py(+230 -4)➕
comfy_kitchen/backends/amd.py(+28 -0)📝
comfy_kitchen/backends/eager/__init__.py(+82 -1)📝
comfy_kitchen/backends/eager/conv3d.py(+89 -0)📝
comfy_kitchen/backends/eager/quantization.py(+70 -0)➕
comfy_kitchen/backends/rdna1/CMakeLists.txt(+263 -0)➕
comfy_kitchen/backends/rdna1/README.md(+199 -0)➕
comfy_kitchen/backends/rdna1/__init__.py(+4110 -0)➕
comfy_kitchen/backends/rdna1/dlpack_bindings.cpp(+3079 -0)➕
comfy_kitchen/backends/rdna1/embed_hsaco.cmake(+18 -0)➕
comfy_kitchen/backends/rdna1/epilogue.h(+129 -0)➕
comfy_kitchen/backends/rdna1/fp8_utils.h(+183 -0)➕
comfy_kitchen/backends/rdna1/gemm_common.h(+100 -0)➕
comfy_kitchen/backends/rdna1/gemm_simt.h(+853 -0)➕
comfy_kitchen/backends/rdna1/hadamard.h(+954 -0)➕
comfy_kitchen/backends/rdna1/launchers.h(+99 -0)➕
comfy_kitchen/backends/rdna1/miopen_winograd/Conv_Winograd_v30_3_1_fp32_f2x3_dilation2.s(+42 -0)➕
comfy_kitchen/backends/rdna1/miopen_winograd/Conv_Winograd_v30_3_1_fp32_f2x3_stride1.s(+42 -0)...and 76 more files
📄 Description
What this PR does
Adds an optional
rdna1backend to comfy-kitchen for RDNA1 (gfx1010, e.g. RX 5600M / 5700 XT), built for thatone target from its own copy of the HIP sources. It registers only for gfx1010,
declines tensors on any other device, and leaves the
hipbackend and every otherGPU untouched.
Why
On gfx1010 the eager backend cannot run INT8 models at all: its INT8 matmul is
torch._int_mm, which PyTorch sends to hipBLASLt, and ROCm ships no hipBLASLt kernelsfor gfx1010. It also has no INT8 attention, so ComfyUI's
--use-ck-attentionrefusesto start, and Triton is no alternative since it miscompiles on this target. This
backend supplies those kernels itself and never calls
torch._int_mm.Hardware constraints
gfx1010 is a "transition" architecture between the older Vega and Navi 20 chips. It has:
arithmetic;
v_dot4/sdot4): int8 products go throughv_mad_i32_i24, or through fp16 FMAs, in which int8 values are exact;-mno-wavefrontsize64).PyTorch's ROCm libraries support it (marked as stable in ROCm 10.1), but gfx1010 does not have composable-kernel support, so it cannot use hipBLASLt, and is restricted to the older rocBLAS backend.
Why not extend HIP?
hipkernels are built around WMMA tiles, so RDNA1 needs its own GEMMs (gemm_simt.h, the packed fp16 FMA GEMM, the implicit-GEMM conv3d) and a software tile policy for attention.hiphas no tier it fits.architectures.jsonhaselementwise_only,wmma_gfx11andwmma_gfx12. A fourth, non-WMMA tier would thread#ifbranches through every GEMM and attention kernel the supported cards share.#if GFX12 ... #elsecode that assumed the else branch meant gfx11 gave wrong masked int8 attention on gfx1010. CI has no RDNA1 hardware, so every HIP port could reintroduce that class of bug.backends/hip.rdna1registers only when a gfx1010 is visible and declines tensors on any other device.rdna1drops flash decode and GatedDeltaNet decode (they need bf16) and addsgemm_f16_packedandtranspose_cast. As a separate backend, the missing ops fall through to eager via the registry instead of needing per-op arch guards insidehip.COMFY_KITCHEN_DISABLE_RDNA1=1turns it off, and removing it is mostly deleting one directory and its tests, plus the small dispatch shim inbackends/amd.py.What this backend provides
on a thread-level, register-blocked GEMM (
gemm_simt.h); short M packs into 16-or 32-row tiles and splits K.
fp16_packed_linear/fp16_packed_conv3d: fp16 weights onv_pk_fma_f16, partialsums folded into fp32 every 32 products, activations of any range scaled by a power
of two. The conv is an implicit GEMM with no im2col workspace. ConvRot INT8 linears
with group size 256 run on the same packed GEMM.
mma.h), plus anfp16-FMA Sage kernel for unmasked head_dim 64/128 and
int8_block_sparse_attention.Not provided: NA2D, flash decode and the GatedDeltaNet decode (the last two need bf16
arithmetic), and the NVFP4 and MXFP8 layouts. Those fall through to eager. Where the
fused ConvRot quantizer cannot take K, the activation is rotated eagerly and quantized
onto this backend's GEMM.
Dispatch
The backend registers as
rdna1when a gfx1010 is visible, and every op's call ruledeclines tensors on any other device, so it sits beside
hipin one process. Whereit registers, priority is
rdna1 -> hip -> eager; Triton is left out. Calls thatbypass the registry (fp8
scaled_mm_v2, Sage attention,sol_attn_chunked) resolveper device through
comfy_kitchen/backends/amd.py.COMFY_KITCHEN_DISABLE_RDNA1=1removes the backend.
Testing
Built with:
The INT8 references in
tests/test_rdna1.pyrun eager with an exact fp32 matmul inplace of
torch._int_mm.Benchmark: Z-Image Turbo on upstream ComfyUI
Stock upstream ComfyUI on an RX 5600M (6 GB), 2026-10-10. A is the best configuration
the eager backend can run; B is this backend.
--use-ck-attentionB samples 2.5x faster and peaks 1.7 GB lower. Both images of a seed show the same
composition.
The int8_convrot models do not run in configuration A: the first sampling step fails
in eager's
int8_linearwithHIPBLAS_STATUS_INVALID_VALUEfromtorch._int_mm(
rocblaslt error: Cannot read "TensileLibrary_lazy_gfx1010.dat"). fp8 is thereforethe eager baseline.
Where B's time goes
A B run with the GPU synchronized around each call, per 4-step image:
int8_linear)int8_attention_from_prequantized)--cpu-vae)Upstream ComfyUI's own
int8_linearand attention calls reach these kernels; nothingin ComfyUI was changed. The VAE decode and, on a cold run, the text encoder run on the
CPU in both configurations, which is why the wall-clock ratio is smaller than the
sampling ratio.
Setup
3a52aae(upstream master), no custom nodes, Python 3.14.amd-torch-device-gfx1010and
rocm-sdk-devel10.1.0 fromhttps://stable.repo.amd.com/rocm/whl-next/.--disable-dynamic-vram --lowvram --cpu-vae,HIP_VISIBLE_DEVICES=0. A adds--use-quad-cross-attentionand uses comfy-kitchen 0.2.37 from PyPI, where only theeager backend is active on gfx1010. B adds
--use-ck-attentionand uses this branchbuilt against the same ROCm.
res_multistep/simple, AuraFlow shift 3)at 4 steps, 1024x1024, batch 1, one fresh server per configuration.
z-image-turbo_fp8_scaled_e4m3fn_KJ.safetensors(Kijai/Z-Image_comfy_fp8_scaled)and
qwen_3_4b_fp8_mixed.safetensors(Comfy-Org/z_image_turbo).z_image_turbo_int8_convrot.safetensors(Comfy-Org/z_image_turbo) andqwen3-4b_int8_convrot_fp16emixed.safetensors(martin-rizzo/Qwen3-4B-INT8-ConvRot-ComfyUI).ae.safetensors(Comfy-Org/z_image_turbo).Caveats
configurations need
--disable-dynamic-vram.--lowvramruns the text encoder on the CPU, where this backend declines thetensors; the int8_convrot encoder is dequantized by eager there.
the other 3.7 GB from host RAM each step.
mem_info_vram_usedsampled at 20 Hz, which includes PyTorch'scaching allocator; the card holds 20 MB at idle.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.