Skip to content

CUDA: only disable CUDA graphs when mul_mat_id actually needs a stream sync - #26802

Merged
ggerganov merged 1 commit into
ggml-org:masterfrom
grafail:cuda-mmid-graphs
Aug 11, 2026
Merged

CUDA: only disable CUDA graphs when mul_mat_id actually needs a stream sync#26802
ggerganov merged 1 commit into
ggml-org:masterfrom
grafail:cuda-mmid-graphs

Conversation

@grafail

@grafail grafail commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

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_ID passes, 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:

npl tg t/s master tg t/s PR speedup
4 807.49 813.72 1.01
16 1400.80 1580.76 1.13
32 2250.95 2434.14 1.08

bf16 decode, CUDA_VISIBLE_DEVICES=0 llama-bench -ngl 99 -fa 1 -p 0 -n 128 -r 5:

model config tg128
LFM2-8B-A1B BF16 master 357.17 +/- 0.64
LFM2-8B-A1B BF16 PR 374.34 +/- 3.04
LFM2-8B-A1B BF16 PR + GGML_CUDA_DISABLE_GRAPHS=1 357.29 +/- 0.65

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):

model config tg64
GLM-5.2 753B UD-IQ1_S master 50.52 +/- 0.65
GLM-5.2 753B UD-IQ1_S PR 50.45 +/- 0.82

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: Yes, I used AI to write code, review changes and verify the factuality of the overview I provided. I take full responsibility for the code in this PR.

@grafail
grafail requested review from a team and ggerganov as code owners August 9, 2026 12:10
@github-actions github-actions Bot added testing Everything test related ggml changes relating to the ggml tensor library for machine learning CUDA Related to the CUDA backend labels Aug 9, 2026
@am17an

am17an commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

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.

if (ggml_cuda_should_use_mmq(src0->type, cc, ne12, /*n_experts=*/ne02)) {
ggml_cuda_mul_mat_q(ctx, src0, src1, ids, dst);
return;
}

@grafail grafail changed the title CUDA: only disable CUDA graphs when mul_mat_id actually needs a stream syncc CUDA: only disable CUDA graphs when mul_mat_id actually needs a stream sync Aug 9, 2026
@grafail

grafail commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

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.

if (ggml_cuda_should_use_mmq(src0->type, cc, ne12, /*n_experts=*/ne02)) {
ggml_cuda_mul_mat_q(ctx, src0, src1, ids, dst);
return;
}

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.

@am17an am17an added the merge ready A maintainer can use this label to indicate that they consider the changes final and ready to merge. label Aug 10, 2026
@am17an

am17an commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Tested this locally and didn't find any issues. Should be good to merge

@ggerganov
ggerganov merged commit ebb546b into ggml-org:master Aug 11, 2026
27 of 32 checks passed
gabe-l-hart added a commit to gabe-l-hart/llama.cpp that referenced this pull request Aug 12, 2026
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)
  ...
huaxel pushed a commit to huaxel/CachyLLama that referenced this pull request Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CUDA Related to the CUDA backend ggml changes relating to the ggml tensor library for machine learning merge ready A maintainer can use this label to indicate that they consider the changes final and ready to merge. testing Everything test related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants