CUDA: only disable CUDA graphs when mul_mat_id actually needs a stream sync - #26802
Conversation
|
Most of the time it does not need a sync as we use the MMQ path which does not synchronize. It's just that we haven't enabled CUDA graphs for them, we can try doing that as it is a more useful change than bf16/f16 experts. llama.cpp/ggml/src/ggml-cuda/ggml-cuda.cu Lines 1898 to 1901 in 09b4774 |
The predicate already handles that case, it keys on whether the sync fallback would actually run, so quantized models above the MMVQ batch limit that go through MMQ keep CUDA graphs too. Measured on Qwen3-30B-A3B Q4_K_M with llama-batched-bench: +13% tg at npl=16 and +8% at npl=32 (npl=4 unchanged since both builds have graphs there). Added the tables to the description. |
|
Tested this locally and didn't find any issues. Should be good to merge |
Signed-off-by: Gabe Goodhart <ghart@us.ibm.com> * origin/master: (383 commits) cmake : introduce semantic versioning (ggml-org#26839) gguf : harden loader against malformed tensor dims and metadata types (ggml-org#25596) kleidiai: Add runtime feature detection mechanism for aarch64/kleidiai (ggml-org#26076) model : disallow integer dflash sliding_window_pattern (ggml-org#26900) sync : ggml cmake : add config version support (ggml/1582) server : support slot save/restore with media inputs (ggml-org#26640) ui: add read_media tool (ggml-org#25877) opencl: default FA c8 cluster width to 16 on X1E (ggml-org#26433) tests : update speculative params (ggml-org#26925) vulkan: add TQ2_0 (ternary) support (ggml-org#25850) wavtokenizer-dec : bound posnet/convnext block_count against n_layer_all (ggml-org#26892) convert : handle per_layer_config in Gemma4 (transformers 5.15) (ggml-org#26882) opencl: use flat mv q5_k when weight exceeds image1d_buffer_t limit (ggml-org#26880) chat : fix muse-glimmer detection of tool calls after EOM (ggml-org#26879) ci : add missing release check (ggml-org#26923) CUDA: only disable CUDA graphs when mul_mat_id actually needs a stream sync (ggml-org#26802) cuda : add warp-per-row wkv7 kernel for single-token decode (ggml-org#26111) spec : update speculative-simple (ggml-org#26904) chat : tighten bare function parsing for Qwen models (ggml-org#26793) ...
Overview
CUDA graphs are currently disabled for any model with a MUL_MAT_ID node that is unquantized or over the MMVQ batch limit, even though MMQ and MMF serve most of those cases without a stream sync. This affects quantized MoE models in parallel decode (which take the sync-free MMQ path) and bf16/f16 MoE models everywhere, including batch-1 decode. Refines the check from #18958: adds a predicate that mirrors the mul_mat_id dispatch exactly and only disables graphs when the sync fallback would actually run. The fallback now asserts the predicate (resolving the existing TODO), so any future drift between the two aborts loudly instead of corrupting graph capture.
Also adds bf16 MUL_MAT_ID eval cases to test-backend-ops, since bf16 experts now run under captured graphs via MMF.
test-backend-ops test -b CUDA0 -o MUL_MAT_IDpasses, including the new bf16 cases.Parallel decode on a quantized MoE,
llama-batched-bench -m Qwen3-30B-A3B-Q4_K_M.gguf -ngl 99 -fa on -c 8192 -npp 64 -ntg 64 -npl 4,16,32, RTX 5090, CUDA 13.3, vs master 7ba604f. At npl above the MMVQ batch limit the experts take the sync-free MMQ path, so the PR keeps CUDA graphs there. npl=4 is a control where both builds already have graphs:bf16 decode,
CUDA_VISIBLE_DEVICES=0 llama-bench -ngl 99 -fa 1 -p 0 -n 128 -r 5:The third row reproduces master, so the whole gain is the graphs restoration.
No-regression control on a quantized model at batch 1 (
-n 64 -r 3, 8x GPU layer split):Requirements