Conversation
…t8 down in one slab) The JustVugg#1370 experiment: Q4_K_M keeps down/output in Q6_K, our gs64 int4 loses 2.5 % perplexity against it, and all-int8 experts close the gap (7.153 against 7.147). The first number JustVugg asked for is down alone at more bits with everything else unchanged. --down-bits N (5..8, with --ebits <= 4) quantizes down_proj at N bits (--down-gs groups along its input, 0 = per row) and writes one uint8 slab per expert: [gate int4 packed | up int4 packed | down int8], 2*inter*hidden bytes -- neither the int4 (1.5x) nor the int8 (3x) size, so the engine can tell the layouts apart from the bytes, as it does today. qs stays [gate | up | down]. meta gains expert_down_bits / expert_down_gs. The selftest covers the mixed round trip byte for byte. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X2HPETYXNwT4RmQkdMMyPS
… CPU path The slab is told apart by size (2*inter*hidden bytes); gate|up unpack into the slot's int8 block as the int4 container does, down's int8 rows are copied behind them, the scales come as [gate | up | down] with down_proj's own group size (expert_down_gs, 0 = per row) from qwen36_meta.json. matmul_qd dispatches down_proj on its own layout; gate/up stay on matmul_qe. The VRAM tier takes one format per expert, so COLI_CUDA=1 is refused with a line on a mixed container until the tier learns it. Tiny fixture (inter 64, gs 64): int8 16/16 tokens, int4 gs64 12/16, mixed 16/16; cap 1, cap 2, PILOT=1 WIDE=2 and ASan/UBSan clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X2HPETYXNwT4RmQkdMMyPS
…JustVugg#1370 numbers in "Which container?" Tiny job: the inter-64 fixture converted with --down-bits 8 must be detected by size, give identical ids at cap 1/2/8 (cap 1 recycles the one slot after every expert, where a wrong slab offset shows), and refuse COLI_CUDA=1 with the line. Docs: the knob, the four perplexity figures, and the verdict -- down alone is a quarter of the gap, the tier does not take the layout yet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X2HPETYXNwT4RmQkdMMyPS
kreuzzelg
force-pushed
the
qwen36-down-bits
branch
from
September 18, 2026 20:22
c44da5f to
6561024
Compare
Owner
|
Retried this in today's merge pass and it no longer applies: |
This branch has not been deployed
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.
The experiment #1370 asked for:
downat more bits with everything else unchanged. This is the knob thatproduced the numbers posted there, kept as a measurement tool and a middle step, not as the answer to the gap.
Numbers (Qwen3.6-35B, wikitext-2, 16 x 512 tokens, same tokens and harness as #1370)
downalone recovers a quarter of the gap to int8 (paired -0.0060 nats vs gs64, SE 0.0037); three quarters sit ingate/up, and at equal bits Q4_K_M's asymmetric quantizer is ahead. So the format decision is the min-and-scale
quantizer on gate/up (your second step); this PR only makes the measurement repeatable and gives boxes with RAM
to spare a middle step.
What changes
--down-bits N(5..8, with--ebits <= 4) and--down-gswrite one uint8 slab per expert,[gate int4 packed | up int4 packed | down int8], 2interhidden bytes -- neither the int4 (1.5x) nor theint8 (3x) size, so the engine tells the layouts apart from the bytes as it does today.
qsstays[gate | up | down]; meta gainsexpert_down_bits/expert_down_gs. The--selftestcovers the mixedround trip byte for byte.
container does, down's rows are copied behind them;
matmul_qddispatchesdown_projon its own scale layout(per row or
expert_down_gs), gate/up stay onmatmul_qe. The planner prices the expert bytes from thetensor sizes as before.
COLI_CUDA=1with a line and runs CPU-only. Teaching the tier three formats per expert is a follow-up if the layout is
wanted beyond measurements.
--down-bits 8; the engine must detectthe layout, give identical ids at cap 1/2/8 (cap 1 recycles the single slot after every expert, where a wrong
slab offset would show) and refuse the tier with the line. Tiny results: int8 16/16 tokens, int4 gs64 12/16,
mixed 16/16; cap 1, cap 2, PILOT=1 WIDE=2 and ASan/UBSan clean.
For the measurement itself the 35B container was assembled from the existing gs64 (gate/up) and int8 (down)
containers -- both from the same checkpoint with the same deterministic quantizers, so byte-identical to what
--down-bits 8writes from the source (the selftest is the proof on tiny tensors).Thanks to Claude Code for the help along the way.
https://claude.ai/code/session_01X2HPETYXNwT4RmQkdMMyPS