Files
DarkRoom/tools/quantise-models.sh
T
dtourolle 06422a07db Offer three denoise networks and a method to choose between them
AI Denoise's Apply switch becomes Method: Bilinear, Fast, Medium, Best,
default Best, so an untouched raw writes nothing and develops through the
mixture. `apply` is still read and never written: 0 is Bilinear, 1 keeps
a network already chosen.

- Best is the mixture of a flat and an edge expert with a learned gate;
  Medium and Fast are students distilled from it. 2.48 s, 0.79 s and
  0.57 s for a 20 MP frame on TensorRT fp16.
- Each network carries its own tile border (256 for the mixture, 192 for
  the students) through `dr_denoise::Shipped` and `TileNet::halo`.
- The file is hashed once at open and each network keys its own cached
  result; Bilinear keeps the result in memory for the way back.
- Each has an .a16w16 sibling for the Hexagon: 0.00 dB on the 6D gate,
  at most 0.11 dB with the noise scaled x0.5 to x4.
- APK BUNDLED 19 -> 23; the PKGBUILD installs all three.
2026-10-04 08:02:25 -04:00

40 lines
1.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Produce the Hexagon's form of each model (docs/dev/inference.md §1.5, §5).
#
# ./tools/quantise-models.sh PHOTO_DIR [MODEL ...]
# ./tools/quantise-models.sh --ranges RANGES.json mosaic-medium-1408
#
# Writes `<stem>.<form>.onnx` beside each canonical file under models/: a QDQ
# graph from QNN's own quantisation config, per-channel weights, in the form
# the engine's `Rung::form` names for that role — A16W8, A16W16 or int8, each
# the narrowest that held the model's accuracy on the tablet. The activation
# ranges come from running the f32 model over the photographs in PHOTO_DIR,
# fed exactly as the app feeds them (letterbox maths, pads, normalisation,
# face crops through the app's own similarity), which is why this is a
# release-time step and not something the device does. With no MODEL, every
# model in the table.
#
# The denoiser is calibrated on noisy mosaics, not photographs: its ranges
# come from darkroom-denoise's precision gate (`--ranges`), computed on a
# smaller tile of the same network — activation ranges do not depend on the
# tile's size, and the tensor names match.
#
# Then measure before shipping: a quantised form is a different network, and
# the numbers in inference.md §1.5 are what each one had to hold.
#
# A venv per run, like fix-face-model-shapes.sh: the tools are not a build
# input and nothing in the tree should have them on its path.
set -euo pipefail
if [ "$#" -lt 1 ]; then
sed -n '2,27p' "$0" >&2
exit 2
fi
WORK="$(mktemp -d -p /var/tmp quantise-models.XXXXXX)"
trap 'rm -rf "${WORK}"' EXIT
echo "==> venv in ${WORK}"
uv venv --python 3.12 "${WORK}/venv" >/dev/null
VIRTUAL_ENV="${WORK}/venv" uv pip install --quiet onnx onnxruntime pillow numpy sympy
exec "${WORK}/venv/bin/python" "$(dirname "$0")/quantise-models.py" "$@"