Skip to content

ENG-EXPERT-STREAM: decode the two encodings the Qwen3.8-2.4T checkpoints are 97% made of - #946

Merged
localai-bot merged 4 commits into
mainfrom
row/ENG-EXPERT-STREAM-IQ1S
Aug 15, 2026
Merged

ENG-EXPERT-STREAM: decode the two encodings the Qwen3.8-2.4T checkpoints are 97% made of#946
localai-bot merged 4 commits into
mainfrom
row/ENG-EXPERT-STREAM-IQ1S

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

ENG-EXPERT-STREAM streams routed expert slices off NVMe, and never asked whether this tree can DECODE the bytes it streams. It cannot, or could not: each published Qwen3.8-2.4T-A95B checkpoint was missing exactly one encoding, and that encoding is 96.92 % of the model. A slice the streamer can address but not decode moves bytes for nothing, so this is the row's precondition rather than an adjacent nicety.

Closes nothing on its own; it is W9 and W12 of .agents/specs/expert-streaming.md, tracked by #912. Files #933 for what the new oracle still owes.

What the measurement found

Every published GGUF of unsloth/Qwen3.8-2.4T-A95B-GGUF at revision 567d3e6ac2 was censused by parsing tensor headers over HTTP range requests, no full download. Coverage is total rather than sampled: 1702 tensor records against the 1702 declared in split.tensors.count, for each quant.

The two candidate checkpoints are structurally IDENTICAL: same 276 expert tensors, same 96.92 %, same six other encodings at the same counts. Only the expert encoding differs.

Checkpoint Expert encoding bpw Size Was
UD-Q1_0 IQ1_XXXS, ggml 66 1.1875 370 GiB in no upstream llama.cpp
UD-IQ1_S IQ1_S, ggml 19 1.5625 473 GiB upstream, absent here

Everything else (Q5_K, Q6_K, Q4_K, Q8_0, Q2_K, F32) was already served. An earlier draft recorded Q2_K as missing too; that came from a stale header comment listing six encodings, and reading the dispatch showed it has been served all along. Support status in this PR is read from the code.

The fork oracle, and what it is not

Type 66 is defined by no upstream llama.cpp: our pin 237ad9b96 ends at GGML_TYPE_Q1_0 = 41, and ggml-org master ad1de39e0 (2026-08-15) at GGML_TYPE_Q2_0 = 42. It exists only on unslothai/llama.cpp branch iq1-narrow.

This PR first refused that checkpoint on policy grounds, then admitted it on developer direction. The refusal rested on a policy premise rather than a technical one, and a recorded pin answers it. So unslothai/llama.cpp joins the oracle table as llama-cpp-unsloth, pinned at 36fe8e1cc, scoped to the sub-IQ1_S encodings alone. It never outranks vLLM or upstream llama.cpp and is a mirror source for one encoding family, not a design reference.

It is pinned gateable = no. AGENTS.md admits an oracle as gateable only once it demonstrably builds and runs the model, and neither has happened here: the port is grounded in the fork's SOURCE, read and cited, which is weaker than a running comparison. Running it needs the full 370 GiB checkpoint and, per Unsloth's own documentation, at least 450 GB of RAM. #933 owes that measurement, so the ungateable lane is visible debt.

The identification does not rest on trust: the bits per weight derived independently from GGUF offset deltas, before the fork was located, came out at 1.1875, matching the fork's own declaration exactly.

Review notes, for the parts worth arguing about

The grid cannot be validated by the obvious test. Both the vec_dot and the dequantizer read the same codebook, so a mistranscribed table moves both sides together and they still agree. Consistency is not correctness. Both tables are therefore extracted mechanically from their pinned blobs and sealed with a digest plus a lane census. That census earned its keep immediately: this branch first asserted the IQ1_S codebook was +/-1, and the table disproved it. It is TERNARY (6649 zeros, 4860 +1, 4875 -1), and five comments were wrong until the assertion failed. The seal binds harder for IQ1_XXXS, because a BRANCH can be rebased under its own name.

One bound was widened, and here is the reasoning rather than an assertion. The MatmulBTQuant NMSE case gained a per-case ceiling of 2e-3 for both new types. That case does not bound decode at all: it compares a Q8_K-quantized activation against an f32 reference, so it measures activation error, and Q8_K carries ONE scale per 256 elements. Uniformly random scale fields spread neighbouring 32-groups over a 15x range that no encoder emits, measured at 3.8e-4 against 3.8e-5 for a bounded spread. The synthetic scale was narrowed for the same reason the MXFP4 exponent already is, and the residual sits at 5.2e-4 on the thinnest shape, where m=4 and n=1 is four dot products. Mutation says where the empty band is: the weakest decode defect reads 2.7e-2, then 3.0e-1, 9.4e-1, 5.7, 5.7e+1. Decode stays bounded exactly by vec_dot versus an independent f64 dequantize-then-dot, and by MatmulBTQuant versus per-row vec_dot.

Evidence

  • RED first, both encodings: the census test failed on ggml 19 and on ggml 66 alone, other five encodings passing, 10 of 12 assertions green each time.
  • 19 mutations, all caught, each reported as applied/compiled/caught so a mutant that failed to build could not read as a pass. Tree restored byte-for-byte after each. The geometry and reader mutations are caught by the traits cross-check and keep-quant routing rather than by the numerics, which is what those cross-checks exist for.
  • Gate: 485/485 ctest, 0 failed, re-run after merging origin/main.
  • Coverage is not claimed from a grep of a passing log, which proves nothing because doctest prints captures only on failure: test_ops_quant_dot goes 184089 to 203611 assertions across 24 to 25 cases.

Owed, named rather than left to be discovered

The CUDA arm for both encodings (W10, W13). cuda_quant_dot.cu:1531 maps an unknown weight dtype to return false, which is a SILENT CPU fallback: a 2.4 T model would emit correct tokens at CPU speed and look healthy, and no token gate can see it. Listed in the spec.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]

@localai-bot
localai-bot force-pushed the row/ENG-EXPERT-STREAM-IQ1S branch from 238fce5 to e2676b9 Compare August 15, 2026 19:48
@localai-bot

Copy link
Copy Markdown
Collaborator Author

Merged on LOCAL evidence, not CI

CI is saturated, so the gate below was run locally on the exact merged tree (rebased onto c2019b0e3, linear, no merge commits). Recording what was and was not covered, so the substitution is auditable rather than implied.

Run here, green:

Check Result
ctest full suite 485/485 passed, 0 failed (2 pre-existing skips)
agent-preflight.sh 75 gates ok
check-commit-trailers / check-commit-style pass
check-oracle-pins / check-agent-record pass
ASan + UBSan on both new decoders ALL CLEAN
Mutation, IQ1_S 9/9 caught
Mutation, IQ1_XXXS 10/10 caught
Real-checkpoint decode vs independent transcription 1179648 weights bit-identical

The sanitizer run is a targeted substitute for CI's sanitize-cpu. The whole-project ASan build fails on a PRE-EXISTING GCC -Werror=array-bounds false positive at laguna_weights.cpp:156 (p.mlp_only_layers = {0}), unrelated to this change, so the two new decoders plus two already-shipped controls (IQ2_S, Q6_K) were compiled and run under -fsanitize=address,undefined directly, on EXACT-size heap buffers so an overrun is detectable rather than absorbed by slack.

That harness earned its controls immediately: the first run reported a Q6_K NaN, which was the harness writing the f16 delta at offset 0 for every type when q6_K trails it at 208. A control failing is how that got caught rather than being read as a Q6_K defect.

One test needed a note. test_cpu_x86_llamacpp_floor fails under box load and passes when idle (18.3 s, 10/10). It was control-proven on clean main at 5a0ffe9e3 under the same load, where it fails identically, so it is environmental and not this change.

Not run locally, and honestly outside what this box can do: windows-msvc-*, build-test-cpu-arm64, build-test-vulkan (llvmpipe only here), and cuda-fat-build (no nvcc on this host). This change is CPU-only decode plus records, so none of them exercise its new code paths, but that is a reason they are low risk, not a claim they ran.

mudler added 4 commits August 15, 2026 19:58
…oint is 97% made of

This row streams routed expert slices off NVMe, but it never asked whether the
tree can DECODE the bytes it streams. Measuring that changed the target.

Every published GGUF of unsloth/Qwen3.8-2.4T-A95B-GGUF at revision
567d3e6ac2 was censused by parsing tensor headers over HTTP range requests.
Coverage is total, not sampled: 1702 tensor records against the 1702 declared
in split.tensors.count. Of the UD-IQ1_S encodings, exactly one was missing from
this tree, and it is 96.92% of the parameters: IQ1_S, ggml type 19, the
ffn_down/gate/up_exps of all 92 non-MTP layers. Q5_K, Q6_K, Q4_K, Q8_0 and Q2_K
were already served, so nothing else gates a 92-layer forward pass.

