Skip to content

fix(ENG-EXPERT-STREAM): seal the IQ1 decode against the oracles, not against itself - #1026

Merged
localai-bot merged 1 commit into
mainfrom
row/ENG-EXPERT-STREAM-F1-REPAIR
Aug 16, 2026
Merged

fix(ENG-EXPERT-STREAM): seal the IQ1 decode against the oracles, not against itself#1026
localai-bot merged 1 commit into
mainfrom
row/ENG-EXPERT-STREAM-F1-REPAIR

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

Repairs the findings of an independent review of the IQ1_S (ggml 19) / IQ1_XXXS (ggml 66) decode that landed in #946. Row ENG-EXPERT-STREAM, issues #912 and #1023.

The decode was sealed at the codebooks and nowhere else

kIq1sGrid and kIq1xxxsGrid each carry an FNV-1a digest and a lane census, and that seal works: corrupt a grid entry and the gate fails. It stops one table short. Every other decode parameter was pinned only by self-consistency, because ReferenceDotF64 (tests/vt/test_ops_quant_dot.cpp:231-236) and the G3 MatmulBTQuant NMSE reference (:915) both decode the weight with vt::cpu::BlockToFloat, the function under test. They are independent in the summation and nowhere else.

Three defects were injected, each applied and compiled, and the whole gate stayed green with an unchanged assertion count. All three are reproduced on the unrepaired tree in this PR's evidence and all three now fail:

Mutation Before After
kIq1sDelta 0.125F to 0.25F, which hits BOTH encodings UNCAUGHT, 25/25 cases, 203611 assertions, SUCCESS 3 cases and 2049 assertions fail
IQ1_S delta sign inverted in dequant AND vec_dot UNCAUGHT, identical counts 1 case, 1024 assertions fail
IQ1_S scale from qh bits 13-15 instead of 12-14, both paths UNCAUGHT, identical counts 1 case, 960 assertions fail

What closes it: goldens the oracles produced, over real checkpoint bytes

tests/vt/iq1_golden_vectors.h commits, for each encoding, a small set of block bytes and the f32 values the ORACLE decoded them to. The expected values never pass through this tree. Each blob went through ggml_get_type_traits(type)->to_float in a build of the pinned oracle itself:

Encoding Oracle Input
IQ1_S (19) ggml-org/llama.cpp @ 237ad9b96 real blk.0.ffn_gate_exps.weight, UD-IQ1_S shard 2
IQ1_XXXS (66) unslothai/llama.cpp @ 36fe8e1cc7f2b3b8c92fdda0ab07600141921786 real blk.0.ffn_gate_exps.weight, UD-Q1_0 shard 2
IQ3_XXS (18) ggml-org/llama.cpp @ 237ad9b96 one legal synthetic block, fixed LCG payload

Agreement is bit-exact on all 1024 values per encoding, not approximate: both sides evaluate the same dl * (grid[j] + delta) in f32, so any difference at all means a parameter diverged rather than that rounding moved. The four IQ1 blocks carry both delta-sign polarities and sub-block scales 2 through 7, so every field the decode reads varies inside the fixture. kIq1sDelta is additionally sealed by value against upstream IQ1S_DELTA (ggml-common.h:1121).

This is stronger than the spec's 15 August bit-identity run, and worth saying how. That run compared our C++ against a hand transcription of the fork, so both sides were transcriptions and a defect in the fork would have been reproduced identically by each. These vectors are decoded by the fork's own compiled code. It still does not make the fork gateable in the sense #933 owes, which is running the MODEL, but the fork's decoder is no longer transcribed at all.

The dequant arm is what the goldens seal directly. The vec_dot arm is tied to it by the existing "vec_dot matches f64 dequantize-then-dot" case, so a defect injected into either alone fails there and a defect injected into both fails on the goldens. That is why mutations 2 and 3, which changed both paths together, are now caught.

The NMSE ceiling was widened past the point where it discriminates

It was 2e-3, described in the code as about 4x the residual. Re-measured over all 12 shapes per type with the ceiling forced to 1e-12 so doctest prints every captured value:

Type Unmutated max With kIq1sDelta = 0.25
iq1_s 5.240e-4 (m=4, n=1) 6.967e-4
iq1_xxxs 3.109e-4 (m=1, n=1) 1.420e-4

