Current status
The repositories' position pages, rendered verbatim from the pinned commits. Nothing is summarised or reworded here, and the tier counts beside each heading are taken from that repository's claim register at the same commit.
Evidence vocabulary
The words the position pages and the claim registers use, defined once in docs/system-manifest.json (identical in both repositories) and rendered verbatim:
- confirmed
- a public receipt plus an independent confirmation cell (kernel register)
- verified
- a public receipt plus an independent check (runtime register)
- measured
- the run happened and the receipt is public in the repository
- measured-private
- the run happened and the receipt lives outside the repository; NOT publicly reproducible from the repository alone
- projected
- arithmetic from measured inputs, not a run
- open
- a statement the documents make that has no evidence either way yet; it backs no capability
- superseded
- replaced by a later claim that names it; kept as the record, never current
- retired
- withdrawn; kept as the record, never current
experts4bit-qlora v0.35.3 — docs/STATUS.md at 0c2a256dcdc2 (claims tiered in the public register: 161 measured · 6 measured-private · 3 open · 7 superseded · 6 retired)
Status — what this package does, what changed, what is open
As of 2026-09-06, version 0.35.2 (the version of record is pyproject.toml's). One page. The README argues the case; this page states the position. Every line has an entry in docs/claims.json with its evidence path, and nothing is here that does not.
Evidence words, used strictly: measured = a run with a receipt in this repository. measured-private = the run happened and the number is real, but the receipt lives in a private audit tree, so you cannot check it from here — those are named as such. retired = published, now known wrong, kept so the retraction is findable. superseded = still true as measured, but a later entry is the number to quote.
---
What you get today
It fits, and it trains. Full bf16 OLMoE-1B-7B OOMs a 12 GB card; in 4-bit it loads at 4.70 GB and trains under 8 GB, and QLoRA on the frozen NF4 experts moves a held-out Alpaca eval from 1.4813 to 1.0290. The streaming loader never materialises the bf16 model in CPU or GPU RAM.
It scales past VRAM. With expert offload, Qwen3-30B-A3B peaks at 7.16 GB and Gemma-4-26B-A4B at 8.47 GB during a training step — both OOM without it — for about +11% s/step at OLMoE scale. Against a descending host-RAM cap the on-disk arena needs 2.56× to 6.40× less host RAM than the pinned-RAM path, and at 8.59 GB Qwen3-30B is OOM-killed on host RAM and completes on the arena.
The fused training path is faster at equal loss. Across two 30B-class MoEs, five datasets each, 200 steps per cell: 1.52–1.81× per step at 0.75–0.81× peak VRAM and 0.86–0.92× energy, with loss parity on both registered criteria and the frozen 4-bit stack bit-identical over 16.31 GB hashed. Default to enable_fast_train(model, dgrad=True).
Training on real weights is receipted per family (lane tp1, 2026-09-05, one rented RTX 5090 under the shipped 0.35.0 / 0.30.0 code; measured — receipt bench/train-parity-20260905/tp1/, table in its RESULTS-tp1.md; register e4b.train.parity.tp1.<family>.<arm>.2026-09-05; all six families through the registered arms, 18 result lines, every attempt a row, nothing pending). Each family goes through the direct load_moe_4bit_streaming + verify_moe_4bit(strict=True) path on real weights, then reference (the per-expert loop), fused (enable_fast_train(dgrad=True)) and batched (enable_batched_train) for 60 steps on the registered clinical text, judged in the registered units — |Δ final train loss| ≤ 0.05 and median step-wise |Δ| ≤ 0.05 against the family's own reference, same box — with cost reported and never gated. The fused path PASSES on every family that has one: Granite-3.1-3B-A800M (0.01329 / 0.01270; ×5.86 per step at ×0.20 J/step — on the corrected-counter re-run after a HARNESS_ERROR first attempt, a closure bug in the harness's kernel counter, amendment 3, not the shipped code; the family's first direct real-weight load and first training receipt), OLMoE-1B-7B-Instruct (0.01327 / 0.01249; ×3.22 per step at ×0.34 J/step — the first reading on a registered text with real weights for that family), Qwen3-30B-A3B resident on the 32 GB card (0.01315 / 0.01050; ×2.56, ×0.41 J/step), Gemma-4-26B-A4B-it — the -it checkpoint, loaded on that host without the #344 fault — (0.02385 / 0.04742: inside the band by 0.0026, the tightest cell, read with that margin; ×2.37, ×0.48 J/step) and Mixtral-8x7B-Instruct under offload=True (0.00953 / 0.00945; ×1.26 at ×0.49 the reference loop's peak VRAM — its first training receipt, and the family enters the capability's list on it). The batched path PASSES where its kernel engages and is VOID where it does not: PASS on Granite-3.1-3B-A800M (0.01553 / 0.01681; ×3.93 — the family's first direct real-weight load) and Mixtral (0.00766 / 0.01057; ×1.27); VOID on OLMoE, Qwen3 and Gemma-4 — enable_batched_train patched every layer, but engines/batched.py falls back to the reference forward per call above _PAD_WASTE_LIMIT with no counter, and on ≈100-token rows over 64 or 128 experts the kernel was reached on only some layers (Gemma-4: on 9 of 60 steps on none) — a VOID row carries no parity number, however its loss curve reads. gpt-oss fused / batched are REFUSED (0 patched: the loader builds its experts bare); attention-only QLoRA over its frozen experts trains with the stacks bit-exact (10.75 GB hashed), and the kernel package's experimental MXFP4 route trains its experts on its own text with the step-0 canary passing (top-1 0.906, KL 0.025) and provenance holding — experimental, never licensed. The capability list (qlora-fused-moe-experts.model_families in capabilities.json) is exactly the families whose fast_train is supported: olmoe, qwen3_moe, gemma4_text, mixtral, granitemoe — the last two entered on this lane; gpt_oss stays out. No convergence claim, no cross-family ratio, no training throughput position; a PASS is a PASS on one text.
Training support is stated per path, never as a flat flag (phase directive 2026-09-05): the tp1 receipt classifies every row as one of OK / REFUSED / HARNESS_ERROR / ALARM / OOM / NOT_RUN / EXPERIMENTAL, mechanically from its artefacts, with the parity verdict as a separate column; Granite's first fused attempt stays a HARNESS_ERROR row beside its re-run (and the follow-up script's own abort between them, amendment 5, is listed in the re-run's reason), and every amendment stays visible in the bundle's README. The same reading, per family and per path:
| model_type | quantize | reference_train | fast_train (the headline path) | batched_train | nvme_train | native_mxfp4_train |
|---|---|---|---|---|---|---|
olmoe | supported (tp1) | supported (tp1; e4b.train.olmoe-converges) | supported — tp1 OK · PASS on the registered text with real weights (e4b.train.parity.tp1.olmoe.fused.2026-09-05) | void — tp1 OK · VOID: the _PAD_WASTE_LIMIT fallback engaged without a counter (…olmoe.batched…) | not_tested (the arena ladder is measured-private, no shipped bake) | n/a |
qwen3_moe | supported (tp1, resident on a 32 GB card; flagship) | supported (tp1; flagship) | supported — tp1 OK · PASS resident on one 5090 (…qwen3.fused…), beside the flagship's five datasets (e4b.train.flagship-matrix) | void — tp1 OK · VOID: the kernel reached on a fraction of the layers every step (…qwen3.batched…); the dgrad-gate trajectory stands on its own fixture | not_tested (measured-private) | n/a |
gemma4_text | supported (tp1: the -it checkpoint loaded on this host, no #344; flagship: base) | supported (tp1; flagship) | supported — tp1 OK · PASS with the step-wise median inside the band by a small margin (…gemma4.fused…), beside the model-2 flagship (e4b.train.flagship-matrix) | void — tp1 OK · VOID: on some steps no layer reached the kernel (…gemma4.batched…) | not_tested (measured-private) | n/a |
granitemoe | supported (tp1: the first direct real-weight load) | supported (tp1 OK) | supported — tp1 OK · PASS on the corrected-counter re-run (…granite.fused…; attempt 1 a kept HARNESS_ERROR of the harness's counter, …granite.fused.attempt1…, amendment 3) — entered model_families on it | supported — tp1 OK · PASS (…granite.batched…) | not_tested | n/a |
gpt_oss | supported (bare GptOssExperts4bit; tp1) | refused — no ExpertsLoRA; attention-only QLoRA trains (…gptoss.attn_only…, OK · no pair) | refused — enable_fast_train returns 0 (…gptoss.fused…, REFUSED) | refused — enable_batched_train returns 0 (…gptoss.batched…, REFUSED) | refused — enable_mxfp4_nvme_residency refuses bias-carrying modules (#402; it had defaulted to the V4 epilogue, #397), enable_nvme_train_residency refuses bare modules, and the arena_train=True wrap is refused on structure | experimental — grouped-nf4-gemm's ExpertsMxfp4LoRA; tp1 canary and provenance passed on its own text (…gptoss.mxfp4…, EXPERIMENTAL); never licensed |
mixtral | supported (tp1: the first real-weight pass through the w1/w3/w2 fusion, offload=True) | supported (tp1, offload) | supported — tp1 OK · PASS under offload at half the reference loop's peak VRAM (…mixtral.fused…); entered model_families on this row | supported — tp1 OK · PASS, the kernel reached everywhere (the 8-expert shape; …mixtral.batched…) | not_tested | n/a |
Each cell is one of supported (completed under the registered protocol with a PASS/OK receipt), refused (with the reason), void (ran, unreadable), harness_error, not_tested, experimental, n/a — per path, never a flat flag; the machine-readable form, with the claim id behind every supported / void / refused cell, is training_support in capabilities.json, validated by scripts/check_capabilities.py, and model_families is exactly the families whose fast_train is supported. Row statuses in the tp1 receipt are one of OK / REFUSED / HARNESS_ERROR / ALARM / OOM / NOT_RUN / EXPERIMENTAL with the parity verdict (PASS / FAIL / VOID) as a separate column.
Against Unsloth, end-to-end, on one identical training problem (lane p38, 2026-09-05, one rented RTX 5090, box 49975389; measured — receipt bench/h2h-20260905/p38/, table in its RESULTS-p38.md, the pre-registration verbatim as its PREREG.md; register e4b.train.h2h.unsloth.qwen3.5090.2026-09-05 with its .quality-n60, .curve-n200 and .e4b-internal-parity rows and one row per arm). Qwen3-30B-A3B at one pinned revision, the registered clinical fixture tokenised once and asserted by sha in every arm, seq 512, r 8 / α 16 on attention q/k/v/o and every expert, the router frozen, 321,257,472 trainable parameters asserted, the same optimizer, LR, batch, steps, precision and held-out eval on both sides — experts4bit-qlora 0.35.0 + grouped-nf4-gemm 0.30.0 (the fused dgrad path with NF4 attention, the shipped TRAIN_ATTN_4BIT mechanism) against Unsloth 2026.9.2 + unsloth_zoo 2026.9.1 (its 4-bit MoE path, native_torch backend; the two stacks' transformers/peft versions differ and are recorded). At 60 steps: s/step ratio Unsloth/e4b 1.413 (2.151 vs 1.522 s — e4b faster per step at this workload), peak VRAM 21.371 vs 23.141 GB, 157.1 vs 224.7 J/step, time to a held-out loss of 0.32 92.5 vs 130.3 s, held-out loss comparable (0.2923 vs 0.2975, |Δ| 0.0052 ≤ the 0.05 reading threshold). At 200 steps the curves separate in Unsloth's favour: 0.2713 vs 0.2881 — e4b's flattens near 0.29 from step 60 while Unsloth's keeps falling. That row is quoted beside the position wherever the position is quoted; its causes — the eval schedule, the checkpointing mode, the two stacks' transformers / peft versions, the expert adapter's precision (bf16 on this side, because the loader passes the model dtype to ExpertsLoRA; fp32 on Unsloth's) — are candidates, not established. e4b's own fused-vs-reference pair passes its band on that box (0.00131 / 0.01138, ×2.92 per step; informational, tp1 owns the licence). The pre-registration predicted the opposite sign at this workload and said the finding ships either way; it does. One workload (≈86 tokens per step, batch 1, resident), one box, one family: no general speed claim, nothing licensed, and the 2026-08-26 "1.17× ahead" memory (never a claim) is disqualified as a comparison.
tp2 / P40 (2026-09-06): the Unsloth head-to-head now covers all six families, one box, one fixture (lane tp2 / P40, one rented RTX 5090, Vast box 50005568 on a Ryzen 7 5700X3D host, train-anchor class pcie-full/launch-fast; measured — receipt bench/h2h-20260906/tp2/, reducer table in its RESULTS-tp2.md, the pre-registration verbatim as its P40-PREREG.md; register e4b.train.h2h.unsloth.<family>.5090.2026-09-06 — one row per attempt under ….arm.<framework>.<arm>, position and .quality-n60 rows on Qwen3 and Mixtral, a .footprint row on Mixtral, .coverage rows on Granite and OLMoE, .e4b-internal-parity rows on Granite, OLMoE, Qwen3 and Mixtral). P38's fixture exactly (seq 512, r 8 / α 16, lr 1e-4, accum 1, N=60, held-out every 20), tokenised once per family with that family's tokenizer; e4b at the shipped cut a user installs today — 0.35.1 + grouped-nf4-gemm 0.30.2 from PyPI, NF4 attention via the shipped TRAIN_ATTN_4BIT mechanism — against Unsloth 2026.9.2 in its own venv. Positions exist on two families; on the other four the statuses are the result. Qwen3-30B-A3B: s/step ratio Unsloth/e4b 1.457 (5.986 vs 4.108 s — e4b faster per step), peak 21.371 vs 23.141 GB, 383.9 vs 561.4 J/step, held-out COMPARABLE (0.2935 vs 0.3087, Δ +0.0152 ≤ the 0.05 reading threshold; e4b.train.h2h.unsloth.qwen3.5090.2026-09-06, ….quality-n60) — the cross-lane anchor: +3.1% from P38's 1.413, inside the pre-registered ±10% (prediction P2 held: the sign and size of the per-step position reproduce on a second box; P38's 200-step curve row, in Unsloth's favour, still stands beside any position of this family). Mixtral-8x7B: the footprint trade leads the row — the e4b arm trained its experts under CPU offload at a 3.223 GB peak (the registered design for this family, tp1's offload=True; a trainable-on-smaller-cards capability, its own row e4b.train.h2h.unsloth.mixtral.5090.2026-09-06.footprint) while Unsloth ran resident (its only mode) at 29.163 GB, and what that VRAM buys it is speed per step: ratio 0.361 — a footprint-vs-speed trade under the registered design, not a kernel deficit; e4b's energy is lower (298.3 vs 350.2 J/step); held-out COMPARABLE (0.2590 vs 0.2502, Δ −0.0087; e4b.train.h2h.unsloth.mixtral.5090.2026-09-06, ….quality-n60); prediction P4 (Unsloth resident OOMs at seq 512 on 32 GB) falsified. No position on the other four, and the coverage rows are results, not empty cells: Granite — the comparator could not train the experts: Unsloth's arm completed but is VOID — it attached LoRA to the attention only, 2,621,440 trainable parameters against e4b's 49,807,360 with ExpertsLoRA on all 32 MoE layers, 0 Params4bit expert stacks, no 'Enabling LoRA on MoE parameters' banner — its MoE-LoRA path never engaged on granitemoe (e4b.train.h2h.unsloth.granite.5090.2026-09-06.coverage, ….arm.unsloth.ckpt_unsloth); e4b's arms are VALID (fused 0.641 s/step, ×5.59 its own reference). OLMoE — the comparator could not train the family at all: Unsloth's process died at MoE-LoRA engage, rc=1, before its first receipt write (HARNESS_ERROR; e4b.train.h2h.unsloth.olmoe.5090.2026-09-06.coverage, ….arm.unsloth.ckpt_unsloth); e4b's arms are VALID (fused 0.708 s/step, ×3.73). gpt-oss — three refusals, as pre-registered (P5 held): e4b's attention-4-bit refuses on structure (96 of 96 attention projections carry a bias), its fused path patches nothing (tp1's REFUSED row re-proven on this box), and Unsloth's load fails on the MXFP4 weight conversion (e4b.train.h2h.unsloth.gptoss.5090.2026-09-06.arm.*); the attention-only secondary row trains (1.464 s/step, 14.687 GB, ….arm.e4b.attn_only). Gemma-4 — both e4b attention-4-bit arms died on the converter's own count check (quantize_attention_projections_4bit converted 100 projections, expected 120 — #412; the bf16-attention fast_train path stays exactly as tp1 left it), while Unsloth's arm is OK · VALID at 3.510 s/step (e4b.train.h2h.unsloth.gemma4.5090.2026-09-06.arm.unsloth.ckpt_unsloth) — recorded with the receipt. e4b's internal fused-vs-reference parity PASSES on all four families that ran both arms (×5.59 / ×3.73 / ×2.69 / ×1.23 per step on Granite / OLMoE / Qwen3 / Mixtral, e4b.train.h2h.unsloth.<family>.5090.2026-09-06.e4b-internal-parity; informational, tp1 owns the licence). training_support in capabilities.json now records the attention-4-bit configuration per family from these receipts — inside the per-path structure, never a flat flag. No gate, threshold or licence moved; nothing here supersedes P38 (two boxes, two measurements, never averaged).
Serving is at parity with the model's own attention on three of four families, and not on the fourth. This is the part that changed most this week. Measured against a chunk-free reference — one full forward, no chunk boundaries — the paged decode path is indistinguishable from the model's own attention on Granite, gpt-oss and Qwen3, and is not on Gemma-4:
| family | paged vs reference | that model's noise floor | reading |
|---|---|---|---|
| Granite-3.1-3B-A800M | 0.00229 nats | 0.00330 | indistinguishable |
| gpt-oss-20b | 0.00288 nats | 0.01758 | indistinguishable |
| Qwen3-30B-A3B | 0.00173 nats | 0.00641 | indistinguishable |
| Gemma-4-26B-A4B | +0.093 … +0.247 (three windows) | no stable floor: HF's own cache −0.107 … +0.271 | no reference at this resolution (#359) |
Read that table with its floor column or not at all. Two arithmetically equivalent forwards of a mixture-of-experts model do not agree, because rounding flips which experts the router picks — 4.52% of layer-token choices on gpt-oss, 6.77% on Qwen3 — and the disagreement is carried almost entirely by the flipped tokens (KL 0.0504 against 0.0013). A parity delta below the floor means indistinguishable, never "a small cost". Method in METHODOLOGY.md §13.1; per-family table in SERVING-PARITY.md.
Gemma-4 has no reference at this resolution. On three 512-token windows the paged path sits +0.093, +0.114 and +0.247 nats from a one-shot forward — and transformers' own cached forward sits −0.107, +0.271 and +0.081 from that same one-shot forward on the same windows. The cause is the model, not a path: plain transformers with no e4b code gives the same 255 tokens an NLL that moves by 0.4 nats depending only on which tokens follow them (bf16 batch-shape variance in the expert gathers, 0.2% at layer 1, amplified by the router to 35% of the hidden state by layer 19; Qwen3 shows the mechanism at a tenth of the amplitude and loses 0.001). Running the router in fp32 (plain transformers) does not remove the amplification (layer-19 divergence 0.25 against 0.34, top layer unchanged) and itself moves the same tokens' NLL by 1.1 nats, so router precision is not a lever; the sensitivity is the model's. The paged path's one localised, measured cost is the fp8 cache and dot: 0.046 nats, concentrated on the five 512-dim layers, 0.017 with 32-wide K groups. Method: METHODOLOGY §13.2; numbers: SERVING-PARITY.
Serving speed, Qwen3-30B-A3B on a rented RTX 5090: the licensed position is the census's, below — ×2.067 at B=1 (238.1 tok/s on box 49916675) and ×2.602 at B=16 (1327.5 tok/s), the streamed-calibrated stack bo6c licensed on both texts (e4b.serve.census.bo7.qwen3.b1.5090.2026-09-05 / e4b.serve.census.bo7.qwen3.b16.5090.2026-09-05, measured). The 2026-09-03 numbers this paragraph used to lead with — about 100 tok/s on the NF4 baseline, 204.6 tok/s with calibrated int4 attention and round-to-nearest int4 experts, about 1,238 tok/s aggregate at B=16 — are real and stand as measured (e4b.serve.b1.qwen3-30b.int4attn-calib.5090, measured-private; e4b.serve.b16.qwen3-30b.int4.5090, measured), but that RTN-int4 configuration class later FAILED the registered gate on its second text (lane bo5, +0.063 ppl on C4 validation, below) and is not the licensed stack: quote them as the speed of an unlicensed configuration on its box, never as the position. On the 2026-09-04 validation box the same class went from 156.1 to 177.9 tok/s at B=1 (×1.14) when 0.34.0's round-2 fold started engaging on the calibrated int4 attention it had silently skipped (#375) — measured, receipt in the bo3 bundle below, the same caveat.
Against vLLM, same box, same session, identical prompt token ids (lane p37, 2026-09-05, Vast 49975016, an RTX 5090 on an EPYC 7Q83 host; measured — receipt bench/h2h-20260905/p37/, table in its RESULTS-p37.md, the pre-registration verbatim as its PREREG.md; register e4b.serve.h2h.vllm-0.28.0.qwen3.5090.2026-09-05 and one row per arm): vLLM 0.28.0 serving Qwen's GPTQ-Int4 checkpoint (Marlin, default CUDA graphs) decodes at 286.0 tok/s at B=1 and 2030.0 aggregate at B=16 (fp8-KV arm 300.9 / 2206.5; eager 20.8 / 322.5); this package's NF4 control on the same box reads 113.4 / 500.1 (repeats 113.5 / 499.9) — vLLM / e4b-NF4 2.52 at B=1 and 4.06 at B=16, the only licence-free ratio the lane can quote, and it is against the slowest configuration this package ships. The ratio against the licensed stack is not quoted: every licensed e4b arm on that box is VOID under the pre-registered pack-fingerprint rule — the streamed calibration there packed 11522 gptq / 766 rtn expert matrices where the licensed pack (bo6b, bo6c, bo7) reads 11512 / 776, the same recipe but not the licensed bytes, and speed cannot inherit a licence. The recipe's speed on that box — 236.4 tok/s at B=1 (repeat 235.8), 1305.3 at B=16, ×2.08 / ×2.61 over its own NF4 control, bo7's ×2.067 / ×2.602 reproduced within 1% — is measured and unlicensed, an observation never divided into a position. Amendment 3 (pre-registered after TP_DONE) ran the registered K8 gate on that box's own pack and it FAILED (e4b.serve.h2h.vllm-0.28.0.qwen3.5090.2026-09-05.gate, measured): wikitext Δ −0.0230 ppl, pass; C4 validation Δ +0.1093 ppl against the +0.05 budget — where the licensed pack read −0.0662 on the same window. VOID stands; no ratio against the licensed stack exists on that lane; the recipe re-derived on another host is a different pack with a different verdict (an open item, below). The 2026-09-03 comparison (e4b.serve.h2h.vllm.same-box (superseded): ×1.47 / ×1.55 on a different box against the 0.27.0/0.21.0 RTN stack, vLLM version unrecorded) is superseded for current-position use and stays true as measured. Quality is quoted, never equated: neither checkpoint is scored on that lane.
Per-family throughput is now measured in-repo (2026-09-04): six families under one protocol on one rented 5090 class, with every refused arm named — that list became the build-out, and 0.33.0 ships it. Table and receipt: SERVING-THROUGHPUT.md.
One more family reaches the reference's ratio with the build-out, and one claimed to has been retracted (0.33.0; measured — the validation lane's full receipt, every run and its verdict in the gate's own units, is bench/hybrid-g9/throughput-20260904/bo3/, and the licensed-best table is in SERVING-THROUGHPUT.md): Gemma-4-26B-A4B at 121 tok/s B=1 with int4 experts + round-1 norms + router epilogue (×1.69 over NF4; int4 experts alone ×1.20 B=1 / ×1.39 B=16; ×1.68 at B=16). Mixtral reaches ×2.14 (×2.29 with calibrated attention). gpt-oss stays NF4-only: a uniform int4 grid cannot hold its MXFP4 experts (+0.63 nats measured), and the native path is not yet a lever. Granite-3.1-3B-A800M's "302 tok/s, ×1.59" row is retracted as a parity claim: its int4 experts cost +0.063 ppl on the same window, over the registered 0.05-ppl gate (k8_gate, uncalibrated rule), and the 0.33.0 text quoted the row without applying that gate. The speed is real; the configuration is not licensed. Granite's licensed stack keeps NF4 experts (round-1 + round-2 folds + router epilogue) and its combined number is 259.1 tok/s at B=1 (×1.37) and 1689.6 at B=16 (×1.18), +0.019 ppl — measured, in the same receipt.
The second text (2026-09-04, lane bo5; measured — receipt bench/hybrid-g9/throughput-20260904/bo5/, table in its RESULTS.md). The registered K8 gate is in perplexity: an uncalibrated arm |Δppl| ≤ 0.05 on every text, a calibrated pack ≤ +0.05 on every text with an improvement claimable only when it holds with the same sign on two; nats are quoted beside the verdict and never change it. bo3 had scored one text; bo5 scored C4 validation on one box (49841214, the same 5090 class) for every calibrated pack bo3 left at "one text", and every one FAILS as registered: Qwen3's all stack +0.063 ppl (+0.0038 nats — every attribution arm on that text is inside the family's 0.0095-nat floor and the exact folds alone read −0.073, so the reading is noise, not a component; the verdict is not retuned), Mixtral's all +0.116 ppl, and Granite's C4-calibrated int4 experts (e4b#384, draft) +0.387 ppl at 10× the floor — that route is refused. Mixtral's uncalibrated int4-expert stack — called licensed in P30 and bo3 on wikitext (−0.046 ppl there) — fails the second text by 0.008 (+0.058 ppl, +0.0070 nats; this family's floor is unmeasured), so that label is withdrawn under the rule as written, pending a decision on re-registering the gate in nats against a measured floor. Licensed and re-measured on the bo5 box: Granite's NF4 stack 294.1 tok/s B=1 / 1736.1 B=16; gpt-oss's MXFP4 store under the route rule (GEMV for single rows, NF4 kept for batched rows) 173.3 (×1.270) / 719.7 (×0.971 — the ×0.81 B=16 penalty is recovered), quality gate open on that family as before. Measured speed of configurations NOT licensed under the registered rule: Qwen3 all 204.1 / 1251.6 (with #385's glue, ×1.057 at B=1 on that box), Mixtral all 123.3 / 377.3, Mixtral's int4-expert stack 112.0 / 376.5. #387's fused q/k/v is quality-clean (−0.0011 nats on Granite, +0.0002 on Mixtral) and buys nothing (Granite ×0.968 B=1, Mixtral ×1.032) — it stays a draft.
Closing the gap, not the gate (2026-09-04, lane bo6; measured — receipt bench/hybrid-g9/throughput-20260904/bo6/, table in its RESULTS.md). The registered gate stays in perplexity; the int4-expert arms that failed their second text with round-to-nearest experts were re-run with per-expert GPTQ calibration (e4b#384) on one box, against NF4 re-scored on that box. Sequential calibration is the mechanism that ships (0.35.0): on Qwen3-30B-A3B the calibrated experts alone read c4val1 +0.150 ppl (FAIL) when every layer's Hessian is accumulated against the unquantised prefix and packed afterwards, and −0.050 (pass on that text) when each layer chunk is packed before the next chunk's Hessians accumulate — the same box, batches and damping; the order alone moves the reading 0.200 ppl and flips the verdict (e4b.serve.buildout.bo6.qwen3.calibration-order.c4val1.2026-09-04; the instrument is run-to-run deterministic there, e4b.serve.buildout.bo6.qwen3.k8-deterministic.5090.2026-09-04). More calibration text helps (64k tokens −0.211, 256k −0.141; damping 0.1 fails at +0.054), and none of those is claimed as an improvement until wikitext agrees. Qwen3's calibrated int4 experts pass the registered gate under it: the full calibrated stack — calibrated experts + calibrated int4 attention + folds + epilogue + glue — passes on both texts (wikitext −0.060 / c4val1 +0.035, e4b.serve.buildout.bo6.qwen3.all-calibexp-allatonce.k8.2026-09-04; that pack was calibrated all-at-once) and reads 158.0 tok/s at B=1 / 993.6 at B=16 on that Threadripper-hosted box (e4b.serve.buildout.bo6.qwen3.b1.5090.2026-09-04 / e4b.serve.buildout.bo6.qwen3.b16.5090.2026-09-04 — quoted with its box, no ratio: the lane has no NF4 speed arm). Qwen3-30B-A3B's licensed serving stack is the streamed one (bo6c, 2026-09-05, same box, receipt in the same bundle): sequentially calibrated int4 experts at 64k C4-validation tokens + C4-calibrated int4 attention + round-1/2 folds + router epilogue + decode glue — wikitext −0.053 / c4val1 −0.066 ppl (−0.0083 / −0.0040 nats, both inside the 0.0095-nat floor): pass on both texts as registered, licensed under the unchanged gate, at parity or better on both texts, no improvement claimed by a number (e4b.serve.buildout.bo6c.qwen3.all-calibexp-streamed-64k.k8.2026-09-05). The 64k experts-only pack is at parity on wikitext (−0.0002) and −0.211 in-domain (e4b.serve.buildout.bo6c.qwen3.calibexp-streamed-64k.k8.2026-09-05), and the streamed calibration is itself run-to-run deterministic (e4b.serve.buildout.bo6c.qwen3.calib-deterministic.5090.2026-09-05). That stack's speed is not on this lane — bo7 measures the calibrated stack at the hook's 16k-token default, not 64k. Granite stays NF4 (bo5: calibrated experts +0.387 ppl, not closable with this lever). Sequential calibration closed Qwen3's gap and did not close Mixtral's: its calibrated int4-expert stack passes the in-domain text (c4val1 +0.039) and fails the out-of-domain one (wikitext +0.077 ppl, +0.0234 nats; this family's floor is unmeasured) — FAIL as registered, measured, not licensed (e4b.serve.buildout.bo6.mixtral.lic-calibexp-streamed.k8.2026-09-04), the mirror image of bo5's RTN stack; not a reference shift (same window sha, NF4 agrees with bo5c to 0.001 nats). Next levers are not gate changes: a per-expert NF4 fallback for the largest-residual experts, or the 64k calibration set scored on wikitext. The lane's Mixtral speed arms and its 64k-token arm were killed by their own per-arm alarms during the ~85-min streamed calibration and were not measured — a harness limit, not a model result; bo7 dropped those arms too. Qwen3's NF4 reference sits 0.006 nats from bo5's on the identical window while Mixtral's agree to 0.001 — that shift stays open, and no sub-0.01-nat number is compared across lanes.
The throughput census (2026-09-05, lane bo7; measured — receipt bench/hybrid-g9/throughput-20260904/bo7/, table in its RESULTS.md). Speed only, under the shipped code (0.35.0 + 0.30.0 at their main, hook v6 at its 16k default), all six families on one rented RTX 5090 (EPYC 7Q83 host, instance 49916675), 48 arms at B=1 and B=16, every ratio to that family's own NF4 arm on that box and every licence label copied from this register — bo7 licenses nothing, and no bo3/bo5/bo6 number is divided into a bo7 number. What the box says, three axes per licensed best (ratio over NF4 on this box; rental-measured tok/s on this box; anchor-class projection — which exists only for Qwen3-30B at B=1 and is not computed here): Granite's licensed stack (NF4 experts + folds + epilogue) is ×1.341 at B=1 (304.9 tok/s) and ×1.160 at B=16 (1836.8; e4b.serve.census.bo7.granite.b1.5090.2026-09-05 / e4b.serve.census.bo7.granite.b16.5090.2026-09-05); OLMoE's position is NF4 (282.5 / 1347.5, ×1.000; e4b.serve.census.bo7.olmoe.b1.5090.2026-09-05 / e4b.serve.census.bo7.olmoe.b16.5090.2026-09-05) because nothing above it is licensed on this register — the tp row's "best licensed" label predates the two-text clause and its calibrated attention is refused on this family, so its full stack is ×2.070 / ×2.289 measured, not licensed; gpt-oss's quoted best is its own reference arm (NF4 + exact folds, 144.5 / 761.6; e4b.serve.census.bo7.gptoss.b1.5090.2026-09-05 / e4b.serve.census.bo7.gptoss.b16.5090.2026-09-05) and the MXFP4 store under the route rule reads ×1.293 / ×0.970 with the quality gate open; Qwen3's licensed stack — the streamed 64k calibrated pack bo6c licensed on both texts — measured on the same box under the lane's amendment 2 (pre-registered 06:05Z, run after TP_DONE): ×2.067 at B=1 (238.1 tok/s; anchor-class projection 159.2 × 2.067 ≈ 329 tok/s, a projection from an uncertified class) and ×2.602 at B=16 (1327.5 tok/s; no anchor projection) — e4b.serve.census.bo7.qwen3.b1.5090.2026-09-05 / e4b.serve.census.bo7.qwen3.b16.5090.2026-09-05. Its speed is identical to the lane's 16k arm (4.20 vs 4.20 ms; 1327.5 vs 1338.8, within 1%) and to the RTN stack: a calibrated pack's kernels do not depend on the calibration size, as the amendment predicted — the pack changes the values, not the kernel or the bytes. Gemma-4 has no K8 instrument, so no arm carries a K8 licence; the register's position with that caveat is the exact round-1 fold + epilogue on NF4 (r1epi), ×1.281 at B=1 (103.6 tok/s) and ×1.106 at B=16 (675.8; e4b.serve.census.bo7.gemma4.b1.5090.2026-09-05 / e4b.serve.census.bo7.gemma4.b16.5090.2026-09-05), and the quoted int4 best (bo3's stack) reads ×1.705 / ×1.697 measured, no quality verdict — Gemma-4-it loaded on this host without the #344 fault. Mixtral's position is NF4 (50.3 / 191.4, ×1.000; e4b.serve.census.bo7.mixtral.b1.5090.2026-09-05 / e4b.serve.census.bo7.mixtral.b16.5090.2026-09-05): the exact folds are ×1.062 / ×1.018 but unscored as a combined arm, the RTN int4 stack ×2.329 / ×1.959 and the calibrated-attention stack ×2.597 / ×1.962 are measured, not licensed (bo5's second-text FAILs stand), and the calibrated-expert arms were dropped under the lane's amendment (FAIL as registered on bo6b, ~85-min calibration) and print as a row that says so. Two int4 facts the box adds: a calibrated int4-expert pack costs nothing over an RTN one in speed (Granite 2.04 vs 2.05 ms, Qwen3 4.197 vs 4.204), and the streamed calibration's pack counts reproduce across hosts (Granite 2524/36, Qwen3 10820/1468 — bo5's and bo6's counts). All 50 arms ran — 48 in the lane (TP_DONE 07:00Z, 5.0 h) and amendment 2's two (TP2_DONE 08:52Z) — with no alarm, refusal or traceback.
---
What changed — retired, superseded, corrected
- The 2026-09-04 Qwen3 "best licensed" throughput rows are SUPERSEDED (2026-09-05):
e4b.serve.tp.qwen3.b1.5090.2026-09-04(superseded) ande4b.serve.tp.qwen3.b16.5090.2026-09-04(superseded) now point at the census rows of the licensed stack (e4b.serve.census.bo7.qwen3.b1.5090.2026-09-05/e4b.serve.census.bo7.qwen3.b16.5090.2026-09-05); the RTN-int4 class they quoted failed its second text on bo5, and their numbers stand as measured. The other four families' 2026-09-04 rows keep their numbers with the "best licensed" label withdrawn in the sentence (measured, not licensed), and every active claim whose sentence asserts a licence now names its K8 verdict row (licensed_by) —scripts/check_claims_register.pyholds the register to that and to its own structure (evidence paths that exist, dated measured rows, successors that resolve, no "pending" on an active row). The 2026-09-03 single-stream stack this page led with is the same RTN class and is quoted above as unlicensed speed. - The 2026-09-03 same-box vLLM comparison is SUPERSEDED (2026-09-05):
e4b.serve.h2h.vllm.same-box(superseded; ×1.47 / ×1.55 on box 49702459, the 0.27.0/0.21.0 RTN stack, vLLM version unrecorded) points ate4b.serve.h2h.vllm-0.28.0.qwen3.5090.2026-09-05— lane p37, vLLM 0.28.0 pinned, identical prompt ids, every knob recorded — which quotes vLLM against this package's NF4 control (2.52× / 4.06×) and, as pre-registered, quotes no ratio against the licensed stack because its arms were VOID on that box (the pack fingerprint 11522/766 against the licensed 11512/776). Amendment 3's gate on that pack failed on C4 validation (+0.1093 ppl;e4b.serve.h2h.vllm-0.28.0.qwen3.5090.2026-09-05.gate), so no head-to-head against the licensed stack exists on that lane. - The 2026-08 "vLLM 6.31× ahead" figure is RETIRED by id — the retired row is
e4b.retired.vllm-6.31x-ahead: template prompts and a different box; the same-box, same-prompt comparison (e4b.serve.h2h.vllm.same-box(superseded)) supersedes it and now names it, with its own two limits stated (vLLM version unrecorded; the e4b arm is the unlicensed RTN class). e4b.retired.13.47x-training-speedupisretired, notsuperseded: the "about 7.2× against a current baseline" restatement has no receipt of its own in this repository, so there was no successor row to name; the correction below stands as written.- "The fp8 paged KV cache costs +0.047 ppl on Qwen3" — RETIRED. That is +0.0058 nats, below the model's own 0.0095-nat floor. Indistinguishable from reordering the arithmetic; not attributable to the cache. The rule derived from it ("buy headroom back from the cache first") goes with it — there was nothing to buy back.
- "gpt-oss's +0.078 nats is a real signal about sinks and sliding windows" — RETIRED. Against a chunk-free reference the path sits at 0.00288 nats. The chunked oracle it had been compared against is 6× further from the truth than the path it was judging; the gap tracked the oracle's chunk-boundary count.
- "Chunked scoring breaks on sliding-window families" — mechanism RETIRED. The measurement stands; widening the window past the context leaves the gap, and every cache class reproduces it. The cause is router flips, which applies to every MoE model.
- The pre-registered KL gate is FALSIFIED, by its own first measurement: it rejects NF4 experts, which this project ships (0.029 nats against a 0.01 threshold). The threshold was calibrated from a signed NLL difference and applied to a full-vocabulary KL. It is left textually unchanged in METHODOLOGY §13 and marked falsified rather than retuned.
- "Granite reaches the Qwen3 ratio: 302 tok/s, ×1.59 with int4 experts" (0.33.0 changelog and this page) — RETRACTED. The int4 experts on that row cost +0.0118 nats = +0.063 ppl against NF4 on the same 2048-step window, over the registered 0.05-ppl uncalibrated gate. The lane table read nats against the family's 0.0033-nat noise floor (which the row clears by 3.6×) and never against the budget; a floor says an effect is real, a budget says whether it ships. The pattern was already on record — int4-b32 experts are quality-neutral at ≥13B active and cost ~1.2–1.8% ppl at ≤1B active — and this row is that pattern. The 0.32.0 throughput table's Granite int4 rows carry the same delta (1.6741 → 1.6859) and are re-labelled in
SERVING-THROUGHPUT.mdandclaims.json. - "Gemma-4 behaves (−0.0078 nats)" — SUPERSEDED, and then "Gemma-4 is not at parity: 0.247 nats, 3× its floor" — SUPERSEDED the same day. Both compared one 512-token window to one reference. Three windows and a three-forward test in plain transformers show the model has no reference at that resolution (above). What survives is the fp8 share, 0.046 nats. #359 stays open, re-scoped.
- "4-bit on a card that already fits is a 1.2–2.3× energy penalty: NF4 is storage-only and the GEMM runs in bf16 either way" — SUPERSEDED, number unchanged (2026-09-04). The measurement stands as its receipt made it — one OLMoE-dims expert projection on an RTX A2000, dequantize-then-
linearand a bitsandbytes 0.50-dev fork build'smatmul_4bitrouting against native bf16 — and is re-registered with that comparator and version named ase4b.train.energy-honest.scoped-a2000(e4b.train.energy-honestissuperseded, pointing at it). What is withdrawn is the mechanism sentence as a universal: bitsandbytes ≥ 0.50.0 CUDA inference can consume packed 4-bit weights directly for supported ordinary 2-D cells, routed grouped MoE execution is a separate contract, and training's input gradient is separate again (BITSANDBYTES.md). The receipt names its build only as "0.50.0.dev0 / the fork", so which path its 4-bit arm exercised is not recoverable from it — remeasure with a recorded version: #392. - The 13.47× training speedup is ~7.2× against a current baseline. transformers v5 fused the per-expert loop upstream, moving the baseline from 50.86 to 26.6 s/step. The grouped arm did not regress. Roughly half the published multiple is now upstream's work.
docs/INFERENCE.md's decode grid is superseded for decode by the pipelined and paged engines (that document says so itself).- "int8-offload posts the best training eval" is confounded — the audit found an evaluator offset the same order as the effect, and the bundle's CSV mislabels host for half the repeat jobs.
- Informed hot sets did not replicate on an A6000 with a 128-expert model and were withdrawn as evidence there.
---
What is open
- The licensed serving pack does not reproduce bit-for-bit across boxes. Lane p37 (
bench/h2h-20260905/p37/) re-derived Qwen3's streamed 64k calibrated pack with the same recipe on another host and read 11522 gptq / 766 rtn expert matrices against the licensed 11512 / 776 (bo6b, bo6c, bo7): ten of 12,288 matrices crossed themin_rowsthreshold the other way — and the registered K8 gate run on that pack (amendment 3,e4b.serve.h2h.vllm-0.28.0.qwen3.5090.2026-09-05.gate) fails on C4 validation: +0.1093 ppl against the +0.05 budget (wikitext −0.0230, pass), where the licensed pack read −0.0662 on the same window and the two boxes' NF4 references agree to 0.0002 ppl. The reference travels; the calibrated pack does not: the streamed calibration recipe does not reproduce its licence across hosts. bo6c's licence stands on its box as measured; what is open is the recipe's host-dependence — same checkpoint, same text, same knobs, a different pack and a different verdict on another host (#405). enable_batched_train's engagement envelope. It falls back to the reference forward per call above_PAD_WASTE_LIMIT(engines/batched.py); a positive return value is a patch count, not kernel engagement. In the code tp1 measured (0.35.0) the fallback was silent: OLMoE's, Qwen3's and Gemma-4'sbatchedarms are VOID on exactly this (on 9 of 60 Gemma-4 steps no layer reached the kernel); it engaged everywhere only on Mixtral's 8-expert and Granite's 40-expert shapes. 0.35.1 (#402) makes the fallback countable —batched_fallback_stats(model)— so a batched arm can be read from the path itself; the envelope (which shapes engage) is still open and is measured, not tuned.- gpt-oss has no expert-LoRA training path under the shipped e4b code.
enable_fast_trainandenable_batched_trainrefuse it (0 patched), by design, and 0.35.1 (#402) makes the refusal a contract: a wrapper whose base breaks the stock epilogue raisesEpilogueContractError, andenable_mxfp4_nvme_residencyrefuses bias-carrying modules (it had defaulted to the V4 epilogue, #397). What stays open is a gpt-oss-aware adapter; the kernel package'sExpertsMxfp4LoRAroute is the experimental alternative (tp1: canary and provenance pass, never licensed). - #412 — Gemma-4 attention 4-bit:
quantize_attention_projections_4bitconverted 100 projections where 120 were expected, so both e4b attention-4-bit arms of lane tp2/P40 died on the converter's own count check before a step ran (e4b.train.h2h.unsloth.gemma4.5090.2026-09-06.arm.e4b.*, receipt statusvoid_attn4). Attention-4-bit training ongemma4_texthas no receipt and is not supported pending it; the bf16-attentionfast_trainpath stays as tp1 left it. - #344 — Gemma-4 fails to load on 2 of 6 rented hosts with
CUDA error: invalid argument, after the experts quantise. A 2 GiB host-hop fix was merged and reverted the same day: the model's largest tensor is 1.375 GiB, so it never triggered. The live lead is that CUDA reports asynchronously, so the traceback site need not be the faulting kernel. - #341 — a flaky end-to-end KV test (unseeded inputs, an f32-mode tolerance applied to the fp8 default on sm_120).
- #392 — the energy receipt does not record its bitsandbytes build.
docs/METHODOLOGY.mdnames the build only as0.50.0.dev0(§1) and "the fork (bnb 0.50-dev)" (the packaging note covering §9–§10), with no commit; the harness prints the GPU name, notbitsandbytes.__version__. Until it is rerun on a recorded release,e4b.train.energy-honest.scoped-a2000is a one-card, one-build number. - No shipped tool bakes the arena. Reproducing the training receipt from published artifacts still needs a quantise-and-emit step you write yourself.
- #359 — Gemma-4, re-scoped: (1) DONE in 0.32.0 with grouped-nf4-gemm 0.26.0 — 32-wide key scales on the 512-dim heads take the paged path from 3.59239 to 3.57228 nats on the P26b window; (2) still open: a parity instrument that survives batch-shape variance — a long window, or matched routing — before any verdict is quoted for this family.
- Several older documents carry open debts of their own, and say so:
POST_AUDIT_WORK_QUEUE.md(quarantines Q1–Q4 in force),TRAIN_PLACEMENT_CERTIFICATE.md(a scoped S10 — one same-host bf16 pair unexplained by any measured mechanism),LAYOUT_FACTS.md(full-run training determinism UNKNOWN).
---
Two things about the documentation itself
Anchored documents are never edited in place. Several docs here carry an OpenTimestamps footer, and their bytes must keep matching their proof. On 2026-09-03 three PRs appended a serving-parity section to the anchored support_matrix.md; that content now lives in SERVING-PARITY.md and the anchored file is restored to its anchored bytes. The precedent for doing it this way is ARCHITECTURE_SUPPORT.md, which exists as a separate file for exactly this reason.
Separately, and predating that: support_matrix.md's footer discloses a pre-footer content hash that no longer matches the file's pre-footer bytes. That discrepancy is older than this cleanup and is not fixed here, because fixing it means editing an anchored document. It is recorded so a reader is not surprised by a failing check.
measured-private is not a synonym for measured. The 2026-09-03 single-stream serving speed numbers and the calibrated-int4 quality numbers come from a private audit tree (the same-box head-to-head against vLLM is now in this repository, bench/h2h-20260905/p37/; its 2026-09-03 predecessor was private and is superseded). They are real runs with real receipts that this repository does not carry, and they are labelled that way in claims.json. Treat them as you would any number you cannot check.
grouped-nf4-gemm v0.30.2 — docs/STATUS.md at e2af4cfb91b2 (claims tiered in the public register: 11 confirmed · 9 measured · 3 measured-private · 1 projected · 3 open · 1 superseded · 2 retired)
Status — what this kernel does, what changed, what is open
As of 2026-09-05, grouped-nf4-gemm version 0.30.2. One page. The README argues; this page states. Every line here has an entry in docs/claims.json with its evidence path, and nothing is here that does not.
Evidence tiers, unchanged from the rest of the repo: confirmed = pre-registered, stamped, blind confirmatory run; measured = a run with a committed receipt; projected = arithmetic, not a run. One addition, because it was being blurred: measured-private = the run happened and the number is real, but the receipt lives in a private audit tree, so you cannot check it from this repository. Those are marked. Treat them as you would any unverifiable number. The vocabulary is status_vocabulary in claims.json and evidence_vocabulary in system-manifest.json; every line below names its claim ID.
---
What it does today
The kernel. One Triton launch runs the grouped expert GEMM directly on 4-bit-packed weights — NF4 on the bitsandbytes layout, and native MXFP4 (OCP e2m1 + e8m0) on a checkpoint's exact released bytes. With fp32 accumulation it has never measured less accurate than the dequantise-to-bf16-then-GEMM comparator in any registered confirmatory cell (gnf4.kernel.fused-more-accurate-than-dequant-bf16).
| Item | measured | tier | claim ID |
|---|---|---|---|
| Decode, census MoE shapes vs the dequant path (sm_86) | 1.16–2.73× median | confirmed | gnf4.kernel.decode-speed-census |
| Energy, J/token below baseline | 104 of 112 cells | confirmed | gnf4.kernel.energy-104-of-112 |
| Real OLMoE QLoRA finetune, fused vs per-expert loop (prose) | 4.50× (4090), 4.75× (H100) | confirmed | gnf4.kernel.e2e-training-real-prose |
| vs Unsloth's own kernel, 4-bit-storage regime, decode | 1.70× (H100), 2.79× (4090) | confirmed | gnf4.kernel.h2h-unsloth |
vs torch._grouped_mm on bf16, Qwen3-30B cell (RTX 5090) | 2.1–6.0×, on half the bytes | measured | gnf4.kernel.sm120-census-vs-grouped-mm |
| Training backward, one launch, E=256 step | 403.7 → 26.5 ms | measured | gnf4.kernel.dgrad |
Three things that limit those numbers, stated here rather than in a footnote:
- Against a CUDA-graphed baseline the fused path loses at decode (0.949× on a 4090, 0.858× on an H100). What survives graphing is the memory-traffic win at training shape on bandwidth-limited cards (1.489× on the 4090; parity on the H100). A "fused wins at decode" reading that ignores graphing is wrong (
gnf4.kernel.graphed-baseline-decode-loses). - Unsloth wins its own regime. Against their bf16-resident kernel they run 2.6–5.3× faster at prefill on an H100. The advantage above is the 4-bit-storage regime specifically (
gnf4.kernel.h2h-unsloth). The model-level, training-axis end-to-end comparison is a separate claim in experts4bit-qlora's register (e4b.train.h2h.unsloth.qwen3.5090.2026-09-05); it does not supersede this kernel-level one. - Known losers:
top_k=1cells are instance-unstable in both directions; shapes under about 5 M weight elements lose outright (0.24–0.35× speed, 4–7× energy) and are routed back to the dequant path by a dispatch floor (gnf4.kernel.decode-speed-census).
Serving (sm_120). Both decode knobs ship ON, capability-conditional: an unset env takes fp8 where fp8 can run and the f32 path otherwise, and an explicit request is never silently downgraded. The paged attention is therefore two support states, and capabilities.json carries it as two entries: the fp8 compute path (fp8-paged-attention-fp8-compute; sm_89+ precondition; measured on the RTX 5090 only; gnf4.serve.m3-defaults-on) is supported; the f32 compute path (fp8-paged-attention-f32-compute) — the sm_80–sm_88 default, the fallback where an fp8 constraint fails, and every explicit f32 request on any card — is open under #319 (gnf4.open.f32-compute-modes-triton34) and carried as unsupported until it closes. The certified single-stream anchor for Qwen3-30B-A3B on the RTX 5090 class is 7.37 ms/step ±4.2% (≈130–142 tok/s) — the class carries 8.5% inter-box dispersion while each box repeats itself to 0.16%, so quote the range, not a point (gnf4.serve.decode-anchor-5090).
fp8_paged_decode_attention takes sliding windows, attention sinks, a custom attention scale and per-layer stride overrides (0.24.0), which is what lets one engine serve Granite, Gemma-4 and gpt-oss geometries. 35 of 35 fp8-mode GPU tests pass on a 5090; window=0, sinks=None is byte-for-byte the old path (gnf4.serve.fp8-paged-attn-windows-sinks-scale).
Reaching past VRAM. Qwen3-235B-A22B decodes at 4.3–4.4 tok/s on 15.2 GB of VRAM from a 438 GB checkpoint held in pinned host RAM, replicated across five pods. The law is additive and per-box: t_token ≈ c_box + bytes/link, with c_box measured at 53.5–114.0 ms across seven hosts. A fixed fraction-of-waterfall is not the law and was retired in July (gnf4.flagship.235b-phaseB).
The NVMe tier is a batch tier: at S ≈ 3.45 GB/s a fully cold 235B is ~2.3 s/token and a K3-class model ~7.5 s/token. It buys reachability and provenance, not latency (gnf4.nvme.tier-batch-only).
Provenance. gpt-oss-120b serves on its exact released MXFP4 bytes at ppl 26.72 against the shipped-precision reference 26.75 — the +9.4% NF4-requantisation tax is deleted — and QLoRA-trains at 9.82 GB peak with 144/144 hashes identical before, during and after (gnf4.mxfp4.serve-tax-deleted, gnf4.mxfp4.train-9.82gb). The reference MXFP4 decode reproduces Kimi K3's own declared reference exactly (33,030,144 elements, max delta 0; gnf4.k3.oracle-exact).
---
What changed — retired, superseded, corrected
Kept here because a claim that quietly disappears is worse than one that was wrong.
sm_120is no longer "parked". The README's roadmap still says three cloud provisioning failures parked Blackwell work. That was true in July; since 0.15.0 the RTX 5090 has been the primary serving target — the M=1 config retune, the sm_120 census, the decode anchor, the M3 defaults, the int4 lanes and the paged attention were all measured on rented 5090s. Retired as stale (gnf4.retired.sm120-parked).- The "4.67× vs the grouped-bf16 execution class" number is superseded. That backend never executed Unsloth's own kernel, and the proxy it did run is 1.33× slower than the real thing — so the comparison was against a weaker opponent than the label implied. The head-to-head (1.70× / 2.79×) replaces it. The old number is kept in the README with that caveat attached, not rescaled (
gnf4.kernel.comparators-v6-execution-class, superseded bygnf4.kernel.h2h-unsloth). - Split-K on the decode GEMV is refuted (flat at
gate_up, ~14% worse atdown). The kernel ships dormant as the evidence (the retired claimgnf4.retired.splitk-gemv). - A fixed fraction-of-waterfall is retired as a law (two 0.77 readings were a two-host coincidence).
- The cold-engine "free floor" premise is refuted on its target box: no AVX-512 means bitsandbytes' CPU dequant runs at 0.041 GB/s against a ~12 GB/s ceiling (
gnf4.cold-engine.phase0-premise-refuted). - Expert prefetch is closed, negative, over four registered arcs. Speculation moves (2−H)× the bytes and break-even needs H ≳ 0.95, above this model's 0.93 predictor ceiling (
gnf4.flagship.prefetch-closed-negative). - #87 is closed by observation in every carrier (PR #342; boundary test
kernel/test_expert_offset_boundary.py; GPU run on an RTX 5090 2026-09-05: 10 passed). The line this page carried until 0.30.1 — "gemm_4bit_groupedint32 offset overflow at largemax(expert_ids), distinct from the 2 GiB stride fix in 0.13.2/0.14.0" — was not supported by the issue text: the expert-id cast the issue asked for shipped in 0.13.2 (NF4) and 0.14.0 (MXFP4), and the carriers it flagged by inspection (split-K, dgrad) plus the ones it did not name (int4-b32, the fp8 paged readers) had never been exercised above the boundary. Now they are, each above-boundary case in its own process (gnf4.kernel.expert-offset-boundary.5090.2026-09-05, measured; the test file and the changelog entry are the public evidence, the GPU log is in the private receipt tree). #324's pre-launch shape refusal ships in the same release and moves no registered number. - Register bookkeeping corrected (0.30.2).
gnf4.serve.m3-defaults-on's sentence described the fp8 predicate ask_groups in (1,2,4)— the predicate as it stood at the 2026-08-27 run;fp8_compute_unsupportedhas admitted(1, 2, 4, 8, 16)since 0.26.0 and the sentence now says so, with the measurement unchanged. Everyevidenceentry inclaims.jsonis now a path that resolves at HEAD (structured forms for changelog sections, globs and cross-repository receipts:claims-schema.md); every measured, measured-private and confirmed row carries an ISOmeasured_ontaken from its receipt or, where the receipt states no run date, the receipt's first commit; the retiredgnf4.retired.splitk-gemvcarries itsretired_reason; andscripts/check_claims_register.py+scripts/check_readme_claims.pyhold the register and this page to it in CI. No number, gate or verdict moves.
---
What is open
- #319 — the f32 paged-decode compute modes miss their reference on torch 2.8.0+cu128 / triton 3.4.0 (10 of 35 tests, up to 0.074 against a 0.02 tolerance), on unmodified
main. The fp8 modes — the default on sm_89+ where the constraints pass, sm_120 serving included — pass, so that serving path is unaffected; the sm_80–sm_88 default path and every explicit f32 request (on any card, Hopper included) are not (gnf4.open.f32-compute-modes-triton34). - #73, #60, #58 — arena/NVMe efficiency: host copy is ~71% of a K3 layer; staging blocks ~30% of a training step; 8 requests issued per layer where 2 would do.
- #71 —
PINNED_ROW_FACTORis ~2× conservative on cgroup v1; v2 needs a box the rented pods cannot give. (#73, #60, #58 and #71 aregnf4.open.issues.) docs/context-budgets.mdis rung-one only (A2000-measured KB/token); full-depth real-weight confirmation is pending and the K3 row is a declared gap. Its own text forbids promoting pending rows to the README — that still holds (gnf4.open.context-budgets-rung-two).docs/cold-engine/STAGE3-SYNTHESIS.mdcarries one correction outstanding: gate 1's published read counts are uncorrected, and no read count in that document should be quoted until it is re-run.- Every non-CUDA row is a
port target. ROCm/XPU numbers do not exist;PROJECTIONS-multiarch.mdis arithmetic, stamped before the silicon, and explicitly invites refutation (gnf4.projection.multiarch, projected).
---
Reading the numbers without getting them wrong
- Quote the hardware. Ratios move with the card: the Unsloth margin drops 40% when their TMA path is live; the fused/graphed split reverses between a 4090 and an H100 because the baseline's working set fits H100 cache.
- Quote the baseline. Almost every ratio here is against this project's own per-expert loop or the dequant path — not against a third party's implementation, except the one head-to-head that says so. The dequant path is bitsandbytes
dequantize_4bitper active expert followed by a bf16 matmul, as each receipt ran it. Since bitsandbytes 0.50.0 (upstream #1949, merged 2026-05-21) its supported ordinary 2-D inference cells compute from the packed weights directly; no receipt here times that path, the grouped routed-MoE GEMM is a separate contract upstream does not have, and the conventional 4-bit backward still dequantises for dX. The ratios stay what their receipts measured (noted 2026-09-04). - A benchmark on random token ids understates this kernel by ~1.6×, because prose routes to 98.4% of experts and random ids to 87.5%. Benchmark on real text.
- Peak VRAM does not improve. The fused arms peak higher; only the transient held across forward-to-backward is smaller.
- Quote the register that owns the number. A model-level figure — tok/s for a named model on a named card, a perplexity-gate verdict — is registered in experts4bit-qlora's
docs/claims.json, not here; quote it with that register's claim ID and status, and ameasured-privatestatus there means not publicly reproducible, exactly as it does here. Kernel-level numbers are this register's. measured-privatemeans you cannot check it. Three entries inclaims.jsonare in that state:gnf4.serve.int4-b32-gemv(the GEMV cells),gnf4.serve.gptq-pack-int4-b32(the calibrated-pack quality numbers),gnf4.serve.decode-glue-kernels(the composition). They are real runs with real receipts, in a tree this repository does not carry.
CURRENT · source: pjordanandrsn/experts4bit-qlora@0c2a256dcdc2 · rendered package: 0.35.3 · latest published package: 0.35.3
CURRENT · source: pjordanandrsn/grouped-nf4-gemm@e2af4cfb91b2 · rendered package: 0.30.2 · latest published package: 0.30.2