CUDA: size MMQ ids-path tail padding from the flattened row count, not ne11 - #27044
CUDA: size MMQ ids-path tail padding from the flattened row count, not ne11#27044glennneuber wants to merge 1 commit into
Conversation
|
Hi @glennneuber, thanks for your contribution! Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:
Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below. |
The ids branch of ggml_cuda_mul_mat_q() sizes the src1_q8_1 data term from ne12*n_expert_used but the tail-padding term from ne11. The correct row count is computed just below as ne11_flat. For MoE gate/up the activations are broadcast, so ne11 == 1, and ggml_cuda_mmq_get_J_max() returns 0 for that. The buffer then has no tail padding while MMQ reads in tiles of up to 512 rows past the end.
e9dd2c5 to
5d958f7
Compare
|
This is a regression imho. I was able to pin it to a commit. It was introduced by 6eddde0 ("CUDA: refactor MMQ kernel configuration", #24127), build b9992. That commit changed the padding term in both allocation branches: - get_mmq_x_max_host(cc)*sizeof(block_q8_1_mmq);
+ ggml_cuda_mmq_get_J_max(src0->type, fallback, cc, ne11) * sizeof(block_q8_1_mmq);
- get_mmq_x_max_host(cc)*sizeof(block_q8_1_mmq);
+ ggml_cuda_mmq_get_J_max(src0->type, fallback, cc, ne11) * sizeof(block_q8_1_mmq);That is correct for the The difference matters because the two functions have different failure modes. Last clean build is b9990 (259ae1d), first affected is b9992. b9991 is not tagged and the only other commit in that range is Vulkan-only. Bisected by source, then checked at runtime on both sides of the boundary. Same GPU, same request, cold server, first request each time,
For anyone hitting this through ollama: v0.32.1 is the last release on a clean llama.cpp, v0.32.2 is the first affected. |
docs(tasks): the regression comment to post on ggml-org/llama.cpp#27044
Overview
The
idsbranch ofggml_cuda_mul_mat_q()sizes thesrc1_q8_1allocation from two different row counts. The data term usesne12*n_expert_used. The tail-padding term usesne11. The correct value is already computed a few lines below asne11_flat.For MoE gate/up projections the activations are broadcast across experts, so
ne11 == 1.ggml_cuda_mmq_get_J_max()withne11 == 1computesmin(1,512) = 1, then1 - 1%8 = 0, skips its loop and returns 0. The buffer gets no tail padding at all, while MMQ reads in tiles of up toJ_max = 512rows and runs past the end.ffn_downis affected too but less: it passesne11 = 8, so padding is sized for 8 rows instead ofne12*n_expert_used.The
!idsbranch above is correct, because therene11really is the buffer's row count.This patch uses
ne12*n_expert_usedfor the padding term.Additional information
Hit this on a MoE vision model (256 experts, 8 used, q4_K gate/up) on sm_120 / CUDA 13.0 when a whole image was submitted as one 2040-token ubatch:
The failing node is
ffn_moe_gate, withne2=2040 ne02=256 ne11=1 ne12=2040, type q4_K, taking the mmq branch. Thefind_slotline also shows up on runs that do not crash, so it marks the path rather than the fault.Notes for testing:
test-backend-opsdoes not catch it. The over-read lands in padding rows the kernel discards, so output is unchanged and NMSE is unaffected.compute-sanitizer --tool memcheckdoes flag it.512 * sizeof(block_q8_1_mmq)= 72 KB per call, and does not grow withne12.Tested with 4 cold runs on the patched build (no fault) against 2 unpatched controls from the same tree (both fault).
May be related to #24399, #19705 and #18331. I have not reproduced those configurations, so this is a guess, but the
GGML_CUDA_FORCE_CUBLAS=ONworkaround in #24399 skips MMQ entirely and requantising changes the allocation size, which would both hide this.Requirements