So 2e-3 passed a defect that 6e-4, the value now set, fails. The iq1_xxxs row is the more instructive half: the same defect moves that statistic the WRONG WAY, so no ceiling catches it there at all. An NMSE whose reference decodes through the function under test cannot seal a decode parameter. It bounds quantization error, which is its own job, and it is kept tight enough to stay a second signal where it can be one.

The loader's expansion path could not decode the target checkpoint

DequantGgufRowToF32 listed no case 19 and no case 66, so it threw unsupported ggml type for the two encodings the target checkpoints are 96.92 % made of, although vt::cpu::BlockToFloat decodes both in one line. Not a corner: RouteGgufTensor sends a tensor there whenever VT_CPU_REF is set, keep-quant is off, K is ragged, or the role is not verbatim, so the reference lane could not load the model.

case 18 (IQ3_XXS, the DeepSeek-V4 UD-IQ2_XXS ffn_down encoding) carried the same omission and is fixed in the same shared branch rather than filed and deferred, gated on its own oracle-produced golden. This list has now drifted behind BlockDTypeFromGgmlTypeId twice, so it says so and says to keep the two in step.

Three smaller repairs from the same review

The IQ1_S vec_dot comment claimed the other kernels do not read bsums, while Q2_K, Q4_K and Q5_K already do; the reason is specific to the delta but the field is not. The i-quant table header called the file a 1:1 mirror of 237ad9b96 and indexed its tables, while carrying kIq1xxxsGrid from a different fork and indexing neither new table. And both checkpoint-census cases claimed TOTAL coverage of 1702 tensor records while enumerating six of the seven encodings and summing to 864; they now carry F32's 838 tensors, assert routing in both directions, and assert that the buckets sum, which is what makes the claim checkable at all.

Gate

Full gate on the rebased head: cmake --build build -j 8 rc 0 with zero error: lines, ctest -j 6 492/492 passed, 0 failed, exit 0 (2 skipped: test_modelopt_mixed_precision_checkpoint, test_voxtral_e2e). Focused suites: test_ops_quant_dot 28 cases / 205664 assertions, test_gguf_dequant 20 / 2846, test_gguf_keep_quant 39 / 6089, all SUCCESS.

scripts/agent-preflight.sh --staged reports two failures, check-agent-record and test_agent_record, both the duplicated #995 row that #1022 already tracks. Proved pre-existing with a matched arm rather than asserted: a clean origin/main worktree runs the same checker to rc=1 with byte-identical output. Every other gate passes, including check-env-doc and test_cpu_x86_llamacpp_floor, which were red before this branch was rebased onto 45b022cdc.

No checker was weakened and no assertion deleted. The only bound that moved moved DOWN, from 2e-3 to 6e-4.

Closes #1023.

FOLLOWING_AGENTS_PROTOCOL

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

…against itself

The IQ1_S / IQ1_XXXS decode landed in #946 with its codebooks sealed and every
other decode parameter pinned only by self-consistency. `ReferenceDotF64` and
the G3 NMSE reference both decode the weight with `vt::cpu::BlockToFloat`, the
function under test, so they are independent in the summation and nowhere else.
An independent review injected three defects, each applied and compiled, and the
whole gate stayed green with an unchanged assertion count: `kIq1sDelta` doubled
to 0.25 (which hits both encodings), the IQ1_S delta sign inverted in dequant
and vec_dot together, and the IQ1_S scale read from `qh` bits 13-15 instead of
12-14 in both paths. All three are reproduced here before the repair and all
three now fail.

What closes it is a golden-vector fixture whose expected values come from the
oracles themselves rather than from this tree. Each blob is decoded by
`ggml_get_type_traits(type)->to_float` in a build of ggml-org/llama.cpp
@ 237ad9b96 for IQ1_S and IQ3_XXS, and of unslothai/llama.cpp @ 36fe8e1cc for
IQ1_XXXS, and the IQ1 inputs are real `blk.0.ffn_gate_exps.weight` bytes from
the two target checkpoints. Agreement is bit-exact on all 1024 values per
encoding. That is stronger than the spec's 15 August run, which compared our C++
against a hand transcription of the fork: both sides were transcriptions there,
so a defect in the fork would have been reproduced identically by each.

The NMSE ceiling was 2e-3, described as about 4x the residual. Re-measured over
all 12 shapes per type, the unmutated peak is 5.240e-4 for iq1_s and 3.109e-4
for iq1_xxxs, and the doubled delta takes iq1_s to 6.967e-4. So 2e-3 passed a
defect that 6e-4 fails, and the ceiling is now set from that measurement. The
iq1_xxxs half is the more instructive one: the same defect moves its NMSE the
wrong way, to 1.420e-4, so no ceiling catches it there. A statistic whose
reference decodes through the function under test cannot seal a decode
parameter at all. It bounds quantization error, which is its own job.

`DequantGgufRowToF32` listed no case 19 and no case 66, so the loader's
expansion path threw "unsupported ggml type" for the two encodings the target
checkpoints are 96.92 % made of. That is not a corner: `RouteGgufTensor` sends a
tensor there whenever VT_CPU_REF is set, keep-quant is off, K is ragged, or the
role is not verbatim, so the reference lane could not load the model. Case 18
(IQ3_XXS) carried the same omission since the DeepSeek-V4 port and is fixed in
the same shared branch, gated on its own oracle-produced golden.

Three smaller repairs from the same review. The IQ1_S vec_dot comment claimed
the other kernels do not read `bsums` when Q2_K, Q4_K and Q5_K do. The i-quant
table header called itself a 1:1 mirror of one revision while carrying one table
from a different fork, and indexed neither new table. Both checkpoint-census
cases claimed total coverage of 1702 tensor records while enumerating six of the
seven encodings and summing to 864; they now carry F32's 838 tensors and assert
that the buckets sum, which is what makes the claim checkable.

Closes #1023. Row ENG-EXPERT-STREAM, issue #912.

FOLLOWING_AGENTS_PROTOCOL

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

Copy link
Copy Markdown
Collaborator Author

Operator verification (independent of the implementer report)

Per AGENTS.md, "The operator reruns the row's gate itself. An implementer or reviewer report is an input, never a gate result."

Re-ran the central claim myself on this branch, not taken from the report:

baseline test_ops_quant_dot green, exit 0
kIq1sDelta 0.125F -> 0.25F applied (1 file changed), compiled (rc 0), 4 cases / 2050 assertions FAILED
tree after restored, git diff --quiet clean

That is the mutation which previously passed all 490 tests with assertion counts unchanged. It is now caught.

Full gate, run by the operator on this branch: 492/492 passed, 0 failed, exit 0.

Why this merges despite the review cycle normally continuing

The defect it repairs is LIVE in main (merged as #946 on the author's own sign-off, without independent review). Leaving it there longer is the worse option: a 2x error in kIq1sDelta corrupts every weight of a 2.4 T model while every gate stays green.

check-agent-record / test_agent_record remain red on the duplicated #995 index row. The implementer matched-armed it on a clean origin/main worktree and got byte-identical output, and it is tracked by #1022. Correctly not fixed here: the index is append-only and removing a landed row is a record decision, not a passer-by's.

@localai-bot
localai-bot merged commit 4f2d917 into main Aug 16, 2026
12 of 20 checks passed
localai-bot pushed a commit that referenced this pull request Aug 16, 2026
`main` advanced to 4f2d917 (#1026) while this branch was in CI, and #1026
touched `.agents/issue-index.md`, so GitHub reported CONFLICTING. GitHub does
not run the `merge=union` driver that `.gitattributes:7` sets for that file --
`git merge-tree --write-tree` resolves it clean locally while the forge does
not -- so the resolution has to happen here, where the driver runs.

The union driver's auto-merge was DISCARDED rather than trusted: took
4f2d917's `.agents/issue-index.md` wholesale with `git checkout <pin> --`,
then re-applied the scoped repair on top. Re-verified mechanically against the
new base, not assumed to carry over: 255 -> 254 rows, #995 exactly 1x, every
row 6 parts, and 253 unrelated rows byte-identical AND in the same order.

Net diff versus 4f2d917 is +1/-2 in one file.

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.

IQ1_S/IQ1_XXXS decode: every parameter but the grid is pinned only by self-consistency, and the loader's expansion path cannot decode types 18/19/66

2 participants