Models and published artifacts
Runner accepts GGUF v2/v3. Safetensors checkpoints must be converted to GGUF
first. Standard llama.cpp multi-part sets (<prefix>-00001-of-000NN.gguf) load
natively from any part: every part must be present in the same directory, and
its split.no, split.count, and split.tensors.count metadata must agree.
Missing or inconsistent parts are refused before model binding. Nonstandard
filenames and remote/streamed parts are not resolved automatically; merge or
rename those sets to the standard layout first.
Fetch the small test model with:
./download-model.sh
For manual downloads, verify both the command exit status and resulting byte size. A partially downloaded GGUF can otherwise look like a model failure.
Requantization and expert pruning
Repack weight matrices to q8_0, q4_0, q3_k, q4_k, q6_k, f16, or
bf16:
./runner -m model-f16.gguf --quantize model-q4.gguf --quant q4_0
Norms, biases, and rope factors stay f32; tensors already smaller than the
target are retained, as are rows the target type cannot describe (q3_k needs
a row width divisible by 256, q8_0/q4_0 by 32). MoE router weights
(ffn_gate_inp*) keep their source type on every path, including a
--type-plan that names them: the router selects which expert runs, so an
error there swaps a whole FFN, and it is a fraction of a percent of the file.
Metadata is copied.
A q4_0 repack is lossless where the source is already on the q4_0 grid,
which is the case for quantization-aware-trained checkpoints: every value is
one per-block scale times an integer code, so the answer is already in the
file. Runner recovers that scale and those codes exactly instead of
re-deriving a scale from the block’s extreme value - the derived route is
correct only when a block’s codes actually reach zero, and on a block where
they do not it saturates the far end of the range and changes values a pure
repack had no need to touch. A candidate is accepted only when the value the
dequantizer will produce equals the source float bit for bit across the whole
block, so a source that is not on a grid falls through to the derived scale
and its output is byte-for-byte what it was before.
--prune-experts rewrites stacked-layout MoE tensors using an explicit JSON
plan. It is a mechanism, not a quality claim: pruning needs a model-specific
evaluation against the unpruned parent.
{"layer_0":[0,3,7],"layer_1":[1,2,5]}
# Prune only; surviving tensors keep their current quant type.
./runner -m model.gguf --quantize pruned.gguf --prune-experts keep.json
# Prune and requantize the survivors.
./runner -m model.gguf --quantize pruned-q4.gguf \
--prune-experts keep.json --quant q4_0
A layer omitted from the plan keeps all experts. Invalid keys, empty lists,
out-of-range IDs, and unsupported tensor layouts fail instead of silently
producing a different model. The layer’s router (ffn_gate_inp) and its
per-expert selection bias (exp_probs_b, in either on-disk spelling - the
.weight of the DeepSeek-style GGUFs and the .bias of nemotron_h_moe) are
sliced along with the expert banks, so the survivors in plan order become the
new expert index space with no runtime remapping. Non-uniform coverage-pruned
nemotron_h_moe layers resolve their expert count from each layer’s router and
run on CPU; CUDA names and declines this layout because its MoE kernels require
one model-wide expert count.
scripts/moe-prune-plan.py can build a plan from calibration data.
A non-uniform prune describes itself with a per-layer key, and an artifact
built that way still has to say where it runs. GGUF defines ONE
<arch>.expert_count for the whole model. Every prune plan now also writes
<arch>.expert_count_per_layer, a u32 array with one entry per block (0
for a non-MoE block) holding each layer’s real post-prune count; a plain
--quantize carries it through and a later plan re-authors it. When a plan
leaves every MoE layer at the same new count, the global key is rewritten as
well and both agree. When layers end at different counts, or some are left
unpruned, the global key deliberately stays at the parent’s number, which
remains every layer’s true ceiling, and the array is the exact description.
At load Runner validates the array against every router tensor and refuses,
by name, a header that disagrees with its tensors; a file without the array
predates it and each layer’s count comes from its router alone, as before.
An engine that reads only the global key still mis-sizes such a file, so
a published artifact from a non-uniform prune must state that it is
Runner-correct and untested elsewhere, in the same place it states its
fidelity; a uniform prune carries no such caveat. The key is a proposed
convention, published here so other loaders can adopt it.
Sublayer removal
--remove-sublayer drops one block’s attention or dense-FFN tensors from
the file, so a surgery that found a block’s attention dispensable saves the
bytes and the KV cache instead of shipping a same-size file with zeroed
weights. A mechanism, not a quality claim: which block can go is a
measurement against the parent, made elsewhere.
# drop block 48's attention; survivors keep their bytes
./runner -m model.gguf --quantize cut.gguf --remove-sublayer attn:48
# several at once, and requantize the survivors in the same pass
./runner -m model.gguf --quantize cut-q8.gguf \
--remove-sublayer attn:48,mlp:12 --quant q8_0
The absence is declared, not inferred: the writer turns the block-wide
<arch>.attention.head_count and head_count_kv (or feed_forward_length)
into per-block arrays with a 0 at the removed block. That is the reading
llama.cpp’s own Nemotron-51B (“deci”) files already use for attention-free
and FFN-free blocks, so the file describes itself in the format’s existing
vocabulary rather than a private key. What goes is the branch proper: every
blk.N.attn_* tensor except the attn_norm pre-norm (projections, Q/K
norms, sinks, gates, biases), or every blk.N.ffn_* tensor except
ffn_norm. The kept norms cost kilobytes and leave the residual plumbing
identical to the zeroed form, which is what the gate compares against: a
removed block scores bit-identically to the parent with that block’s output
projection zeroed, and differs from the untouched parent. The writer prints
exactly what it dropped, in tensors and bytes.
At load the arrays are validated against the bytes in both directions: a
tensor missing without a declaration is still error: missing tensor, and
a declaration whose tensors are still present is refused by name. A removed
attention reserves no KV rows, so the cache shrinks by that block’s share at
every context length (the -v banner lists sublayers removed). Limits,
each refused rather than approximated: the CPU path only (the device decode
loops still drive every block; pass --gpu off), dense blocks only (MoE
FFNs, the hybrid SSM families, gemma-4 E-series shared-KV/per-layer
embeddings, fused-QKV exports and NextN heads are declined by name), one
head width across the file (a non-zero entry that differs from the rest is
heterogeneous geometry, not a removal), and no --lora or --train on a
removed file yet. docs/sublayer-removal.md has the design and the gates.
Published artifacts
Artifacts produced by this project are published only after their stated gate against the named parent. Read each repository’s provenance before treating a derivative as equivalent to an original checkpoint.
Every fidelity claim below is measured under the adopted dual-column bar (margin-qualified top-1 >= 97% AND mean KLD <= 0.05 vs the named parent, 400 teacher-forced positions, zero point exact; plain top-1 always reported beside it).
- Qwen3-30B-A3B selective precision
(attention Q8_0 / experts Q4_0, 17.99 GB) passes the bar where the
official uniform Q4_K_M fails it, from a byte-verified first-party Q8_0
source. Built with
--type-plan; the exact plan is on the card. The artifact class this project now leads with. - Qwen3-Coder-30B keep-120 (expert-pruned, 17.5 GB) passes both the original and the current bar - the only published artifact to clear the original bar unaided.
- gpt-oss-20b-keep30-MXFP4 (11.5 GB, 32-to-30-expert derivative) does not pass the current bar; its originally published number did not reproduce and the card leads with the measured status. Kept published as a near-miss with its numbers in the open.
- gemma-4-E2B-it Q4_K_M/Q4_0 mix (2.63 GB) is the smoke-test artifact from the quickstart: fails the fidelity bar (the card carries the dual-column numbers) and remains the fastest way to try the runner on an 8 GB machine.
- NVIDIA-Nemotron-Nano-9B-v2 Q8_0
(8.81 GB) is not a bar-gated derivative but the first Mamba-2 hybrid
(
nemotron_h) artifact the runner supports - a plain, near-lossless Q8_0 of NVIDIA’s base, quantised by the runner’s own canonical (ggml-byte-identical) quantiser and verified 5/6 greedy token-identical vs llama.cpp b10353 at Q8_0 (the sole miss a quant-noise near-tie). NVIDIA Open Model License; the card leads with the tool-calling differentiator. - gemma-4-31B-it, attention block 48 removed
(17.58 GB, Q4_0) is the first sublayer-removal artifact: one attention
sublayer physically dropped from Google’s QAT Q4_0 release, declared with
the per-block zeros of
--remove-sublayer. It frees 64 MiB of KV cache at 4k context and 512 MiB at 32k, plus 74.3 MB of file, and tracks its parent at clean KLD 0.0223 on 44,413 held-out positions (measured 2026-08-30 on the identical zeroed form, carried over by bit identity 2026-09-04). It loads only in this runner from the 0.4.7 release on, CPU path, and llama.cpp refuses it by name; the card says so beside the numbers. - Measurement reports over third-party artifacts, no weights republished,
every measured file bound by SHA:
Hermes-4-14B quant fidelity
(the 4-bit size threshold and the split story), the
Qwen3 speculative pair
(measured draft acceptance, and why the engine’s printed tok/round must
not be tuned on), and the two Mamba-2 hybrid support reports -
granite-4.0-h-small
(
granitehybrid, 3/5 greedy-identity at the noise floor) and Nemotron-3.5-Lightning-30B-A3B (nemotron_h_moe, 4/5) - each carrying its measured-envelope manifest. Two frontier reports (2026-08-20, no weights republished - nothing cleared the bar AND beat upstream): the Lightning-30B prune frontier (keep-126 passes at 99.50%/0.026; the plan is published, the 1.37% saving was not worth an artifact) and the Muse-Glimmer-30B quant frontier (Meta’s own Q4_K_M passes the bar; six runner plans measured, none beat it - stated openly).
This page is the README section of the same name, copied at build time; the README on GitHub is the source.