perf(qwen36): opt-in Q8→Q4 requant reward profile (~+6.3% @512)#350
Open
andriypolanski wants to merge 2 commits into
Open
perf(qwen36): opt-in Q8→Q4 requant reward profile (~+6.3% @512)#350andriypolanski wants to merge 2 commits into
andriypolanski wants to merge 2 commits into
Conversation
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.
Summary
Load-time Q8_0 → Q4_K requant for Qwen3.6 UD GDN projections, gated behind a single SN74-facing knob:
On
Qwen3.6-35B-A3B-UD-Q4_K_M.gguf@ ctx=512 (128 generated tokens, RTX 5090), this trims ~47% of weight bytes on the hottest GDN qkv+gate reads on layers ≥15 while staying inside the accuracy gate (top-1 ≥ 0.90, KL ≤ 0.20).Bottleneck: Qwen3.6 UD ships attn/GDN weights as Q8_0. At short context those MMVQ reads dominate decode (~36% GPU time @512). Requantizing once at load and decoding via the existing Q4_K int8 MMVQ path cuts bandwidth on the selected tensors without touching MoE experts, shared expert Q8 paths, or the LM head.
Scope:
kernels/csrc/cuda/quant/ffn_down_requant.cu,kernels/include/sparkinfer/kernels/quant.h,runtime/src/models/qwen35.cpponly — per CONTRIBUTING.md miner paths.Default: OFF. No env var → native Q8_0 weights (same path as main for Qwen3.6 UD).
Proof of speedup
sm_120)Decode tok/s (end-to-end, same binary, interleaved env on/off @ ctx=512, n=128, after merge with
main):PROFILE, native Q8)SPARKINFER_Q80_REQUANT_PROFILE=reward)Correctness gate
Same binary,
PROFILE=rewardvs default OFF, held-out 100 positions (self_consistency.py):SPARKINFER_Q80_REQUANT_PROFILE=rewardFull-scope requant (all layers / all Q8 projections) fails KL (0.25–0.9+). The reward profile is the measured KL-safe slice:
SPARKINFER_Q80_REQUANT_PROFILErewardqkvz(GDNattn_qkv+attn_gateonly)LAYER_OFF=15(layers 0–14 stay native Q8_0)Equivalent explicit knobs:
Reproduce locally:
Implementation notes
launch_q80_requant_q4k: dequant Q8_0 blocks to fp32 in registers, pack to ggml Q4_K super-blocks via llama.cpp-stylemake_qkx2(same fitter upgraded for dense-FFN down requant).qwen35.cpp: at GGUF load, selected Q8_0 attn/GDN tensors are rewritten to Q4_K in VRAM; downstream decode uses existinglaunch_mmvq_q4k/ GDN qkv+z fuse on requantized layers.SPARKINFER_GDN_QKVZ_FUSEcan engage on layers ≥15 (further bandwidth win, no extra env).Maintainer/debug scopes (
SPARKINFER_Q80_REQUANT_Q4K,LAYER_MOD,LAYER_REM) remain for walking the KL gate; miners should usePROFILE=rewardonly.Test plan
PROFILE=rewardvs default OFF: top-1 92/100, KL 0.18 (gate pass)Files changed
kernels/csrc/cuda/quant/ffn_down_requant.culaunch_q80_requant_q4kkernels/include/sparkinfer/kernels/quant.hruntime/src/models/qwen35.cppPROFILE=reward, scope/layer filters, load-time hook