Skip to content

fused_gr: TILE=1280 kernel specialization for sm_75 (Turing) down-projection - #258

Closed
hireymage wants to merge 1 commit into
Niko1221:mainfrom
hireymage:sm75-tile1280
Closed

hireymage wants to merge 1 commit into
Niko1221:mainfrom
hireymage:sm75-tile1280

Conversation

@hireymage

Copy link
Copy Markdown

Title:
fused_gr: TILE=1280 kernel specialization for sm_75 (Turing) down-projection

Body:

What this does

On Turing (sm_75) the fused gate/rescale down-projection kernel runs with
the default tile geometry sized for larger shared-memory budgets. Turing
has 64 KiB of shared memory per block (opt-in), which fits a different,
more efficient shape: a TILE=1280 specialization fits 8 activation
tokens in a single ~40 KiB launch
instead of the default tile's
smaller working set, and drops register pressure (REG 76 → 64) enough to
raise occupancy.

  • Adds a sm_75-guarded TILE=1280 instantiation of the down-projection
    kernel alongside the default geometry.
  • Bit-exact: the kernel still accumulates in strictly increasing
    (tile, chunk) order, so results are unchanged — verified greedy
    generation matches the default build with temperature 0.
  • No effect on other architectures (guarded, default path untouched).

Measured on my machine

i7-8700K (AVX2), RTX 2070 (sm_75), Qwen3.8-Flash-Next native Q2_0 pack
(spec verified from the GGUF header, ~125.7B-parameter MoE), standalone
kernel microbench, temperature 0.

  • Kernel level (verify-window timing of the down-projection launches,
    stage profiler on):
    • GDN down: 2.73–2.80 → 1.88–1.98 ms/window (−30 %)
    • QSA down: 0.90–0.93 → 0.62–0.65 ms/window (−30 %)
  • End to end on this rig: within noise, because decode is CPU
    expert-pool bound here
    (the CPU AVX2 expert pool dominates the
    window). This change frees GPU time the CPU cannot consume yet, so its
    end-to-end benefit should appear on rigs with a faster CPU or a larger
    model where the GPU down-projection is the bottleneck.
  • Profiling context (Nsight Compute, verify-window kernel capture): the
    grouped-expert kernels on sm_75 are L1TEX-pipe bound (~95 % of peak,
    DRAM ~22–33 %), driven by uncoalesced 8-byte weight reads. The tile
    change improves occupancy and per-launch batching without touching the
    access pattern or the summation order.

Please test on other devices

I can only measure one machine. This is a Turing-specific specialization,
so other sm_75 cards (RTX 2060/2070/2080 variants) are the direct target:

  • RTX 20-series owners: please rerun a fixed-prompt greedy decode
    (temperature 0) before/after and compare wall-clock decode time, and
    ideally per-window kernel time if you use the stage profiler.
  • Non-Turing GPUs should be unaffected (guard), but confirmation is
    welcome — especially Ampere+ cards with the larger default smem budget,
    to confirm the default path is untouched.
  • Rigs with fast CPUs (where GPU decode share is larger) are where the
    end-to-end effect should actually show.

Greedy outputs should be identical before/after; if you see a difference,
that's a bug, please report it.

…nged

Turing (sm_75) opt-in shared memory is 64 KiB. With the old fixed
TILE=2560 staging the down kernel could hold at most 6 tokens
(2560*6*4 = 60 KiB), so 7+ token windows split into two launches and,
more importantly, a single 40 KiB tile at T=4 filled the SM so only
one block per SM fit next to the resident expert/attention work.

Specialize gr_down_multi_kernel on the per-token tile size:
- sm_75: TILE=1280 -> up to 8 tokens staged in one 40 KiB launch
  (kFusedGrMaxT=8 covered), and T-token tiles fit 1-3 blocks/SM
  depending on T, so concurrent hc lanes can overlap.
- every other arch keeps TILE=2560 exactly as before.

Per-lane weight chunk order within a tile stays strictly increasing
in (tile, chunk), so the accumulation order for every (expert, row)
is identical to the 2560 path and results are bitwise unchanged.

Measured on RTX 2070 (8700K host, engine 0.1.27, Qwen3.6 125B Q2_0,
29K context, temperature 0, identical benchmark): GDN hc0 down
2.73-2.80 -> 1.88-1.98 ms/window (-30%), QSA hc0 down 0.90-0.93 ->
0.62-0.65, up/norm kernels unchanged, GPU util 91.7 -> 93.5%,
decode tok/s slightly higher on average (within per-run noise;
window is CPU expert-scheduling bound).

Co-Authored-By: Claude <noreply@anthropic.com>
@BlueKingMuch

Copy link
Copy Markdown
Contributor

Data point for Ada: forced on an RTX 4080 SUPER (sm_89; IQ3_S, 262K, 8K context, STRATA_VERIFY_PROFILE=1), the 1280 tile also speeds up v1's down projection: read-1 down 1.02 -> 0.92 ms per window (DeltaNet 0.77 -> 0.69, attention 0.25 -> 0.23), read 2 + router 2.80 -> 2.70 ms. GPU wait per round in deterministic requests (no prompt-lookup drafts, no expert swaps; profiling on): 12.60 -> 12.21 ms greedy, 12.98 -> 12.47 ms sampled. Same tokens. So limiting it to sm_75 may leave a little on the table on sm_89 as well.

@Niko1221

Niko1221 commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Released in 0.1.31: rebased onto 0.1.30's pre-Volta capacity rule; bitwise identical on our cards. Merged under your name (GitHub doesn't show it as merged because it went in by hand). Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants