fix(dnn): wire the int8 redirect into --tiny-model and stop vmaf_tiny_v3.int8 double-scaling - #1320
fix(dnn): wire the int8 redirect into --tiny-model and stop vmaf_tiny_v3.int8 double-scaling#1320lusoris wants to merge 9 commits into
Conversation
4919f64 to
bc9d6ad
Compare
The int8 redirect added earlier on this branch turned a working
`--tiny-model model/tiny/nr_metric_v1.onnx` invocation into a hard
`-EIO`: the sidecar declares `quant_mode: dynamic`, so the loader
redirected to `nr_metric_v1.int8.onnx`, which clears the size cap and
the op allowlist but fails ORT session creation on any ONNX Runtime
build without a `ConvInteger` kernel ("Could not find an implementation
for ConvInteger(10)"). `core/test/dnn/test_cli.sh` failed on exactly
that; it passes against master's loader.
ADR-1032's "better degraded than dead" rule covers this for the same
reason it covers a missing int8 file, so both loader twins now retry the
fp32 baseline once when `vmaf_ort_open()` fails on a redirected path.
`vmaf_ort_open()` leaves the out-parameter untouched on error, so the
retry cannot leak the failed session. Kept in both `dnn_api.c` and
`dnn_attach_api.c`, and the AGENTS.md invariant now pins that the
fallback has two triggers.
Also:
- `core/test/dnn/test_vmaf_use_tiny_model.c`: split the new redirect
test into `stage_redirect_triple()` / `expect_tiny_attach()` so no
function exceeds the `readability-function-size` branch budget, and
bracket the added block with the tree's cited
`NOLINTBEGIN(modernize-use-nullptr)` (ADR-1138) so the file stays at
its ADR-1142 ratchet baseline of 51 rather than growing to 62.
- `docs/usage/cli.md`, `docs/ai/quantization.md`: document the second
fallback trigger, and correct the claim that the CLI has a
`--log-level debug` flag — it does not; the binary runs at
`VMAF_LOG_LEVEL_INFO` and only API callers can see the fallback line.
- `docs/state.md`: the two closed rows and the opened row now cite
`PR #1320` instead of the branch name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bc9d6ad to
335850f
Compare
The int8 redirect added earlier on this branch turned a working
`--tiny-model model/tiny/nr_metric_v1.onnx` invocation into a hard
`-EIO`: the sidecar declares `quant_mode: dynamic`, so the loader
redirected to `nr_metric_v1.int8.onnx`, which clears the size cap and
the op allowlist but fails ORT session creation on any ONNX Runtime
build without a `ConvInteger` kernel ("Could not find an implementation
for ConvInteger(10)"). `core/test/dnn/test_cli.sh` failed on exactly
that; it passes against master's loader.
ADR-1032's "better degraded than dead" rule covers this for the same
reason it covers a missing int8 file, so both loader twins now retry the
fp32 baseline once when `vmaf_ort_open()` fails on a redirected path.
`vmaf_ort_open()` leaves the out-parameter untouched on error, so the
retry cannot leak the failed session. Kept in both `dnn_api.c` and
`dnn_attach_api.c`, and the AGENTS.md invariant now pins that the
fallback has two triggers.
Also:
- `core/test/dnn/test_vmaf_use_tiny_model.c`: split the new redirect
test into `stage_redirect_triple()` / `expect_tiny_attach()` so no
function exceeds the `readability-function-size` branch budget, and
bracket the added block with the tree's cited
`NOLINTBEGIN(modernize-use-nullptr)` (ADR-1138) so the file stays at
its ADR-1142 ratchet baseline of 51 rather than growing to 62.
- `docs/usage/cli.md`, `docs/ai/quantization.md`: document the second
fallback trigger, and correct the claim that the CLI has a
`--log-level debug` flag — it does not; the binary runs at
`VMAF_LOG_LEVEL_INFO` and only API callers can see the fallback line.
- `docs/state.md`: the two closed rows and the opened row now cite
`PR #1320` instead of the branch name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
335850f to
e921ff8
Compare
The int8 redirect added earlier on this branch turned a working
`--tiny-model model/tiny/nr_metric_v1.onnx` invocation into a hard
`-EIO`: the sidecar declares `quant_mode: dynamic`, so the loader
redirected to `nr_metric_v1.int8.onnx`, which clears the size cap and
the op allowlist but fails ORT session creation on any ONNX Runtime
build without a `ConvInteger` kernel ("Could not find an implementation
for ConvInteger(10)"). `core/test/dnn/test_cli.sh` failed on exactly
that; it passes against master's loader.
ADR-1032's "better degraded than dead" rule covers this for the same
reason it covers a missing int8 file, so both loader twins now retry the
fp32 baseline once when `vmaf_ort_open()` fails on a redirected path.
`vmaf_ort_open()` leaves the out-parameter untouched on error, so the
retry cannot leak the failed session. Kept in both `dnn_api.c` and
`dnn_attach_api.c`, and the AGENTS.md invariant now pins that the
fallback has two triggers.
Also:
- `core/test/dnn/test_vmaf_use_tiny_model.c`: split the new redirect
test into `stage_redirect_triple()` / `expect_tiny_attach()` so no
function exceeds the `readability-function-size` branch budget, and
bracket the added block with the tree's cited
`NOLINTBEGIN(modernize-use-nullptr)` (ADR-1138) so the file stays at
its ADR-1142 ratchet baseline of 51 rather than growing to 62.
- `docs/usage/cli.md`, `docs/ai/quantization.md`: document the second
fallback trigger, and correct the claim that the CLI has a
`--log-level debug` flag — it does not; the binary runs at
`VMAF_LOG_LEVEL_INFO` and only API callers can see the fallback line.
- `docs/state.md`: the two closed rows and the opened row now cite
`PR #1320` instead of the branch name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The int8 redirect added earlier on this branch turned a working
`--tiny-model model/tiny/nr_metric_v1.onnx` invocation into a hard
`-EIO`: the sidecar declares `quant_mode: dynamic`, so the loader
redirected to `nr_metric_v1.int8.onnx`, which clears the size cap and
the op allowlist but fails ORT session creation on any ONNX Runtime
build without a `ConvInteger` kernel ("Could not find an implementation
for ConvInteger(10)"). `core/test/dnn/test_cli.sh` failed on exactly
that; it passes against master's loader.
ADR-1032's "better degraded than dead" rule covers this for the same
reason it covers a missing int8 file, so both loader twins now retry the
fp32 baseline once when `vmaf_ort_open()` fails on a redirected path.
`vmaf_ort_open()` leaves the out-parameter untouched on error, so the
retry cannot leak the failed session. Kept in both `dnn_api.c` and
`dnn_attach_api.c`, and the AGENTS.md invariant now pins that the
fallback has two triggers.
Also:
- `core/test/dnn/test_vmaf_use_tiny_model.c`: split the new redirect
test into `stage_redirect_triple()` / `expect_tiny_attach()` so no
function exceeds the `readability-function-size` branch budget, and
bracket the added block with the tree's cited
`NOLINTBEGIN(modernize-use-nullptr)` (ADR-1138) so the file stays at
its ADR-1142 ratchet baseline of 51 rather than growing to 62.
- `docs/usage/cli.md`, `docs/ai/quantization.md`: document the second
fallback trigger, and correct the claim that the CLI has a
`--log-level debug` flag — it does not; the binary runs at
`VMAF_LOG_LEVEL_INFO` and only API callers can see the fallback line.
- `docs/state.md`: the two closed rows and the opened row now cite
`PR #1320` instead of the branch name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
e921ff8 to
328b1f3
Compare
The rebase onto master produced two Recently-closed rows for each of T-TINY-V3-INT8-SIDECAR-MISSING-ONNX-HAS-SCALER-2026-09-04 and T-DNN-ATTACH-INT8-REDIRECT-MISSING-2026-09-04, which failed the ADR-0165 uniqueness gate in Pre-Commit. The two copies of each differed only in the reference column: one cited the branch name, the other cited PR #1320. Kept the PR citation -- a branch name is precisely the placeholder reference that state-md-touch-check.sh's placeholder-ref hardening rejects, and it stops meaning anything once the branch is deleted. check-state-md-rows: OK (373 rows, no duplicate ids). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Cleared three of the four failures; the fourth needs a test I'd rather flag than guess at. Fixed and pushed:
Still failing — Coverage Gate, and it is this PR's own new code: Every other critical file passes. The 1-point miss is the int8→fp32 retry branch this PR adds to if (rc < 0 && load_path != onnx_path) {
load_path = onnx_path;
rc = vmaf_ort_open(&s->ort, onnx_path, cfg);
}Why the existing test does not cover it. The mechanism to test it already exists: Holding this PR in the merge train meanwhile so it stops blocking the window — it has held it for about an hour across four CI rounds. |
Pull request was converted to draft
f14afde to
df68949
Compare
The int8 redirect added earlier on this branch turned a working
`--tiny-model model/tiny/nr_metric_v1.onnx` invocation into a hard
`-EIO`: the sidecar declares `quant_mode: dynamic`, so the loader
redirected to `nr_metric_v1.int8.onnx`, which clears the size cap and
the op allowlist but fails ORT session creation on any ONNX Runtime
build without a `ConvInteger` kernel ("Could not find an implementation
for ConvInteger(10)"). `core/test/dnn/test_cli.sh` failed on exactly
that; it passes against master's loader.
ADR-1032's "better degraded than dead" rule covers this for the same
reason it covers a missing int8 file, so both loader twins now retry the
fp32 baseline once when `vmaf_ort_open()` fails on a redirected path.
`vmaf_ort_open()` leaves the out-parameter untouched on error, so the
retry cannot leak the failed session. Kept in both `dnn_api.c` and
`dnn_attach_api.c`, and the AGENTS.md invariant now pins that the
fallback has two triggers.
Also:
- `core/test/dnn/test_vmaf_use_tiny_model.c`: split the new redirect
test into `stage_redirect_triple()` / `expect_tiny_attach()` so no
function exceeds the `readability-function-size` branch budget, and
bracket the added block with the tree's cited
`NOLINTBEGIN(modernize-use-nullptr)` (ADR-1138) so the file stays at
its ADR-1142 ratchet baseline of 51 rather than growing to 62.
- `docs/usage/cli.md`, `docs/ai/quantization.md`: document the second
fallback trigger, and correct the claim that the CLI has a
`--log-level debug` flag — it does not; the binary runs at
`VMAF_LOG_LEVEL_INFO` and only API callers can see the fallback line.
- `docs/state.md`: the two closed rows and the opened row now cite
`PR #1320` instead of the branch name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`model/tiny/vmaf_tiny_v3.int8.onnx` bakes the StandardScaler into the graph as `Sub` / `Div` Constant nodes, but its sidecar omitted `"onnx_has_scaler": true`. `core/src/libvmaf.c` therefore normalised the canonical-6 feature vector a second time before inference. Measured on the Netflix `src01_hrc00/hrc01_576x324` pair (48 frames, CPU backend): pooled `vmaf_tiny_model` mean 16.020865 without the field vs 71.952113 with it, against an fp32 `vmaf_tiny_v3.onnx` baseline of 72.359458. Per-frame PLCC vs fp32 goes 0.975443 -> 0.999876 (drop 0.000124, inside the sidecar's declared 0.01 budget). Adds a consistency gate over every `model/tiny/*.int8.onnx`: a graph containing both `Sub` and `Div` must have a companion sidecar declaring `"onnx_has_scaler": true`. Enforced in `core/test/dnn/test_registry.sh`, `python/test/model_registry_schema_test.py`, and `ai/scripts/validate_model_registry.py`; detection prefers the `onnx` parser and falls back to a protobuf byte scan on legs without it. Refs #1242
`--all` and the positional form both resolve through
`model/tiny/registry.json`: the positional path must live under
`model/tiny/`, and the PLCC-drop budget comes from that entry's
`quant_accuracy_budget_plcc`. A model that is not committed yet — PTQ or
QAT scratch output, a CI smoke artifact, a release candidate — has
neither, which is Research-2029 gap 5.
`--fp32 PATH --int8 PATH` measures an explicit pair and never loads the
registry; `--budget` supplies the drop budget (default 0.01, the same
registry-wide default) and `--id` labels the row. The overrides are
rejected alongside `--all` or a positional path (exit 2); exit codes are
otherwise unchanged.
Verified against the shipped v3 pair in the vmaf-dev-mcp container:
measure_quant_drop.py --fp32 model/tiny/vmaf_tiny_v3.onnx \
--int8 model/tiny/vmaf_tiny_v3.int8.onnx --budget 0.002
[PASS] vmaf_tiny_v3 mode=override PLCC=0.999880 drop=0.000120 \
budget=0.0020 worst_abs=2.2058
Refs #1242
`_build_train_loader_factory` handed every config to `VmafTrainDataModule`, which only materialises rank-2 tabular rows (the canonical-6 feature vector plus a scalar MOS). A 2D CNN — `learned_filter`, `nr_metric` — needs image batches and fails inside its first `Conv2d`. `ai/configs/learned_filter_v1_qat.yaml` only appeared to work because its parquet cache is uncommitted, so the missing-cache branch silently downgraded the run to `--smoke` and trained nothing. Research-2029 §5 gap 4. The loader is now selected by the rank of `qat.input_shape` — the same shape `_build_example_inputs` traces with, so the loader and the FX trace cannot disagree. Rank 2 keeps the datamodule; rank 4 reads an `.npz` with `x` (N, C, H, W) and `y`; any other rank downgrades to smoke mode with a message on stderr rather than failing deep in a forward pass. The archive is validated when the loader is built, so a malformed cache fails before the fp32 warm-start burns an epoch. Refs #1242
Each placeholder is replaced with the audited state of the tree rather than a restated plan. sidecar-online-training.md: the "no stability gate ... planned per Research-0733 §3.4" line becomes a Checkpoint quarantine section that tabulates §3.4 element by element. Atomic checkpoint writes and the `.sha256` file exist (`ai/sidecar/sgd_ema.py`, `online_trainer.py`); the stability gate, the fixture set, the `unstable` tag, `spec.versionPolicy`, `stability_plcc_delta`, automatic rollback, and node-side digest verification do not — `cmd/vmafx-node/` contains no SHA-256 check at all. Every committed checkpoint is picked up unvetted. extractor-template.md: the large-N row called `feature_transnet_v2.c` "planned". It shipped, as `core/src/feature/transnet_v2.c`. The new subsection documents the 100-slot ring buffer, the `[1, 100, 3, 27, 48]` tensor, the fact that the suggested strided submission was not taken (the network runs once per frame), the ~50-frame warm-up, and that per-shot aggregation is backlog-only. inference.md: "planned: self-hosted runner" was wrong in both directions. Two `gpu-full` jobs exist, but the only registered runner is labelled `sycl-arc` and `GPU_COVERAGE_ENABLED` is unset, so neither can be scheduled; and neither would cover the cross-device tiny-AI bounds this page quotes. Opened as T-GPU-RUNNER-LABEL-MISMATCH-2026-09-05 in docs/state.md. Refs #1242
The fp32 sidecar carries an `int8_sha256` for its quantised sibling, but neither `vmaf_dnn_session_open` nor `vmaf_use_tiny_model` parses it — the only load-time gates are the 50 MB size cap and the op allowlist. Integrity of the shipped artefacts is enforced by the registry gates and by `--tiny-model-verify`, not by the loader. Adding a digest check would introduce a third outcome (mismatch) that ADR-1032's fp32-fallback semantics do not define, and would have to land in both twins at once, so it needs its own ADR. Documented in docs/ai/quantization.md and pinned as an invariant in core/src/dnn/AGENTS.md rather than left as an unstated gap. Refs #1242
Wiring the int8 redirect inline pushed `vmaf_use_tiny_model` to 106 lines and introduced two clang-tidy findings the earlier commit did not clear: `bugprone-redundant-branch-condition` on an `if (have_meta)` nested inside a branch already guarded by `have_meta &&`, and a `clang-analyzer-deadcode.DeadStores` on the `rc = 0` that reset the fallback path. The redirect is now `resolve_quantised_load_path()` (out-param for the resolved path, so the sentinel `NULL` return goes away too), the sidecar load is `load_optional_sidecar()`, and the shape query plus `vmaf_ctx_dnn_attach` are `attach_opened_session()`. The entry point is 54 lines — under both the 60-line threshold and master's pre-existing 63. clang-tidy on the file now reports only the two `modernize-use-nullptr` warnings that master already carries. Behaviour is unchanged: the 13-test meson `dnn` suite passes with `-Denable_dnn=enabled` and ONNX Runtime in the container, `test_vmaf_use_tiny_model` included. All three helpers sit inside the `#if VMAF_HAVE_DNN` guard, so the ADR-0374 disabled-build stub is untouched. Refs #1242
The int8 redirect added earlier on this branch turned a working
`--tiny-model model/tiny/nr_metric_v1.onnx` invocation into a hard
`-EIO`: the sidecar declares `quant_mode: dynamic`, so the loader
redirected to `nr_metric_v1.int8.onnx`, which clears the size cap and
the op allowlist but fails ORT session creation on any ONNX Runtime
build without a `ConvInteger` kernel ("Could not find an implementation
for ConvInteger(10)"). `core/test/dnn/test_cli.sh` failed on exactly
that; it passes against master's loader.
ADR-1032's "better degraded than dead" rule covers this for the same
reason it covers a missing int8 file, so both loader twins now retry the
fp32 baseline once when `vmaf_ort_open()` fails on a redirected path.
`vmaf_ort_open()` leaves the out-parameter untouched on error, so the
retry cannot leak the failed session. Kept in both `dnn_api.c` and
`dnn_attach_api.c`, and the AGENTS.md invariant now pins that the
fallback has two triggers.
Also:
- `core/test/dnn/test_vmaf_use_tiny_model.c`: split the new redirect
test into `stage_redirect_triple()` / `expect_tiny_attach()` so no
function exceeds the `readability-function-size` branch budget, and
bracket the added block with the tree's cited
`NOLINTBEGIN(modernize-use-nullptr)` (ADR-1138) so the file stays at
its ADR-1142 ratchet baseline of 51 rather than growing to 62.
- `docs/usage/cli.md`, `docs/ai/quantization.md`: document the second
fallback trigger, and correct the claim that the CLI has a
`--log-level debug` flag — it does not; the binary runs at
`VMAF_LOG_LEVEL_INFO` and only API callers can see the fallback line.
- `docs/state.md`: the two closed rows and the opened row now cite
`PR #1320` instead of the branch name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ator graph_bakes_scaler() guarded onnx.load() against the library being absent but not against the file being unparseable. On a corrupt or non-ONNX blob onnx.load raises google.protobuf.message.DecodeError, which propagated out of _consistency_check() and aborted the whole validation run. That is the wrong failure mode twice over. A validator exists to report problems, not to raise on them; and raising here discards every other finding it had collected -- including the sha256 mismatch that is usually the actual reason the file is bad. test_consistency_check_int8_sha_mismatch writes b"int8payload" precisely to assert that mismatch, and got a DecodeError instead. Degrade to the same length-prefixed byte scan the no-onnx-installed path already uses. On arbitrary bytes it finds no Sub/Div markers and answers False, so _consistency_check finishes and reports the real error. Verified both paths: ai/tests/test_validate_model_registry_unit.py is 22/22, and with a stub onnx module whose load() raises DecodeError (the CI condition, which cannot be reproduced in a venv without onnx installed) the helper returns False rather than propagating. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
df68949 to
4aa0b92
Compare
Summary
Completes the int8 half of epic #1242.
vmaf_use_tiny_model()— the entry point behind--tiny-model— ignored the sidecar'squant_modeand always opened the fp32 graph; it now mirrorsvmaf_dnn_session_open(), redirecting to<stem>.int8.onnxand falling back to fp32 per ADR-1032 with a debug log line.model/tiny/vmaf_tiny_v3.int8.jsonshipped without"onnx_has_scaler": truealthough the graph bakes the StandardScaler, solibvmaf.cdouble-scaled the canonical-6 vector: on the Netflixsrc01_hrc00/hrc01_576x324pair (48 frames, CPU) pooledvmaf_tiny_modelwas 16.020865 and is now 71.952113 against an fp32 baseline of 72.359458, with per-frame PLCC vs fp32 going 0.975443 to 0.999876. A scaler/sidecar consistency gate over everymodel/tiny/*.int8.onnxnow runs in three places so this cannot recur. On the Python side,measure_quant_drop.pygained--fp32/--int8/--budget/--idso an uncommitted model can be gated without a registry entry (verifiedPLCC=0.999880 drop=0.000120on the shipped v3 pair), andqat_train.pynow picks its training loader from the rank ofqat.input_shape— rank-4 configs likelearned_filter_v1_qat.yamlpreviously could not train at all, because every config went to the tabular datamodule and the missing-cache branch silently downgraded the run to--smoke. The threedocs/ai/placeholders (#1242's last docs task) are replaced with the audited state of the tree rather than restated plans. Verification: mesondnnsuite 13/13 with-Denable_dnn=enabled+ ONNX Runtime in the container, Netflix golden gate 271 passed / 12 skipped / 0 failed, 40 Python tests green. Two things are deliberately not here and are recorded rather than half-wired: the loader still does not verifyint8_sha256(documented indocs/ai/quantization.mdand pinned incore/src/dnn/AGENTS.md— a digest mismatch is a third outcome ADR-1032 does not define, so it needs its own ADR), and the discovery that the twogpu-fullCI jobs can never be scheduled is filed asT-GPU-RUNNER-LABEL-MISMATCH-2026-09-05indocs/state.mdrather than fixed here.Follow-up fix on this branch: the redirect must not fail an invocation that worked
The first cut of the redirect only fell back to fp32 when the int8 file was
missing or failed the op allowlist. That is not the only way an int8 graph can
be unusable:
model/tiny/nr_metric_v1.jsondeclaresquant_mode: "dynamic",so
--tiny-model model/tiny/nr_metric_v1.onnxnow redirected tonr_metric_v1.int8.onnx— which clears the size cap and the allowlist and thenfails ORT session creation with
-EIOandCould not find an implementation for ConvInteger(10)on any ONNX Runtime build without that kernel.core/test/dnn/test_cli.shcaught it: it fails with this branch's loader andpasses with
master's. Both twins now retry the fp32 baseline once whenvmaf_ort_open()fails on a redirected path (vmaf_ort_open()leaves itsout-parameter untouched on error, so the retry cannot leak the failed session).
meson test -C build-cpu --suite dnnis 13/13 again.Type
fix— bug fix — int8 redirect missing fromvmaf_use_tiny_model(), and a shipped sidecar that double-scaled its features.Checklist
make format && make lintis green locally (pre-commit on every touched file;clang-tidy -p core/build core/src/dnn/dnn_attach_api.creports only the twomodernize-use-nullptrwarnings master already carries — the function-size, redundant-branch-condition and dead-store findings the first draft introduced were refactored away).meson test -C /tmp/build-dnn --suite dnn13/13 OK with-Denable_dnn=enabled;pytest ai/tests/test_measure_quant_drop_unit.py ai/tests/test_qat_train_loader.py29 passed / 4 skipped;pytest python/test/model_registry_schema_test.py11 passed / 1 xfailed;bash core/test/dnn/test_registry.shandpython ai/scripts/validate_model_registry.pyboth OK on 26 entries.docs/ai/quantization.md,docs/ai/inference.md,docs/ai/extractor-template.md,docs/ai/sidecar-online-training.md,docs/usage/cli.md.dnn_attach_api.canddnn_api.care twins and both are edited here: the redirect logic and the two-trigger fp32 fallback are identical in each, andcore/src/dnn/AGENTS.mdpins that they must stay so. No new C source files. No breaking change — the redirect only fires for sidecars declaringquant_mode != fp32, which no default model does. No ADR: ADR-1032's fallback semantics are applied to a failure mode it did not enumerate, not changed; the alternative (fail loudly on an unopenable int8 graph) would regress--tiny-modelinvocations that work onmastertoday, so there is no second reasonable option to weigh.Bug-status hygiene (ADR-0165)
docs/state.md— closedT-DNN-ATTACH-INT8-REDIRECT-MISSING-2026-09-04andT-TINY-V3-INT8-SIDECAR-MISSING-ONNX-HAS-SCALER-2026-09-04(Recently closed, with the measured before/after scores); openedT-GPU-RUNNER-LABEL-MISMATCH-2026-09-05(Open bugs).Netflix golden-data gate (ADR-0024)
assertAlmostEqual(...)score in the Netflix golden Python tests.Deep-dive deliverables (ADR-0108)
docs/research/2029-int8-static-qat-readiness.md, already landed onmasterin PR docs(ai): int8 static PTQ / QAT readiness smoke for the 1.0.0 retrain #1293; this PR implements its findings (§5 gaps 1, 2, 4, 5) and adds no new research.docs/ai/quantization.md§Mode selection (redirect vs. explicit-path alternatives), backed bydocs/research/2029-int8-static-qat-readiness.md§2 and §6 already onmaster.AGENTS.mdinvariant note —core/src/dnn/AGENTS.md§"Invariant — int8 loader redirect and scaler declaration contract"changelog.d/fixed/vmaf-tiny-v3-int8-scaler.md,changelog.d/fixed/dnn-attach-int8-redirect.md,changelog.d/added/measure-quant-drop-path-overrides.md,changelog.d/added/qat-train-4d-image-loader.md,changelog.d/changed/docs-ai-gaps-1242.mddocs/rebase-notes.mdentryReproducer
Known follow-ups
int8_sha256. Documented indocs/ai/quantization.mdand pinned as an invariant incore/src/dnn/AGENTS.md; adding it needs an ADR because a digest mismatch is a third outcome ADR-1032's fp32-fallback semantics do not define, and it would have to land in both loader twins at once.T-GPU-RUNNER-LABEL-MISMATCH-2026-09-05(docs/state.md, Open bugs): theCoverage GPU (advisory)andSYCL float_ssim Parityjobs targetruns-on: [self-hosted, linux, gpu-full], but the only registered runner is labelledsycl-arcandGPU_COVERAGE_ENABLEDis unset, so neither can be scheduled. No CI job covers tiny-AI cross-device parity at all.docs/ai/inference.mdnow records this instead of "planned: self-hosted runner"; the CI fix is a separate change.quant_format=QuantFormat.QDQinptq_static.py/qat_train.py(tracked asT-AI-PTQ-STATIC-QUANT-FORMAT-UNPINNED-2026-09-03), and the end-to-end VMAF delta gate.🤖 Generated with Claude Code