Skip to content

perf(qwen3.6): Q4_K on-read LM head — requantize the Q6_K output projection at load#308

Open
minion1227 wants to merge 1 commit into
gittensor-ai-lab:mainfrom
minion1227:minion_lmhead_q4k
Open

perf(qwen3.6): Q4_K on-read LM head — requantize the Q6_K output projection at load#308
minion1227 wants to merge 1 commit into
gittensor-ai-lab:mainfrom
minion1227:minion_lmhead_q4k

Conversation

@minion1227

Copy link
Copy Markdown

What

Requantize the Qwen3.6 output projection (LM head) from Q6_K to Q4_K once at model load, then decode it on-read via the existing int8 dp4a Q4_K MMVQ. The LM head (vocab 248320 × hidden 2048) is the single largest weight read per decoded token; Q6_K→Q4_K trims that read ~31% (6.5625 → 4.5 bpw).

Why

The output projection runs once per token and is the largest single weight read on the decode path (~11–12% of decode bandwidth). Every other big projection already runs int8 dp4a / split-K; the LM head was still full Q6_K on-read.

How

  • New kernels/csrc/cuda/quant/lmhead_requant.cu — a per-32-value affine k-quant fit (weighted least-squares over a short offset ladder) that emits standard Q4_K super-blocks. Runs once at load; no per-token cost.
  • Load path (qwen35.cpp) — dequant the Q6_K output → requant to Q4_K → swap in, set lm_head_type = 12. Scoped to the Qwen3.6 output (vocab 248320), so the Qwen3-30B guard model stays on its original path.
  • Forward — a Q4_K branch reuses launch_mmvq_q4k_f32 against the pre-quantized Q8_1 activation.
  • SPARKINFER_LMHEAD_Q4K=0 restores the Q6_K path.

Results — RTX 5090 (sm_120), same-box A/B (SPARKINFER_LMHEAD_Q4K=0 vs =1)

context Q6_K tok/s Q4_K tok/s Δ
128 280.08 289.47 +3.35%
512 277.42 286.59 +3.31%
4k 265.78 273.91 +3.06%

No regression at any context (uniform +3%, since it only shrinks a per-token read).

Accuracy vs llama.cpp (pinned reference 6f4f53f, teacher-forced, 100 positions):

  • top-1 token agreement: 0.970 (bar ≥ 0.90)
  • mean KL(llama‖spark): 0.0197 nats (bar ≤ 0.20)
  • PPL: 2.83 → 2.86

Correctness stays well inside the gate because the reduction is confined to the final projection and the k-quant fit is weighted toward the high-magnitude logits.

@skyrocket2026 skyrocket2026 added area:runtime subsystem (emission weight 0.26) area:kernels subsystem (emission weight 0.42) not-tested Awaiting maintainer approval to run on RTX 5090; not evaluated labels Jul 10, 2026
…ection at load

The output projection (LM head, vocab 248320 x hidden 2048) is the single largest
weight read per decoded token and ships as Q6_K (6.5625 bpw). Requantize it to Q4_K
(4.5 bpw) once at model load, then decode on-read through the existing int8 dp4a Q4_K
MMVQ path, trimming that per-token read ~31%.

- New kernels/csrc/cuda/quant/lmhead_requant.cu: a per-32-value affine k-quant fit
  (weighted least-squares over a short offset ladder) emitting standard Q4_K
  super-blocks; runs once at load. Scoped to the Qwen3.6 output (vocab 248320) so the
  Qwen3-30B guard model is left on its original path.
- SPARKINFER_LMHEAD_Q4K=0 restores the Q6_K path.

RTX 5090 (sm_120), same-box A/B: +3.4% (128-ctx) / +3.3% (512) / +3.1% (4k) decode,
no regression at any context. Accuracy vs llama.cpp (pinned ref, teacher-forced):
top-1 0.970 (bar >=0.90), KL 0.0197 nats (bar <=0.20). PPL 2.83 -> 2.86.
@skyrocket2026 skyrocket2026 added the needs-rebase Verified speedup but not the round winner — rebase after merge-first lands label Jul 11, 2026
@skyrocket2026

Copy link
Copy Markdown
Member

⏸ Merge conflict — rebase before eval

This branch conflicts with main, so the RTX 5090 eval is skipped until you rebase.

Please rebase onto main and push — the bot re-evaluates on the next poll once the PR is cleanly mergeable.

@skyrocket2026

Copy link
Copy Markdown
Member

The round's merge-first PR was just merged. Please rebase this branch onto main — once you push the rebase the bot re-evaluates it against the new frontier (crediting your marginal gain on top of what merged).

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

Labels

area:kernels subsystem (emission weight 0.42) area:runtime subsystem (emission weight 0.26) needs-rebase Verified speedup but not the round winner — rebase after merge-first lands not-tested Awaiting maintainer approval to run on RTX 5090; not evaluated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants