ModelsGitHub

The Minirun artifact format

What a published Minirun artifact contains, how its bytes relate to the upstream checkpoint, and what makes it verifiable.

An artifact is a repack, not a re-encode

A Minirun artifact is a byte-preserving repack of an upstream checkpoint. A tile container is a reordering of the checkpoint's own packed and scale streams; a plain stream is the checkpoint's bytes verbatim. The only bytes a builder writes that did not come from the checkpoint are container headers and the zero padding of an under-full scale sub-region.

The stored precision of an artifact is therefore the upstream checkpoint's precision. Minirun does not dequantize and requantize weights while packing them, and it does not produce its own quantization. That is a standing owner decision recorded in the engineering specification at v0.6.11, not a limitation waiting to be lifted: a repack must be able to state that the numbers it serves are the numbers the publisher released.

The practical consequence is that an artifact can be checked against its source. Every packed block, scale and bias in the container is the block, scale and bias the upstream file contained, so a comparison against the source repository is a byte comparison rather than a tolerance.

Repository layout

An artifact is published as one Hugging Face repository whose name ends in the suffix -minirun. Inside it, weights are grouped into units — a directory per layer or per component — so that a transfer, a repair, and a run can all address the same boundaries. Metadata files sit beside the payload rather than inside it.

The three published artifacts differ in how many units they need and what a unit means, which is why the layout is described per model rather than as a single universal tree. The largest single payload file is 5,240,799,232 B in K3, 1,140,867,072 B in V4 Flash and 5,061,033,024 B in H3; the metadata beside it is comparatively tiny, at 19,614,826 B, 527,260 B and 782,716 B respectively.

  • The -minirun suffix is the discovery contract. The app lists repositories owned by the publishing account whose name carries that suffix, so a newly published artifact appears without an app release.
  • Sixteen of H3's payload files are stored as plain git blobs rather than Git LFS objects, so they carry a git-blob SHA-1 and no SHA-256 at all. That is a property of the publication, and the verifier reports it rather than inventing a digest.
Unit directories, file counts, and payload bytes walked from each published repository tree.
ArtifactUnit directoriesPayload filesMetadata filesPayload bytes
nanguoyu/Kimi-K3-minirunlayer00/ through layer92/, plus global/372991,559,976,181,760
nanguoyu/DeepSeek-V4-Flash-0731-minirunlayers00/ through layers42/, mtp00/ through mtp02/, plus global00/57751166,893,192,184
nanguoyu/MiniMax-H3-minirundit-block-00/ through dit-block-49/, dit-refiner-00/ and dit-refiner-01/, dit-global/, te-embed/, te-layer-00/ through te-layer-49/, te-visual/, adaln-cache/, lora-turbo/, tae/, vae-audio/, vae-video/, tokenizer/, configs/77811863,969,279,450

index.json and its three shapes

Each artifact publishes an index.json at its root. It is not a schema-versioned document; three shapes exist across the three published artifacts, and the reader recognizes each by what it carries. A fourth shape is not a crash — it is reported as unrecognized, with the document's actual top-level keys shown, rather than guessed at.

The index is parsed defensively and never throws. An index.json that cannot be read describes an artifact whose identity is unknown, which the interface can show; an exception during a directory walk is not.

singleSourceTotals (Kimi K3)
source_repo, source_revision, files and bytes at the top level, with format, format_version, relationship, layers and globals alongside them. One upstream repository, one pair of totals.
singleSourceUnits (DeepSeek V4 Flash)
source_repo and source_revision, then units[], each entry naming a unit with its own files and bytes, and total_bytes for the artifact.
multiSourceUnits (MiniMax H3)
a sources map instead of a single repository. Each entry carries repo, revision, a role sentence describing what that upstream contributed, and its license. H3 is assembled from five upstreams, so the roles are what distinguish them.
unrecognized
valid JSON that names no repository the reader understands. Shown as an unidentified artifact, with the sorted top-level keys, so an operator sees what the document actually contained.

Tokenizer and configuration identity

An index may also publish a tokenizer object and a configuration object. These are execution evidence rather than display metadata: a runner must open that exact root file through the artifact's full-verification authority, because a repository name or a compatible-looking JSON document is not a substitute for the recorded bytes.

Both objects are parsed fail-closed. Every required field must be well formed or the whole identity is absent — not partially filled in, and not defaulted. A provenance that was completed by a defaulting rule is a provenance nobody published.

file
A canonical repository-root file name. It may not contain a path separator, may not be . or .., and is restricted to letters, digits, hyphen, period and underscore.
bytes
The recorded byte count, which must be a positive integer rather than a boolean or a string.
sha256
Exactly 64 hexadecimal characters. Anything shorter, longer, or non-hexadecimal makes the identity absent.
source_repo
A canonical Hugging Face repository id, checked as such rather than accepted as any string.
source_revision
Exactly 40 lowercase hexadecimal characters. An immutable commit, never a branch name.
license
A canonical root file name, on the tokenizer object only. The configuration object carries the other five fields and no license field.

The tile container

Quantized weights are stored in tile containers. A container begins with the eight-byte magic MNRNTIL1 followed by a header; current builds read format versions 1, 2 and 3, and a writer emits the lowest version that can express what it was asked to write, so every caller that needed only version-1 features still produces a byte-identical version-1 file.

The body is a sequence of tiles. Each tile holds a packed sub-region, then a scale sub-region, then — in affine mode only — a bias sub-region.

[ header, 16384 bytes, padded ]
[ tile 0: packed bytes | scale bytes | bias bytes (affine only) ]
[ tile 1: packed bytes | scale bytes | bias bytes (affine only) ]
...

Why 16 KiB, and why the format fixes it

Every tile starts on a 16 KiB boundary, and inside a tile the packed, scale and bias sub-regions each start on a 16 KiB boundary. That number is a constant of the format and is deliberately not taken from the host's page size. Apple silicon pages are 16 KiB and x86-64 pages are 4 KiB, so a layout derived from the running machine's page size would produce a file that only validates on the architecture that wrote it. 16 KiB is a multiple of both, so a file written anywhere is correctly aligned everywhere.

The alignment is what makes the read cheap. One tile is one pread into one slot, and that same slot is then adopted as two or three MLX arrays — packed at offset zero, scales at the scale offset, biases at the bias offset. MLX wraps an adopted pointer for the Metal backend, which requires page-aligned memory, so each sub-region has to be independently aligned or the later adoptions fall off the zero-copy path. A geometry that cannot satisfy this is rejected when the container is constructed, rather than silently padded into something that looks valid.

Tiling runs along output rows only, never along the reduction axis. Row-tiled outputs concatenate with no cross-tile accumulation, so a result assembled from streamed tiles performs the same arithmetic in the same order as a fully resident one. That is what allows the project to require bit-identical output between a streamed run and a resident run rather than merely close output.

Quantization modes and content kind

The container is not an MXFP4-only format. A quantization mode is recorded per container, and the scale element type is a header field rather than an inference from the mode, because for affine weights it genuinely is not derivable — MLX returns scales in the source tensor's own dtype, so a bfloat16 checkpoint yields bfloat16 scales and a float16 one yields float16.

mxfp4
OCP MX FP4: e2m1 elements, one uint8 e8m0 exponent per group, no bias. The group size is fixed at 32 by the OCP MX specification.
affine
The MLX affine form, w = scale × q + bias, with one scale and one bias per group. The group size is a converter choice, validated as a positive power of two and carried in the header rather than assumed.
fp8-e4m3-block
FP8 e4m3 elements with a two-dimensional grid of e8m0 block scales — one exponent byte per block of rows by group. MLX has no primitive that consumes this, and that is the point: the container carries such a checkpoint's bytes verbatim rather than requantizing into a shape MLX happens to like today.
contentKind
Whether a container's bytes can be recomputed (synthetic-deterministic, used by the storage benchmark) or only checked (checkpoint-derived). Recording it in the file lets a regeneration check refuse rather than silently compare checkpoint bytes against a pseudo-random sequence.

Digests and feature flags

From format version 2 the header can carry one SHA-256 per tile, in tile order. Checkpoint-derived content cannot be regenerated for comparison, so a recorded digest is how a reader states what the bytes should be.

Optional structure is declared through a feature-flag word rather than through implicit behavior. Four flags are defined today: a bias sub-region follows the scales; the header carries per-tile digests; scales form a two-dimensional block grid; a sub-region's payload is followed by zero padding to the alignment. A file that sets a bit this build does not understand is rejected — the reader refuses rather than reading on with the unknown feature ignored.

Version 3 exists for exactly one reason: it adds the field that says how many matrix rows one scale covers. A two-dimensional scale grid read by a version-2 reader would size every scale sub-region too large and walk off each tile boundary after the first, so the field is required rather than convenient. Version 3 appends its fixed fields where version 2 kept the digest table, which moves the table — a compatible change only because the table's offset was already a header field rather than an assumption.

Who is the authority for what

Verification separates two questions that are easy to conflate: are these the right bytes, and is this all of the files. They have different authorities, and the app requires both to agree before it records a positive result.

The Hugging Face recursive tree endpoint is the digest authority: it supplies the per-file blob or LFS digest metadata. It is also paginated, and a missing continuation header is ambiguous — it can mean the last page, or that something along the way stripped the continuation. A stable truncated response is the dangerous case, because a catalog descriptor and a verifier derived from that same truncated tree would agree with each other and call a partial artifact fully verified.

So completeness comes from somewhere else. The repository-info endpoint, pinned to the exact 40-hex commit, returns the siblings set, which the platform documents as the files constituting the model. The path set from the paginated tree must equal that siblings set, and the response's own commit must equal the requested revision. Missing or malformed authority, a commit disagreement, or any missing or unexpected path fails closed before a digest is started.

Verification authorities, as decided in ADR 0004.
SourceAuthority forNot authority for
Repository tree endpointPer-file blob and LFS digests at a pinned commit.Whether the file list is complete, because its pagination can be truncated.
Repository-info siblings setThe exact set of paths that constitute the model at that commit.File content; it carries no digests.
index.jsonA reconciliation claim the artifact makes about itself.Completeness or content. It counts payloads only, omits a complete metadata file set, and published manifests have been wrong while the neighbouring files were right.

A result is bound to filesystem objects, not to paths

A positive verification result is not a label attached to a folder name. It is evidence for one publication and one set of local filesystem objects. Readers open bounded descriptors from that held evidence — every path component opened with symbolic-link following disabled, and only for paths present in the evidence — so a large weight file is never reopened through a pathname adapter and never loaded whole into memory.

Within one mounted session, an open descriptor must match on device, inode and timestamps exactly. Across an unmount and remount the rule is stricter about what may change and what may not: the mounted-session device number is allowed to change, but only when the volume's UUID, every persistent object id, the size, the nanosecond modification time and the nanosecond status-change time all still match. The volume UUID is bound only after the held descriptor reports that the volume supports persistent object ids. A changed volume UUID, or any changed object metadata, invalidates the evidence.

A result held under the older, stricter mounted-session rule needs one new pass before it can survive a remount. Separately, iOS can report the same directory as /private/var through one interface and /var through another; those two fixed spellings are treated as one lexical identity, and no other symbolic link is resolved.

Verified tiles are not re-hashed at decode

A DeepSeek V4 run may not begin until a complete check is held for the exact pinned revision — 630 files and 166.9 GB on the current artifact — and that authority stays held, with its registered root open, for the whole run. The layer reader trusts that check rather than re-hashing the same bytes on every load.

Re-hashing every tile on every load cost more than the reads it was guarding: on a real artifact it took the larger part of a decode pass, over the same bytes the check had already read once.

ADR 0013 makes exactly one check conditional: the SHA-256 over a tile's bytes, and only when the reader holds real verification authority naming the same repository and revision. Every load still performs the rooted open and its full identity recheck, reconciles the file's current length against both the manifest byte count and the container header's own total, checks the requested geometry against the header before a byte is read, and checks the tile length.

The honest cost is stated rather than waved away: silent media corruption occurring after verification, which alters no metadata the identity set records, is no longer caught within the run. It is caught by the next full verification pass. A replaced or mutated file is still caught immediately, because size and both nanosecond timestamps are part of the evidence.

What the format does not yet do

The tile container can carry a digest per tile, but that is not the same as an artifact that can vouch for itself. The published artifacts' manifests have no checksum fields, and the artifact as a whole carries no per-file digest. Full verification therefore borrows its authority from the hosting platform's metadata, where an LFS object id is the content SHA-256 — which means an artifact is verifiable online against the host that serves it rather than offline against itself.

A digest in the container header — the per-tile SHA-256 generalized to a whole-file statement — or per-file digests in the manifests would make artifacts self-verifying offline. It is a recommended next revision of the format, and it is stated here as an open item rather than as a property the format already has.

The engineering specification that defines this format describes its own status as exploration and pre-architecture. The format is versioned and its compatibility policy is explicit, but it is not frozen.