Skip to content

perf(qwen35): fused Q4K/Q6K->int8 dequant + token-parallel GDN conv + lane-parallel fallback attention (+78% pp @32k on top of #465)#464

Merged
skyrocket2026 merged 1 commit into
gittensor-ai-lab:mainfrom
James-CUDA:perf/prefill-attn-lane-par
Jul 16, 2026
Merged

perf(qwen35): fused Q4K/Q6K->int8 dequant + token-parallel GDN conv + lane-parallel fallback attention (+78% pp @32k on top of #465)#464
skyrocket2026 merged 1 commit into
gittensor-ai-lab:mainfrom
James-CUDA:perf/prefill-attn-lane-par

Conversation

@James-CUDA

@James-CUDA James-CUDA commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Three profiling-guided fixes to the Qwythos (Qwen3.5) batched-prefill path. Rebased on and composing with the merged #463 (half-precision smem tiles) and #465 (int8-MMA prefill attention): the two big wins here are in stages #465 doesn't touch, and they stack on top of it.

  1. Fused Q4_K/Q6_K → int8-row dequant (dequant_gguf.cu). Every projection dequantized the weight to a bf16 scratch (2B/value written) then re-read and row-quantized it to int8 for the perf(qwen35): int8 tensor-core prefill GEMM for Qwythos [DRAFT — awaits #398] #422 int8 tensor-core GEMM. deq_rows_i8_kernel decodes superblocks in registers and writes int8 + per-row scale directly (1B/value, no bf16 bounce), one block per row instead of one thread per superblock. The N <= 8192 int8-GEMM gate is also lifted — int8 scratch moves to its own arena, so an alloc failure at huge N degrades to the bf16 GEMMs instead of the token loop (this is why main's pp32k ran bf16 GEMMs until now).
  2. Token-parallel GDN conv (batched_prefill.cu). pf_gdn_conv_kernel looped all N tokens sequentially with a __syncthreads() per token on only 64 blocks (2.7 ms/layer, ~21 ms/layer at 32k). The causal 4-tap conv reads only in-buffer raw inputs (the prompt starts at position 0), so it is token-parallel: one block per (token, head), ~0.1 ms/layer. Same taps/SiLU/L2-norm math and conv-state layout. SPARKINFER_PREFILL_GDN_CONV_SEQ=1 restores.
  3. Lane-parallel prefill attention (prefill_attn_window.cu) — written before perf(qwen35): int8 tensor-core prefill attention for Qwythos #465 landed; with perf(qwen35): int8 tensor-core prefill attention for Qwythos #465's MMA kernel default-on this now only upgrades the SPARKINFER_PREFILL_ATTN_MMA=0 fallback path (the scalar kernels walk keys one per query-warp with a 5-shuffle reduce + two dependent expf per key; this one scores 32 keys per warp in parallel, 18.3 → 5.7 ms/layer, exact fp32 math). Kept env-gated (SPARKINFER_PREFILL_ATTN_LANEPAR=0 restores the scalar kernels); no effect on the default MMA path.

Decode paths, CUDA graphs, and the Qwen3.6 model are untouched.

Proof of speedup

  • Tested on RTX 5090 (sm_120)

Decode tok/s (end-to-end, from bench/scripts/bench.sh — fill if this PR targets decode):

decode tok/s
before (main) 295.54
after (this PR) 295.34

This PR does not target decode and does not modify the decode path. The row above is a
no-regression check at ctx=4096, not a claimed gain (-0.07% is run noise). The prefill
table below is the actual claim.

Prefill pp tok/s (Qwythos / Qwen3.5 — fill if this PR targets prefill; use --ctx 4096, 32768,
65536, or 131072 and copy the prefill pp line — report your best context):

prefill pp tok/s
before prefill (main) 8419.18
after prefill (this PR) 14951.55
# qwen3_gguf_bench (the binary bench/scripts/bench.sh wraps), RTX 5090 sm_120,
# Qwythos-9B-Claude-Mythos-5-1M-Q4_K_M, default path, post-warmup, 3-rep median.
# before = clean clone of main @ 9fdf68a (includes #463 + #465), same box, same build flags.

### BEFORE (main @ 9fdf68a)
SWEEP_JSON {"4096":{"decode_tps":295.5379,"prefill_pp":8457.7366},
            "32768":{"decode_tps":294.1757,"prefill_pp":8419.1842}}

### AFTER (this PR, rebased on 9fdf68a)
SWEEP_JSON {"4096":{"decode_tps":295.3402,"prefill_pp":13987.3013},
            "32768":{"decode_tps":293.9429,"prefill_pp":14951.5538}}

ctx=4096   prefill pp   8457.74 -> 13987.30  (+65%;  llama.cpp same box: 11741.24)
ctx=32768  prefill pp   8419.18 -> 14951.55  (+78%;  llama.cpp same box: 10413.76)

Correctness. qwen3_gguf_prefill_check (batched prefill vs token-by-token fill, prefix 4096,
cont 16), same box, same build flags, both on top of the merged int8-MMA attention:
this PR top-1 13/16 · KL 0.0164 · seed 290 vs main @ 9fdf68a top-1 13/16 · KL 0.0152 ·
seed 290
— identical top-1 and seed, KL at the same level. (The fused dequant quantizes from
the exact fp32 dequant instead of the bf16-rounded scratch — pre-#465 it measured tighter than
the then-main: KL 0.0164 vs 0.0191.) ctest 7/7 pass.

@James-CUDA
James-CUDA marked this pull request as draft July 16, 2026 06:03
@James-CUDA
James-CUDA marked this pull request as ready for review July 16, 2026 06:24
@James-CUDA
James-CUDA force-pushed the perf/prefill-attn-lane-par branch from 706b1fc to 8e7e027 Compare July 16, 2026 12:34
@skyrocket2026 skyrocket2026 added area:runtime subsystem (emission weight 0.26) area:kernels subsystem (emission weight 0.42) test-on-5090 Maintainer-approved to evaluate on RTX 5090 (greenlight) eval:REJECT sparkinfer auto-eval verdict: REJECT eval-qwen35:REJECT eval-qwen36:none labels Jul 16, 2026
@skyrocket2026

Copy link
Copy Markdown
Member

❌ sparkinfer auto-eval — 8e7e027

metric value
label eval:REJECT
Qwen3.5 score eval-qwen35:REJECT (fail)
Qwen3.6 score eval-qwen36:none (pass)
Qwen3.5 scored decode (128 ctx) ? tok/s
Qwen3.5 correctness top-1 0.0% · KL ?
Qwen3.6 vs same-box main 481.85 tok/s → +0.0% (+0.2)
Qwen3.6 scored decode (512 ctx · 512-context) 482.08 tok/s
Qwen3.6 correctness top-1 93.0% · KL 0.0559
Qwen3.6 128-token no-regression gate 488.5 tok/s vs main 488.74 tok/s · pass
Qwen3.6 512-context no-regression gate 482.08 tok/s vs main 481.85 tok/s · pass
Qwen3.6 4k-context no-regression gate 462.55 tok/s vs main 462.59 tok/s · pass
Qwen3.6 16k-context no-regression gate 450.26 tok/s vs main 450.44 tok/s · pass
Qwen3.6 32k-context no-regression gate 425.39 tok/s vs main 425.37 tok/s · pass
Qwen3.5 optimize eval:REJECT · ? tok/s · fail
Qwen3.6 optimize eval:none · 482.08 tok/s · pass
Qwen3.6 optimize — Qwythos-9B (Q4_K_M) guard accuracy top-1 94.0% · KL 0.0327 · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 128 488.5 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 512 482.08 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 4k 462.55 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 16k 450.26 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 32k 425.39 tok/s · pass

Rejected — primary (Qwythos-9B (Q4_K_M)) produced no verdict (infra error).

RTX 5090 (sm_120) · 128-token decode scored vs same-box main · built from source · correctness vs llama.cpp. Automated — not merged; merge manually after review.

@James-CUDA

Copy link
Copy Markdown
Contributor Author

The eval:REJECT here is an infra failure, not an optimization/correctness failure — quoting the bot's own verdict line:

Rejected — primary (Qwythos-9B (Q4_K_M)) produced no verdict (infra error).

The primary Qwythos scoring run never executed (? tok/s, top-1 0.0% · KL ? = no data), so there is nothing measured to reject on. Every check that did run in the same eval passed:

  • Qwythos guard accuracy (same model, same build): top-1 94.0% · KL 0.0327 · pass — the very model the primary failed to score ran fine under the Qwen3.6 guard, which rules out a build or correctness problem with this PR.
  • All five Qwen3.6 no-regression gates pass (128/512/4k/16k/32k, all within noise of same-box main).
  • Built from source successfully; CI guard/gate/cap green.

For reference, measured on RTX 5090 (sm_120) against post-#463 main tooling, this PR's claim is prefill-only: Qwythos pp 2662.61 → 12900.33 tok/s @32k (numbers and qwen3_gguf_prefill_check top-1/KL in the PR body), decode untouched on both models.

Could the bot re-run the Qwythos primary eval? Happy to rebase/push again if that's what re-triggers it.

@James-CUDA
James-CUDA force-pushed the perf/prefill-attn-lane-par branch from 8e7e027 to e2f8dce Compare July 16, 2026 14:07
@James-CUDA James-CUDA changed the title perf(qwen35): lane-parallel prefill attention + token-parallel GDN conv + fused Q4K/Q6K->int8 dequant (4.8x pp @32k) perf(qwen35): fused Q4K/Q6K->int8 dequant + token-parallel GDN conv + lane-parallel fallback attention (+78% pp @32k on top of #465) Jul 16, 2026
@skyrocket2026 skyrocket2026 added eval:REJECT sparkinfer auto-eval verdict: REJECT eval-qwen35:XL eval-qwen36:REJECT 4k-context UI-only: strongest measured context in sparkinfer eval and removed eval:REJECT sparkinfer auto-eval verdict: REJECT eval-qwen35:REJECT eval-qwen36:none labels Jul 16, 2026
@skyrocket2026

Copy link
Copy Markdown
Member

❌ sparkinfer auto-eval — e2f8dce

metric value
label eval:REJECT
Qwen3.5 score eval-qwen35:XL (fail)
Qwen3.6 score eval-qwen36:REJECT (fail)
Qwen3.5 vs same-box main 7662.72 tok/s → +83.6% (+6409.4)
Qwen3.5 scored decode (4096 ctx · 4k-context) 286.84 tok/s
Qwen3.5 scored prefill (32768 ctx · 32k-context) 14072.17 pp tok/s · eval-prefill:XL
Qwen3.5 correctness top-1 93.3% · KL 0.038
Qwen3.5 128-token no-regression gate 296.29 tok/s vs main 296.7 tok/s · pass
Qwen3.5 4k-context no-regression gate 286.84 tok/s vs main 286.72 tok/s · pass
Qwen3.5 32k-context no-regression gate 285.42 tok/s vs main 285.38 tok/s · pass
Qwen3.5 64k-context no-regression gate 285.5 tok/s vs main 285.44 tok/s · pass
Qwen3.5 4k prefill no-regression gate 12821.44 pp tok/s vs main 7792.88 pp tok/s · pass
Qwen3.5 32k prefill no-regression gate 14072.17 pp tok/s vs main 7662.72 pp tok/s · pass
Qwen3.5 64k prefill no-regression gate 14182.92 pp tok/s vs main 7825.4 pp tok/s · pass
Qwen3.5 128k prefill no-regression gate 0.0 pp tok/s · pass
Qwen3.6 vs same-box main 462.2 tok/s → +0.0% (+0.0)
Qwen3.6 scored decode (4096 ctx · 4k-context) 462.76 tok/s
Qwen3.6 correctness top-1 87.8% · KL 0.0629
Qwen3.6 128-token no-regression gate 488.49 tok/s vs main 488.75 tok/s · pass
Qwen3.6 512-context no-regression gate 481.81 tok/s vs main 481.93 tok/s · pass
Qwen3.6 4k-context no-regression gate 462.76 tok/s vs main 462.2 tok/s · pass
Qwen3.6 16k-context no-regression gate 450.12 tok/s vs main 450.27 tok/s · pass
Qwen3.6 32k-context no-regression gate 425.15 tok/s vs main 425.36 tok/s · pass
Qwen3.5 optimize eval:XL · 14072.17 tok/s · fail
Qwen3.5 optimize — Qwen3.6-35B-A3B guard accuracy top-1 87.8% · KL 0.0629 · FAIL
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 128 296.29 tok/s · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 4k 286.84 tok/s · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 32k 285.42 tok/s · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 64k 285.5 tok/s · pass
Qwen3.6 optimize eval:REJECT · 462.76 tok/s · fail
Qwen3.6 optimize — Qwythos-9B (Q4_K_M) guard accuracy top-1 93.3% · KL 0.038 · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 128 488.49 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 512 481.81 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 4k 462.76 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 16k 450.12 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 32k 425.15 tok/s · pass

Rejected — correctness gate: top1=0.877551 (need >= 0.9), kl=0.062888 (need <= 0.2).

RTX 5090 (sm_120) · 128/512/4k/16k/32k guarded · Qwen3.5 prefill at 4k/32k/64k · scored vs same-box main · built from source · correctness vs llama.cpp. Automated — not merged; merge manually after review.

@James-CUDA

Copy link
Copy Markdown
Contributor Author

The reject is a near-threshold flake on the Qwen3.6 guard, not a regression from this diff — three observations:

  1. This PR cannot change Qwen3.6 output. All three changes live behind the batched-prefill path, which early-returns for the MoE hybrid (qwen35_prefill.cpp: if (!s.gguf || !c.hybrid || !c.dense_ffn || n <= 0) return -1;). The new dequant kernel is only called from that path, and the conv/attention kernels are only launched by it. Qwen3.6 runs the untouched sequential + decode path — the eval's own table confirms it: Qwen3.6 decode is +0.0% vs same-box main at all five contexts (128/512/4k/16k/32k, all pass).

  2. The previous eval of this same functional diff passed the same guard with margin: 8e7e027 measured Qwen3.6 correctness top-1 93.0% · KL 0.0559 · pass. Between 8e7e027 and e2f8dce the only delta is a rebase over perf(qwen35): int8 tensor-core prefill attention for Qwythos #465/governance: block jsdevninja and james3773 (missing denylist entries) #468, neither of which touches Qwen3.6 either. 93.0% → 87.8% across two runs of identical Qwen3.6 code is measurement noise around the 90% bar (KL passes both times: 0.0559 / 0.0629 vs ≤ 0.2).

  3. The Qwythos side — the model this PR actually changes — passed its accuracy guard (top-1 93.3% · KL 0.038) and scored eval-prefill:XL at +83.6% (7662.72 → 14072.17 pp @32k) with every decode/prefill no-regression gate green.

Could the Qwen3.6 guard be re-run? Happy to push a rebase to re-trigger if that's the preferred mechanism.

…nv + fused Q4K/Q6K->int8 dequant

Three batched-prefill bottlenecks on the Qwythos (Qwen3.5) path, found by
profiling against llama.cpp (which led Qwythos prefill 3.7x at pp4096):

1. Prefill attention (prefill_attn_window.cu): the windowed/tiled kernels
   walked keys one per query-warp — a 5-shuffle reduction plus two dependent
   expf per key, latency-bound at 18.3 ms/layer. New lane-parallel kernel:
   one key per lane (zero shuffles to score 32 keys), tile-level online
   softmax, 4 queries per warp so each K/V smem read feeds 4 accumulators.
   5.7 ms/layer (3.2x), same sink+window semantics, LANEPAR=0 restores.

2. GDN conv (batched_prefill.cu): pf_gdn_conv_kernel looped all N tokens
   sequentially with a __syncthreads per token on 64 blocks. The causal
   4-tap conv over the raw in-buffer inputs is token-parallel; new kernel
   is one block per (token, head). 2.7 ms -> ~0.1 ms per layer.

3. Weight dequant (dequant_gguf.cu): every projection dequanted Q4_K/Q6_K
   to a bf16 scratch then re-read + row-quantized it to int8 for the int8
   tensor-core GEMM. Fused deq_rows_i8 kernel decodes superblocks in
   registers and writes int8 + per-row scale directly (1B/value written,
   no bf16 bounce), and the N<=8192 int8 gate is lifted (own arena, falls
   back to bf16 GEMMs on alloc failure instead of the token loop).

RTX 5090 (sm_120), Qwythos-9B Q4_K_M, default window path:
  prefill pp4096   6724 -> 12848 tok/s  (+91%)
  prefill pp32768  2663 -> 12791 tok/s  (+380%)
  decode unchanged (294.3 vs 294.6 tok/s, run noise)
  prefill_check 4096/16: top-1 13/16, KL 0.0164 (main kernels: 13/16, 0.0191)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@James-CUDA
James-CUDA force-pushed the perf/prefill-attn-lane-par branch from e2f8dce to b699eb5 Compare July 16, 2026 14:50
@James-CUDA

Copy link
Copy Markdown
Contributor Author

To be precise about which gate blocked what, since the dual-model table is easy to misread:

  • The withheld score is eval-qwen35:XL (+83.6% scored prefill) — blocked by its cross-model guard: "Qwen3.5 optimize — Qwen3.6-35B-A3B guard accuracy · top-1 87.8% · FAIL".
  • Qwythos's own correctness passed in both directions: 93.3% · KL 0.038 as the primary, and the same values as the guard of the Qwen3.6 pass.

So the only failing measurement in the whole eval is taken on Qwen3.6-35B — the model this diff never executes on (batched prefill early-returns on !dense_ffn; Qwen3.6 decode measured +0.0% vs same-box main at all 5 contexts in this same run; the prior eval measured the same guard at 93.0% pass on a functionally identical build). Re-triggered at b699eb5 — if the guard lands back at its usual ~93%, the XL score should stand.

@skyrocket2026 skyrocket2026 added eval:REJECT sparkinfer auto-eval verdict: REJECT eval-qwen35:XL and removed eval:REJECT sparkinfer auto-eval verdict: REJECT eval-qwen35:XL eval-qwen36:REJECT labels Jul 16, 2026
@skyrocket2026 skyrocket2026 reopened this Jul 16, 2026
@skyrocket2026 skyrocket2026 added eval:REJECT sparkinfer auto-eval verdict: REJECT eval-qwen35:XL eval-qwen36:REJECT 32k-context UI-only: strongest measured context in sparkinfer eval and removed eval-qwen35:XL eval-qwen36:REJECT eval:REJECT sparkinfer auto-eval verdict: REJECT 4k-context UI-only: strongest measured context in sparkinfer eval labels Jul 16, 2026
@skyrocket2026

Copy link
Copy Markdown
Member

❌ sparkinfer auto-eval — b699eb5

metric value
label eval:REJECT
Qwen3.5 score eval-qwen35:XL (fail)
Qwen3.6 score eval-qwen36:REJECT (fail)
Qwen3.5 vs same-box main 7662.72 tok/s → +83.7% (+6416.8)
Qwen3.5 scored decode (32768 ctx · 32k-context) 285.42 tok/s
Qwen3.5 scored prefill (32768 ctx · 32k-context) 14079.51 pp tok/s · eval-prefill:XL
Qwen3.5 correctness top-1 93.8% · KL 0.0244
Qwen3.5 128-token no-regression gate 296.25 tok/s vs main 296.7 tok/s · pass
Qwen3.5 4k-context no-regression gate 286.52 tok/s vs main 286.72 tok/s · pass
Qwen3.5 32k-context no-regression gate 285.42 tok/s vs main 285.38 tok/s · pass
Qwen3.5 64k-context no-regression gate 285.49 tok/s vs main 285.44 tok/s · pass
Qwen3.5 4k prefill no-regression gate 12818.75 pp tok/s vs main 7792.88 pp tok/s · pass
Qwen3.5 32k prefill no-regression gate 14079.51 pp tok/s vs main 7662.72 pp tok/s · pass
Qwen3.5 64k prefill no-regression gate 14186.56 pp tok/s vs main 7825.4 pp tok/s · pass
Qwen3.5 128k prefill no-regression gate 0.0 pp tok/s · pass
Qwen3.6 vs same-box main 425.36 tok/s → -0.1% (-0.3)
Qwen3.6 scored decode (32768 ctx · 32k-context) 425.05 tok/s
Qwen3.6 correctness top-1 0.0% · KL 99.0
Qwen3.6 128-token no-regression gate 488.31 tok/s vs main 488.75 tok/s · pass
Qwen3.6 512-context no-regression gate 455.95 tok/s vs main 481.93 tok/s · fail
Qwen3.6 4k-context no-regression gate 460.63 tok/s vs main 462.2 tok/s · pass
Qwen3.6 16k-context no-regression gate 449.68 tok/s vs main 450.27 tok/s · pass
Qwen3.6 32k-context no-regression gate 425.05 tok/s vs main 425.36 tok/s · pass
Qwen3.5 optimize eval:XL · 14079.51 tok/s · fail
Qwen3.5 optimize — Qwen3.6-35B-A3B guard accuracy top-1 0.0% · KL 99.0 · FAIL
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 128 296.25 tok/s · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 4k 286.52 tok/s · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 32k 285.42 tok/s · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 64k 285.49 tok/s · pass
Qwen3.6 optimize eval:REJECT · 425.05 tok/s · fail
Qwen3.6 optimize — Qwythos-9B (Q4_K_M) guard accuracy top-1 93.8% · KL 0.0245 · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 128 488.31 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 512 455.95 tok/s · fail
Qwen3.6 optimize — Qwen3.6-35B-A3B 4k 460.63 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 16k 449.68 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 32k 425.05 tok/s · pass
regressions regression-qwen35-32k, regression-qwen35-32k

No context cleared the 2% significance gate while at least one context regressed. Auto-closing this PR.

RTX 5090 (sm_120) · 128/512/4k/16k/32k guarded · Qwen3.5 prefill at 4k/32k/64k · scored vs same-box main · built from source · correctness vs llama.cpp. Automated — not merged; merge manually after review.

@James-CUDA

Copy link
Copy Markdown
Contributor Author

Ran the accuracy gate locally to characterize the failing Qwen3.6 guard — full seed matrix, both trees built clean from source on an RTX 5090 (main = 9fdf68a, PR = b699eb5), pinned GGUF (sha ac0e2c11… verified), bench/scripts/accuracy.sh unmodified:

SPARKINFER_EVAL_SEED main top-1 / KL this PR top-1 / KL
fixed 0.910000 / 0.0749 0.910000 / 0.0749
12345 0.887324 ❌ / 0.0431 0.887324 ❌ / 0.0431
777 0.925287 / 0.0327 0.925287 / 0.0327
20260716 0.901460 / 0.0809 0.901460 / 0.0809

Two facts fall out:

  1. The PR is bit-identical to main on Qwen3.6 — all four seed pairs match to six decimal places (same tokens, same KL, same PPL), consistent with the code being unreachable for the MoE hybrid.
  2. The guard's top-1 straddles the 0.90 bar on pristine main as a function of the prompt seed alone: range 0.887–0.925 across four seeds, with seed 12345 failing the bar on main itself (0.887 — right where this PR's eval landed, 0.877). KL passes everywhere with 3-6x margin.

So the ≥0.90 top-1 bar sits inside the prompt-sampling noise band of the Qwen3.6 UD-Q4_K_M weights themselves — any PR (including an empty diff) has roughly a coin-flip guard on an unlucky seed. Re-run requested at b699eb5; longer-term it may be worth pinning the guard prompt or averaging top-1 over 2-3 seeds so the gate measures the diff rather than the draw.

@skyrocket2026

Copy link
Copy Markdown
Member

⚠️ Infra invalidation — b699eb5 eval (2026-07-16)

The posted eval:REJECT on the latest run is not a valid regression verdict. Remote log shows:

>> [guard36] model Qwen3.6-35B-A3B-UD-Q4_K_M.gguf ...
>> WARN: bench sweep failed (rc=1): [FAIL] load

After the Qwythos primary prefill sweep, the 35B guard pass failed to load (GPU memory). The harness continued and reported top1=0.0% · KL=99.0 — the default when accuracy.sh produces no METRIC line, not a real correctness failure.

Valid results from that run:

  • Qwythos prefill XL (+83.7% pp vs same-box main)
  • Qwythos correctness 93.8% top-1
  • All Qwythos decode + prefill no-regression gates pass

Harness fixes are landing (fail-closed on [FAIL] load / missing METRIC, longer GPU cooldown between bidir passes). Re-running eval after box cleanup.

@skyrocket2026 skyrocket2026 added eval:XL sparkinfer auto-eval verdict: XL eval-qwen35:XL eval-qwen36:none and removed eval-qwen35:XL eval:REJECT sparkinfer auto-eval verdict: REJECT eval-qwen36:REJECT labels Jul 16, 2026
@skyrocket2026

Copy link
Copy Markdown
Member

✅ sparkinfer auto-eval — b699eb5

metric value
label eval:XL
Qwen3.5 score eval-qwen35:XL (pass)
Qwen3.6 score eval-qwen36:none (pass)
Qwen3.5 vs same-box main 7662.72 tok/s → +83.5% (+6395.1)
Qwen3.5 scored decode (65536 ctx · 64k-context) 285.21 tok/s
Qwen3.5 scored prefill (32768 ctx · 32k-context) 14057.87 pp tok/s · eval-prefill:XL
Qwen3.5 correctness top-1 93.4% · KL 0.0442
Qwen3.5 128-token no-regression gate 295.97 tok/s vs main 296.7 tok/s · pass
Qwen3.5 4k-context no-regression gate 286.22 tok/s vs main 286.72 tok/s · pass
Qwen3.5 32k-context no-regression gate 284.84 tok/s vs main 285.38 tok/s · pass
Qwen3.5 64k-context no-regression gate 285.21 tok/s vs main 285.44 tok/s · pass
Qwen3.5 4k prefill no-regression gate 12808.24 pp tok/s vs main 7792.88 pp tok/s · pass
Qwen3.5 32k prefill no-regression gate 14057.87 pp tok/s vs main 7662.72 pp tok/s · pass
Qwen3.5 64k prefill no-regression gate 14149.94 pp tok/s vs main 7825.4 pp tok/s · pass
Qwen3.5 128k prefill no-regression gate 0.0 pp tok/s · pass
Qwen3.6 vs same-box main 462.2 tok/s → +0.2% (+0.7)
Qwen3.6 scored decode (4096 ctx · 4k-context) 462.9 tok/s
Qwen3.6 correctness top-1 92.4% · KL 0.0597
Qwen3.6 128-token no-regression gate 488.89 tok/s vs main 488.75 tok/s · pass
Qwen3.6 512-context no-regression gate 482.16 tok/s vs main 481.93 tok/s · pass
Qwen3.6 4k-context no-regression gate 462.9 tok/s vs main 462.2 tok/s · pass
Qwen3.6 16k-context no-regression gate 449.92 tok/s vs main 450.27 tok/s · pass
Qwen3.6 32k-context no-regression gate 425.5 tok/s vs main 425.36 tok/s · pass
Qwen3.5 optimize eval:XL · 14057.87 tok/s · pass
Qwen3.5 optimize — Qwen3.6-35B-A3B guard accuracy top-1 92.4% · KL 0.0597 · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 128 295.97 tok/s · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 4k 286.22 tok/s · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 32k 284.84 tok/s · pass
Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 64k 285.21 tok/s · pass
Qwen3.6 optimize eval:none · 462.9 tok/s · pass
Qwen3.6 optimize — Qwythos-9B (Q4_K_M) guard accuracy top-1 93.4% · KL 0.0442 · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 128 488.89 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 512 482.16 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 4k 462.9 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 16k 449.92 tok/s · pass
Qwen3.6 optimize — Qwen3.6-35B-A3B 32k 425.5 tok/s · pass

Verified speedup over same-box origin/main — 14057.87 tok/s (main was 7662.72 tok/s).

RTX 5090 (sm_120) · 128/512/4k/16k/32k guarded · Qwen3.5 prefill at 4k/32k/64k · scored vs same-box main · built from source · correctness vs llama.cpp. Automated — not merged; merge manually after review.

@skyrocket2026 skyrocket2026 added the merge-first Round's biggest verified speedup — merge this first label Jul 16, 2026
@skyrocket2026
skyrocket2026 merged commit cb34dc1 into gittensor-ai-lab:main Jul 16, 2026
4 checks passed
@skyrocket2026

Copy link
Copy Markdown
Member

✅ Auto-merged as the round's merge-first winner — verified same-box speedup over main, all checks green. Thanks for the contribution!

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

Labels

32k-context UI-only: strongest measured context in sparkinfer eval area:kernels subsystem (emission weight 0.42) area:runtime subsystem (emission weight 0.26) eval:XL sparkinfer auto-eval verdict: XL eval-qwen35:XL eval-qwen36:none test-on-5090 Maintainer-approved to evaluate on RTX 5090 (greenlight)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants