#!/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-hq-1408 # # Writes `.
.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" "$@"