feat(cuda): fuse activations and residual add into mmv f/q epilogues#67
Draft
roberteg16 wants to merge 1 commit into
Draft
feat(cuda): fuse activations and residual add into mmv f/q epilogues#67roberteg16 wants to merge 1 commit into
roberteg16 wants to merge 1 commit into
Conversation
Extend the mul_mat_vec_f/q fusion path to fold, into the GEMV epilogue, patterns that previously ran as separate kernels on the decode path: - non-gated unary activation: mul_mat -> [reshape] -> sigmoid|silu - activation followed by an elementwise mul: mul_mat -> [reshape] -> silu -> mul (a per-row activation_mul operand; wins over the standalone unary_mul fusion) - residual add through a view: mul_mat -> reshape -> add The fusions reuse the existing mm_fusion_args plumbing (adding an activation enum and an activation_mul operand) and only touch the non-gated branch of the epilogue, leaving the GLU/gate path unchanged. Detection writes the fused result using the matmul geometry into the final node's buffer; a targeted overlap check allows aliasing the mul/add operand (in-place, same-index) while forbidding aliasing the matmul inputs. On Qwen3.6-35B-A3B (gfx1151, Q4_K_M) decode this folds the beta/shared-expert sigmoids, the gated-norm silu*x, and all attn residual adds into their matmuls; tg128 ~58.7 -> ~59.5 t/s with output unchanged. Co-Authored-By: Claude Opus 4 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the
mul_mat_vec_f/mul_mat_vec_qfusion path to fold several post-matmul patterns into the GEMV epilogue on the decode path (ncols_dst == 1). Each of these previously ran as its own kernel launch. The change is additive and only touches the non-gated branch of the epilogue; the existing GLU / gate fusion path is untouched.What changed
New fused patterns, detected in
ggml_cuda_try_fuseand executed inside the mmv f/q kernels:mul_mat -> [reshape] -> sigmoid|silumul_mat -> [reshape] -> silu -> mul, carried by a new per-rowactivation_muloperand; tried before the standaloneunary_mulfusion so the wholesilu(x) * ycollapses into the matmul instead of leaving themulexposed.mul_mat -> reshape -> add, the common case where a projection output is reshaped before its residual add (e.g. the GDN/linear-attention layers), which the existing{MUL_MAT, ADD}fusion could not match because it requires the ops to be directly consecutive.Implementation notes:
ggml_cuda_mm_fusion_args_{host,device}plumbing, adding anactivationenum (GGML_UNARY_OP_COUNT= none) and anactivation_muloperand. The activation is dispatched at runtime inside the existinghas_fusionpath, so no new template instantiations are added.reshapesits between the matmul and the fused tail, detection writes the result using the matmul geometry into the final node's buffer (the intermediate reshape/activation/mul/add nodes are elided).mul/addoperand (an in-place op reads and writes the same element index), but must not alias the matmul inputs (read across the full reduction). Same-shape + contiguous operands are required.Why
On the decode path these tiny epilogue ops are individual kernel launches whose latency is only partially hidden. Folding them removes launches and, for the
n_embd-sized residual add, an extra HBM round-trip per layer.Measurements
Qwen3.6-35B-A3B, gfx1151 (Strix Halo), Q4_K_M,
llama-bench -pg 0,128 -r 5(decode):silu(z)*norm, absorbed unary_mul)mulafter the silu is folded together with the activation rather than left standalone. The MoEffn_outresidual adds (~60/token) are not folded by design.beta_sigmoid+shared_expert_gate_sigmoid: folded into their matmuls.silu(z) * norm: folded (no leftover standalonemul).attn_residualadds: fully folded (including the reshaped GDN-layer path).ffn_out(MoE) residual adds are left as-is by design: their first operand is the expert-combine output, not a single GEMV, so there is no matmul to fold into.Output verified unchanged (greedy generation coherent).