SPEC §3.1 defines the pin a manifest carries (conditioning.prior, and a WAI2 rendition's prior): id, sha256, determinism, and the optional form, tier and supersedes. The digest covers the whole parameter set. A set of several files is pinned through its listing, the new registered prior form wai.prior.set. A sink verifies the pin before it decodes, reports a refusal with one of an ordered set of snake_case reasons, and decodes only from the set it verified. Tier is a closed vocabulary; supersedes is informative. A pin that does not resolve makes its capability unsupported for that envelope: SPEC §4 dispatch continues at the fallback, §7.1 selection at the next rendition, and an inert envelope's error names the reasons. A rendition entry may carry id, sha256 and, on a companion, companion_of_id. SPEC §7 gains a Digests subsection, and §8 says how a MINOR revision adds an optional member. In wai-rs: the manifest types are #[non_exhaustive] with builders; a new pin module verifies pins in memory and on disk; Wai::dispatch_verified, WaiMulti::pick and primary check pins and component digests; every neural decoder reads through ParamSource; a codec-free `ffi` feature carries the C envelope surface with wai_envelope_select and wai_neural_decode_ex. wai-web wraps wai::container. New vectors: the int_mlicpp set-form twin and the pin-conformance corpus with an independent Python verifier, plus sha256.json sidecars for the vectors of capabilities that decode against a parameter set. Squashed from wai/stream-a-parameter-set-identity onto link 12. Conflicts are resolved to keep both sides; the integration commits that follow make the two streams agree. Co-Authored-By: Claude Opus 5.5 <[email protected]>
3.6 KiB
Neural Conformance Corpus — integer synthesis
Vectors for the integer-synthesis neural decoder (wai.neural.int_synth).
This is the one neural decoder that can make the promise the reconstruct
cargo classes make: bit-identical output on every machine, no tolerance —
because its synthesis is pure i64 arithmetic (integer transposed
convolutions + arithmetic-shift requantize + integer ReLU), not float ONNX.
Two sinks honoring the spec produce the same bytes on every architecture.
The float decoders (bmshj2018, mbt2018_mean, elic, mlicpp, …) are
deliberately not here: their ONNX synthesis is float, so two conforming
sinks on different hardware may differ in the low bits — a byte-equality
corpus would be a false promise for them. The integer decoder is the member
where intent = replicate is sound, so it is the member with a cross-arch
byte-equality corpus.
Because the decoder pulls in no float runtime, it lives at the crate root
behind the light neural_int feature (no ort), so this corpus is verified
in the same no-system-deps CI matrix as the reconstruct classes, which checks
the integer-exact contract on x86-64 and arm64 (Linux x86_64, Linux arm64 and
macOS arm64) on every push that touches it.
Layout
vectors/<name>/int_synth.json— the integer decoder model (per-layer weights/bias asi32, stride, requantize shift, integer ReLU flag).vectors/<name>/latent.bin— the wire payload (12-byte header + channel-majorint8latents).sha256.json— per vector, the SHA-256 of its decoded output asRGB8(SPEC §7, Digests): the conformance digest.expected_hashes.json— per vector:s_log2,in_channels,layers,width,height, andrgb_hash, a domain-prefixed BLAKE3 of the decoded RGB, kept unchanged as a divergence diagnostic.
The vectors keep their unpinned <dir>/model convention. A sink that pins an
int_synth parameter set pins int_synth.json, the one file that holds it
(SPEC §5).
Synthetic vectors (realistic multi-layer decoders, distinct shapes) — model
weights/latents authored from a fixed integer SplitMix64 sequence, so gen
is reproducible without a float RNG:
gradient— 8×8 latent, 4 ch → ×2 → ×2 = 38×38 RGB, two layers, one ReLU.bloom— 4×4 latent, 8 ch → ×4 (single deep upsample) = 18×18 RGB.facade— 16×16 latent, 3 ch → ×2 → ×2 → refine = 72×72 RGB, three layers, two ReLUs (a deeper integer stack).
And one real trained model on a real photograph:
photo— a 128×128 macOS Sonoma landscape, encoded to a 6,156-byte int8 latent (96×8×8) + a four-layer integer decoder trained on real images (tools/wai_int_synth_real.py: float-train + post-training quantization with per-layer activation-scale calibration). Reconstruction ≈ 21.6 dB at ~3 bpp. This is the honest scope of int_synth: a pure integer transposed-conv decoder with no entropy model — its quality is modest by design; its point is that the decode is bit-identical on every machine. Atgentime the Rust decoder is cross-checked against the tool's python integer-forward (ref_rgb.bin) to max|Δ|=0, and the frozenrgb_hashthen enforces the same bytes on every platform in CI — a real trained model, a real photo, decoded identically everywhere.
Running
cd ../wai-rs
cargo run --features neural_int --bin wai_int_synth_vectors -- verify ../neural-conformance
cargo run --features neural_int --bin wai_int_synth_vectors -- gen ../neural-conformance # regenerate
Pass = decoded-RGB BLAKE3 + dimensions equality, on every machine.