open-standards/wai/tools/wai_determinism_cost.py
Transaction Science ed33fbbaf7 wai: what exactness costs int_hyper, measured; determinism-tiers §7 states what WAI claims
research/determinism-cost.md and its record (record.json): mbt2018_mean at
all eight published qualities, integer export against the model's own
float codec, on the pinned reference set's 24 self-test pictures. BD-rate
by PSNR and MS-SSIM per picture; each codec's decodes repeated across nine
integer and seven float platforms and compared byte for byte, the float
ones placed in or after the entropy decode; decode time and energy with
counter, scope, idle brackets, liveness and ratio over seven rounds.

determinism-tiers §7.1 quotes the record, each figure tied to its place in
it by a marker the verifier checks; §7.2 says what WAI claims and does not,
and makes normative that a record figure is never stated beyond what the
record names, that no receipt takes its energy from it, and that a cost
figure in the spec names its measurement. SPEC §5's int_hyper row points
to §7. CHANGELOG entry.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 13:43:42 -04:00

878 lines
41 KiB
Python

#!/usr/bin/env python3
"""What exactness costs `wai.neural.int_hyper`: the measurement behind
research/determinism-cost.md and its record, research/determinism-cost/record.json.
The float codec is the pretrained mean-scale hyperprior `mbt2018_mean` (MSE, qualities
1-8) as its own library codes and decodes it. The integer codec is the same model exported
the way tools/wai_sota_int_synth_export.py exports quality 6 (per-channel int12 weights,
activations at 2^12, integer IGDN, the integer hyper-decoder deciding every scale bucket),
coded as a `WIH1` payload (extensions/integer-payloads.md §4) and decoded by the reference
decoder (`wai_det_cost`, which runs `int_payload::decode_int`). Every step writes files
under one work directory, so each can be rerun alone and on another machine.
wai_determinism_cost.py select <work> <reference-root> pick and check the pictures
wai_determinism_cost.py export <work> [q ...] pinned checkpoints -> integer sets
wai_determinism_cost.py encode <work> [q ...] both codecs; the float decode on this CPU
wai_determinism_cost.py jobs <work> <out-tag> the integer decode's job list
wai_determinism_cost.py fdecode <work> <tag> [--device cpu|mps|cuda] [--threads N]
decode every float stream again
wai_determinism_cost.py fserve <work> <q> [--device D] [--threads N] [--ids a,b]
the timed float child of wai_det_energy.py
wai_determinism_cost.py metrics <work> distortion of every decode
wai_determinism_cost.py bd <work> BD-rate, integer against float
wai_determinism_cost.py record <work> <record.json> the record: raw readings and their summary
Needs the pinned stack of tools/requirements-sota-int.txt for `export`, `encode` and
`fdecode`; `select`, `jobs`, `metrics` and `bd` need numpy and Pillow only.
"""
import hashlib
import importlib.util
import io
import json
import math
import os
import struct
import sys
import numpy as np
HERE = os.path.dirname(os.path.abspath(__file__))
QUALITIES = list(range(1, 9))
# The published mbt2018_mean (MSE) checkpoints, by quality: the file the library's zoo
# names, and the SHA-256 of its bytes, measured when this record was made. A checkpoint
# with other bytes is refused before it is loaded. Quality 6 is the one
# wai_sota_int_synth_export.py pins, and its digest is the same.
CKPT_SHA256 = {
1: "e522738dc4599d1538fcdb16e21aa56df9146d60e8e083542466b387c1960156",
2: "e54a039d587afddd086b836cdd8eed4e0343d7cdd91028489ad0f3e7a72d307d",
3: "723404a8a039371abe8a14f05160ee1614cf5e0a3fb2a4e5f7ba569b68c22601",
4: "6dba02a30c78ff78baafd2072dd78646c27af6c4dc8416097c2c2858c1f186ce",
5: "d504e8ebe7e6396efd0b5fd093a32136714fd7e4be03db389e6f07aee24fdb39",
6: "a19628aba19732125e02caf5c38e233edbe2a641145a5b1779c51f4527f51dd6",
7: "d5d441d16ba3e5a80ead947e35d2dddc12fb0d9785a8006e9b35a0cef7668d91",
8: "8089ae3e23d9df5b7c68107c82c31da21019147aedddb03f03350de58d5385b7",
}
# The pictures: the reference manifest's PNG entries that it marks `self_test`, each one
# picture of 768x512 or 512x768 (wai/tools/wai_visual_provenance_check.py's manifest).
MANIFEST = "wai-image-references.json"
MANIFEST_SHA256 = "db33c6633f89a66d6742a37cd348208792f6d49810da739ddf26d10dc6554b66"
def sha256(b):
return hashlib.sha256(b).hexdigest()
def jdump(obj, path):
with open(path, "w") as f:
json.dump(obj, f, indent=1, sort_keys=True)
f.write("\n")
def jload(path):
with open(path) as f:
return json.load(f)
def export_module():
spec = importlib.util.spec_from_file_location("sota_export", os.path.join(HERE, "wai_sota_int_synth_export.py"))
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
return m
# ---------------------------------------------------------------- select
def cmd_select(work, root):
raw = open(os.path.join(root, MANIFEST), "rb").read()
if sha256(raw) != MANIFEST_SHA256:
sys.exit(f"the manifest's SHA-256 is {sha256(raw)}, not the pinned {MANIFEST_SHA256}")
man = json.loads(raw)
from PIL import Image
pics = []
for e in man["entries"]:
if not (e.get("self_test") and e["path"].endswith(".png") and len(e["images"]) == 1):
continue
im = e["images"][0]
if (im["width"], im["height"]) not in ((768, 512), (512, 768)):
continue
b = open(os.path.join(root, e["path"]), "rb").read()
if sha256(b) != e["sha256"]:
sys.exit(f"an entry's bytes do not match the manifest ({e['sha256'][:16]})")
px = np.array(Image.open(io.BytesIO(b)).convert("RGB"))
h, w = px.shape[:2]
assert h % 64 == 0 and w % 64 == 0
pid = e["sha256"][:16]
os.makedirs(os.path.join(work, "src"), exist_ok=True)
px.tofile(os.path.join(work, "src", f"{pid}.rgb"))
pics.append({"id": pid, "file_sha256": e["sha256"], "width": int(w), "height": int(h),
"rgb_sha256": sha256(px.tobytes())})
jdump({"manifest_sha256": MANIFEST_SHA256,
"rule": "PNG entries marked self_test with one picture of 768x512 or 512x768",
"pictures": pics}, os.path.join(work, "pictures.json"))
print(f"{len(pics)} pictures")
def pictures(work):
return jload(os.path.join(work, "pictures.json"))["pictures"]
def source_rgb(work, p):
return np.fromfile(os.path.join(work, "src", f"{p['id']}.rgb"), dtype=np.uint8).reshape(p["height"], p["width"], 3)
# ---------------------------------------------------------------- models
def load_model(q, allow_new=False):
"""mbt2018_mean (MSE) at quality q from the published checkpoint, its bytes checked
against CKPT_SHA256 before they are loaded, as tensors only."""
import torch
from compressai.zoo import image as zoo_image
from compressai.zoo.pretrained import load_pretrained
url = zoo_image.model_urls["mbt2018-mean"]["mse"][q]
path = os.path.join(torch.hub.get_dir(), "checkpoints", os.path.basename(url))
if not os.path.exists(path):
os.makedirs(os.path.dirname(path), exist_ok=True)
torch.hub.download_url_to_file(url, path, progress=False)
blob = open(path, "rb").read()
got = sha256(blob)
# The zoo's file names carry the first eight hex digits of the digest.
if not os.path.basename(url).split("-")[-1].startswith(got[:8]):
sys.exit(f"q{q}: {path} has SHA-256 {got}, which does not match the prefix in its name")
want = CKPT_SHA256[q]
if want is None and not allow_new:
sys.exit(f"q{q}: no pinned digest; measured {got}")
if want is not None and got != want:
sys.exit(f"q{q}: {path} has SHA-256 {got}, pinned {want}")
state = torch.load(io.BytesIO(blob), map_location="cpu", weights_only=True)
m = zoo_image.model_architectures["mbt2018-mean"].from_state_dict(load_pretrained(state)).eval()
return m, {"quality": q, "url_name": os.path.basename(url), "sha256": got}
# ---------------------------------------------------------------- integer export
def int_net(E, seq, kind):
"""One integer network from a float Sequential, quantised as E (the quality-6 export
tool) quantises g_s and h_s."""
net = {"afrac": E.AFRAC, "gf": E.GF, "shift": E.SHIFT, "layers": []}
import torch
for layer in seq.children():
t = type(layer).__name__
if t == "ConvTranspose2d":
wi, sc = E.q_weight_pc(layer.weight.detach().numpy())
net["layers"].append({"type": "convT", "in_ch": int(wi.shape[0]), "out_ch": int(wi.shape[1]),
"k": int(wi.shape[2]), "stride": int(layer.stride[0]), "pad": int(layer.padding[0]),
"opad": int(layer.output_padding[0]), "weight": wi.reshape(-1).tolist(),
"mult": np.round(sc * (2 ** E.SHIFT)).astype(np.int64).tolist(),
"bias": np.round(layer.bias.detach().numpy() * (2 ** E.AFRAC)).astype(np.int64).tolist()})
elif t == "Conv2d":
wi, sc = E.q_weight_conv(layer.weight.detach().numpy())
net["layers"].append({"type": "conv", "in_ch": int(wi.shape[1]), "out_ch": int(wi.shape[0]),
"k": int(wi.shape[2]), "stride": int(layer.stride[0]), "pad": int(layer.padding[0]),
"weight": wi.reshape(-1).tolist(),
"mult": np.round(sc * (2 ** E.SHIFT)).astype(np.int64).tolist(),
"bias": np.round(layer.bias.detach().numpy() * (2 ** E.AFRAC)).astype(np.int64).tolist()})
elif t == "GDN":
with torch.no_grad():
beta = layer.beta_reparam(layer.beta).numpy()
C = beta.shape[0]
gamma = layer.gamma_reparam(layer.gamma).reshape(C, C).numpy()
net["layers"].append({"type": "igdn", "c": int(C),
"gamma": np.round(gamma * (2 ** E.GF)).astype(np.int64).reshape(-1).tolist(),
"beta": np.round(beta * (2 ** (2 * E.AFRAC))).astype(np.int64).tolist()})
elif t == "ReLU":
net["layers"].append({"type": "relu"})
elif t == "LeakyReLU":
net["layers"].append({"type": "leaky", "slope_q": 655, "slope_frac": 16})
else:
sys.exit(f"{kind}: no integer form for a {t} layer")
return net
def requant(raw, mult, bias, shift):
"""((raw * mult) >> shift) + bias per output channel, exact: in int64 where the
product provably fits, else in Python integers."""
if np.abs(raw).max(initial=0) * np.abs(mult).max(initial=0) < 2 ** 62:
return ((raw * mult[:, None, None]) >> shift) + bias[:, None, None]
return ((raw.astype(object) * mult[:, None, None]) >> shift).astype(np.int64) + bias[:, None, None]
def conv_t_fast(x, L, shift):
"""The integer transposed convolution of `int_hyper_synth` (weight [in,out,k,k]),
tap by tap: out[:, iy*s+ky, ix*s+kx] += w[:, :, ky, kx]^T x[:, iy, ix]. Integer sums
are exact in any order, so this equals the export tool's per-pixel scatter."""
cin, co, k, s, p, op = L["in_ch"], L["out_ch"], L["k"], L["stride"], L["pad"], L["opad"]
w = np.array(L["weight"], dtype=np.int64).reshape(cin, co, k, k)
_, H, W = x.shape
Ho, Wo = (H - 1) * s + k + op - 2 * p, (W - 1) * s + k + op - 2 * p
raw = np.zeros((co, Ho + 2 * p, Wo + 2 * p), dtype=np.int64)
xf = x.reshape(cin, -1)
assert np.abs(x).max(initial=0) * np.abs(w).max(initial=0) * cin * k * k < 2 ** 63
for ky in range(k):
for kx in range(k):
c = (w[:, :, ky, kx].T @ xf).reshape(co, H, W)
raw[:, ky:ky + s * H:s, kx:kx + s * W:s] += c
raw = raw[:, p:p + Ho, p:p + Wo]
return requant(raw, np.array(L["mult"], dtype=np.int64), np.array(L["bias"], dtype=np.int64), shift)
def conv_fast(x, L, shift):
cin, co, k, s, p = L["in_ch"], L["out_ch"], L["k"], L["stride"], L["pad"]
w = np.array(L["weight"], dtype=np.int64).reshape(co, cin, k, k)
_, H, W = x.shape
Ho, Wo = (H + 2 * p - k) // s + 1, (W + 2 * p - k) // s + 1
xp = np.zeros((cin, H + 2 * p, W + 2 * p), dtype=np.int64)
xp[:, p:p + H, p:p + W] = x
assert np.abs(x).max(initial=0) * np.abs(w).max(initial=0) * cin * k * k < 2 ** 63
raw = np.zeros((co, Ho, Wo), dtype=np.int64)
for ky in range(k):
for kx in range(k):
sub = xp[:, ky:ky + s * Ho:s, kx:kx + s * Wo:s].reshape(cin, -1)
raw += (w[:, :, ky, kx] @ sub).reshape(co, Ho, Wo)
return requant(raw, np.array(L["mult"], dtype=np.int64), np.array(L["bias"], dtype=np.int64), shift)
def run_hs(net, x):
"""The integer hyper-decoder (convolutions and ReLUs only), as `int_hyper_synth`
runs it."""
for L in net["layers"]:
t = L["type"]
if t == "convT":
x = conv_t_fast(x, L, net["shift"])
elif t == "conv":
x = conv_fast(x, L, net["shift"])
elif t == "relu":
x = np.maximum(x, 0)
elif t == "leaky":
x = np.where(x >= 0, x, (x * L["slope_q"]) >> L["slope_frac"])
else:
sys.exit(f"h_s has a {t} layer")
return x
def cmd_export(work, qs, allow_new=False):
"""Per quality, the integer set (integer-payloads §9: entropy.json, g_s.whm, h_s.whm)
and the model's identity."""
import torch
from compressai.entropy_models import GaussianConditional
torch.use_deterministic_algorithms(True)
torch.set_num_threads(1)
E = export_module()
out = {}
for q in qs:
m, ident = load_model(q, allow_new)
g_s = int_net(E, m.g_s, "g_s")
h_s = int_net(E, m.h_s, "h_s")
eb = m.entropy_bottleneck
eb.update()
median = eb._get_medians().reshape(-1).detach().numpy().astype(np.float64)
scale_table = list(torch.exp(torch.linspace(np.log(0.11), np.log(256.0), 64)).numpy().astype(float))
gc = GaussianConditional(scale_table)
gc.update()
ent = {"afrac": E.AFRAC, "frac": E.AFRAC,
"scale_edges": np.floor(np.array(scale_table) * (2 ** E.AFRAC)).astype(np.int64).tolist(),
"cdfs": gc._quantized_cdf.tolist(), "cdf_lengths": gc._cdf_length.reshape(-1).int().tolist(),
"offsets": gc._offset.reshape(-1).int().tolist(),
"z_cdfs": eb._quantized_cdf.tolist(), "z_cdf_lengths": eb._cdf_length.reshape(-1).int().tolist(),
"z_offsets": eb._offset.reshape(-1).int().tolist(),
"z_median_q": np.round(median * (2 ** E.AFRAC)).astype(np.int64).tolist()}
d = os.path.join(work, "sets", f"q{q}")
os.makedirs(d, exist_ok=True)
open(os.path.join(d, "g_s.whm"), "wb").write(E.model_to_bin(g_s))
open(os.path.join(d, "h_s.whm"), "wb").write(E.model_to_bin(h_s))
with open(os.path.join(d, "entropy.json"), "w") as f:
json.dump(ent, f)
jdump(h_s, os.path.join(d, "h_s.json")) # the encoder's copy of h_s
ident["set"] = {n: sha256(open(os.path.join(d, n), "rb").read()) for n in ("entropy.json", "g_s.whm", "h_s.whm")}
ident["N"], ident["M"] = int(m.N), int(m.M)
out[q] = ident
print(f"q{q}: N={m.N} M={m.M} checkpoint {ident['sha256'][:16]}… set g_s {ident['set']['g_s.whm'][:16]}…")
path = os.path.join(work, "models.json")
prev = jload(path) if os.path.exists(path) else {}
prev.update({str(k): v for k, v in out.items()})
jdump(prev, path)
# ---------------------------------------------------------------- encode
def to_rgb8(x_hat):
"""A float reconstruction in [0, 1] as 8-bit samples: x·255 rounded half to even, as
the float library's own tensor arithmetic gives it on the device it ran on."""
import torch
return (x_hat.clamp(0, 1) * 255).round().to(torch.uint8)[0].permute(1, 2, 0).contiguous().cpu().numpy()
def float_container(strings, zshape):
y, z = strings[0][0], strings[1][0]
return b"DETF" + struct.pack("<IIII", zshape[0], zshape[1], len(y), len(z)) + y + z
def read_float_container(b):
assert b[:4] == b"DETF"
zh, zw, ly, lz = struct.unpack("<IIII", b[4:20])
y = b[20:20 + ly]
z = b[20 + ly:20 + ly + lz]
assert 20 + ly + lz == len(b)
return [[y], [z]], (zh, zw)
def float_decode(m, strings, zshape):
"""The float library's own decode of a mean-scale stream (its `decompress`), with the
decoded indexes and symbols kept, so a mismatch can be placed: in the entropy decode
(other indexes or symbols) or after it."""
import torch
with torch.no_grad():
z_hat = m.entropy_bottleneck.decompress(strings[1], zshape)
scales_hat, means_hat = m.h_s(z_hat).chunk(2, 1)
indexes = m.gaussian_conditional.build_indexes(scales_hat)
symbols = m.gaussian_conditional.decompress(strings[0], indexes)
y_hat = symbols + means_hat
x_hat = m.g_s(y_hat).clamp_(0, 1)
idx = indexes.cpu().to(torch.int32).numpy().tobytes()
sym = symbols.cpu().round().to(torch.int32).numpy().tobytes()
return to_rgb8(x_hat), sha256(idx), sha256(sym)
def tables_sha256(m):
"""The entropy tables a float decode reads (both models' quantised CDFs, lengths and
offsets): a decode on another machine is comparable only under the same tables."""
import torch
h = hashlib.sha256()
for em in (m.entropy_bottleneck, m.gaussian_conditional):
for t in (em._quantized_cdf, em._cdf_length, em._offset):
h.update(t.cpu().to(torch.int32).numpy().tobytes())
return h.hexdigest()
def wih1(m_ch, sh, sw, n_z, zh, zw, z_rans, rans):
o = b"WIH1" + bytes([1, 0, 0, 0]) + struct.pack("<6I", m_ch, sh, sw, n_z, zh, zw)
return o + struct.pack("<I", len(z_rans)) + z_rans + struct.pack("<I", len(rans)) + rans
def cmd_encode(work, qs):
import torch
from compressai.ans import RansEncoder
torch.use_deterministic_algorithms(True)
torch.set_num_threads(int(os.environ.get("DET_THREADS", "1")))
E = export_module()
pics = pictures(work)
rows = {}
for q in qs:
m, _ = load_model(q)
m.update()
tables = tables_sha256(m)
d = os.path.join(work, "sets", f"q{q}")
hs = jload(os.path.join(d, "h_s.json"))
ent = jload(os.path.join(d, "entropy.json"))
edges = np.array(ent["scale_edges"], dtype=np.int64)
mq = np.array(ent["z_median_q"], dtype=np.int64)
for sub in ("float", "int", "dec"):
os.makedirs(os.path.join(work, sub, f"q{q}"), exist_ok=True)
for p in pics:
px = source_rgb(work, p)
x = torch.from_numpy(px.astype(np.float32) / 255.0).permute(2, 0, 1).unsqueeze(0)
with torch.no_grad():
# the float codec, as its library codes and decodes it
c = m.compress(x)
fb = float_container(c["strings"], tuple(c["shape"]))
open(os.path.join(work, "float", f"q{q}", f"{p['id']}.detf"), "wb").write(fb)
rgb, ih, sh_ = float_decode(m, c["strings"], tuple(c["shape"]))
rgb.tofile(os.path.join(work, "dec", f"q{q}", f"{p['id']}.float.rgb"))
# the integer codec: the float analysis, then everything the decoder reads in integers
y = m.g_a(x)
z = m.h_a(y)
y_np = y[0].numpy()
eb_median = m.entropy_bottleneck._get_medians().reshape(-1).detach().numpy().astype(np.float64)
z_sym = np.round(z[0].numpy() - eb_median[:, None, None]).astype(np.int64)
Cz, zh, zw = z_sym.shape
z_bits = RansEncoder().encode_with_indexes(
z_sym.reshape(-1).tolist(), np.repeat(np.arange(Cz), zh * zw).tolist(),
ent["z_cdfs"], ent["z_cdf_lengths"], ent["z_offsets"])
zi = z_sym * (2 ** E.AFRAC) + mq[:, None, None]
sm = run_hs(hs, zi)
M = sm.shape[0] // 2
sigma, mu = sm[:M], sm[M:]
resid = np.round(y_np - mu.astype(np.float64) / (2 ** E.AFRAC)).astype(np.int64)
idx = E.det_build_index_vec(sigma, edges)
y_bits = RansEncoder().encode_with_indexes(resid.reshape(-1).tolist(), idx.reshape(-1).tolist(),
ent["cdfs"], ent["cdf_lengths"], ent["offsets"])
pay = wih1(M, sigma.shape[1], sigma.shape[2], Cz, zh, zw, z_bits, y_bits)
open(os.path.join(work, "int", f"q{q}", f"{p['id']}.wih1"), "wb").write(pay)
rows[f"{p['id']}/q{q}"] = {
"float_stream_bytes": len(c["strings"][0][0]) + len(c["strings"][1][0]),
"float_stream_sha256": sha256(fb),
"float_tables_sha256": tables,
"float_cpu": {"rgb_sha256": sha256(rgb.tobytes()), "indexes_sha256": ih, "symbols_sha256": sh_},
"int_stream_bytes": len(z_bits) + len(y_bits),
"int_payload_bytes": len(pay),
"int_payload_sha256": sha256(pay),
}
row = rows[f"{p['id']}/q{q}"]
print(f"q{q} {p['id']}: float {row['float_stream_bytes']} B, integer {row['int_stream_bytes']} B", flush=True)
path = os.path.join(work, "encoded.json")
prev = jload(path) if os.path.exists(path) else {}
prev.update(rows)
jdump(prev, path)
def cmd_jobs(work, tag):
"""One line per integer payload: its set, the payload, where the decode goes."""
lines = []
for q in QUALITIES:
d = os.path.join(work, "int", f"q{q}")
if not os.path.isdir(d):
continue
os.makedirs(os.path.join(work, "dec", f"q{q}"), exist_ok=True)
for f in sorted(os.listdir(d)):
pid = f.split(".")[0]
out = os.path.join(work, "dec", f"q{q}", f"{pid}.int.{tag}.rgb") if tag != "-" else "-"
lines.append(f"{os.path.join(work, 'sets', f'q{q}')}\t{os.path.join(d, f)}\t{out}")
sys.stdout.write("\n".join(lines) + "\n")
def cmd_fdecode(work, tag, device, threads):
"""Decode every float stream in a fresh process on `device`: the RGB8, the indexes and
the symbols, by SHA-256."""
import platform
import torch
torch.use_deterministic_algorithms(True)
if threads:
torch.set_num_threads(threads)
out = {"tag": tag, "device": device, "threads": torch.get_num_threads(), "torch": torch.__version__,
"machine": platform.machine(), "system": platform.system(), "results": {}}
srcs = {p["id"]: p for p in pictures(work)}
for q in QUALITIES:
d = os.path.join(work, "float", f"q{q}")
if not os.path.isdir(d):
continue
m, _ = load_model(q)
m.update()
out.setdefault("tables_sha256", {})[f"q{q}"] = tables_sha256(m)
m = m.to(device)
for f in sorted(os.listdir(d)):
strings, zshape = read_float_container(open(os.path.join(d, f), "rb").read())
rgb, ih, sh_ = float_decode(m, strings, zshape)
pid = f.split(".")[0]
src = source_rgb(work, srcs[pid])
diff = rgb.astype(np.int64) - src.astype(np.int64)
out["results"][f"{pid}/q{q}"] = {"rgb_sha256": sha256(rgb.tobytes()), "indexes_sha256": ih,
"symbols_sha256": sh_, "sse": int((diff * diff).sum())}
print(f"q{q}: {len(os.listdir(d))} decoded on {device}", flush=True)
os.makedirs(os.path.join(work, "fdecode"), exist_ok=True)
jdump(out, os.path.join(work, "fdecode", f"{tag}.json"))
def cmd_fserve(work, q, device, threads, ids):
"""The timed child of tools/wai_det_energy.py for the float decode: the library's own
`decompress` of every float stream at quality q (or of the pictures `ids`) on
`device`, then the 8-bit samples on the host. Each decode's RGB8 is hashed and
compared with the first decode of its stream; a differing decode is counted, not
hidden (`done <decodes> <ns> mismatches=<n>`)."""
import time
import torch
torch.use_deterministic_algorithms(True, warn_only=device != "cpu")
if threads:
torch.set_num_threads(threads)
m, _ = load_model(q)
m.update()
m = m.to(device)
d = os.path.join(work, "float", f"q{q}")
files = [f for f in sorted(os.listdir(d)) if not ids or f.split(".")[0] in ids]
streams = [read_float_container(open(os.path.join(d, f), "rb").read()) for f in files]
def one(st):
with torch.no_grad():
x_hat = m.decompress(st[0], st[1])["x_hat"]
return sha256(to_rgb8(x_hat).tobytes())
want = [one(st) for st in streams]
print(f"ready {len(streams)}", flush=True)
for line in sys.stdin:
w = line.split()
if not w or w[0] == "exit":
return
k = int(w[1])
t0 = time.monotonic_ns()
n = bad = 0
for _ in range(k):
for st, h in zip(streams, want):
bad += one(st) != h
n += 1
print(f"done {n} {time.monotonic_ns() - t0} mismatches={bad}", flush=True)
# ---------------------------------------------------------------- metrics
GAUSS = None
MSSSIM_W = (0.0448, 0.2856, 0.3001, 0.2363, 0.1333)
def _gauss():
global GAUSS
if GAUSS is None:
g = np.exp(-((np.arange(11) - 5.0) ** 2) / (2 * 1.5 ** 2))
GAUSS = g / g.sum()
return GAUSS
def _filt(x):
"""Separable 11-tap Gaussian (sigma 1.5), valid region only."""
g = _gauss()
h, w = x.shape
t = sum(g[i] * x[i:h - 10 + i, :] for i in range(11))
return sum(g[i] * t[:, i:w - 10 + i] for i in range(11))
def ms_ssim_channel(a, b):
"""MS-SSIM of one channel, 8-bit samples (dynamic range 255): five scales, an 11-tap
Gaussian window of sigma 1.5, K1 0.01, K2 0.03, 2x2 mean pooling between scales
(an odd row or column dropped), contrast-structure at the first four scales and
luminance-contrast-structure at the fifth, weights 0.0448, 0.2856, 0.3001, 0.2363,
0.1333, each term clamped at zero before its power."""
C1, C2 = (0.01 * 255) ** 2, (0.03 * 255) ** 2
a, b = a.astype(np.float64), b.astype(np.float64)
val = 1.0
for s in range(5):
mu_a, mu_b = _filt(a), _filt(b)
saa = _filt(a * a) - mu_a ** 2
sbb = _filt(b * b) - mu_b ** 2
sab = _filt(a * b) - mu_a * mu_b
cs = (2 * sab + C2) / (saa + sbb + C2)
if s < 4:
val *= max(cs.mean(), 0.0) ** MSSSIM_W[s]
h, w = a.shape[0] // 2 * 2, a.shape[1] // 2 * 2
a = a[:h, :w].reshape(h // 2, 2, w // 2, 2).mean(axis=(1, 3))
b = b[:h, :w].reshape(h // 2, 2, w // 2, 2).mean(axis=(1, 3))
else:
l = (2 * mu_a * mu_b + C1) / (mu_a ** 2 + mu_b ** 2 + C1)
val *= max((l * cs).mean(), 0.0) ** MSSSIM_W[s]
return val
def ms_ssim(a, b):
return float(np.mean([ms_ssim_channel(a[:, :, c], b[:, :, c]) for c in range(3)]))
def cmd_metrics(work, tags):
pics = pictures(work)
enc = jload(os.path.join(work, "encoded.json"))
rows = {}
for p in pics:
src = source_rgb(work, p)
for q in QUALITIES:
k = f"{p['id']}/q{q}"
if k not in enc:
continue
r = {}
for path, fname in (("float", f"{p['id']}.float.rgb"), ("int", f"{p['id']}.int.{tags[0]}.rgb")):
rgb = np.fromfile(os.path.join(work, "dec", f"q{q}", fname), dtype=np.uint8)
rgb = rgb.reshape(src.shape)
d = rgb.astype(np.int64) - src.astype(np.int64)
r[path] = {"sse": int((d * d).sum()), "samples": int(d.size), "ms_ssim": ms_ssim(rgb, src),
"rgb_sha256": sha256(rgb.tobytes())}
rows[k] = r
print(p["id"], flush=True)
jdump(rows, os.path.join(work, "metrics.json"))
# ---------------------------------------------------------------- BD-rate
def psnr(sse, n):
return 10 * math.log10(255.0 ** 2 * n / sse)
def ms_ssim_db(v):
return -10 * math.log10(1 - v)
def pchip_slopes(x, y):
"""Interior slopes of the monotone piecewise-cubic Hermite interpolant (weighted
harmonic mean of the neighbouring secants, zero at a change of sign), end slopes by
the three-point shape-preserving formula."""
n = len(x)
h = [x[i + 1] - x[i] for i in range(n - 1)]
d = [(y[i + 1] - y[i]) / h[i] for i in range(n - 1)]
m = [0.0] * n
for i in range(1, n - 1):
if d[i - 1] * d[i] > 0:
w1, w2 = 2 * h[i] + h[i - 1], h[i] + 2 * h[i - 1]
m[i] = (w1 + w2) / (w1 / d[i - 1] + w2 / d[i])
def end(h0, h1, d0, d1):
s = ((2 * h0 + h1) * d0 - h0 * d1) / (h0 + h1)
if s * d0 <= 0:
return 0.0
if d0 * d1 <= 0 and abs(s) > abs(3 * d0):
return 3 * d0
return s
m[0] = end(h[0], h[1], d[0], d[1])
m[-1] = end(h[-1], h[-2], d[-1], d[-2])
return m
def pchip_integral(x, y, a, b):
"""The integral from a to b of the interpolant through (x, y): each segment's cubic
Hermite polynomial integrated exactly."""
m = pchip_slopes(x, y)
total = 0.0
for i in range(len(x) - 1):
lo, hi = max(a, x[i]), min(b, x[i + 1])
if hi <= lo:
continue
h = x[i + 1] - x[i]
def F(t): # antiderivative in t = (u - x_i)/h, times h
h00 = t - t ** 3 + t ** 4 / 2
h10 = t ** 2 / 2 - 2 * t ** 3 / 3 + t ** 4 / 4
h01 = t ** 3 - t ** 4 / 2
h11 = -t ** 3 / 3 + t ** 4 / 4
return h * (h00 * y[i] + h10 * h * m[i] + h01 * y[i + 1] + h11 * h * m[i + 1])
total += F((hi - x[i]) / h) - F((lo - x[i]) / h)
return total
def bd_rate(r_ref, q_ref, r_test, q_test):
"""Bjontegaard delta rate (ITU-T VCEG-M33), log-rate interpolated as a monotone
piecewise cubic of quality and averaged over the overlap of the two quality ranges:
the percentage by which the test needs more rate than the reference at equal quality.
None when either curve is not strictly increasing in quality."""
def prep(r, qv):
pts = sorted(zip(qv, (math.log10(v) for v in r)))
xs = [p[0] for p in pts]
if any(b <= a for a, b in zip(xs, xs[1:])):
return None
return xs, [p[1] for p in pts]
A, B = prep(r_ref, q_ref), prep(r_test, q_test)
if A is None or B is None:
return None
lo, hi = max(A[0][0], B[0][0]), min(A[0][-1], B[0][-1])
if hi <= lo:
return None
ia = pchip_integral(A[0], A[1], lo, hi)
ib = pchip_integral(B[0], B[1], lo, hi)
return (10 ** ((ib - ia) / (hi - lo)) - 1) * 100
def cmd_bd(work):
pics = pictures(work)
enc = jload(os.path.join(work, "encoded.json"))
met = jload(os.path.join(work, "metrics.json"))
per = {}
for p in pics:
n = p["width"] * p["height"]
rf, ri, pf, pi, sf, si = [], [], [], [], [], []
for q in QUALITIES:
k = f"{p['id']}/q{q}"
rf.append(enc[k]["float_stream_bytes"] * 8 / n)
ri.append(enc[k]["int_stream_bytes"] * 8 / n)
pf.append(psnr(met[k]["float"]["sse"], met[k]["float"]["samples"]))
pi.append(psnr(met[k]["int"]["sse"], met[k]["int"]["samples"]))
sf.append(ms_ssim_db(met[k]["float"]["ms_ssim"]))
si.append(ms_ssim_db(met[k]["int"]["ms_ssim"]))
per[p["id"]] = {"bd_rate_psnr": bd_rate(rf, pf, ri, pi), "bd_rate_ms_ssim": bd_rate(rf, sf, ri, si)}
print(p["id"], per[p["id"]])
jdump(per, os.path.join(work, "bd.json"))
# ---------------------------------------------------------------- the record
def stats(v):
v = sorted(v)
n = len(v)
if n == 0:
return None
med = v[n // 2] if n % 2 else (v[n // 2 - 1] + v[n // 2]) / 2
return {"n": n, "median": med, "mean": sum(v) / n, "min": v[0], "max": v[-1]}
def summarise(rec):
"""Everything the record states beyond its raw readings, computed from them alone:
tools/wai_determinism_cost_verify.py recomputes each value independently."""
pics = rec["pictures"]["items"]
pts = rec["points"]
qs = sorted(int(q) for q in rec["models"])
out = {}
bd = {"psnr": {}, "ms_ssim": {}}
for p in pics:
n = p["width"] * p["height"]
ks = [f"{p['id']}/q{q}" for q in qs]
rf = [pts[k]["float_stream_bytes"] * 8 / n for k in ks]
ri = [pts[k]["int_stream_bytes"] * 8 / n for k in ks]
for metric, f in (("psnr", lambda r: psnr(r["sse"], r["samples"])), ("ms_ssim", lambda r: ms_ssim_db(r["ms_ssim"]))):
bd[metric][p["id"]] = bd_rate(rf, [f(pts[k]["float"]) for k in ks], ri, [f(pts[k]["int"]) for k in ks])
out["bd_rate_percent"] = {m: {"per_picture": v, **stats([x for x in v.values() if x is not None]),
"undefined": sorted(k for k, x in v.items() if x is None)} for m, v in bd.items()}
perq = {}
for q in qs:
ks = [f"{p['id']}/q{q}" for p in pics]
perq[f"q{q}"] = {
"float_bpp": stats([pts[k]["float_stream_bytes"] * 8 / (pts[k]["float"]["samples"] / 3) for k in ks]),
"rate_ratio": stats([pts[k]["int_stream_bytes"] / pts[k]["float_stream_bytes"] for k in ks]),
"float_psnr_db": stats([psnr(pts[k]["float"]["sse"], pts[k]["float"]["samples"]) for k in ks]),
"delta_psnr_db": stats([psnr(pts[k]["int"]["sse"], pts[k]["int"]["samples"]) - psnr(pts[k]["float"]["sse"], pts[k]["float"]["samples"]) for k in ks]),
"delta_ms_ssim_db": stats([ms_ssim_db(pts[k]["int"]["ms_ssim"]) - ms_ssim_db(pts[k]["float"]["ms_ssim"]) for k in ks]),
}
out["per_quality"] = perq
ref_int = {k: v["int"]["rgb_sha256"] for k, v in pts.items()}
xi = {}
for tag, d in rec["integer_decodes"].items():
r = d["results"]
xi[tag] = {"decodes": len(r),
"identical": sum(1 for k, h in r.items() if h == ref_int.get(k)),
"refused": sum(1 for h in r.values() if h.startswith("refused:")),
"missing": sorted(k for k in ref_int if k not in r)}
xi[tag]["differ"] = xi[tag]["decodes"] - xi[tag]["identical"] - xi[tag]["refused"]
out["integer_cross_platform"] = xi
out["integer_cross_platform_total"] = {"platforms": len(xi), **{f: sum(v[f] for v in xi.values()) for f in ("decodes", "identical", "differ", "refused")}}
xf = {}
for tag, d in rec["float_decodes"].items():
r = d["results"]
c = {"decodes": len(r), "identical": 0, "rgb_differ": 0, "indexes_differ": 0, "symbols_differ": 0,
"tables_differ": sorted(q for q, h in d.get("tables_sha256", {}).items() if h != rec["float_tables_sha256"][q])}
dps, dsym = [], []
for k, v in r.items():
ref = pts[k]
same = v["rgb_sha256"] == ref["float"]["rgb_sha256"]
c["identical"] += same
c["rgb_differ"] += not same
c["indexes_differ"] += v["indexes_sha256"] != ref["float_cpu_indexes_sha256"]
c["symbols_differ"] += v["symbols_sha256"] != ref["float_cpu_symbols_sha256"]
dp = psnr(v["sse"], ref["float"]["samples"]) - psnr(ref["float"]["sse"], ref["float"]["samples"])
if not same:
dps.append(dp)
if v["symbols_sha256"] != ref["float_cpu_symbols_sha256"]:
dsym.append(dp)
c["delta_psnr_db_where_differ"] = stats(dps)
c["delta_psnr_db_where_symbols_differ"] = stats(dsym)
c["missing"] = sorted(k for k in pts if k not in r)
xf[tag] = c
out["float_cross_platform"] = xf
def live(b):
"""energy-measurement §3.1: the rail advanced in two consecutive intervals, in at
least five and in at least four of every five, over at least 300 ms."""
return bool(b) and b["longest_run"] >= 2 and b["advanced"] >= 5 and 5 * b["advanced"] >= 4 * b["intervals"] and b["span_ns"] >= 300_000_000
tm = {}
for run in rec["timing"]:
rs = run["rounds"]
t = {"rounds": len(rs), "decodes_per_round": sorted({r["decodes"] for r in rs}),
"ms_per_decode": stats([r["child_wall_ns"] / r["decodes"] / 1e6 for r in rs]),
"load_avg_1min": stats([r["load_avg_before"][0] for r in rs] + [r["load_avg_after"][0] for r in rs])}
if all("task" in r for r in rs):
t["task_j_per_decode"] = stats([r["task"]["energy_nj"] / r["decodes"] / 1e9 for r in rs])
t["task_cpu_ms_per_decode"] = stats([r["task"]["cpu_ns"] / r["decodes"] / 1e6 for r in rs])
t["billed_j_per_decode"] = stats([r["task"]["billed_nj"] / r["decodes"] / 1e9 for r in rs])
for cn in ("rapl", "ioreport-gpu"):
if all(cn in r for r in rs):
ok = [r for r in rs if r[cn].get("verdict") in ("clean", "relative-only")
and all(live(r[cn][b]) for b in ("busy", "idle_before", "idle_after"))]
if cn == "ioreport-gpu":
ok = [r for r in ok if (r.get("gpu_time", {}).get("share") or 0) >= 0.99]
t[cn] = {"verdicts": [r[cn].get("verdict") for r in rs],
"live_rounds": sum(all(live(r[cn][b]) for b in ("busy", "idle_before", "idle_after")) for r in rs),
"ratio": stats([r[cn]["ratio"] for r in rs if r[cn].get("ratio") is not None]),
"usable_rounds": len(ok),
"marginal_j_per_decode": stats([r[cn]["marginal_nj"] / r["decodes"] / 1e9 for r in ok]),
"publishable": len(ok) >= 7 and all(r[cn]["verdict"] == "clean" for r in ok)}
if cn == "ioreport-gpu":
t[cn]["gpu_share"] = stats([r["gpu_time"]["share"] for r in rs if r.get("gpu_time", {}).get("share") is not None])
tm[run["label"]] = t
out["timing"] = tm
return out
def cmd_record(work, dest):
pics = jload(os.path.join(work, "pictures.json"))
enc = jload(os.path.join(work, "encoded.json"))
met = jload(os.path.join(work, "metrics.json"))
models = jload(os.path.join(work, "models.json"))
points, tables = {}, {}
for k, e in sorted(enc.items()):
q = k.split("/")[1]
if q in tables and tables[q] != e["float_tables_sha256"]:
sys.exit(f"{k}: other float tables than its quality's other pictures")
tables[q] = e["float_tables_sha256"]
points[k] = {"float_stream_bytes": e["float_stream_bytes"], "int_stream_bytes": e["int_stream_bytes"],
"int_payload_bytes": e["int_payload_bytes"], "float_stream_sha256": e["float_stream_sha256"],
"int_payload_sha256": e["int_payload_sha256"],
"float_cpu_indexes_sha256": e["float_cpu"]["indexes_sha256"],
"float_cpu_symbols_sha256": e["float_cpu"]["symbols_sha256"],
"float": met[k]["float"], "int": met[k]["int"]}
if met[k]["float"]["rgb_sha256"] != e["float_cpu"]["rgb_sha256"]:
sys.exit(f"{k}: the measured float decode is not the one the encoder wrote")
rec = {"format": "wai-determinism-cost/1", "procedure": "wai/research/determinism-cost.md",
"runs": "wai/research/determinism-cost/runs/", "measured": os.environ.get("DET_MEASURED", "2026-10-22"),
"pictures": {"manifest_sha256": pics["manifest_sha256"], "rule": pics["rule"],
"items": [{kk: p[kk] for kk in ("id", "file_sha256", "width", "height", "rgb_sha256")} for p in pics["pictures"]]},
"models": {q: {"checkpoint_sha256": v["sha256"], "checkpoint_name": v["url_name"], "N": v["N"], "M": v["M"], "set_sha256": v["set"]}
for q, v in sorted(models.items(), key=lambda kv: int(kv[0]))},
"float_tables_sha256": tables, "points": points,
"integer_decodes": {}, "float_decodes": {}, "timing": []}
xd = os.path.join(work, "xplat")
for f in sorted(os.listdir(xd)) if os.path.isdir(xd) else []:
if f.endswith(".tsv"):
tag = f[:-4]
meta = jload(os.path.join(xd, tag + ".json"))
res = {}
for line in open(os.path.join(xd, f)):
c = line.rstrip("\n").split("\t")
k = f"{os.path.basename(c[0]).split('.')[0]}/{os.path.basename(os.path.dirname(c[0]))}"
res[k] = f"refused:{c[2]}" if c[1] == "REFUSED" else c[1]
rec["integer_decodes"][tag] = {"platform": meta, "results": dict(sorted(res.items()))}
fd = os.path.join(work, "fdecode")
for f in sorted(os.listdir(fd)) if os.path.isdir(fd) else []:
if not f.endswith(".json"):
continue
d = jload(os.path.join(fd, f))
meta = jload(os.path.join(fd, f[:-5] + ".meta")) if os.path.exists(os.path.join(fd, f[:-5] + ".meta")) else {}
rec["float_decodes"][d["tag"]] = {"platform": {**meta, "device": d["device"], "threads": d["threads"], "torch": d["torch"],
"machine": d["machine"], "system": d["system"]},
"tables_sha256": d.get("tables_sha256", {}), "results": d["results"]}
ed = os.path.join(work, "energy")
for f in sorted(os.listdir(ed)) if os.path.isdir(ed) else []:
if f.endswith(".json"):
run = jload(os.path.join(ed, f))
# The child's command line, relative to each host's work area (no home or volume paths).
run["child"] = [a.split("/wai-build/", 1)[1] if "/wai-build/" in a else a for a in run["child"]]
rec["timing"].append(run)
rec["summary"] = summarise(rec)
jdump(rec, dest)
print(json.dumps(rec["summary"]["bd_rate_percent"]["psnr"] | {"per_picture": None}, indent=1))
def main(argv):
if len(argv) < 3:
sys.exit(__doc__)
cmd, work = argv[1], argv[2]
rest = argv[3:]
if cmd == "select":
cmd_select(work, rest[0])
elif cmd == "export":
allow = "--allow-new" in rest
cmd_export(work, [int(a) for a in rest if a != "--allow-new"] or QUALITIES, allow)
elif cmd == "encode":
cmd_encode(work, [int(a) for a in rest] or QUALITIES)
elif cmd == "jobs":
cmd_jobs(work, rest[0] if rest else "-")
elif cmd == "fdecode":
tag = rest[0]
dev = rest[rest.index("--device") + 1] if "--device" in rest else "cpu"
th = int(rest[rest.index("--threads") + 1]) if "--threads" in rest else 0
cmd_fdecode(work, tag, dev, th)
elif cmd == "fserve":
q = int(rest[0])
dev = rest[rest.index("--device") + 1] if "--device" in rest else "cpu"
th = int(rest[rest.index("--threads") + 1]) if "--threads" in rest else 0
ids = rest[rest.index("--ids") + 1].split(",") if "--ids" in rest else []
cmd_fserve(work, q, dev, th, ids)
elif cmd == "metrics":
cmd_metrics(work, rest or ["native"])
elif cmd == "bd":
cmd_bd(work)
elif cmd == "record":
cmd_record(work, rest[0])
else:
sys.exit(__doc__)
if __name__ == "__main__":
main(sys.argv)