- MERNIK β Measure-First Quantization Protocol
- 0. TL;DR β what the last weeks produced
- The first MoE build (2026-10-25): Ling NETPURE-4500 wins every KLD column at 93 MiB less weight β mean 0.0951, max 8.72; HE 0/3 NOISE, fidelity win stands (not Q6: stock Q6_K sits at 0.0221 mean / 4.61 max)
- 3D smoke β my test (2026-10-25): NETPURE writes a working voxel scene first try; Q4_K_M writes broken geometry even on second run
- The 9B verdict (2026-10-23): a zero-shot Gnom statistically ties the imatrix-trained SMSE β blindness costs nothing. The vendor stock row closed same-day: task-tie at +470 MiB, fidelity collapse (KLD +34% vs the best arm, worst tail, worst canary)
- The stock control row: plain Q4_K_M (2026-10-23, running now)
- Pre-registered: the 9B test (written 2026-10-22, before the result)
- The verdict column β all five arms, all pairs
- 1. The two rings (revised 2026-10-16)
- 2. The laws (all of them, in one place)
- L0 β The sub-4 law (confirmed 2026-09-23)
- L1 β The budget law (SMAPE small, MSE big)
- L2 β The depth law: the first blocks carry the damage (2026-10-21)
- L3 β Which block exactly is architecture-specific β and that is why a learned ranker wins
- External confirmation (the literature caught up)
- L4 β The 1D/F32 law
- L5 β Saturation rule
- 3. Quick Start & CLI
- 4. Engine mechanics
- 5. Gnom β the learned ranker
- 6. Slow-ring protocol (HumanEval execution)
- 7. Reference results (links β the tables live on the family cards)
- 8. Advanced experiments
- 9. Supported architectures
- 10. Ecosystem & repositories
- 0. TL;DR β what the last weeks produced
MERNIK β Measure-First Quantization Protocol
MERNIK ("the one who measures") is the evolution of the ASHQ1 battlefield zoo: fewer utility duels, more verdicts. The method (priority-queue allocation) is built; MERNIK is how we prove and certify it.
Think of MERNIK as a finetune of ASHQ1: same base weights (queue, pins, tied groups), retrained objective (measure-first protocol, columns that carry their own ring), and expanded capabilities (slow capability ring, KLD-aware teachers, relief ceilings, the zoo bench, and norms shields).
0. TL;DR β what the last weeks produced
The first MoE build (2026-10-25): Ling NETPURE-4500 wins every KLD column at 93 MiB less weight β mean 0.0951, max 8.72; HE 0/3 NOISE, fidelity win stands (not Q6: stock Q6_K sits at 0.0221 mean / 4.61 max)
The first MoE family is on the shelf: Ling-3.0-tiny-MERNIK-4500-NETPURE.gguf (4,725,910,720 B = 4507 MiB) against the vendor Ling-3.0-tiny-Q4_K_M.gguf (4,823,894,944 B = 4600 MiB), both on the protocol corpus (wiki.test.raw, 297 chunks, Q8-base ref 47.7 GB, base PPL 12.9500, -c 1024 -b 128 --seed 7). The 4500 rung is the floor, not a choice: the Q4_K base with the F32 pins is 4454 MiB, so 4000/4200 are unreachable without --allow-q3-or-lower. Stock Q6_K (Ling-3.0-tiny-Q6_K.gguf, 6,499,262,368 B = 6499 MiB) is the fidelity ladder's top rung, same protocol.
| metric (wiki vs Q8 ref) | stock Q4_K_M | MERNIK 4500 NETPURE | stock Q6_K | delta (ours vs Q4) |
|---|---|---|---|---|
| weight | 4600 MiB | 4507 MiB | 6499 MiB | β93 MiB (β2.0%) |
| PPL (canary) | 13.327 (+2.91%) | 13.503 (+4.27%) | 12.69 | +0.176 (+1.3%) |
| mean KLD | 0.114020 Β±0.000619 | 0.095092 Β±0.000525 | 0.022102 Β±0.000163 | β16.6% |
| median KLD | 0.048512 | 0.039573 | 0.008468 | β18.4% |
| max KLD | 14.354789 | 8.715995 | 4.612892 | β39.3% |
| RMS Ξp | 9.405 Β±0.054% | 8.588 Β±0.052% | 4.347 Β±0.038% | β0.82 pp |
| same top p | 85.799 Β±0.090% | 86.875 Β±0.087% | 93.647 Β±0.063% | +1.08 pp |
The absolute numbers are the record. 0.0951 mean is the lowest of any Q4-class build on file (4B NETPURE: 0.1769; 4B stock: 0.1666; 9B arms: 0.1209β0.1262) and 8.72 is the lowest max KLD of any non-Q8 arm (4B NETPURE: 14.17; 9B arms: 25.5β30.0). Only the Q8 references and the near-ceiling 4B 4050-GNOMF16 control (mean 0.0623) sit lower on mean; cross-model absolutes are not a ranking. Within its own control the direction is unambiguous: every KLD column improves, at 93 MiB less weight. The canary disagrees (PPL +1.3%), which is exactly why this project labels PPL a canary and dropped the plain-PPL pass from the teacher entirely β the pre-registered fidelity column is KLD and it does not get overturned by the canary.
Q6_K refutes the "Q5/Q6 level" guess. At 6499 MiB stock Q6_K sits at mean 0.0221 / max 4.61 β 4Γ closer to base than our 0.0951, and its PPL (12.69) beats stock Q4 (13.33). So the NETPURE-4500 is a Q4-class build, not Q5/Q6; the win is fidelity per byte, not fidelity per quant. The honest claim: the best Q4-class arm on the shelf, at Q4 weight, 93 MiB lighter than the stock Q4 it beats.
Provenance. The allocator is the sighted ranker: the training pool now carries 821 units β 512 dense (Spark X2.6-4B Q4/Q3/Q2) + 309 real Ling units β with 160 tied-group predictions for the MoE (90 structural tensors skipped by the 1D/F32/rank-1 law). The Ling leg is also the first ranker retrain that changes a different model's allocation: on Ornith it retiers 30/442 tensors (rank-corr +0.42 with the dense-only netpred), Q8βQ5 in the middle, layer 0/31 attention up, 1β4 down, same total size β recorded in the Fracture card, not here.
HE closed (2026-10-25, same sampling: temp 1.0, top_k 20, top_p 0.95, min_p 0.05, max_tokens 8192, ctx 16384, --reasoning-effort high, --cache-ram 2048). Stock Q4_K_M: HE 131/164 (79.9%), HE+ 128/164 (78.0%), empties 24. MERNIK NETPURE-4500: HE 130/164 (79.3%), HE+ 124/164 (75.6%), empties 29. Duel scripts/duel.py: 0/3 β NOISE (HE p=1.00, HE+ p=0.60, empties p=0.38). The capability column does not separate the arms β the win is fidelity only, and it is the pre-registered column. This is the instrument's floor (SD ~5.9 tasks, resolution 13) plus saturation above Q4, not the model's ceiling.
3D smoke β my test (2026-10-25): NETPURE writes a working voxel scene first try; Q4_K_M writes broken geometry even on second run
Files (assets/probes/3d/ β also see probe_info.md for full prompt + settings):
NETPURE.html(22688 B): working scene βScene,WebGLRenderer,OrbitControls, legend, coherent voxel geometry (screenshot_netpure_20-16-02.png).Q4_K_M.html(17518 B): broken geometry β scattered blocks, missing elements, no coherent layout (screenshot_q4_20-15-51.png).probe_info.md: full prompt + settings.
The 9B verdict (2026-10-23): a zero-shot Gnom statistically ties the imatrix-trained SMSE β blindness costs nothing. The vendor stock row closed same-day: task-tie at +470 MiB, fidelity collapse (KLD +34% vs the best arm, worst tail, worst canary)
The pre-registered 9B batteries (below) closed on 2026-10-22; the vendor control (plain Q4_K_M, no imatrix, no allocator) closed 2026-10-23 16:17. Duel scripts/duel.py (McNemar exact, Ξ±=0.05, same protocol, 164 tasks):
| duel | HE | HE+ | empties | verdict |
|---|---|---|---|---|
| NETPURE (Gnom, zero-shot) vs SMSE (imatrix) | 137 vs 140 (p=0.66) | 129 vs 133 (p=0.48) | 14 vs 19 (fewer better, p=0.23) | 0/3 β NOISE |
| stock Q4_K_M (vendor) vs NETPURE | 137 vs 137 (p=1.00) | 125 vs 129 (p=0.60) | 18 vs 14 (p=0.45) | 0/3 β NOISE |
| stock Q4_K_M (vendor) vs SMSE | 137 vs 140 (p=0.69) | 125 vs 133 (p=0.17) | 18 vs 19 (p=1.00) | 0/3 β NOISE |
| arm | bet | HE (runner) | HE+ (evalplus) | empties | PPL wiki | KLD wiki vs Q8 ref | KLD wiki vs BF16 ref | KLD rlmini (interim) |
|---|---|---|---|---|---|---|---|---|
| Gnom (netpure) β ranker never saw the 9B, no imatrix | Q8 on the early peaks + Q4 floor | 137/164 (83.54%) | 129/164 (78.66%) | 14 | 8.7973 Β±0.0626 | 0.12267 Β±0.00199 | 0.12150 Β±0.00197 | 0.2889 Β±0.0064 |
| SMSE β imatrix-driven, trained on Ornith's own data | Q5 pyramid through the middle | 140/164 (85.37%) | 133/164 (81.10%) | 19 | 8.7349 Β±0.0619 | 0.12620 Β±0.00206 | 0.12427 Β±0.00203 | 0.2915 Β±0.0065 |
| DEEP (opposite-bet control) | β | β | β | β | 8.7760 | 0.12394 | 0.12225 | 0.2972 (worst, as intended) |
| LAW (hand-law control) | β | not run | not run | β | 8.7879 Β±0.0625 | 0.12270 | 0.12094 (top) | β |
| stock Q4_K_M (vendor) β no imatrix, no allocator, +470 MiB | frozen llama.cpp pattern (Q6Γ35, Q8Γ0) | 137/164 (83.54%) | 125/164 (76.22%) | 18 | 8.8456 Β±0.0626 (worst) | β (ref deleted) | 0.16304 Β±0.00228 (worst of five) | β |
What the tie is worth. The 0/3 columns read "crown must not move" β and the tie has teeth: the learned ranker, blind (zero-shot, no imatrix, never trained on the 9B), holds an even score on both pass columns against an allocator trained on this model's own imatrix. The pre-registered outcome is (c) tie on capability β the next fight is below Q4, where the arms diverge on 117/442 tensors (open).
Decisiveness axis (pre-registered as a separate column): Gnom delivers fewer empties β 14 vs 19 (5-task lead, p=0.23 β a lead, not a result, same discipline as the 4B p=0.035). And the direction reverses the 4B empties law: there, empty count grew monotonically with the depth of the upgrade (blk.27 β 9, blk.7 β 13, blk.0 β 18 empties "protect the earliest blocks and the model becomes more hesitant"). Here the arm that puts bits on the earliest blocks delivers fewer refusals at 97-tensor intervention scale. The 4B empties-monotonic claim does not survive its first big-intervention test β demoted to small-intervention artifact (recorded with both numbers, kept as history).
Fidelity columns β landed (2026-10-23 06:52, both ref legs closed, zero failures). KLD on the protocol corpus (302-chunk wiki.test) measured twice per arm: against a Q8-base ref and a BF16-base ref (the 4B protocol's tier). The ref-tier debate is answered, and boringly: the tier moves every arm by the same small constant (+0.0012β¦+0.0019, mean +0.0016, 4/4 same sign) and flips no ranking β NETPURE/LAW hold the top-2 on both refs (their β€0.00056 order swap is deep inside Ο), DEEP between, SMSE the furthest from base on BOTH refs. So future batteries rank identically on either tier; the honest "distance to base" number is the BF16 one; the Q8 ref is 4Γ cheaper to build (22 min vs ~75 min on this box, byte-identical 73.6 GB file format). Deviation note by the protocol law: the 4B batteries measured against a BF16 ref β both tiers are now on file and the offset is measured, not assumed.
The cross-metric tension (noise-level, stated β it is the honest texture of this verdict): SMSE wins the canary (PPL 8.7349 vs 8.7973, ~0.7Ο) and the task column by raw count (140 vs 137, p=0.66) β but it is the arm drifted furthest from base on the protocol KLD (0.12427 vs 0.12150 = 0.98Ο vs BF16 ref; same sign vs the interim rlmini ref, 0.4Ο β 3/3 refs). NETPURE β blind, imatrix-free, never trained on the 9B β is the one closest to base. Both directions live inside noise, which is exactly why the verdict column stays a tie.
The hand-law control also earned its slot: LAW is top-of-ranking on the BF16 ref (0.12094) and co-top on Q8 (0.12270) β never scored on tasks by design, but the hand-law allocation is not fidelity-nonsense; its PPL hole closed at 8.7879 Β±0.0625.
The stock control row: plain Q4_K_M (2026-10-23, running now)
The row the top never had: Ornith-1.5-9B-Q4_K_M.gguf (5,780,090,240 B), quantized from
the BF16 base by plain llama-quantize Q4_K_M β no imatrix, no allocator, the vendor
heuristic exactly as anyone gets it. Through the full shelf right now: HE (164 tasks,
same protocol) β HE+ (evalplus) β PPL (wiki canary) β KLD (wiki, vs the BF16 ref).
Numbers land here when the run closes; the duel column pair is already armed
(stock vs netpure, stock vs smse, McNemar exact).
The vendor fingerprint, counted from the file (scripts/audit_tiers.py --per-layer,
the same tool over all three arms):
| build | file | tensors above Q4 | notes |
|---|---|---|---|
| stock Q4_K_M | 5.78 GB | Q6 Γ35, Q8 Γ0 | static llama.cpp pattern: attn_qkv+ffn_down Q6 on layers 0,1,2,6,9,12,18,21,24,28β31 (attn_v on the full-attention layers 3,15,27,31,32) + output head; layers 4,5,7,8,β¦ at full Q4 |
| Gnom (netpure) | 5.31 GB | Q8 Γ23, Q5 Γ1 | Q8 = first blocks' attn_qkv/attn_gate/ssm_alpha/ssm_beta layers 1β4 + heads β the exact zone the Fracture labels call the epicenter |
| SMSE (imatrix) | 5.31 GB | Q5 Γ82, Q8 Γ8 | the activation-magnitude pyramid through attention projections + gates |
Three sentences of physics from that table: (1) the stock carries +470 MiB more than either allocator and places every upgrade by a frozen layer-list, not by a measurement β not one tensor above Q6, no Q8 anywhere; (2) layers 0β2 happen to be covered, but layers 4β8 β the measured damage epicenter of this family β sit at untouched full Q4; (3) both allocator builds spend a smaller budget and still aim Q8 at the zone the blame lives in. The answer landed same day (16:17): the stock ties BOTH allocator builds on tasks (0/3 both duels: HE p=1.00/0.69, HE+ p=0.60/0.17, empties p=0.45/1.00) while paying +470 MiB β and collapses the fidelity board: KLD 0.16304 = +34% over the best arm, the worst tail of all five builds (max 30.60), the worst canary PPL 8.8456, and more refusals than Gnom (18 vs 14). The frozen pattern buys nothing and pays the physics price; "fewer bytes, same scores" is now measured, not assumed.
Sources: scripts/audit_tiers.py audit dumps 2026-10-23; battery in flight
shelf_9b_stockq4.log, sidecar-stamped when closed.
Sources: eval_results/humaneval_ornith5300{netpure,smse}* (sidecar-stamped, git 8cce6d2), duel run 2026-10-23; HE shelf_9b.log, fidelity legs shelf_9b_kld.log (rlmini/Q8-forge interim), shelf_9b_kld_wiki.log (Q8 ref, closed 04:24), shelf_9b_ref_ab.log (BF16 ref, closed 06:52); refs assets/refs/ref_ornith{q8,bf16}_wiki.dat β 73,599,454,980 B each, byte-identical format (BF16 ref kept on disk); stock control row shelf_9b_stockq4.log + eval_results/humaneval_ornithstockq4km* (in flight 2026-10-23, sidecars land with the run, fingerprint via scripts/audit_tiers.py); HE column = runner's per-task passed (.jsonl_results.jsonl); evalplus base_status disagrees by the usual ~0.5pp harness gap (136/139).
Pre-registered: the 9B test (written 2026-10-22, before the result)
The 4B shelf could not separate the allocations (0/3 columns on four of five pairs). The 9B can: at the Q4 floor (5300 MiB) the two allocations differ in 97 tensors of 442, so the verdict column finally has the power to tell them apart.
| Q8_0 | Q5_K | Q4_K | the bet | |
|---|---|---|---|---|
| SMSE (imatrix) | layer 32 only | 82 (layers 0, 3, 7, 13β31) | 168 | a broad Q5 pyramid through the middle |
| Gnom (zero-shot) | layers 1β4 + 32 | 1 | 230 | depth is safe at Q4; bits only on the first blocks |
(layer 32 in Q8 in both arms is the allocator's fallback for the last block, not a decision of either method.)
Provenance: the ranker behind the Gnom arm was trained on the 1.7B/4B rlmini legs only β the 9B leg was not in its training set, so this is a genuine zero-shot on an unseen model.
Pre-registered outcomes (recorded before the batteries finished):
| result | what it means |
|---|---|
| Gnom β₯ SMSE on HE/HE+ | the law transfers to a hybrid architecture it never saw β the first capability win for the learned allocator |
| SMSE clearly better | "early layers are fragile" is transformer-specific and fails on the recurrent/SSM hybrid: the deep blocks cannot hold Q4 here. The ranker gets a boundary of applicability β worth more than a win |
| tie on capability | as on Spark: capability does not separate them and the win stays quality-per-megabyte. Then the next fight is below Q4, where the arms diverge on 117/442 tensors |
| empties trend deeper (recorded as a third, separate axis) | on the 4B, empties were monotonic in the depth of the upgrade (SMSE blk.27 β 9 empties, LAWONLY blk.7 β 13, Gnom blk.0 β 18). If it repeats on the 9B, the first blocks govern decisiveness, not just signal β and the right answer would be Q8 for the first blocks, but not F16 for them wholesale |
Falsification controls, built before the result (models/netpred_ornith_law.json,
models/netpred_ornith_deep.json): if the "deep" arm β the opposite bet β also wins,
then the win was not about depth at all. One command from a build, no re-training.
The named risk. If the 9B hybrid's depth genuinely cannot hold Q4, that is not the law failing: the ranker was trained on Spark (1.7B/4B) and knows nothing about recurrent blocks. The 9B's own labels do support the bet (57.2% of the damage in layers 0β5, 8.9% in β₯24, blocks 0β2 at 7.4Γ the middle) β so a collapse would indict the transfer, not the measurement.
One model, one byte budget, three beliefs about where the bits go. Spark-X2.6-4B
(released hours after its weights leaked; same spark2_5 architecture as X2.5,
post-training only). All three MERNIK arms are the same 2254.8 MiB with the same tier
multiset (Q4_K Γ213 + Q5_K Γ4) β they differ only in which tensors got the Q5.
| allocation | who chose | PPL (wiki) | max KLD vs BF16 | mean Ξp |
|---|---|---|---|---|
| stock Q4_K_M (2479.8 MiB) | llama.cpp heuristic | 20.6148 | 17.65 | β1.015% |
| SMSE | the imatrix (layer 27) | 19.2660 | 17.77 | β0.733% |
| LAWONLY | the depth law, by hand (layer 7) | 18.6080 | 18.71 | β0.445% |
| Gnom (netpure) | the ranker trained on measured damage (layer 0) | 18.3646 | 14.17 | β0.306% |
The learned ranker beats the static lens and a hand-picked reading of its own law β and by 24% on the tail. The monotone prior cannot see the layer-0 spike; the ranker can.
The PPL ladder β llama-perplexity on wikitext-2-raw test, ctx 1024, seed 7. Same
corpus, same harness; PPL is the canary, but it is the cheapest cross-build comparison we
have, so it gets written down:
| build | weight | PPL | note |
|---|---|---|---|
| MERNIK-2250-Gnom | 2254.8 MiB | 18.3646 | Gnom-driven (Q5 on layer 0) |
| MERNIK-2250-LAWONLY | 2254.8 MiB | 18.6080 | law picked by hand (layers 7, 11) |
| MERNIK-4050-GNOMF16 | 4053.4 MiB | 18.6228 | F16 on the fragile layers (46 tensors) |
| BF16 base (anchor) | 7848.7 MiB | 18.8263 | zero-loss reference, not a quant |
| stock Q8_0 | 4172.3 MiB | 19.0307 | "almost lossless" (KLD 0.0061 β 27Γ closer to BF16) |
| MERNIK-2250-SMSE | 2254.8 MiB | 19.2660 | imatrix-driven (Q5 on layer 27) |
| stock Q4_K_M | 2479.8 MiB | 20.6148 | vendor mix (853 MiB in Q6) |
The three 2255 MiB arms beat the stock Q8_0 on PPL while being 46% smaller β but the KLD column below says plainly what Q8 buys: it is 27Γ closer to the BF16 base (mean KLD 0.0061 vs 0.1769) and keeps the argmax on 96.94% of positions against our ~82%. Q8 is the honest "touch nothing" reference; our arms are the cheap ones, and what they trade away is written down in the same table.
The KLD column, in full β every build against the same BF16 reference (wiki test,
302 chunks, ctx 1024, llama-perplexity --kl-divergence --kl-divergence-base):
| metric | stock Q4_K_M | stock Q8_0 | MERNIK-2250-SMSE | MERNIK-2250-Gnom | MERNIK-2250-LAWONLY | MERNIK-4050-GNOMF16 |
|---|---|---|---|---|---|---|
| Mean KLD | 0.166641 Β± 0.000872 | 0.006139 Β± 0.000161 | 0.180843 Β± 0.000904 | 0.176940 Β± 0.000894 | 0.178306 Β± 0.000894 | 0.062301 Β± 0.000481 |
| Maximum KLD | 17.646482 | 6.612764 | 17.770252 | 14.172658 | 18.709267 | 13.859949 |
| 99.9% KLD | 4.042008 | 0.442399 | 4.074759 | 4.134612 | 3.953914 | 2.491301 |
| 99.0% KLD | 1.346914 | 0.059898 | 1.493514 | 1.490102 | 1.489377 | 0.624270 |
| 95.0% KLD | 0.582286 | 0.016562 | 0.644909 | 0.637474 | 0.640173 | 0.209655 |
| 90.0% KLD | 0.386221 | 0.009498 | 0.425906 | 0.414667 | 0.419712 | 0.127790 |
| Median KLD | 0.077591 | 0.001394 | 0.083268 | 0.080211 | 0.081173 | 0.025654 |
| Mean Ξp | -1.015 Β± 0.024 | -0.083 Β± 0.005 | -0.733 Β± 0.024 | -0.306 Β± 0.024 | -0.445 Β± 0.024 | 0.089 Β± 0.015 |
| Maximum Ξp | 99.747 | 97.502 | 99.924 | 99.639 | 99.818 | 98.523 |
| 99.9% Ξp | 55.175 | 12.304 | 63.900 | 67.559 | 65.434 | 46.425 |
| 99.0% Ξp | 25.209 | 4.206 | 28.549 | 30.309 | 29.513 | 18.499 |
| 95.0% Ξp | 10.534 | 1.671 | 11.624 | 12.468 | 12.188 | 7.753 |
| 90.0% Ξp | 5.344 | 0.869 | 5.888 | 6.464 | 6.336 | 4.214 |
| 75.0% Ξp | 0.560 | 0.117 | 0.695 | 0.907 | 0.838 | 0.680 |
| Median Ξp | -0.015 | -0.000 | -0.009 | -0.002 | -0.004 | -0.000 |
| Minimum Ξp | -99.741 | -98.934 | -99.072 | -99.094 | -98.129 | -99.536 |
| RMS Ξp | 9.444 Β± 0.055 | 1.904 Β± 0.046 | 9.539 Β± 0.052 | 9.398 Β± 0.053 | 9.460 Β± 0.052 | 5.817 Β± 0.046 |
| Same top p | 82.199 Β± 0.097 | 96.940 Β± 0.044 | 81.482 Β± 0.099 | 81.769 Β± 0.098 | 81.644 Β± 0.099 | 88.864 Β± 0.080 |
The imatrix carries across the model version almost unchanged (Spearman 0.9964, top-50 overlap 100% between X2.5 and X2.6), so the X2.5 labels applied to X2.6 without re-measuring. That is why the arms above are comparable at all.
The verdict column β all five arms, all pairs
| arm | weight | HE | HE+ | empties | PPL | max KLD | same-top |
|---|---|---|---|---|---|---|---|
| stock Q8_0 | 4172.3 MiB | 140/164 (85.37%) | 132/164 (80.49%) | 13 | 19.0307 | 6.61 | 96.94% |
| stock Q4_K_M | 2479.8 MiB | 139/164 (84.76%) | 132/164 (80.49%) | 14 | 20.6148 | 17.65 | 82.20% |
| MERNIK-2250-LAWONLY | 2254.8 MiB | 137/164 (83.54%) | 127/164 (77.44%) | 13 | 18.6080 | 18.71 | 81.64% |
| MERNIK-2250-Gnom | 2254.8 MiB | 136/164 (82.93%) | 130/164 (79.27%) | 18 | 18.3646 | 14.17 | 81.77% |
| MERNIK-2250-SMSE | 2254.8 MiB | 136/164 (82.93%) | 130/164 (79.27%) | 9 | 19.2660 | 17.77 | 81.48% |
| MERNIK-4050-GNOMF16 | 4053.4 MiB | 134/164 (81.71%) | 129/164 (78.66%) | 16 | 18.6228 | 13.86 | 88.86% |
Every pair, arbitrated by scripts/duel.py (McNemar exact, Ξ± = 0.05):
| duel | HE | HE+ | empties | verdict |
|---|---|---|---|---|
| stock Q4_K_M vs Q8_0 | p=1.00 | p=1.00 | p=1.00 | 0/3 β noise |
| stock Q4_K_M vs GNOMF16 | p=0.38 | p=0.66 | p=0.77 | 0/3 β noise |
| Q8_0 vs GNOMF16 | p=0.34 | p=0.73 | p=0.58 | 0/3 β noise |
| Gnom vs SMSE | p=1.00 | p=1.00 | p=0.035 | 1/3 β empties only |
| Gnom vs LAWONLY | p=1.00 | p=0.73 | p=0.33 | 0/3 β noise |
What the whole shelf actually says (honest reading).
- At this scale the verdict column cannot separate any of the allocations β 0 of 3 columns for four of the five pairs. The three 2250 MiB arms (SMSE / Gnom / LAWONLY) score the same HE (136 / 136 / 137) and even swap tasks symmetrically (Gnom vs SMSE: 15 stock-only vs 15 Gnom-only discordant pairs, p=1.00). Which three tensors get the Q5 does not move capability.
- The one column that did separate is empties, and it points against us: Gnom gives up on 18 tasks vs SMSE's 9 (p=0.035) β and it is monotonic in depth: the deeper the upgrade (SMSE blk.27/35 β 9 empties; LAWONLY blk.7 β 13; Gnom blk.0 β 18). Protect the earliest blocks and the model becomes more hesitant. But: that p=0.035 is 1 of 15 comparisons run tonight, so it does not survive multiple-comparison correction (Bonferroni 0.0033) β it is a lead to chase, not a result.
- Q8_0 β the near-lossless reference β is NOT better than Q4_K_M (140 vs 139 HE, all columns p=1.00). At 4B scale capability is indifferent to fidelity across this whole range, which kills the "just use Q8" intuition and vindicates spending the bytes elsewhere.
- So the win is not capability β it is quality-per-megabyte: the same verdict (indistinguishable), 9.1% less weight, a 20% cheaper tail (max KLD 14.17 vs 17.65) and 2.25 better PPL. The PPL/KLD advantages are real measurements that do not convert into capability at this intervention size.
And the honest bottom line for the write-up: the damage law (first blocks carry the damage) is a measurement β it is what the KLD labels say, and it transfers across architectures. Whether spending bits there buys capability is a separate question that at 4B/3-tensor scale the instrument cannot answer. It stays open, and the heavier arms (46 tensors in F16, the 9B with a looser budget, the sub-4 regime) are where it can be tested.
And the limit of the claim. Moving 3 tensors out of 290 is below what the verdict column can resolve (13-task floor). The law has to show up where the intervention is larger β the F16-blend arm (46 tensors in F16) or the 9B, where the budget is looser.
What is in the files (read straight from the GGUF headers β the allocation, not a claim):
| stock Q4_K_M | MERNIK-2250 (any arm) | stock Q8_0 | MERNIK-4050-GNOMF16 | |
|---|---|---|---|---|
| Q4_K | 180 (1620.8 MiB) | 213 (2011.7 MiB) | β | β |
| Q5_K | β | 4 (237.2 MiB) | β | β |
| Q6_K | 37 (853.1 MiB) | β | β | 44 |
| Q8_0 | β | β | 217 | 85 |
| F16 | β | β | β | 46 (1510 MiB) |
| attn_proj | Q4_KΓ54 Q6_KΓ18 | Q4_KΓ70 Q5_KΓ2 | β | β |
| ffn_down | Q4_KΓ18 Q6_KΓ18 | Q4_KΓ36 | β | β |
| gate | Q4_KΓ36 | Q4_KΓ35 Q5_KΓ1 | β | β |
The stock mix spends 853 MiB in Q6 (and gives ffn_down the lion's share of it); the
2250 arms spend 237 MiB in Q5 on four tensors. 3.6Γ less high-tier weight, better
perplexity, 9% smaller file β that is the project thesis in two rows: measured importance
beats blind spreading. The whole gap between SMSE and Gnom is three tensors:
SMSE upgrades blk.27.attn_gate/qkv + blk.35.attn_output; Gnom upgrades
blk.0.attn_gate/qkv + blk.11.attn_output β same count, same bytes, and that is the
entire difference between 19.2660 and 18.3646. Whether that shows up in the verdict column
is an open question: three tensors out of 290 is a small intervention, and the verdict column
has a 13-task floor. The heavier arms (46 tensors in F16, the 9B) are where the law can
actually be tested.
The law behind it (measured on rlmini KLD labels, three models, transfers zero-shot):
| model | share of damage in layers 0β5 | in layers β₯24 |
|---|---|---|
| Spark-1.7B-Q4 (measured) | 43.2% | 3.2% |
| Spark-4B-Q4 (measured) | 36.4% | 7.4% |
| Ornith-1.5-9B (ranker zero-shot) | 48.3% | 6.4% |
1. The two rings (revised 2026-10-16)
MERNIK strictly separates allocation signals from capability certification:
| Ring | Columns | Role | Cadence |
|---|---|---|---|
| Fast / Allocator | PPL only | per-decision canary for the queue | every run |
| Slow / Verdict | HE, HE+, KLD | the only columns authorized to crown or kill a build | once per release |
Rule: Allocator signals never certify. Capability scores never steer. Mixing them leads to the PPL disease.
2026-10-16 revision. KLD moved from the allocator ring to the verdict ring: the KLD column is a full-model measurement against the unquantized base over the whole corpus (302 chunks, ~24 min/build), not a cheap per-decision signal. PPL is now the only fast-ring column β and it is a canary: cheap, always available, and frequently misleading (it saturates on reasoning-critical layers and can be bought by sharpening). A build that only wins on PPL has won nothing.
KLD's blind spots stand as recorded: fixed span, fixed chunks, Flash-Attention β blind to long context, instruction drift, and tool formats. It is a fidelity column, not a capability column.
Decision rules. Divergence β if metrics disagree, KLD wins allocator arguments; if they agree, trust the pair. Silence is signal β empty completions scale with weakness (Ox 4β5 β Neo 20β27 β Q2_K 63 β S2 115; Mellum-10000 24 β 7500 35 β Q6 39); weak models go silent rather than babble. Decisiveness is governed by the finetune, not model size (on Qwen3.5 bones, Neo hesitates while OxCoder commits). Saturation rule β bases at ~98% cannot resolve fine differences; capability duels need bases at 60β85% or they only answer the collapse threshold.
The rules (all of them, in one place)
- Allocator signals never certify. Capability scores never steer. Mixing them is how the PPL disease started.
- PPL is a canary β never quoted without that label, and never as a result.
- Verdicts travel with MDE. A difference of 5 tasks out of 164 is a direction, not a rank. Below ~8β10 tasks nothing is reproducible.
- The verdict column certifies preservation, not rank (nine-way tie at the top: 151, then eight on 150).
- Every claim carries a number, a date, and a source (a file, a repo link, a battery tag). A claim without all three is a story, not a measurement.
- One table per subject. The same numbers must not appear in two sections β link instead. Family tables live on their own cards for exactly this reason.
- Dead results stay filed, with the number that killed them β that is how we avoid re-testing them.
- A censored unit is never imputed. TERMINAL records (
damage: null,retryable: false) are visible and excluded by construction, not filled in. - Cross-family verdicts are void β different models, different rulers.
2. The laws (all of them, in one place)
Everything we have learned about where quantization damage lives and what to do about it. Each law carries the number that proves it.
L0 β The sub-4 law (confirmed 2026-09-23)
Any tier below Q4 hurts, and fewer is better. --allow-q3-or-lower at ~4 GB is lava in
every family: MiMo-4500-SMAPE (PPL 10.53 / HE 29.88%) lands exactly where
NeoHorse-3650-Q2 did (10.36 / 23.78%) β same physics, different bones. SMSE-4500
(9.41 / 54.88%, +25pp) proves that limiting sub-4 exposure rescues the build. TOX
(Γ2.0 effective-MSE penalty, constants.py) called it; SMSE proved it on the verdict
column.
L1 β The budget law (SMAPE small, MSE big)
SMAPE owns small budgets, MSE owns big ones. Direction only, not rank β the legs differ by 5β6 tasks, below the 13-task resolution floor (6500: 141 vs 135; 5100: 136 vs 131). The lava leg survives on 3/3 columns plus effect size. Above Q4, utilities debate inside the floor; below Q4, physics decides.
Floor-first confirmation (Mellum, 2026-10-10): the MoE floor sits at 7428 MiB β no build below it without sub-Q4 tiers (5500 arithmetically impossible; 5688 even with Q3 allowed). At 6500: SMSE 126 vs recovery 123 vs stock Q4 125 β the whole shelf is one tie-zone, and the weights differ (ours 1 GB lighter).
L2 β The depth law: the first blocks carry the damage (2026-10-21)
Where this came from (first person). I checked my own first hand-made quant β
gemma-4-12B-it-SHQ6, June 2026, a manual allocation I wrote before any of this was
measurable. Its card already said it: layers 0-1 are 3228Γ more important than middle
layers (23, 35); attention projections on the first layer (attn_q, score 5.11e8) dominate
the importance distribution. The community noticed the effect without knowing the cause
("truly black magic", and it beat unsloth's Q4_K_XL while being smaller and faster).
Six months later the same thing showed up again β on families that differ enormously architecturally:
| model | family | damage in layers 0β5 | in layers β₯24 | how measured |
|---|---|---|---|---|
| gemma-4-12B-it | dense, 48 layers | β | β | manual imatrix, June 2026 (SHQ6) |
| Spark-X2.5-1.7B | hybrid SWA, 28 layers | 43.2% | 3.2% | KLD labels (teacher) |
| Spark-X2.5-4B | hybrid SWA, 36 layers | 36.4% | 7.4% | KLD labels (teacher) |
| Ornith-1.5-9B | hybrid + SSM, 33 layers | 57.2% | 8.9% | KLD labels (teacher, blind to the ranker) |
A ranker trained on the 1.7B/4B legs predicted the Ornith profile before it was measured (48.3% vs 6.4% predicted; 57.2% vs 8.9% measured) β zero-shot transfer across architecture, direction and magnitude both right.
On the 9B the hot band is 7.4Γ the middle of the stack: mean damage in blocks 0β2 is
+0.00217 against +0.00029 for blocks 10β30. The fingerprint is stable too: the hottest
blocks on the 9B are 0, 1, 2, 3 and 11 β and the Gnom arm on the 4B independently
picked blk.0 and blk.11. Different families, different sizes, different instruments
(the imatrix by hand in June, the teacher in October, the ranker as a prediction) β the same
fingerprint.
So the law is not "a property of that model": the first blocks are where quantization damage lives, and the error there has not yet been smoothed by the layers above it.
The mechanism: activation magnitude grows with depth, so the imatrix keeps handing bits to the late layers while measured reasoning damage lives early. The two allocations disagree on purpose, and the disagreement is the experiment:
| Ornith-9B | SMSE @5310 | Gnom @5310 | SMSE @4000 | Gnom @4000 |
|---|---|---|---|---|
| Q8 | 15 | 30 | 15 | 32 |
| Q6 | 0 | 3 | 0 | 3 |
| Q5 | 88 | 4 | 44 | 1 |
| Q4 | 162 | 228 | 78 | 113 |
| IQ2 (sub-4) | β | β | 117 | 110 |
| tensors moved | β | 103/442 | β | 117/442 |
SMSE builds a pyramid (88 Q5 in the middle); Gnom says "Q4 everywhere, bits only to the early peaks" β and its leg is leaner (4 Q5 vs 88), which is L0 ("fewer is better") applied to the upper tiers. At 4000 both arms fall into sub-4 (lava), so the meaningful duel is at the Q4 floor.
L3 β Which block exactly is architecture-specific β and that is why a learned ranker wins
The zone is always the first blocks; which one spikes is a property of the architecture:
layer 0 vs the average of layers 1β3 is 4.6Γ (4B Q4), 3.3Γ (4B Q3), 2.3Γ (1.7B Q4),
but only 1.1Γ on the 9B, where the hot band is 0β2 with blk.1 on top.
A monotone prior ("damage decays with depth") cannot express a band or a spike β it puts
the first block at rank 1 or 2 and stops thinking. The learned ranker can, because it learns
the profile, not the trend: on the 4B it upgrades blk.0.attn_gate/qkv where the
hand-picked law build takes blk.7. That single decision is worth β0.24 PPL
(18.3646 vs 18.6080) β the gap between the learned allocator and the best monotone
reading of its own law. Read L2 and L3 together: the law says early, the ranker says
which early.
External confirmation (the literature caught up)
The law above was found by hand (June 2026) and measured (October 2026). Four independent papers published in the same window describe the same physics:
- arXiv:2608.08188 β Quantization Degradation in LLMs: A Signal-Noise Perspective (CASIA, 8 Aug 2026). Degrades to two linked processes: how errors arise inside a module, and how they accumulate across layers (R(l+1) β G(l)Β·R(l) + Q(l)). The propagated error dominates at every depth, the per-layer source error becomes secondary as errors build up β and their closing sentence is our thesis in their words: "the goal is to control the errors that drive downstream degradation, rather than to minimize all errors uniformly."
- arXiv:2504.09629 β Quantization Error Propagation: Revisiting Layer-Wise PTQ (Apr 2025): the activation difference grows exponentially with depth β the mathematical form of the snowball.
- arXiv:2505.15909 β Is (Selective) Round-To-Nearest Quantization All You Need? (Kogan, MIT, 21 May 2025). Selective precision by layer: for smaller Llama models perplexity improves fastest when the first layers stay in 8-bit; and crucially which layers pay is architecture-specific β middle for Llama-3.1-405B, last for Phi-3-mini and Dolly-v2. That is exactly our L3: the zone is early, the exact block is the model's business β which is why a learned ranker beats a hand-picked rule.
- arXiv:2411.07191 β The Super Weight in Large Language
Models (Jul 2025): the few weights whose damage destroys the model sit in
mlp.down_projof the early layers, consistently across Llama, Mistral and OLMo.
Read together: the mechanism (errors born early are amplified through the depth), the practical consequence (keep the early blocks precise), and the caveat (which block is architecture- specific) are all established independently. MERNIK's contribution is the measurement instrument β per-tensor damage labels on a reasoning corpus, and a ranker that transfers the rule to models it has never seen.
L4 β The 1D/F32 law
The binary writes 1D tensors (norms, biases) and ssm_conv1d as F32 whatever the rules
say, so --pin-norms is a proven no-op (it warns when it changes 0 tensors) and the old
"norms are load-bearing precision" reading was budget-redirect, not precision. The
pre-flight audit exists to catch exactly this class of mistake.
L5 β Saturation rule
Bases at ~98% cannot resolve fine differences (97% vs 96%). Capability duels require bases at 60β85%, or they only answer the collapse threshold.
3. Quick Start & CLI
Basic execution
pip install -r requirements.txt
# 1. Preview tier allocation & dry-run (~1 sec)
python main.py --model M.gguf --imatrix M.imatrix.gguf --size 6800
# 2. Execute actual quantization
python main.py --model M.gguf --imatrix M.imatrix.gguf --size 6800 --run
Stock llama.cpp binaries required (llama-quantize, llama-perplexity, llama-server);
override with LLAMA_QUANTIZE, LLAMA_PPL, LLAMA_SERVER.
Flags
| Flag | Description |
|---|---|
--model M.gguf |
Source weights (BF16/F16) β required |
--imatrix I.gguf |
Imatrix file; repeatable (--imatrix A --imatrix B --imatrix-method max|mean) |
--imatrix-method max|mean |
How repeat imatrix lenses combine (default: max) |
--size MIB |
Target file size in MiB (the primary budget knob) |
--output O.gguf |
Output path (default: <model>-MERNIK.gguf) |
--run |
Execute llama-quantize (without it: dry-run estimate only) |
--utility NAME |
Queue gain metric β see the modes table below |
--mix-base NAME |
MIX utility: gain for non-king groups (mse/rmse/smape/logcosh) |
--mix-top-frac F |
MIX utility: fraction of top-importance king groups (default: 0.2) |
--top-down |
Reverse allocation: everything from F16, downgrade cheapest-loss-first |
--pin-norms |
Top-down native norms shield (proven no-op β warns when it changes 0 tensors) |
--allow-q3-or-lower |
CAN_Q3 types (ffn_gate/up/down, attn_output, ssm_out) may drop to IQ2_XXS |
--pin-small MIB |
Pin every tensor under MIB MiB (F16 weight) at F16, outside the budget (bottom-up only). Measured: Mellum k/v heads (2.3 MB F16) cost 126 MiB for 56 tensors β protection priced loudly, 0 = off |
--relief labels.jsonl --relief-thr -0.5 |
Groups below threshold get ceiling Q4; budget flows elsewhere |
--relief-thr F |
Relief cutoff (default: β0.5) |
--max-tier T |
Runtime override of CLASS_MAX_TIER for every class (e.g. F16 lets kings rise above Q8_0); bottom-up only, constants.py untouched |
--free-pins |
EXPERIMENTAL: output/token_embd/MTP/routers join the budget pool |
--squeeze |
SQUEEZE mode (separate path): only IQ1_S or F16 per tensor, bottom-up only |
--legacy-1d |
LEGACY: price 1D tensors (norms/biases) and ssm_conv1d as quantizable F16 β reproduces pre-2026-09-28 budgets |
--imatrix-tol F / --imatrix-legacy-combine |
Refuse when lens files diverge beyond tolerance (default 1%); legacy flag restores max/mean-combine with a split-brain binary |
--verify gpqa|he|all |
Slow-ring verify on fresh build or existing --output (busy GPU port aborts LOUDLY, never steals) |
--verify-tag TAG |
Result tag (default: from --output basename) |
--show-config / --show-floors |
Print tensor config / hard tier floors |
--no-preflight / --strict-preflight |
Skip the dry-run audit, or abort if any assigned tier cannot fire (default: audit runs, ~1s) |
--ssim-table P / --ptable P / --frag-w F |
ssim / pw_ssim tables + smape_frag modulation weight (default 0.5) |
--huber-delta D |
huber/logcosh scale splitting small vs large deltas (default 3e-4) |
--pow-alpha A |
The Ξ±-axis itself: g = ec^Aβen^A (1=MSE, 0.5=RMSE, β0 log-ratio) |
--hinge-w W |
Smooth sub-4 boost multiplier on any mode (bias on the decision, not the loss); 0 = off |
--cv-w F / --linf-w F |
Hybrid (dead by construction): concentration discount / worst-case boost weights |
--netpred P / --netdmg-w F |
Gnom predicted damage per group + modulator weight (default 0.5) |
--invert |
ADVERSARIAL CONTROL (operator's idea): negate importance β kings down, junk up. If it still scores, importance is bunk; if it collapses, importance is causal |
--invert-keep K |
Soft invert: top-K importance groups exempt (small-budget dial; inert at big budgets where the ceiling binds, not priority) |
--aggro F |
[deprecated] Use --size instead |
--verbose |
Detailed output |
Utility modes β one row per belief
Each mode is a belief about where damage lives. This table is the extension point for new modes.
| mode | belief | status / evidence |
|---|---|---|
mse (default) |
relative-blind absolute gain; tiers spread evenly (Q5/Q6-heavy middle) | best PPL/KLD on dense 9B |
smape |
barbell: junk to the Q4 floor, kings to Q8 penthouses | owns small budgets, loses big ones (L1) |
smse |
geometric mean of the SMAPE-relative and MSE-absolute halves; SMAPE's (ec+en) denominator silently cancels the sub-4 toxicity penalty, so the blend carries real toxicity through its absolute half |
the best hand-tuned mode; owns small+medium budgets (MiMo-4500 lava rescue, +25pp) |
rmse |
perfectionist rescale of MSE | zoo: beats MSE on PPL twice; RINIQ-M2-6500-RMSE-Q38: PPL 7.5411, GPQA 50.00%, HE 88.41% β takes recognition, trails MSE by 3pp on verdict (sub-floor: direction, not rank) |
srmse |
SMAPE-relative Γ compressed absolute (sqrt squeezes toxicity Γ1.41 instead of Γ2.0) | demoted 2026-09-28; MiMo-5100 duel 0/3 (109β115 on a bit-identical file) β manners without verdict. Filed, not crowned |
huber |
fat middle: Huber loss on deltas pushes Q4/Q6 stragglers into Q5_K | best of six at FrogNano-3500 (122/164; SMSE 118, MSE 109, logratio 110, Ξ±0.25 117, Ξ±0.75 120); Mellum-7500 123 vs SMSE 125, duel 0/3 β the middle does not decide there |
logratio |
left edge of the Ξ±-axis: log(ec/en) β extreme barbell, sub-4 toxicity survives structurally | 110/164 on FrogNano-3500 |
powalpha (+ --pow-alpha A) |
the axis itself: g = ec^Aβen^A | 117 β 120 as A goes 0.25 β 0.75; MSE (A=1) collapses to 109. The axis is not monotonic; the pure-absolute endpoint is the worst seat |
recovery |
asymmetric relative: (ecβen)/ec, fraction of current damage recovered | ties SMSE at Mellum-6500 (123 vs 126) |
mix (+ --mix-base) |
kings by MSE, rest by another base metric; formulas live on different scales (mse Ξ ~1e-3 vs smape ~1.2), so _scale() normalizes every formula to O(1) first β without it smape junk outbids mse kings 800:1 and the mix collapses |
dry-run geometry is new (wide Q5 spread, no Q8); verdict queued |
ssim / smape_ssim / smape_frag / pw_ssim |
SSIM-flavoured variants | table-driven, --ssim-table / --ptable |
netdmg |
modulator: Gnom-predicted damage as a bias on the lens | duel vs SMSE came back 0/3 β manners, not a verdict |
netpure |
the queue's gain IS the predicted damage; group weight 1.0 β demotion order is damage per byte saved; the static lens is not re-inserted | X2.6-4B @2250: PPL 18.3646 (vs 19.2660 SMSE), max KLD vs BF16 14.17 vs 17.77 (β20%) |
netfd |
F16-blend for bigger budgets: the fragile blocks are kept in full precision instead of upgraded a tier (top-down only) | X2.6-4B @4050: 46 tensors in F16 (1510 MiB), PPL 18.6228 β beats a solid stock Q8_0 (4172 MiB, 19.0307) while being smaller |
--hinge-w (sub-4 boost multiplier): 105/164 on FrogNano, β13 vs plain SMSE β the "free
boost" backfired, filed as dead.
Recently added (2026-09-28 β 2026-10-16, all CPU-cheap, all verified)
scripts/fuse_layers.py --expect "15:b,..."β gates the resolved donor map (ranges expanded, tissue suffixes checked); exits 2 with a diff before one output byte. Plus a soup shape-guard: mismatched donor shapes fail LOUD, never a corrupt file.scripts/group_damage_sweep.py --units TAGS --timeout S --ngl Nβ subset sweeps; failures go to*.failures.jsonl, second failure of a unit becomes a TERMINAL censored label (damage: null, never retried, never imputed).--kld-onlyskips the plain-PPL pass and emits the 5-column KLD family.--max-tier F16lets kings rise above Q8_0 without touchingconstants.py(reproduces the raised-ceiling geometry byte-exact in dry-run; 13/13 golden geometries still green).- MoE golden geometries:
Mellum2.1 @7500 smse(Q4 171 / routers F16 Γ28) andhuber(Q4 163 / Q5 34) β first regression net over a Mixture-of-Experts allocation (14/14 green + 8/8 provenance). scripts/run_humaneval.py:HE_CHUNK="start,count"slices the sorted task list;HE_CTX=Nreplaces the protocol default-c;serve_sha256sidecar key +scripts/twin.pypre-battery twin gate (same sha β reuse, else measure).--cache-ram 0on HE chains (164 distinct prompts share nothing, so the prompt cache only eats RAM β unbounded on hybrid archs);LLAMA_PPL_BATCHenv overrides the sweep's hardcoded-b 512(forge iGPU OOMs a 9B at 512; 128 holds).scripts/audit_tiers.pyβ tier auditing:
python scripts/audit_tiers.py --model M-6500.gguf
python scripts/audit_tiers.py --model M-6500.gguf --big 10
python scripts/audit_tiers.py --model M-6500.gguf --layer 31
python scripts/audit_tiers.py --model M-6500.gguf --per-layer # every layer
scripts/consolidate_labels.pyβ builds the clean label pool (corpus-tagged, dedup-checked) so a mixed archive can never leak into a training run again.scripts/shelf_x26.shβ resumable measurement queue (one GPU job at a time, skips finished arms): KLD vs BF16 β HE batteries β HE+ per arm.
Example: mapping the Ξ±-axis (dry-runs, CPU seconds)
for A in 0.1 0.25 0.5 0.75 0.9; do
python main.py --model M.gguf --imatrix M.imatrix.gguf --size 3500 \
--utility powalpha --pow-alpha $A # concentrationβdistribution knob
done
python main.py --model M.gguf --imatrix M.imatrix.gguf --size 3500 \
--utility logratio # left edge: extreme barbell
python main.py --model M.gguf --imatrix M.imatrix.gguf --size 3500 \
--utility smse --hinge-w 0.5 # sub-4 boost on any mode
4. Engine mechanics
Queue & allocation principles
Every tensor starts at a floor tier based on its functional class. A global max-heap drains the target budget best-first by sum(importance) Γ Ξ / MiB. Tied groups (identical imatrix energy) upgrade as a single unit with summed importance. Structural pins β MTP heads (β Q8_0), output/token embeddings (β Q5_K), MoE routers (assigned F16, F32 in file) β sit outside the budget queue.
Certify vs report (tool boundary)
Three tools, two jobs. scripts/manifest.py and scripts/ledger.py REPORT: buildβmodel
identity (three keys: score+time+family) and standings generated from artefacts β every
number travels with its identity status. scripts/duel.py ARBITRATES: paired McNemar
across the columns, refuses to average across harnesses. Nothing certifies except a
significant duel; everything else is a report.
Pre-flight audit & the size ceiling
Every invocation runs a dry-run audit (~1s) comparing intended vs actually-written tiers per
tensor β the only thing that can catch a --tensor-type rule that cannot fire. Bottom-up
caps every class at CLASS_MAX_TIER, so a model can saturate below --size: MiniCPM5-2B
caps at exactly 2359.4 MiB, and --size 2600 silently produced a 2359 MiB file. It now
says so loudly and names the blocking classes.
Norms shield & attention core insights (re-labelled 2026-09-28)
TD-MSE vs MSE: β3.7pp HE with identical PPL (7.7701 vs 7.7695). The old reading ("norms are load-bearing walls for code") is mechanically impossible (L4): no norm was ever requantized. What the numbers measure is budget redirect: top-down routing moved ~5 MiB between tied attention groups while the "shield" guarded precision that was never spent. The Norms Shield (TDN) +1.2pp stands as a measured effect with a redirect mechanism, not a precision mechanism.
Distribution comparison @ 6500 MiB (427 tensors, incl. 177 F32 forced by the binary)
Tier BU-MSE (spread) BU-SMAPE (barbell) TD-MSE TD-SMAPE (F16 core)
F16 177 (2 MiB) 177 (2 MiB) 147 (2 MiB) 85 (949 MiB)
Q4_K 48 (972 MiB) 91 (1989 MiB) 71 (972) 236 (2368 MiB)
Q5_K 28 (1994 MiB) 3 (1345 MiB) 28 (1983) 7 (1411 MiB)
Q6_K 66 (2114 MiB) 7 (249 MiB) 71 (2127) 14 (486 MiB)
Q8_0 108 (1417 MiB) 149 (2913 MiB) 110 (1417) 85 (1287 MiB)
Takeaway: MSE fills the middle (Q5+Q6 = 94 tensors). SMAPE hollows it (10 tensors) to double the Q4 floor and gain 41 extra Q8 penthouses.
5. Gnom β the learned ranker
What it is. A tiny neural ranker (150 params, CPU, seconds) that learns which tensors carry quantization damage instead of guessing importance from proxy signals. It is trained on measured damage labels, then ranks models it has never seen.
The labels β MERNIK-Fracture:
per-tensor KLD damage on a reasoning corpus (rl_reasoning_mini), five columns per row
(mean / max / median KLD + Ξp RMS + same-top), deterministic, uniform schema across models
and tiers. The 9B file took ~13 days of continuous sweeping; the 1.7B/4B legs minutes each.
Cheap instruments are for the shelf; the expensive one is for the model you care about.
The corpus ships with the repo β corpus/rl_reasoning_mini.raw (343 prompts,
479,633 B, sha256 82b2e153β¦de400866fbe; the same bytes the forge and GTX-1070 legs
measured against). Rebuilding a reference against it is one
llama-perplexity --save-all-logits call on your machine, so a volunteer run reproduces
the exact measurement stack.
What the labels bought (clean rlmini pool, 512 units, 768 tensors, 0 censored):
| exam | result |
|---|---|
| strict leave-one-MODEL-out, trunk variant | LOMO 0.801 (bar 0.45, Γ6 MDE) β held-out rl17 0.805, held-out rl4b 0.798 |
| same, modelbias | 0.689 PASS |
| same, moeshared | 0.179 FAIL |
| static imatrix proxy (timp) | β0.103 (the learned ranker beats the proxy by a mile, on unseen models) |
| mixed 4-fold exam | moeshared LOMO 0.579, rank LOMO-acc 0.760 |
The old "no transfer" verdict was an artifact of contaminated labels; on clean data the transfer exists and is large. See L2 and L3 for what the ranker actually learned, and Β§0 for what it buys on a real build.
The teacher (5-column, KLD-only, 2026-10): group_damage_sweep.py --kld-only skips
the plain-PPL pass (it lies) and scores five columns per unit against the unquantized
reference on rl_reasoning_mini: damage_kld (mean), damage_kld_max (tail
detonations), damage_kld_median (core), damage_dp_rms (decisiveness),
damage_same_top (rank). ppl/damage are null β not measured.
- Machine split: the 9B (Ornith) sweeps on the 16 GB Vega-11 forge (memory-bandwidth-bound; a 9B is unreasonable to torture through a 1070), the 1.7B and 4B on the GTX 1070.
- Cost: 9B β 90 min/unit Γ 210 = ~13 days continuous (the crown-jewel file); 1.7B β 7.5 h; 4B β 5 h.
- Result: the
MERNIK-Fracturedataset β complete, clean, uniform schema β the origin of the project's current paradigm.
Adding a leg to the pool:
- sweep the model:
group_damage_sweep.py --model M.gguf --imatrix I.gguf --kld-base ref.dat --kld-only --drop-tier Q4_K(and Q3/Q2 for the curve); build_features.py --model M.gguf --imatrix I.gguf --out gnom/features/<m>.npz;scripts/consolidate_labels.pyβ clean pool +pool.json;- add the row to the pool file, retrain, check the bars (0.45 / 0.60).
6. Slow-ring protocol (HumanEval execution)
Server (one model at a time, GPU is a strict queue):
llama-server -m MODEL.gguf --port 28082 -ngl 99 -c 8192 --jinja --log-disable
Sampling (protocol default):
temperature 1.0, top_p 0.95, top_k 20, min_p 0.0,
presence_penalty 0.0, repetition_penalty 1.0, max_tokens 2048
presence_penalty 1.5 (vendor recipe) breaks thinking templates; 0.0 verified. Preflight
/health before every battery; mid-run watchdog every 10 tasks (dead server aborts LOUDLY,
never scores empties silently). Long-ctx servers accumulate commit (KV + prompt cache never
shrink) β chunked batteries (HE_CHUNK, fresh server per ~30 tasks, stitch in order) plus
--cache-ram 0 (164 distinct prompts share nothing). Family sampling: thinking families run
their vendor recipe (K2: temp 1.0 + top_p 0.95 only, top_k 40 / min_p 0.05 = llama defaults,
ctx 16384, --reasoning-effort high; Spark-X2.6: temp 1.0, top_p 0.95, top_k 0, min_p 0.05,
effort high, ctx 16384, max_tokens 8192) β cross-family verdict comparisons stay void,
different rulers. Runner: scripts/run_humaneval.py (env HE_*, HE_CHUNK, HE_CTX,
HUMANEVAL_OUT, HUMANEVAL_SERVER; HUMANEVAL_SERVE_MODEL = self-serve with auto-kill).
Eval: human_eval.evaluation.evaluate_functional_correctness, pass@1, k=[1]. Results:
eval_results/humaneval_<tag>.jsonl. Strictness upgrade: every battery is rescored with
EvalPlus HumanEval+ (80Γ tests, CPU) β the HE+ column.
Reproduce any number below (runner + rescorer ship in this repo):
export HUMANEVAL_SERVE_MODEL=/path/to/MODEL.gguf HUMANEVAL_OUT=eval_results/humaneval_mytag.jsonl
export HE_TEMP=1.0 HE_TOP_P=0.95 HE_TOP_K=20 HE_MIN_P=0.0 HE_PRESENCE=0.0 HE_MAX_TOKENS=2048
python scripts/run_humaneval.py # serves, runs 164 tasks, kills server, writes .meta.json sidecar
evalplus.evaluate humaneval --samples eval_results/humaneval_mytag.jsonl # HE+ column
The .meta.json sidecar (model path, git sha, full sampling, timestamps) is written at
battery time β it is what makes a new battery verifiable instead of
permanent-unverifiable.
Answered 2026-09-29: the same file twice at temp 0.0 scored 98/164 twice, per-task verdicts 164/164 identical, completions 163/164 byte-identical. Greedy does not narrow the verdict column β it reproduces it. The column can stop being sampled: temp-0 batteries are certificates, temp-1.0 batteries are draws. (Caveat kept: the sampler skips RNG at temp β€ 0, but logits still depend on batch composition β so far, no spread observed.)
Fast-ring diagnostic: GPQA-Recognition
Recognition decisiveness (first-token P(letter) over top-30, no CoT). Via
scripts/gpqa_duel.py.
| Build | GPQA-rec | HE pass@1 | Note |
|---|---|---|---|
| Neo-MSE-6500 | 51.5% | 85.98% | Thinker spreads first-token mass |
| Neo-SMAPE-5100 | 48.0% | 82.93% | Compact barbell |
| Ox-MSE-6500 | 49.5% | 90.24% | Decisive stabs the letter |
| Ox-SMAPE-5100 | 49.0% | 88.41% | High task execution |
7. Reference results (links β the tables live on the family cards)
| family | card | load-bearing line |
|---|---|---|
| NeoHorse-1-9B | wepiqx/NeoHorse-1-9B-MERNIK-GGUF | 6500-MSE 141/164 (85.98%); 5100-SMAPE 136/164 ties stock Q6_K 135/164 at β2.2 GB |
| OxCoder-9B | wepiqx/OxCoder-9B-MERNIK-GGUF | SMSE-6500 150/164 (91.46%), Q8 148/164, SMAPE-5100 145/164 β one cluster, no crown inside it |
| RINIQ series (layer-fused) | wepiqx/RINIQ-GGUF | nine-way statistical tie (151, then eight on 150) β no crown, the top is shared |
| Mellum2.1-12B-A2.5B | wepiqx/Mellum2.1-12B-A2.5B-Thinking-MERNIK-GGUF | 10000-SMSE 134/164 beats stock Q6 119/164 by +15 at β0.7 GB (3/3 SIGNIFICANT); 7500-SMSE ties stock Q4_K_M 125/125 (triple p=1.0) |
| FrogNano-4B | family card (lab notes) | the Ξ±-axis laboratory: 110β117β120β122β109, and stock Q6 wins the temp-0 duel 3/3 (β16 tasks real) |
| K2-Horizon-7B | family card | thinking family, saturated shelf: 5500 SMSE 147/164 vs stock Q4_K_M 152/164, Q6 148/164 β all inside the noise floor |
| Spark-X2.6-4B | family card | the current generation β see Β§0 |
The noise budget, as a number. Verdict noise is a binomial draw β SD 5.9 tasks/run at p=0.70, 8.3 for a difference of two runs. That IS the Β±3.6pp band and IS the 8-task MTP re-run gap. Below ~8β10 tasks nothing is reproducible at n=164 β a property of the instrument, not a measurement error. Verdicts travel with MDE; the column certifies preservation, not rank (nine-way tie at the top: 151, eight on 150).
Verdict ledger (the duels that shaped the method β all pre-KLD-paradigm, kept so the same experiments are not re-run):
| duel | numbers | verdict |
|---|---|---|
| MiMo-4500 SMSE vs SMAPE (allow-q3) | PPL 9.4092 vs 10.5343; HE 54.88% vs 29.88% | lava rescue (+25pp) β L0 |
| MiMo-5100 SMSE vs stock | PPL 8.7389 vs 8.7435 (tie); HE 71.34% vs 70.12% (+1.2pp), 3 empties | 0/3 (HE p=0.88, HE+ the other way, empties p=0.13) β NOISE, crown demoted |
| MiMo-6500 SMSE vs stock | PPL 8.7275 vs 8.7655 (tie); HE 72.56% vs 75.00% (β2.4pp) | SMSE loses big: at 6500 the middle decides (MSE Q6 67 vs SMSE 41), not penthouses |
| Mellum-10000 SMSE vs stock Q6 | HE 134 vs 119, β0.7 GB | 3/3 SIGNIFICANT β the one real quant-vs-stock win |
| FrogNano-3500 stock Q6 vs ours | temp-0 duel, β16 tasks | stock wins 3/3 β RL-sharpened base, allocation win absent |
| netdmg (Gnom modulator) vs SMSE | β | 0/3 β manners without a verdict; became netpure |
| RINIQ crown | 151, then eight on 150 | nine-way tie β no crown, the top is shared |
8. Advanced experiments
MTP head grafting
Transplant of a 15-tensor (464 MB) MTP donor head onto OxCoder-9B via scripts/graft_mtp3.py.
Draft engages (5β23% acceptance); economics negative (31β20 t/s on mismatched head).
Mechanics proven; full saga in SAGA.md.
Teacher & Gini (v3, 2026-09-19)
Damage-sweep labels train the Gini allocator. v3 complete: 168/168 labels (Q5_KβQ2_K drops, MiniCPM5-2B, forge): damage β0.046β¦+0.515, mean 0.070, Gini 0.364, only 3 reliefs. Late units carry the signal (ffn_gate@41 +0.51, ffn_down@41 +0.33, ffn@39/40) + early attn@2. vs older teacher (Gini 0.498, max 0.173): bigger drops hit harder (max 3Γ) but spread wider (Gini lower) β signal with teeth, less concentrated. MLP un-paused: retrain Gnom on v3 β netdmg duel. Gini answers to Soulfate24. (Superseded as the main instrument by the KLD teacher and Gnom β Β§5.)
KLD battery & relief
KLD-vs-ref was the allocator's rank column (Soulfate24 battery: fixed span, fixed chunks,
Flash-Attention). Measured relief ceilings (--relief) pin sweet-spot groups at Q4 and
release their budget elsewhere. It is now a full-model verdict column (Β§1) β the same
mechanism, measured against the BF16 base instead of a per-decision proxy.
Ceiling & inversion probes (2026-09-30/10-01)
- Ceiling map:
RINIQ-M2-MAXF16(9.01 GB, F16 core 123) measured PPL 7.7357 (worse than 6500-MSE's 7.5263), HE 137/164, HE+ 129 β +4 GB over the 5 GB cluster buys β13 tasks. Kings saturate (Q8βF16 gains nothing) while the Q4 tail drags: at big budgets the MIDDLE decides. - Inversion (adversarial control,
--invert/--invert-keep K): full priority flip at 8350 (PPL 7.6960, HE 145/164, HE+ 137) and at 5100 (PPL 7.5845, HE 145/164, HE+ 137) β duels vs honest arms 0/3 and 0/3. Flipped noise ties, so the lens carries nothing resolvable. - Doctrine consequence: the FLOOR is the whole game, priority among Q4+ is noise (L0/L1).
F16-blend (--utility netfd) β the next generation
At bigger budgets the useful move is not "which tensor gets one more tier" but "which
tensor must not be touched at all". netfd keeps the fragile blocks in full precision
and demotes by damage per byte saved. On X2.6-4B at 4050 MiB: 46 tensors in F16 (1510 MiB),
PPL 18.6228 β beating a solid stock Q8_0 (4172 MiB, 19.0307) while being smaller. This is
L2/L3 turned into an allocator mode.
9. Supported architectures
| Arch | Detection | Key Features |
|---|---|---|
qwen35 |
SSM + QKV | Hybrid attention, SSM layers, GQA, MTP head pinning |
mellum2 |
MoE (exps tensors) |
Mixture of Experts, GQA, routers out-of-budget (F32 in file, 28/28 incl. stock) |
bailingmoe3 |
KDA+MLA + MoE | Ling-3.0 family: routed + shared experts |
granite |
general.architecture |
Dense GQA, 40 layers, split Q/K/V |
spark2_5 |
general.architecture |
Dense + hybrid sliding-window attention (1 full + 3 SWA) |
k2_horizon |
general.architecture (k2-horizon alias) |
Dense GQA thinking family, 36 layers, split attn_q/k/v; vendor sampling (temp 1.0 + top_p 0.95 only), ctx 16384, --reasoning-effort high (NOT qat β without the row it misdetects as gemma4) |
lfm2moe |
general.architecture |
Liquid LFM2.5 hybrid: 30 short-conv + 10 GQA blocks, MoE (top-4/64), 131K ctx; shortconv weight-stats class |
gemma4 |
layer-scale norms | QAT support, Q4_K attention floor |
| llama (generic) | tensor names | Dense GQA (MiniCPM5, NeoHorse, etc.) |
10. Ecosystem & repositories
- π¦ NeoHorse-1-9B-MERNIK-GGUF
- π¦ OxCoder-9B-MERNIK-GGUF
- π¦ MiMo-V2.6-Distill-Qwen-9B-GGUF-MERNIK
- π¦ RINIQ-GGUF
- π¦ RINIQ-NEXT-GGUF
- π¦ Ornith-1.5-9B-MTP-ASHQ1-GGUF
- π¦ Spark-X2.5-1.7B-ASHQ1-GGUF
- π¦ Mellum2.1-12B-A2.5B-Thinking-MERNIK-GGUF
- π MERNIK-Fracture β the labels: KLD-only, 5-column, reasoning-corpus damage (the origin of L2/L3)
- π MERNIK-rlmini-kld β early KLD labels
- π MERNIK-gnom-labels β legacy PPL-era labels (retired prototype)
Lineage: Apache-2.0. Built with Soulfate24, whose KLD
battery ended our PPL theater. Field journals with every scar: FUSION.md (monsters),
README-ZOO.md (utility duels), SAGA.md (MTP graft), DIARY.md.
Model tree for wepiqx/MERNIK
Base model
wepiqx/ASHQ1