Repository navigation
cuda : fuse weighted RMS normalization with SiLU and sigmoid gates - #115
Draft
GenerelSchwerz wants to merge 2 commits into
Draft
GenerelSchwerz wants to merge 2 commits into
GenerelSchwerz wants to merge 2 commits into
Conversation
Assisted-by: Codex
Assisted-by: Codex
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.
Overview
Fuse F32 weighted RMS normalization with an independent same-shape SiLU or sigmoid gate in one CUDA kernel. The existing two-kernel sequence becomes one, removing an intermediate write/read. This extends the previous SiLU-only revision of this PR; it remains independent of activation-reuse PRs #117/#118.
The matcher selects the graph's actual activation, and the kernel specializes SiLU/sigmoid at compile time using the existing scalar formulas. Normalization order, epsilon and weighting remain unchanged. Qwen3.5/Qwen3Next SiLU and Qwen4Exp sigmoid builders expand the independent gate before normalization so eligible graph nodes are adjacent. This is graph dependency ordering, with no model whitelist or new operator.
The four-op closure, F32/layout/shape checks and allocator dependencies remain in place. Broadcast gates, unweighted RMS, extra intermediate consumers, dependent gates, in-place intermediates and other activation functions keep their existing paths. The gated matcher additionally checks output overlap with leaf inputs: a custom output aliasing a broadcast normalization weight reproduced incorrect SiLU results in the previous revision. This revision falls back and matches upstream. Other fusion callers retain their original overlap policy.
Measured operator benefit
RTX 5070 Ti / SM120a, CUDA 13.4.59, release build. Four alternating upstream/previous/new triples per row; complete unprofiled operator-sequence replay, two fresh input/gate passes. Separate CUDA-node profiles prove two kernels become one for eligible SiLU/sigmoid graphs; negative controls keep their kernel counts.
Captured SiLU performance is essentially unchanged versus the previous PR. A tiny graphs-disabled SiLU case is 1.439->1.475us (+2.54% time); this exposes a small direct-execution regression; the added safety/admission work may contribute, but its exact share was not isolated. The matching sigmoid case is 2.758->1.488us versus upstream (46.1% less time). Broadcast-gate controls are flat. Ranges and all negative/neutral results are retained. These component gains are not model throughput gains.
Model regression and limits
Qwen3.5-0.8B Q4_0 supplied-token C1/C4 evaluations use 128 calls, 32 warmups excluded, all GPU layers, F16 KV, FlashAttention and four CPU threads. Four alternating triples: complete first-two/last-two float-logit rows match upstream/previous/new. Previous/new means are 1488.751/1488.215us at C1 and 1948.236/1949.478us at C4, essentially flat.
Full no-MTP Qwen3.5 requests use 9303 real-text prompt tokens and 2048 generated tokens. Eight previous/new requests in ABBA then BAAB have identical complete token IDs and output bytes. The first block shows -2.31% candidate decode throughput, the reversed block +0.51%. Combined means are 488.894/484.366tok/s, with overlapping ranges 478.137-502.212/480.321-490.973. No serving improvement or universal performance guarantee is claimed.
No Qwen4Exp model is installed for a full-model sigmoid run. Sigmoid is proved in upstream operator graphs; its model builder ordering is source-reviewed. Full-model sigmoid speed, a Qwen3Next request, older GPUs, HIP, Windows and multi-GPU are not validated. F16/BF16, broadcast gates, nonadjacent matching and additional gate functions remain outside this scoped fusion.
Validation and reproduction
Both shared build/GPU locks are held for each complete suite. The external correctness resume uses two workers; all profiles, memory checks, performance repeats and serving requests run sequentially. Completed backend regressions are retained rather than repeated after an external-harness construction correction. The existing tester supports
-jfor future correctness runs.Build with
-DGGML_CUDA=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_CUDA_ARCHITECTURES=120. Focused command:test-backend-ops test -b CUDA0 -j 2 -o RMS_NORM_SIGMOID,RMS_NORM_SILU,RMS_NORM,RMS_NORM_MUL_ADD,RMS_NORM_MUL_ROPE,L2_NORM,MOE_REDUCE,GATED_DELTA_NET; repeat with graphs disabled and focused fusion disabled. Parallel backend mode is a reproduction option; this revision's recorded backend passes used one worker.Official base
dcd387a412ca54e172a8d60eb71ef6753850c8ca; previous PR40957049604ed0fc37892bc37fbe142224ecf8e0; measured revision4b88fc8c60b32ebf7fa593cbb5adad699877700c. Exact commands, source/binary/model hashes, helper sources, raw results, outputs and teardown records are retained locally under/home/gencoolpc/moe-cache-tests/results/upstream-kernel-series-20261001:RMS-GATED-EVIDENCE.md,RMS-GATED-MANIFEST.jsonandRMS-GATED-*.json.Requirements