open-standards/wai/wai-rs/tests/int_hyper_synth.rs
Transaction Science fa3f18797b wai: committed tiny conformance vector for int_hyper (CI-verifiable, no 23MB model)
The SOTA int_hyper vector needs a ~23 MB PTQ model that can't be committed, so
the conformance test skipped without it and CI never exercised the decode. This
adds a SMALL synthetic conditional codec (deterministic random integer weights,
fixed seed) that drives the SAME path end to end — factorized z → integer h_s →
integer-σ entropy bucketing → integer rANS → integer synthesis g_s → RGB — with
a committed expected FNV-1a. ~7 KB total, so it commits and verifies anywhere.

- tools/wai_int_hyper_tiny_vector.py: builds the tiny g_s/h_s (convT/igdn/leaky/
  conv) + tiny entropy tables (Gaussian-conditional y + factorized z) + a real
  rANS bitstream (CompressAI encoder), reusing the SOTA export's integer-net
  runner so the math is identical. Emits JSON + compact-binary models, entropy,
  bitstream, and the expected hash.
- tests/vectors/int_hyper/: the committed vector (tiny_{g_s,h_s}.{json,bin},
  tiny_entropy.json, tiny_bitstream.json, tiny.json).
- new test decodes_the_committed_tiny_conformance_vector: NEVER skips; decodes
  the committed bitstream via BOTH the JSON and the compact-binary model and
  asserts both reproduce the committed FNV-1a (7cbe882c42c6725d), byte-for-byte.

The numbers aren't a "real" codec (random weights) — the point is a deterministic,
artifact-free exercise of every integer op, so int_hyper now has the same
committed-conformance footing as the other capabilities.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-25 13:58:02 -04:00