Ported from the pin 237ad9b96 with anchors cited at each site: block_iq1_s
(ggml-common.h:414-419, 50 bytes per 256 elements = 1.5625 bpw),
ggml_vec_dot_iq1_s_q8_K_generic (quants.c:1099), dequantize_row_iq1_s
(ggml-quants.c:2578) and iq1s_grid (ggml-common.h:1124). The GGUF reader gained
its case 19 as well; without it the reader could not even size the tensor.

IQ1_S is the first codebook here whose entries carry the SIGN rather than a
magnitude, so there is no sign array, and qh does three jobs at once: high grid
index bits, the per-32 scale, and the delta sign.

Two decisions a reviewer should weigh rather than skim.

The grid cannot be validated by the obvious test. Both the vec_dot and the
dequantizer read the same kIq1sGrid, so a mistranscribed table moves both sides
together and they still agree; consistency is not correctness. The table is
therefore extracted mechanically from the pinned blob and sealed by a digest
over those bytes plus a lane census. That census earned its place immediately:
this file first claimed the codebook was +/-1, and the table disproved it. It is
TERNARY, 6649 zeros against 4860 +1 and 4875 -1, and five comments were wrong
until the assertion failed.

The NMSE case gained a per-case ceiling for IQ1_S, and that is a widened bound,
so here is the reasoning rather than an assertion. That case does not bound
decode at all: it compares a Q8_K-quantized activation against an f32
reference, so it measures activation error, and Q8_K carries ONE scale per 256
elements. Uniformly random qh spreads neighbouring 32-groups over a 15x scale
range, which no encoder emits, measured at 3.8e-4 against 3.8e-5 for a bounded
spread. The synthetic scale was narrowed for the same reason the MXFP4 exponent
already is, and the residual 5.2e-4 sits on the thinnest shape, where m=4 and
n=1 is four dot products. The ceiling is 2e-3, and mutation says where the
empty band is: the weakest decode defect, dropping the delta term, reads 2.7e-2,
then 3.0e-1, 9.4e-1, 5.7 and 5.7e+1. Decode itself stays bounded exactly by
vec_dot versus an independent f64 dequantize-then-dot.

Nine mutations, each reported as applied/compiled/caught so a mutant that failed
to build could not read as a pass. All nine caught, tree restored byte-for-byte.
Gate: 484/484 ctest, 0 failed.

The spec records why the target checkpoint changed. UD-Q1_0 is refused for now:
its experts are ggml type 66, which is in no upstream llama.cpp (the pin ends at
Q1_0 = 41, master today at Q2_0 = 42) and exists only on the fork branch
unslothai/llama.cpp @ iq1-narrow as IQ1_XXXS at 1.1875 bpw. The bits per weight
derived here from GGUF offset deltas match that declaration exactly, which is
what identified it. Anchoring it to that fork is the next change.

Owed and named rather than left to be discovered: the CUDA arm. cuda_quant_dot
maps an unknown weight dtype to a silent CPU fallback, so IQ1_S on GPU would
emit correct tokens at CPU speed while looking healthy, which no token gate can
see. Recorded as W10 in the spec.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…that fork as an oracle

The previous commit refused UD-Q1_0 because its expert encoding, ggml type 66,
has no upstream definition and so nothing to gate against. Developer direction on
15 August 2026 overruled that, and it was the right call: the refusal rested on
a policy premise rather than a technical one. The fork is public and pinnable,
and a recorded pin answers the objection at its root.

`unslothai/llama.cpp` is admitted to the oracle table as `llama-cpp-unsloth`,
pinned at 36fe8e1cc on branch `iq1-narrow`, scoped to the sub-IQ1_S encodings
alone. It never outranks vLLM or upstream llama.cpp, and it is a mirror source
for one encoding family rather than a design reference.

It is pinned `gateable = no`, and issue #933 owes the measurement. AGENTS.md
admits an oracle as gateable only once it demonstrably BUILDS and RUNS the
model, and neither has happened: this port is grounded in the fork's SOURCE,
read and cited, which is a weaker thing than a running comparison. Running it
needs the full 370 GiB checkpoint and, per Unsloth's own documentation, at least
450 GB of RAM. That is visible debt rather than a discovery for later.

UD-Q1_0 was censused the same way as UD-IQ1_S, over all 10 shards, 1702 tensor
records against the 1702 declared. The two checkpoints are structurally
IDENTICAL: same 276 expert tensors, same 96.92%, same six other encodings with
the same counts. Only the expert encoding differs, 66 against 19. So the same
streaming lane serves both and each needed exactly one new encoding.

