Qwen-Image-2.1 on AMD Strix Halo (gfx1151, ROCm 7.13)

This repository contains no weights. It records what it takes to run Qwen/Qwen-Image-2.1 on an AMD Ryzen AI Max+ 395 (Radeon 8060S, gfx1151) under ROCm 7.13, and the measured cost of doing so.

It runs. The first image takes 19.8 minutes and the second takes 6.8 minutes, and the difference is not the model β€” it is MIOpen tuning convolution kernels once, on a ROCm build that has no pretuned database for this GPU.

Measured

Radeon 8060S / gfx1151, ROCm 7.13, torch 2.10.0 (hip 7.13.99004), diffusers 0.41.0.dev0, bf16, 1024x1024, 24 steps, box otherwise idle. Two runs, same resolution and step count, different prompt and seed.

phase run 1 (cold) run 2 (warm)
pipeline load to GPU 7.3 s β€”
sampler, 24 steps 365.0 s (15.22 s/it) 390.4 s (16.28 s/it)
VAE decode 825.6 s 20.5 s
total (GEN_TIME_S) 1190.6 s 410.9 s
peak GPU allocated 40.55 GB 36.89 GB
peak GPU reserved 42.82 GB 38.60 GB

The VAE decode got 40x faster on the second run. Nothing about the model or the code changed between them.

β›” Why: no MIOpen tuning database for gfx1151 on this ROCm build

MIOpen(HIP): Warning [ParseAndLoadDb] File is unreadable:
"/opt/rocm/share/miopen/db/gfx1151_20.HIP.fdb.txt"

MIOpen ships pretuned performance databases per GPU architecture. On this install (ROCm 7.13) there is none for gfx1151: /opt/rocm/share/miopen/db/ holds 81 files covering gfx908, gfx90a and gfx942, and zero matching gfx1151. So every convolution shape is auto-tuned at runtime the first time it is seen. The transformer is unaffected (it is GEMM work), which is why the sampler rate is stable across both runs. The VAE is convolutional, so it pays the entire tuning bill on run 1.

⭐ Two separate things, and only one is missing here. The CK grouped-convolution kernel library libMIOpenCKGroupedConv_gfx1151.so is present on this system. Only the tuning database is absent. That distinction matters: the related upstream report ROCm/TheRock#5105 describes a worse case where both were missing and convolutions fell back to the GemmFwdRest solver, making an inference workload 3-5x slower than CPU. If you see CK grouped conv library not found for device gfx1151 in addition to the fdb warning, you have that bug, not this one.

⚠️ Version scope. These numbers are ROCm 7.13. AMD has since moved gfx1151 packaging forward (ROCm 10.0 publishes dedicated device-gfx1151 payloads). We have not tested ROCm 10 on this hardware, so do not read this page as a claim about current ROCm β€” it is a measurement of one released version, and the method below is what generalises.

The tuned results persist in ~/.cache/miopen. Evidence that this is the mechanism: the cache was 221,184 bytes after run 1 and 221,184 bytes after run 2 β€” byte-identical, zero new tuning, and the decode collapsed from 825.6 s to 20.5 s.

It looks exactly like a hang

For ~13 minutes there is no log output, one host thread sits at 100%, and the process appears stuck. It is not. Distinguish them by:

signal tuning genuinely hung
/sys/class/drm/card0/device/gpu_busy_percent 94-100% ~0%
~/.cache/miopen size over a 20 s window growing static
process state Rl D / S

⭐ Do not quote a first-run timing as this model's speed on this hardware. Warm the cache, then measure. If a first run must be quick, MIOPEN_FIND_MODE=FAST shortens the search at some cost in kernel quality β€” unset it for the run you actually report.

You can build the tuning database yourself

A missing system performance database is not a dead end β€” MIOpen consults a user PerfDb that overrides it, and AMD documents generating one (tuning performance databases). Exercise your real shapes once with search enabled:

export MIOPEN_USER_DB_PATH="$HOME/.config/miopen"
export MIOPEN_FIND_MODE=NORMAL
export MIOPEN_FIND_ENFORCE=SEARCH_DB_UPDATE
python gen.py ...            # run the resolutions you actually use
unset MIOPEN_FIND_MODE MIOPEN_FIND_ENFORCE

Subsequent runs read the tuned entries. This is what the warm run above is doing implicitly β€” explicit tuning just lets you front-load it deliberately, per shape, instead of paying it inside a user-facing request.

The trap that silently costs you the GPU

This machine's system python3 already had a working ROCm PyTorch (torch 2.10.0, torch.version.hip 7.13.99004, torch.cuda.is_available() True), while other virtualenvs on the box carried CPU-only torch. Letting pip resolve torch freshly, or reusing the wrong venv, runs the entire 33 GB pipeline on CPU without ever erroring.

Build the venv so it inherits the working install, and check afterwards:

python3 -m venv --system-site-packages ~/build/qwen-image/venv
~/build/qwen-image/venv/bin/python -c \
  "import torch; assert torch.cuda.is_available(); print(torch.__version__, torch.version.hip)"

⭐ Make the generator refuse to run on CPU rather than fall back β€” that turns a silent 30x slowdown into an immediate, obvious failure:

if not torch.cuda.is_available():
    print("FATAL: HIP not available - refusing to run on CPU"); sys.exit(2)

Dependencies

QwenImage21Pipeline is newer than any diffusers release on PyPI β€” it needs diffusers >= 0.37.0.dev0. Installed here from GitHub main via the archive zip (the build box has no git):

pip install "diffusers @ https://github.com/huggingface/diffusers/archive/refs/heads/main.zip"
pip install "transformers>=5.17" accelerate safetensors

The text encoder is Qwen3VLForConditionalGeneration, which is why transformers 5.17+ is required. Component sizes: text_encoder 17.53 GB, transformer 14.23 GB (QwenImage21Transformer2DModel, 32 layers, 32 heads x 128), vae 1.35 GB β€” 33.1 GB total in bf16, all of which is resident on the GPU during generation.

Files

file what it is
README.md this document
gen.py the generation script used for both runs (GPU-or-die, prints receipts)

Reproduction

python3 -m venv --system-site-packages ~/build/qwen-image/venv
. ~/build/qwen-image/venv/bin/activate
pip install "diffusers @ https://github.com/huggingface/diffusers/archive/refs/heads/main.zip" \
            "transformers>=5.17" accelerate safetensors

HF_HUB_DISABLE_XET=1 hf download Qwen/Qwen-Image-2.1 --local-dir ~/models/qwen-image-2.1

python gen.py --model ~/models/qwen-image-2.1 --out out/a.png \
  --prompt "A photorealistic red-tailed hawk perched on a saguaro cactus at golden hour" \
  --steps 24 --width 1024 --height 1024 --seed 42

Run it twice. The second run is the honest number.

Licence

Apache-2.0. Weights belong to Qwen under their own licence; this repository contains only measurements and a script.

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for kingjones777/Qwen-Image-2.1-ROCm-gfx1151

Finetuned
(24)
this model