perf(gqh): GQH matvec for gfx1201 — greedy 28.7 tok/s, MTP n-max=2 50.3 tok/s - #1
Open
DeanoC wants to merge 2 commits into
Open
perf(gqh): GQH matvec for gfx1201 — greedy 28.7 tok/s, MTP n-max=2 50.3 tok/s#1DeanoC wants to merge 2 commits into
DeanoC wants to merge 2 commits into
Conversation
…ebox Drop-in of the evolved gqh.cu/gqh.cuh from geo-lucebox PR ggml-org#32 (software- pipelined wire loads DEPTH=3, ncols launcher specialization, occupancy-fit rows-per-warp arm, one LDS level table per rung). tg64 20.81 -> 28.56 tok/s on the R9700 (gfx1201). The lucebox ggml-cuda.cu gate/up pair fusion is NOT ported (upstream's fusion loop diverged; it was worth ~1%).
…-max=2 33.4 -> 50.3 tok/s) Ten evolved passes on the GQH multi-column matvec, the kernel MTP verify batches run. Measured on an AI PRO R9700 (gfx1201) against Qwen38-27B GQH. The defect: the generic <RUNG,8,1> instantiation re-read activations per (row, superblock, column) -- 1024 B per warp per column against 137 B of wire, ~100 GB of x-reads per column per forward at ~12 TB/s effective, i.e. saturating L0. Weights are read once regardless of N, so N=3 should cost about N=1; instead each extra column cost ~+9 ms. - exact-width multi-column instantiations with a shared activation read - wave-uniform addressing on the multi-column arm - shortened per-superblock dependency chain - a fifth column for the exact-width arm, removing the 31 ms pp5 cliff (out of which MTP n-max=4 went 25.9 -> 41.1 tok/s) - per-column activation addressing fixed beyond two columns Steady-state per-forward (llama-bench -r 12, -b 8 -ub 8): pp1 36.1 ms (unchanged) pp3 64.0 -> 38.6 ms pp5 80.1 -> 44.5 ms greedy tg64 28.7 tok/s (unchanged) End-to-end MTP decode (llama-server, temp 0, prose / code): n-max=2 33.4 -> 50.3 / 48.5 tok/s (accept 63% / 59%) n-max=3 46.0 / 49.5 tok/s (accept 44% / 51%) n-max=4 25.9 -> 41.1 / 45.2 tok/s (accept 34% / 41%) n-max=2 is the config to ship; deeper drafts are now limited by drafter acceptance, not by verify cost. Correctness: two frozen sha gates (plain-greedy for the N=1 path, greedy-MTP for the verify path) byte-equal on every landed pass, accumulation term order untouched. test-gqh-backend 54/54 bit-identical to the f32 reference over 3 rungs x 3 shapes x nvec 1..6, with a non-vacuity control that fails at nvec 5. Instantiations outside the exact-width cells are ISA-identical to base. Three passes deliberately landed nothing and recorded refutations instead: a byte-keyed level table (7% slower -- LDS bank conflicts, proven with an instruction-identical probe), occupancy pressure (16 -> 3 waves/SIMD moves pp3 not at all), and disabling CUDA graphs (-8.3% on the -r 3 scoring rig, +3.4% in steady state -- a scorer-only gain, refused). Full record: geo-evo handoffs/progress-gqh_mtp_multicol.md, commits 12c741f0..2396f01f on gqh/evo-multicol-01.
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.
What
Two commits on the GQH matvec (
ggml/src/ggml-cuda/gqh.cu,gqh.cuh), measured on an AMD AI PRO R9700 (gfx1201, 32 GB) against Qwen38-27B GQH (298 GQH4 / 10 GQH3 tensors, 14.0 GiB):0317ed7— port the batch-1 optimizations from geo-lucebox#32: software-pipelined wire loads (DEPTH=3),ncolslauncher specialization, occupancy-fit rows-per-warp arm, one LDS level table per rung. Greedytg6420.8 → 28.6 tok/s.f8dd7c3— optimize the multi-column arm that MTP verify batches run. Greedy path untouched; MTP n-max=2 33.4 → 50.3 tok/s.The multi-column defect
The generic
<RUNG,8,1>instantiation re-read activations per (row, superblock, column) — 1024 B per warp per column against 137 B of wire. That is ~100 GB of activation reads per column per forward, at12 TB/s effective, i.e. saturating L0. Weights stream once regardless of N, so N=3 should cost about N=1; instead each extra column cost **+9 ms**.Fixes: exact-width instantiations with a shared activation read; wave-uniform addressing; a shortened per-superblock dependency chain; a fifth column for the exact-width arm (removing a 31 ms pp5 cliff); per-column activation addressing corrected beyond two columns.
Benchmarks
Steady-state per-forward (
llama-bench -p 1,3,5 -b 8 -ub 8 -r 12):End-to-end MTP decode (
llama-server --spec-type draft-mtp, temp 0, prose / code prompt):n-max=2 is the config to ship. n-max=4 is no longer a regression, but deeper drafts are now limited by drafter acceptance (63% → 34%), not verify cost — further depth gains are a drafter problem, not a matvec one.
Correctness
Two frozen sha gates on every landed pass — plain-greedy output (N=1 path) and greedy-MTP output (multi-column verify path) — both byte-equal to their references, accumulation term order untouched throughout.
test-gqh-backend54/54 bit-identical to the f32 reference over 3 rungs × 3 shapes × nvec 1..6, with a non-vacuity control that fails at nvec 5 so the new width is provably covered. Instantiations outside the exact-width cells are ISA-identical to base.Refutations (recorded, nothing landed)
Three of ten evolution passes deliberately landed nothing:
-r 3rig but −3.4% in steady state (-r 24): ~23% of a-r 3measurement is one-time graph-capture cost that amortizes. A benchmark-only gain, refused.Two separate changes that cut 15% and 10% of hot-loop instructions both measured slower — on this kernel the currency is memory behavior, not instruction count.
Provenance
Evolved by the geo-evo kernel loop (10 iterations each phase). Full per-iteration record, traces, and measurement caveats:
handoffs/progress-lucebox_gqh_matvec.mdandhandoffs/progress-gqh_mtp_multicol.mdin geo-evo.Measured on gfx1201 only. The width and rows thresholds are runtime-derived but validated on this device alone — a second-device run would be worth having before treating them as general.