IQ1_XXXS is the same ternary codebook idea as IQ1_S wound tighter in two ways,
which is where the 0.375 bpw saving comes from. The grid holds 256 entries
rather than 2048, so qs is a WHOLE 8-bit index with no high bits to splice. And
the per-32 scale and delta sign share one NIBBLE of sc rather than a u16 per
sub-block. The grid is correspondingly sparser: 1243 of 2048 lanes are zero,
against 6649 of 16384 for IQ1_S. The delta magnitude is upstream's own
IQ1S_DELTA, reused unchanged by the fork.

The digest seal matters more here than it did for IQ1_S, and for a reason worth
stating: this table comes from a BRANCH, and a branch can be rebased or amended
under its own name. A digest over the bytes actually ported is the only thing
that keeps "the pin" meaningful later, so the grid carries FNV-1a 64
0x24421301ff77509c plus a lane census, both re-derived by the test.

Ten mutations, each reported as applied/compiled/caught so a mutant that failed
to build could not read as a pass. All ten caught, and usefully by different
suites: the geometry and reader mutations are caught by the traits cross-check
and the keep-quant routing rather than by the numerics, which is what those
cross-checks exist for. Tree restored byte-for-byte.

RED first: the UD-Q1_0 census test failed on ggml 66 alone, with the other five
encodings passing, 10 of 12 assertions green. Gate: 484/484 ctest, 0 failed.
Coverage is not asserted from a grep of a passing log, which proves nothing
because doctest prints captures only on failure; test_ops_quant_dot goes from
184089 to 203611 assertions across 24 to 25 cases.

Owed and named: the CUDA arm for this encoding too, W13, for the same reason as
W10. cuda_quant_dot maps an unknown weight dtype to a silent CPU fallback, which
emits correct tokens at CPU speed and no token gate can see it.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…owes

The index, the row's spec and the pull request body must agree on an issue, and
#933 was in the first two but not here. It records what the `llama-cpp-unsloth`
pin does NOT yet have: a build-and-run measurement against the checkpoint, which
is the difference between reading a fork's source and gating on it.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
…eckpoint bytes

Random blocks sweep bit patterns but cannot catch a misunderstanding of the
FILE. A wrong field order, a wrong stride, or a codebook that turns real weights
into legal-looking noise all survive a synthetic test and fail on the first real
tensor.

So the decoder was run on the downloaded UD-Q1_0 shards and compared, on the
SAME bytes, against a separate transcription of the fork's own
dequantize_row_iq1_xxxs reading the fork's grid out of its own tree.
1179648 weights across ffn_gate/up/down_exps, layers 0 and 23, two shards, both
K shapes: bit-identical, max absolute difference 0.0.

The values look like weights rather than noise (mean -4.2e-7, sd 8.6e-4,
symmetric, 24 discrete levels, nothing non-finite), and the layout resolves as
the port assumes: row_bytes = K/256*38, and 1275068416 implied bytes matches 512
experts times 2048x8192 at 1.1875 bpw.

Recorded with its limit stated rather than as a clean win. This removes
transcription error from OUR side, which is what this port was most exposed to.
It does NOT make the oracle gateable, because both sides read the same fork
source, so a defect in the FORK reproduces identically in both. Only building
and running the fork closes that, which is what #933 owes.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
@localai-bot
localai-bot force-pushed the row/ENG-EXPERT-STREAM-IQ1S branch from e2676b9 to 24a634f Compare August 15, 2026 20:09
@localai-bot
localai-bot merged commit a318981 into main Aug 15, 2026
9 of 19 checks passed
localai-bot pushed a commit that referenced this pull request Aug 15, 2026
…25-TOKEN-APPEND

Third move of `origin/main` during this row's review, from `4880c5715` to
`2daa3287f`. Clean auto-merge across nineteen files, two of which this row also
touches: the append-only issue index and `docs/FEATURES.md`.

Merged rather than left mergeable, because "mergeable" was not the whole
obligation. `scripts/check-commit-style.py --range origin/main..HEAD` refuses
outright when the range base is not an ancestor of the range head, so a branch
that merely CAN merge cannot have its own commit-style gate run against the
current base. Merging makes the gate runnable, and it ran green.

`docs/FEATURES.md` auto-merged without a conflict this time, which is the case
worth checking rather than trusting: the two edits landed in different rows.
Verified after the fact, since this row's LTX-2.5 cell sits exactly ON
`MAX_CELL_CHARS` and any silent re-wrap would red the table gate — cell lengths
60 / 28 / 218 / 220 against a 220 cap, row 539 against a 600 cap, and
`check-public-doc-tables.py` green. The issue index carries this row exactly
once at 236 rows, and the READER ANCHORS line still derives to
`756 811 907 923 925 1003 1028 1133 1174` because nothing here touches
`ltx2_video.cpp`.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [claude-code]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants