THE BYTES · CANDIDATE SPEC §6–7 · LYRW v2
DOWN TO THE BYTE
LYRW v2 is the expert-bank codec of VINDEX3 — a binary format simple enough to read with a ruler. This page is that ruler.
What is the LYRW layer file?
LYRW v2 is the layer-weight codec: a 24-byte header, bank and segment descriptors, one region schema per bank, and an entry table of offsets and lengths. A reader needs nothing but the bytes in front of it; unknown tags are preserved rather than fatal, and refusal waits for the operation that actually needs what a reader cannot do. Segments answer to file management, group extents to hardware — two scales, kept deliberately distinct.
A blob you cannot check is a promise you cannot keep.
WHAT THIS FIXES
Most weight files are a header you must trust, followed by bytes you cannot question. When a reader meets something it does not recognise, it guesses or it dies; when a writer changes a layout, every old reader finds out at parse time, in production. LYRW was shaped so neither ever happens: the file carries its whole description, unknown tags are preserved and reported rather than fatal, and refusal waits for the operation that actually needs the thing a reader cannot do.
LYRW v2 — THREE DEPTHS
LYRW is the layer-weight bank format. One binary file holds one layer's weights — or one segment of a very large layer — organised as banks of entries. A file describes itself completely: a reader needs nothing but the bytes in front of it to know what regions exist, in what encoding, at what offsets. Five structures, in the order they appear in the file: header, bank descriptors, segment descriptors, region schemas, entry table. Its place in the container model is stated by the Candidate: this is one segment codec — today the layout of the transitional bank shape's expert banks, under the convergence rule an encoding a graph container's representation may use. A graph container's plain tensor-table segments are the other codec, on the Container page.
STRUCTURE 1 — ONCE PER FILE
The header — 24 bytes
24 bytes · all integers little-endian · all region offsets 64-byte aligned from the start of the containing segment file
STRUCTURE 2 — num_banks ×
The bank descriptor — 24 bytes each
24 bytes × num_banks · a dense layer is a bank with num_entries = 1 — one format for dense and MoE alike
The descriptor says what is stored, never what it means: the binary carries no programme identity. The MoE manifest in the container root binds bank_id to a programme, so the same fact is never declared in two places.
STRUCTURE 3 — num_segments ×
The segment descriptor — 12 bytes each
12 bytes × num_segments · a single-file layer has one segment covering [0, num_entries)
Multi-segment layers repeat the header in every segment file with flags bit 0 set, and index.json lists the segment files per logical layer — the loader never globs a directory.
STRUCTURE 4 — region_schema_count × PER BANK, NOT PER EXPERT
The region schema — 20 bytes each
20 bytes × region_schema_count, per bank · expert banks are homogeneous, so the layout is declared once and every entry shares it
The quiet trick of the format: every expert in a bank has the same shape, so the layout is declared once. Per-expert layout information collapses to two numbers each. And per-expert codec variation — which no grouped kernel supports — becomes unrepresentable by construction, not forbidden by convention.
STRUCTURE 5 — THE ENTRY TABLE
One row per entry per region — 16 bytes each
entry_count × region_schema_count rows of 16 bytes, entry-major — for each entry, one row per region schema, in schema order
Parsing cost is O(schemas), not O(entries × regions): the shape is read once per bank, then the table is pure arithmetic. Physical expert order need not match logical order — the table is the indirection.
the ABI — §6.1 Header
[header]
magic: u32 0x4C595257 ("LYRW")
format_version: u32 = 2
logical_layer: u32
num_banks: u16
num_segments: u16 (segments described by THIS file's tables; ≥1)
flags: u32 (bit 0: this file is one segment of a multi-segment layer)
reserved: u32All integers little-endian. All region offsets are from the start of the containing segment file and 64-byte aligned.
the ABI — §6.4 Region schemas and entry table
Expert banks are homogeneous: every entry in a bank shares the same region layout. The region schema is therefore declared once per bank, and each entry stores only offsets and lengths. (This is the simplification that dropping LYRW v1 binary compatibility buys — see §6.6.)
[bank region schemas] region_schema_count × per bank:
schema_index: u16
role: u16 (§6.5)
format: u16 quant enum — 0=f32 1=f16 2=bf16 3=q4_0 4=q4_k 5=q6_k
6=q8_0 7=fp4_larql 8=mxfp4 9=nvfp4 10=mxfp8 ...
packing: u16 0=row_major, 1=blocks_with_scales_inline,
2=blocks_values / 3=blocks_scales
pair_id: u16 links a blocks_values schema to its blocks_scales
schema; 0xFFFF = unpaired
layout: u16 region payload layout — 0=unspecified,
1=contiguous_halves, 2=interleaved; unknown values
preserved per §5.7. This u16 was draft-2's reserved
pad; claiming it is the schema 3 → 4 bump (§12) —
the record stays 20 bytes, which is exactly why the
schema version had to move rather than the size
rows: u32
cols: u32
[entry table] entry_count × region_schema_count ×:
offset: u64 (from start of containing segment file, 64-B aligned)
length: u64Consequences:
excerpt — trimmed at a word boundary the whole document →
A file that describes itself completely, at the depth you want it: what the five structures are, each one drawn to scale, and the header and entry-table clauses verbatim.
The binary layout — learn: what LYRW is · inspect: five structures, to scale · spec: the clause that governs it. One concept, one URL, the depth of your choosing.
THE NUMBERED VOCABULARIES — WIRE VALUES, VERBATIM
role — u16
0 gate 1 up 2 gate_up_fused 3 down 4 bias 5 scales 6 latent_in 7 latent_out 8..255 reserved-registered 256.. vendor / experimental
format — u16
0 f32 6 q8_0 1 f16 7 fp4_larql 2 bf16 8 mxfp4 3 q4_0 9 nvfp4 4 q4_k 10 mxfp8 5 q6_k … extensible
New roles and formats do not bump format_version. Known kernels may require exactly gate_up_fused + down (or gate + up + down); the presence of other roles never invalidates a file, and the absence of a role a programme requires makes the file un-executable for that programme — not invalid.
THE ENCODER — LAY OUT A FILE YOURSELF
Choose a recipe. The bytes follow.
tables drawn magnified — 1.1 KiB of structure ahead of 612.0 MiB of weights
payload to scale · one tick per entry · first region offset 1.1 KiB
Worked-example geometry: input and output 2048, intermediate 6144 — dimensions divisible by 256, so the block formats pack exactly. Change the format and only the payload changes. Change the region set and the schema count, entry table, and payload all follow. The structure never grows with the weights: parsing stays a few kilobytes, whatever the file weighs.
A routed · 32 experts bank, gate_up_fused + down, in mxfp4: 1.1 KiB of self-description, then 612.0 MiB of weights — 612.0 MiB in all, every region offset 64-byte aligned.
Unknown tags are preserved, not rejected. Refusal belongs at capability-check time — a reader reports what it does not understand, and only the operations that need it are refused.
SEGMENTATION — WHY A LAYER IS SOMETIMES SEVERAL FILES
The spec's own worked example: one routed layer of K3, at exact Q6_K, is 33,030,144 parameters per expert × 896 experts — about 22.61 GiB. That exceeds the 20 GiB shard cap. So the layer ships as two segment files of 448 experts each, about 11.3 GiB apiece. Inside a segment, experts are grouped into extents of 8, 16, or 32 — the unit of disk reads, prefetch, and grouped kernels. Two rules keep the scales honest: segment boundaries fall on group-extent boundaries, and group width divides segment width. Segment width serves file management. Group width serves the hardware.
Two scales, two measurements. The segment answers to file management — as large as the cap allows, so two files, not fourteen. The extent answers to hardware — how much one grouped dispatch reads. Boundaries always agree: segments split only on extent edges.
GREENFIELD, DELIBERATELY
LYRW v2 owes no binary compatibility to the layer files inside VINDEX2 containers — those were never a public contract. There is no adapter and no in-place upgrade. Each generation's loader reads its own format. The magic and version field exist so an old reader fails fast with a precise message, never a parse error. And the compatibility promise lives one level up: one reader supports both generations, indefinitely.
Which encoding a region is stored in — and which stored variant a profile may select — is the representation story.
PUBLISHED 29 AUG 2026 · REVISED 30 AUG 2026 · VERSION 3.0 Candidate
CITEsite build 43a1b6b · built 2026-09-02
CITE THIS
Web page · 3.0 Candidate
Hay, C. (2026). The Bytes. In VINDEX3 Specification (Version 3.0 Candidate). VINDEX3. https://vindex3.org/bytes
A chapter of the specification, citable on its own. Cite the version rather than the site — the canonical reference, and how to use it, live at /cite.
SOURCES
- vindex3-format-spec.md §6–7 (the 3.0 Candidate)
- reference implementation — lyrw2/region_format.rs and the format constants