CUDA: extend MOE fusion to specdec, earlier MOE glu fusion and topk-router fusion were restricted to 1 token - #27621
Conversation
|
The only reason to not do it earlier was because of the compile times. Can you check whether compile times blow up because of this? If so, we can move mmvq into separate compilation units. EDIT: Okay disregard above, this is using the MoE kernel created by @gaugarg-nv, so this should not affect compile times |
| switch (active_glu) { | ||
| case GGML_GLU_OP_SWIGLU: | ||
| result *= ggml_cuda_op_silu_single(gate_value); | ||
| break; | ||
| case GGML_GLU_OP_GEGLU: | ||
| result *= ggml_cuda_op_gelu_single(gate_value); | ||
| break; | ||
| case GGML_GLU_OP_SWIGLU_OAI: | ||
| result = ggml_cuda_op_swiglu_oai_single(gate_value, result); | ||
| break; | ||
| default: | ||
| result = result * gate_value; |
There was a problem hiding this comment.
let's also add sqrtsoftplus used for deepseek4
There was a problem hiding this comment.
I might be missing something here, I don't see sqrtsoftplus in the glu op enum
Line 623 in c060ca9
llama.cpp/ggml/src/ggml-cuda/ggml-cuda.cu
Line 2825 in c060ca9
There was a problem hiding this comment.
Ah okay, then that can be done in a follow-up PR. I was thinking I already added it in #25896
|
Can we add a test-case for the new multi-token test_topk_moe case? |
Eval test are already there (for 1,4,8,9,22 rows) |
Performance sweep DGX Spark
|
ORippler
left a comment
There was a problem hiding this comment.
Thanks! Some more comments from my side, but looking mostly good
| // With multiple rows, keep all rows in one block so no row overwrites logits before another row reads them. | ||
| if (is_topk_moe && ggml_nrows(cgraph->nodes[node_idx]) <= TOPK_MOE_ROWS_PER_BLOCK) { |
There was a problem hiding this comment.
Please check for memory-aliasing aliasing with * bias (applications outside of llama.cpp may not have bias as run-time constants/weights)
There was a problem hiding this comment.
bias is model weight so it can never collide with scratch output right
There was a problem hiding this comment.
For external applications you are right, updated to exempt only logits
22cf151 to
78a8219
Compare
…outer fusion were resticted to 1 token Signed-off-by: ynankani <ynankani@nvidia.com>
Signed-off-by: ynankani <ynankani@nvidia.com>
Signed-off-by: ynankani <ynankani@nvidia.com>
78a8219 to
2373d10
Compare
…outer fusion were restricted to 1 token (ggml-org#27621) * CUDA: extend MOE fusion to specdec, earlier MOE glu fusion and topk-router fusion were resticted to 1 token Signed-off-by: ynankani <ynankani@nvidia.com> * Address review comments Signed-off-by: ynankani <ynankani@nvidia.com> * Add SWIGLU_CLAMP case to multi-token moe fusion Signed-off-by: ynankani <ynankani@nvidia.com> --------- Signed-off-by: ynankani <ynankani@nvidia.com>
… to own fork - cherry-pick upstream ggml-org/llama.cpp#27621 (minus SWIGLU_CLAMP) onto bmoe/expert-ready-hook: fused mul_mat_vec_q_moe handles N>1 batches, topk_moe router 4->8 rows/block, relaxed MMID/alias guards - test-backend-ops: unconditional m_batch {2,4,8} fusion cases + topk boundary cases; 900/900 MUL_MAT_VEC_FUSION + 416/416 TOPK_MOE on CUDA0 - submodule: Helldez/llama.cpp -> OllyJohnston/llama.cpp (public fork), pin 493fe5566 -> 0fe77575e (full fork line incl. port) - docs/seam.md + CHANGELOG 0.24.0 + engine version bump
KV restore batching (ggml-org#27991), kv-cells seq-scan early stop (ggml-org#28011), MOE fusion to specdec + multi-token (ggml-org#27621), mm_ids_helper templated fast path (ggml-org#27978), qwen4exp recurrent state rollback (ggml-org#28123), n_layer_nextn load order (ggml-org#28159), FA K/V XOR-swizzle smem tiles (ggml-org#25635), --lazy-mode -lzm (ggml-org#27837/ggml-org#27969). TQ3/TurboQuant stack and vitriol-* integration auto-merged clean; no conflicts. Experiment E1 of mining-experiment-master-plan-2026-09-01.
…outer fusion were restricted to 1 token (ggml-org#27621) * CUDA: extend MOE fusion to specdec, earlier MOE glu fusion and topk-router fusion were resticted to 1 token Signed-off-by: ynankani <ynankani@nvidia.com> * Address review comments Signed-off-by: ynankani <ynankani@nvidia.com> * Add SWIGLU_CLAMP case to multi-token moe fusion Signed-off-by: ynankani <ynankani@nvidia.com> --------- Signed-off-by: ynankani <ynankani@nvidia.com>
…outer fusion were restricted to 1 token (ggml-org#27621) * CUDA: extend MOE fusion to specdec, earlier MOE glu fusion and topk-router fusion were resticted to 1 token Signed-off-by: ynankani <ynankani@nvidia.com> * Address review comments Signed-off-by: ynankani <ynankani@nvidia.com> * Add SWIGLU_CLAMP case to multi-token moe fusion Signed-off-by: ynankani <ynankani@nvidia.com> --------- Signed-off-by: ynankani <ynankani@nvidia.com>
Overview
This PR extends the BS=1 MoE fusions in the CUDA backend to specdec 2-8 tokens, like MTP and Dflash. The main idea is that mul_mat_vec_q_moe kernel now folds the gate projection, biases, the per-expert NVFP4 scales, the gate scale, and the GLU into the up projection, and the topk_moe router fusion(softmax->topk->get_rows earlier only for nrows==1) is extended to higher batches like 4, this can be further increased to 8 so that fusion can be applied to the full block of 8 rows. This gives 2–22% E2E decode speed-up depending on model, quant, and draft width, with the largest gains at draft widths 2 and 4.
Additional information
Below scores are collected on RTX-PRO-BLACKWELL 6000
Seeing more perf benefit with NVFP4, as scale fusion is also done in it
I will be collecting more perf data on different hardware (WIP)
Requirements