Skip to content

vulkan: chunk batched mat-vec at the column counts that are slow on RDNA3.5 - #1

Merged
dzannotti merged 1 commit into
masterfrom
vulkan/mmv-split-rdna35
Aug 28, 2026
Merged

dzannotti merged 1 commit into
masterfrom
vulkan/mmv-split-rdna35

Conversation

@dzannotti

@dzannotti dzannotti commented Aug 27, 2026 •

Copy link
Copy Markdown
Collaborator

On Strix Halo (RADV, Mesa 26.1) the mat-vec shader variants for 3, 5 and 6 columns — and 4 for q4_K — run several times slower per call than 1, 2 and 4. GGML_VK_PERF_LOGGER on Qwen3.8-Flash-Next: the q6_K LM head 2.24 ms at n=1/2/4 but 12.8 at 3 and 18.5 at 5; q8_0 10240x2560 122 us at 1, 734 at 3, 1177 at 5; q4_K 12288x2560 85 us at 1, 180 at 4. Speculative verification and multi-slot decode live exactly there.

Such batches are dispatched as chunks of column counts measured to scale, at the cost of re-reading the weights once per chunk. 9–16 columns stay on chunked mat-vec rather than the mat-mat kernels, which are worse still at those widths. q8_0 at two columns stays off the q8_1 integer-dot path, where it is 19x slower than f32. GGML_VK_MMV_NO_SPLIT=1 disables all of it.

Measured: four bare slots decoding concurrently 53.5 t/s aggregate (14.4 each) against 47.8 on ROCm; every shape in the census fixed; single-stream within noise.

Scope: gated on VK_VENDOR_ID_AMD and env-disableable — behaviour is unchanged on every other vendor. It is a driver/hardware heuristic tuned for RDNA3.5, which is why it is here rather than in halo-box/llama.cpp.

Build-verified with -DGGML_VULKAN=ON on fedora:44 (vulkan-headers, glslc, glslang, spirv-tools — same toolchain as mimiron/llamacpp-vulkan's build stage).

…DNA3.5

On Strix Halo (RADV, Mesa 26.1) the mat-vec shader variants for 3, 5 and 6
columns -- and 4 for q4_K -- run several times slower per call than 1, 2 and
4. GGML_VK_PERF_LOGGER on Qwen3.8-Flash-Next: the q6_K LM head 2.24 ms at
n=1/2/4 but 12.8 at 3 and 18.5 at 5; q8_0 10240x2560 122 us at 1, 734 at 3,
1177 at 5; q4_K 12288x2560 85 us at 1, 180 at 4. Speculative verification and
multi-slot decode live exactly there.

Such batches are dispatched as chunks of column counts measured to scale
({4,2,1} for q8_0 and q6_K, pairs for the other quants), at the cost of
re-reading the weights once per chunk; 9-16 columns are kept on chunked
mat-vec instead of the mat-mat kernels, which are worse still at those widths
(a 3.3 MB q8_0 weight at n=21: 756 us against 17.5 per mat-vec column); and
q8_0 at two columns stays off the q8_1 integer-dot path, where it is 19x
slower than the f32 path. GGML_VK_MMV_NO_SPLIT=1 disables all of it.

Measured on the same tree: four bare slots decoding concurrently 53.5 t/s
aggregate (14.4 each) against 47.8 on ROCm; every shape in the census fixed;
single-stream within noise.

(cherry picked from commit d737d6e)
@dzannotti

Copy link
Copy Markdown
Collaborator Author

I have not tried it but i'm assuming so because i don't think this change is model specific even if it was benchmarked with one. Happy to test it further before merging

@dzannotti

Copy link
Copy Markdown
Collaborator Author

this seems to bring no difference to 27B performance but affects Flash-Next version so worth merging

@dzannotti
dzannotti merged commit ca94157 into master Aug 28, 2026
@dzannotti
dzannotti deleted the vulkan/mmv-split-rdna35 branch August 28, 2026 10:43
gaetan-puleo pushed a commit to rcfa/strix-llama.cpp that referenced this pull request Oct 16, 2026
gaetan-puleo pushed a commit to rcfa/strix-llama.cpp that referenced this pull request Oct 16, 2026
…sured

The column chunking (halo-box#1) was measured on Qwen3.8-Flash-Next, where the hot
shapes are q8_0 and q6_K. The K-quants and the q4_0 family were put on a
2-column chunk without a measurement, and on a dense Qwen3.8-27B UD-Q4_K_XL
that re-reads 16 GiB of weights once per chunk for nothing: the single
dispatch scales fine at 3, 5, 6 and 8 columns there.

llama-bench pp tok/s, Vulkan (RADV, Mesa 26.1.7), -b 8:

  cols     master   NO_SPLIT   ggml-org d08c787
  2        23.5     23.0       23.0
  3        23.0     32.9       33.1
  5        28.5     43.1       46.7
  8        28.8     47.4       59.9

Restrict chunking, and the 9..16 column chunk path, to q8_0 and q6_K. Every
other type takes upstream's dispatch. GGML_VK_MMV_NO_SPLIT=1 still disables
the rest.

MTP decode on the same model (n_max 4, 3 runs): 9.6/9.8/9.9 tok/s on master
-> 14.8/15.1/15.2 with this change (15.6/15.9/15.7 with NO_SPLIT, the q6_K
tensors of this model are still chunked). Fixes halo-box#25 together with the
n_rs_seq change.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_01LTnaB4ucGc5vkzctYns4Nq
(cherry picked from commit d22fa65)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant