perf(qwen36): Q6→Q4 LM-head via loader + specialize GDN AR#458
perf(qwen36): Q6→Q4 LM-head via loader + specialize GDN AR#458jimcody1995 wants to merge 2 commits into
Conversation
❌ sparkinfer auto-eval —
|
| metric | value |
|---|---|
| label | eval:REJECT |
| Qwen3.5 score | eval-qwen35:REJECT (fail) |
| Qwen3.6 score | eval-qwen36:M (pass) |
| Qwen3.5 vs same-box main | 283.42 tok/s → -0.0% (-0.0) |
| Qwen3.5 scored decode (32768 ctx · 32k-context) | 283.39 tok/s |
| Qwen3.5 scored prefill (4096 ctx · 4k-context) | 4147.79 pp tok/s |
| Qwen3.5 correctness | top-1 95.2% · KL 0.0159 |
| Qwen3.5 128-token no-regression gate | 294.94 tok/s vs main 295.07 tok/s · pass |
| Qwen3.5 4k-context no-regression gate | 284.97 tok/s vs main 285.11 tok/s · pass |
| Qwen3.5 32k-context no-regression gate | 283.39 tok/s vs main 283.42 tok/s · pass |
| Qwen3.5 64k-context no-regression gate | 283.51 tok/s vs main 283.55 tok/s · pass |
| Qwen3.5 4k prefill no-regression gate | 4147.79 pp tok/s vs main 4179.68 pp tok/s · pass |
| Qwen3.5 32k prefill no-regression gate | 2109.4 pp tok/s vs main 4381.54 pp tok/s · fail |
| Qwen3.5 64k prefill no-regression gate | 1266.22 pp tok/s vs main 4392.63 pp tok/s · fail |
| Qwen3.5 128k prefill no-regression gate | 0.0 pp tok/s · pass |
| Qwen3.6 vs same-box main | 479.58 tok/s → +4.1% (+19.5) |
| Qwen3.6 scored decode (128 ctx · 128-context) | 499.05 tok/s |
| Qwen3.6 correctness | top-1 92.5% · KL 0.0284 |
| Qwen3.6 128-token no-regression gate | 499.05 tok/s vs main 479.58 tok/s · pass |
| Qwen3.6 512-context no-regression gate | 490.91 tok/s vs main 472.43 tok/s · pass |
| Qwen3.6 4k-context no-regression gate | 469.59 tok/s vs main 452.94 tok/s · pass |
| Qwen3.6 16k-context no-regression gate | 436.25 tok/s vs main 445.98 tok/s · fail |
| Qwen3.6 32k-context no-regression gate | 438.78 tok/s vs main 424.77 tok/s · pass |
| Qwen3.5 optimize | eval:REJECT · 283.39 tok/s · fail |
| Qwen3.5 optimize — Qwen3.6-35B-A3B guard accuracy | top-1 92.5% · KL 0.0284 · pass |
| Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 128 | 294.94 tok/s · pass |
| Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 4k | 284.97 tok/s · pass |
| Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 32k | 283.39 tok/s · pass |
| Qwen3.5 optimize — Qwythos-9B (Q4_K_M) 64k | 283.51 tok/s · pass |
| Qwen3.6 optimize | eval:M · 499.05 tok/s · pass |
| Qwen3.6 optimize — Qwythos-9B (Q4_K_M) guard accuracy | top-1 95.2% · KL 0.0159 · pass |
| Qwen3.6 optimize — Qwen3.6-35B-A3B 128 | 499.05 tok/s · pass |
| Qwen3.6 optimize — Qwen3.6-35B-A3B 512 | 490.91 tok/s · pass |
| Qwen3.6 optimize — Qwen3.6-35B-A3B 4k | 469.59 tok/s · pass |
| Qwen3.6 optimize — Qwen3.6-35B-A3B 16k | 436.25 tok/s · fail |
| Qwen3.6 optimize — Qwen3.6-35B-A3B 32k | 438.78 tok/s · pass |
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.
Requant Qwen3.6 UD output.weight (Q6_K) to Q4_K inside lm_w so decode uses the existing Q4_K mmvq path (~1/3 fewer LM-head bytes). Also add a fixed-shape gdn_ar_fast_qwen_kernel for 16/32/128 GDN layers. Co-authored-by: Cursor <cursoragent@cursor.com>
PR gittensor-ai-lab#458 eval rejected due to: - Qwen3.5 prefill collapse: LM-head Q6→Q4 fired on Qwythos dense hybrid (shared hybrid fingerprint). Gate to routed-MoE Qwen3.6 only. - 16k decode regression: GDN AR specialization default-on diverged from generic path at long context. Default OFF; opt in with =1. Local A/B (Qwen3.6-35B UD, RTX PRO 6000): ctx=0: 493 → 515 tok/s (+4.3%) ctx=16384: 460 → 478 tok/s (+4.0%) Co-authored-by: Cursor <cursoragent@cursor.com>
31a7f6c to
e972fb8
Compare
|
@skyrocket2026 Reopened with fixes pushed to Thanks for the eval breakdown — traced both failures to overly-broad defaults in the original commit: Root cause → fix
Local re-check (RTX PRO 6000 Blackwell, Qwen3.6-35B-A3B UD, 5-run medians)
Decode gain is preserved; 16k no longer regresses vs same-binary baseline. Qwen3.5/Qwythos should be unaffected since LM-head requant no longer fires on that fingerprint. Ready for re-eval when convenient. |
🚩 Flagged: eval-gamingThis PR involves an account blocked for gaming the SN74 emission mechanism (sybil / coordinated duplicate farming): Per the project's no-gaming policy these accounts are blocked: the PR is not evaluated, scored, or merged. See |
Summary
Two Qwen3.6 decode optimizations on current
main, orthogonal to open PRs (#403 fixed-shape specialize, #445's one-lineSPARKINFER_LMHEAD_REQUANT_Q4Kdefault flip):lm_w— Qwen3.6 UDoutput.weightis Q6_K (~255 MB/token). Detect the hybrid-MoE fingerprint + Q6_K source in the loader and requant to Q4_K so decode uses the existing llama Q4_K mmvq path (~⅓ fewer LM-head bytes). Toggle:SPARKINFER_LMHEAD_REQUANT_Q4K=0.gdn_ar_fast_qwen_kernel<COLS,128,16,32>for Qwen3.6's 16 Q / 32 V / hd128 GDN layers (bake heads, dropvhbounds check,qh = vh & 15). Toggle:SPARKINFER_GDN_AR_SPECIAL=0.Not a copy of #445: that PR only flips
env_enabled(..., q35 || q36)onreq_lm_q4. This PR leaves that line untouched and gates requant insidelm_won fingerprint +ggml_type == 14. Not a copy of #403: that PR specializes conv / pack2 / Q8 dualrow / shared-expert warp counts — this adds a separate GDN AR specialization only.Proof of speedup
sm_120) — same-box A/B on NVIDIA RTX PRO 6000 Blackwell (sm_120, 188 SMs), GGUF shaac0e2c1189e055faa36eff361580e79c5bd6f8e76bffb4ce547f167d53e31a61Decode tok/s (end-to-end
qwen3_gguf_bench; 5-run medians;SPARKINFER_BENCH_DEVICE_LOOP=0):