150 lines
7.9 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! The Rust integer synthesis of a SOTA-class learned codec reproduces the
//! Python export tool's reconstruction BYTE-FOR-BYTE — proving the decode is
//! cross-language / cross-hardware exact at SOTA quality (mbt2018_mean, 42.6 dB,
//! fully integer). The model + input + expected FNV-1a checksum are emitted by
//! `tools/wai_sota_int_synth_export.py` into a directory pointed to by
//! `WAI_SOTA_INT_DIR` (default `/tmp/sota_int`); skipped if absent.
#![cfg(feature = "neural_int")]
use std::path::PathBuf;
use wai::int_hyper_synth::{decode, fnv1a, IntModel};
fn dir() -> PathBuf {
PathBuf::from(std::env::var("WAI_SOTA_INT_DIR").unwrap_or_else(|_| "/tmp/sota_int".into()))
}
fn jload(p: &std::path::Path) -> Option<serde_json::Value> {
serde_json::from_slice(&std::fs::read(p).ok()?).ok()
}
#[test]
fn rust_integer_synthesis_reproduces_the_export_hash() {
let d = dir();
let (Some(conf), Some(model), Some(input)) = (
jload(&d.join("int_synth_sota.json")),
jload(&d.join("int_synth_sota_model.json")),
jload(&d.join("int_synth_sota_input.json")),
) else {
eprintln!("skipping SOTA int-synth: artifacts not in {} (run tools/wai_sota_int_synth_export.py)", d.display());
return;
};
let (c, h, w) = (
input["c"].as_u64().unwrap() as usize,
input["h"].as_u64().unwrap() as usize,
input["w"].as_u64().unwrap() as usize,
);
let latent: Vec<i64> =
input["data"].as_array().unwrap().iter().map(|n| n.as_i64().unwrap()).collect();
let (rgb, oh, ow) = decode(&IntModel::from_json(&model), &latent, c, h, w);
assert_eq!((oh, ow), (conf["out_h"].as_u64().unwrap() as usize, conf["out_w"].as_u64().unwrap() as usize));
assert_eq!(rgb.len(), oh * ow * conf["out_c"].as_u64().unwrap() as usize);
let got = format!("{:016x}", fnv1a(&rgb));
let want = conf["rgb_hash"].as_str().unwrap();
println!("SOTA integer synthesis: {oh}x{ow}, fnv1a {got} (psnr {:.2} dB)", conf["psnr_int"].as_f64().unwrap_or(0.0));
assert_eq!(got, want, "Rust integer synthesis must reproduce the export's reconstruction byte-for-byte");
}
#[test]
fn rust_integer_hyper_decoder_reproduces_the_export_hash() {
let d = dir();
let (Some(conf), Some(model), Some(input)) = (
jload(&d.join("int_hs.json")),
jload(&d.join("int_hs_model.json")),
jload(&d.join("int_hs_input.json")),
) else {
eprintln!("skipping SOTA int h_s: artifacts not in {}", d.display());
return;
};
let (c, h, w) = (
input["c"].as_u64().unwrap() as usize,
input["h"].as_u64().unwrap() as usize,
input["w"].as_u64().unwrap() as usize,
);
let z: Vec<i64> = input["data"].as_array().unwrap().iter().map(|n| n.as_i64().unwrap()).collect();
let (out, oc, oh, ow) = wai::int_hyper_synth::run_net(&IntModel::from_json(&model), &z, c, h, w);
assert_eq!((oc, oh, ow), (
conf["out_c"].as_u64().unwrap() as usize,
conf["out_h"].as_u64().unwrap() as usize,
conf["out_w"].as_u64().unwrap() as usize));
let bytes: Vec<u8> = out.iter().flat_map(|v| v.to_le_bytes()).collect();
let got = format!("{:016x}", fnv1a(&bytes));
println!("integer h_s: z_hat {c}x{h}x{w} -> sigma||mu {oc}x{oh}x{ow}, fnv1a {got}");
assert_eq!(got, conf["params_hash"].as_str().unwrap(), "integer h_s must reproduce the export byte-for-byte");
}
#[test]
fn decodes_the_committed_tiny_conformance_vector() {
// A SMALL synthetic int_hyper codec, committed under tests/vectors/int_hyper/,
// drives the full decode path (factorized z → integer h_s → integer-σ entropy
// → integer g_s) with NO external artifacts — so CI verifies the int_hyper
// capability without the 23 MB SOTA model. Both the JSON and the compact
// binary model must reproduce the committed FNV-1a, byte-for-byte. Never skips.
use wai::int_hyper_synth::{decode_conditional, CondBitstream, CondEntropy};
let d = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/vectors/int_hyper");
let conf = jload(&d.join("tiny.json")).expect("committed tiny.json");
let ent = CondEntropy::from_value(&jload(&d.join("tiny_entropy.json")).unwrap());
let bs = CondBitstream::from_value(&jload(&d.join("tiny_bitstream.json")).unwrap());
let want = conf["rgb_hash"].as_str().unwrap();
let (oh, ow) = (conf["out_h"].as_u64().unwrap() as usize, conf["out_w"].as_u64().unwrap() as usize);
let g_j = IntModel::from_json(&jload(&d.join("tiny_g_s.json")).unwrap());
let h_j = IntModel::from_json(&jload(&d.join("tiny_h_s.json")).unwrap());
let (rgb, h, w) = decode_conditional(&g_j, &h_j, &ent, &bs).expect("tiny json decode");
assert_eq!((h, w), (oh, ow));
assert_eq!(format!("{:016x}", fnv1a(&rgb)), want, "tiny int_hyper (json model) must reproduce the committed hash");
let g_b = IntModel::from_bytes(&std::fs::read(d.join("tiny_g_s.bin")).unwrap()).expect("tiny g_s bin");
let h_b = IntModel::from_bytes(&std::fs::read(d.join("tiny_h_s.bin")).unwrap()).expect("tiny h_s bin");
let (rgb2, _, _) = decode_conditional(&g_b, &h_b, &ent, &bs).expect("tiny binary decode");
assert_eq!(format!("{:016x}", fnv1a(&rgb2)), want, "tiny int_hyper (binary model) must reproduce the committed hash");
println!("tiny int_hyper conformance: {oh}x{ow}, {} z + {} y rANS bytes, fnv1a {want}", bs.z_rans.len(), bs.rans.len());
}
#[test]
fn rust_decodes_the_full_conditional_bitstream_to_the_export_image() {
// The whole NeuralIntegerExact codec, end to end: a real bitstream (factorized
// z + rANS-coded y residuals) decodes — factorized z → integer h_s → σ,μ;
// σ → integer bucket → rANS-decode r → y_hat = r·2^afrac + μ → integer g_s —
// to the SAME image the export tool produced, byte-for-byte (fully integer, so
// identical on every machine). This is the integer-entropy contract assembled.
use wai::int_hyper_synth::{decode_conditional, CondBitstream, CondEntropy};
let d = dir();
let (Some(conf), Some(g_s), Some(h_s), Some(ent), Some(bs)) = (
jload(&d.join("cond.json")),
jload(&d.join("int_synth_sota_model.json")),
jload(&d.join("int_hs_model.json")),
jload(&d.join("cond_entropy.json")),
jload(&d.join("cond_bitstream.json")),
) else {
eprintln!("skipping conditional bitstream: artifacts not in {}", d.display());
return;
};
let (g_s, h_s) = (IntModel::from_json(&g_s), IntModel::from_json(&h_s));
let ent = CondEntropy::from_value(&ent);
let bs = CondBitstream::from_value(&bs);
let (rgb, oh, ow) = decode_conditional(&g_s, &h_s, &ent, &bs).expect("conditional decode");
assert_eq!((oh, ow), (conf["out_h"].as_u64().unwrap() as usize, conf["out_w"].as_u64().unwrap() as usize));
let got = format!("{:016x}", fnv1a(&rgb));
println!(
"conditional bitstream: {} z + {} y rANS bytes -> {oh}x{ow}, fnv1a {got} ({:.2} dB)",
bs.z_rans.len(), bs.rans.len(), conf["psnr_cond"].as_f64().unwrap_or(0.0)
);
assert_eq!(got, conf["rgb_hash"].as_str().unwrap(), "Rust must decode the bitstream to the export image byte-for-byte");
// The COMPACT BINARY model (~½ the size) must decode bit-identically to the
// JSON — same codec, smaller download (what makes the in-browser demo practical).
if let (Ok(g_bin), Ok(h_bin)) =
(std::fs::read(d.join("int_synth_sota_model.bin")), std::fs::read(d.join("int_hs_model.bin")))
{
let g_s2 = IntModel::from_bytes(&g_bin).expect("g_s binary");
let h_s2 = IntModel::from_bytes(&h_bin).expect("h_s binary");
let (rgb2, _, _) = decode_conditional(&g_s2, &h_s2, &ent, &bs).expect("binary conditional decode");
assert_eq!(format!("{:016x}", fnv1a(&rgb2)), conf["rgb_hash"].as_str().unwrap(),
"the compact binary model must decode byte-identically to the JSON model");
println!("compact binary model ({} + {} bytes) decodes byte-identically", g_bin.len(), h_bin.len());
}
}