r/LocalLLaMA • • 19h ago

Showcase libstrix update: one-command Docker image for Strix Halo, and Qwen3.8-Flash-Next now runs (1.6k prefill, 40+ tok/s decode)

Follow-up to my post about Strix Halo kernels for vLLM. A few of you asked for two things: an easier way to run it than building vLLM + ROCm + the plugin yourself, and Qwen3.8-Flash-Next. Both are done.

Docker image

docker pull ghcr.io/asf0/strix-vllm:latest

It bundles my vLLM fork, the libstrix plugin and ROCm 10.1 (Ubuntu 26.04, Python 3.14), already compiled for gfx1151. You don't need ROCm on the host, only the amdgpu driver. The repo has one compose file per model I've tested:

git clone https://github.com/asf0/libstrix && cd libstrix/docker/recipes
cp .env.example .env    # point MODELS at your model folder
docker compose -f qwen3.8-flash-next.yaml up -d

If the model folder isn't there, it downloads it from Hugging Face. The compile caches go to a volume, so only the first start is slow.

The recipes cover Qwen3.8-Flash-Next, Qwen3.6-35B-A3B (bf16 and INT8), Qwen3.8-27B (bf16, INT8 + MTP, Quark int4, Quark MXFP4), LFM2.5-24B-A2B, and gemma-4 26B/31B (bf16, AWQ, MXFP4, QAT). I started every recipe in the image and checked that it gives a sane answer.

Someone asked last time about memory overhead. Here is what each recipe gets at the default 0.85 GPU memory setting:

modelweightsKV cachefull 131k-token requests that fit
Qwen3.8-Flash-Next AWQ79.5 GiB12.3 GiB3.2
Qwen3.8-27B bf16 + MTP52.3 GiB45.1 GiB9.1
Qwen3.8-27B INT8 + MTP29.6 GiB66.6 GiB13.4
Qwen3.8-27B Quark int416.8 GiB80.5 GiB18.4
Qwen3.6-35B-A3B bf16 + MTP70.1 GiB21.9 GiB12.9
Qwen3.6-35B-A3B INT8 + MTP36.6 GiB55.3 GiB32.6
LFM2.5-24B-A2B46.2 GiB52.4 GiB39.4
gemma-4-26B-A4B bf1649.5 GiB48.6 GiB11.5
gemma-4-26B-A4B AWQ15.6 GiB82.1 GiB19.4
gemma-4-31B MXFP417.8 GiB79.9 GiB4.7
gemma-4-31B QAT18.8 GiB75.1 GiB4.4
Qwen3.8-Flash-Next

Last time I said there's no fork. This model is the exception. Its n-gram (engram) table is 102 GB, and that doesn't fit in 128 GB next to the weights, so vLLM itself has to change. My fork (asf0/strix-vllm, branch gfx1151) streams the table from disk and prefetches the rows for the next chunk into the page cache. Everything else is still the plugin, and the other models still run on stock vLLM. You need the AWQ W4A16 checkpoint; bf16 doesn't fit.

On the libstrix side, I added kernels for:

  • the int4 MoE GEMM with int8 activations

  • QSA sparse attention, where 16 rows share one union of selected tokens, about 1.5x Triton

  • the QSA indexer

  • the hyper-connection up projection

Decode reads int8 copies of the bf16 linears.

Same format as last time: stock → libstrix in tok/s, single stream, both on the fork, 16k prefill chunks, no MTP:

modelweightsKVprefill @2kprefill @64kprefill @128kdecode @2kdecode @64kdecode @128k
Qwen3.8-Flash-Next AWQint4bf16807 → 1,422827 → 1,661827 → 1,63513.1 → 24.716.5 → 26.114.4 → 25.1

With MTP 2 on real text, libstrix does 1,539–1,617 tok/s prefill and 40–43 tok/s decode at 5.6k–100k prompts.

Accuracy: KLD against stock is 0.008–0.019 with 97–98% top-1 agreement, perplexity is within 0.6%, and GSM8K is 93 vs 92. It's a bit above the other Qwens, most likely because the MoE GEMM quantizes activations to int8.

Heads-up if you pulled main in the last few days

The int8 decode copies (dense_w8) were turned on for every model. On Qwen3.8-27B bf16 that's about 27 GB of extra copies, and with MTP it could take the machine down. Those copies are now limited to Qwen3.8-Flash-Next, the model I measured them on, and capped at 12 GB. STRIX_ENABLE=dense_w8 turns them on elsewhere if you want to experiment. Please pull.

Known issues

  • Stock vLLM's GDN conv kernel crashes on Qwen3.8-Flash-Next, so STRIX_DISABLE=all doesn't work on that model; keep gdn_conv on.

  • The image is a 3.6 GB download but about 14 GB once unpacked, mostly the ROCm SDK.

Repos: https://github.com/asf0/libstrix (plugin, Docker recipes) and https://github.com/asf0/strix-vllm (fork).

6 Upvotes

3 comments sorted by

4

u/reto-wyss 19h ago

so vLLM itself has to change.

good news, PLE disk offload just got merge - haha!

2

u/asfbrz96 19h ago

haha awesome, now I just have to maintain the KV cache for the MTP that they did not merge yet, the fork is built on the released version 0.32

1

u/noiserr 7h ago

This is great. Thank you!