Files
scene-actor-extraction/scripts/build_trt_engines.sh
T
dtourolleandClaude Opus 5 458116f118 fix(trt): drop explicit shapes for static TransNetV2; gallery over-fetch + dedup
trtexec rejects --minShapes/--optShapes/--maxShapes for a fully static model
("Static model does not take explicit shapes"). TransNetV2's input is fixed at
1x100x27x48x3, so the shape comes from the model itself.

Gallery build now over-fetches TMDB/Wikidata candidates by a configurable
factor: near-duplicate stills (the same photo at different crops or
resolutions) are discarded after embedding, so downloading exactly
images_per_actor left actors short of that many *distinct* embeddings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 17:32:08 +02:00

97 lines
3.7 KiB
Bash
Executable File
Raw 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.
#!/usr/bin/env bash
# Pre-build TensorRT engines for ArcFace and SCRFD with the same shape profiles
# the runtime nodes use. First-run ORT engine builds take 3090 s per model and
# block the pipeline; this script does it offline so cold starts are instant.
#
# Profiles must match src/arcface_embedder.hpp and src/scrfd_decoder.hpp:
# ArcFace : min=1x3x112x112 opt=Nx3x112x112 max=Nx3x112x112 (N = embed batch)
# SCRFD : 1x3x640x640 (fixed; we letterbox to this)
# TransNetV2 : 1x100x27x48x3 (fixed; scene detector window)
#
# Input tensor names are read from each ONNX model at runtime rather than
# hardcoded, since they differ between models (LVFace-B: "data", arcface_r18:
# "input", arcface_w600k_{r50,mbf}: "input.1").
#
# These trtexec-built engines are *not* picked up by the ORT TRT EP cache —
# ORT uses its own engine format. The point of this script is:
# (a) sanity-check that the ONNX models build under TRT at all;
# (b) measure pure inference latency without ORT overhead.
# Run scene_analyze normally and ORT will populate ./trt_cache itself.
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
MODELS="$ROOT/models"
OUT="$ROOT/trt_cache"
mkdir -p "$OUT"
EMBED_BATCH="${EMBED_BATCH:-4}"
ARCFACE_MODEL="${ARCFACE_MODEL:-$MODELS/arcface_w600k_r50.onnx}"
SCRFD_MODEL="${SCRFD_MODEL:-$MODELS/scrfd_500m_bnkps.onnx}"
SCENE_MODEL="${SCENE_MODEL:-$MODELS/transnetv2.onnx}"
run() { echo "+ $*"; "$@"; }
# The input tensor name is not the same across models — LVFace-B uses "data",
# arcface_r18 uses "input", and arcface_w600k_{r50,mbf} use "input.1". A
# hardcoded name makes trtexec fail with "Cannot find input tensor with name
# ...", so read it from the model instead.
input_name() {
python3 - "$1" <<'PY'
import sys
try:
import onnxruntime as ort
except ImportError:
sys.exit("onnxruntime is required to read the model's input name")
sess = ort.InferenceSession(sys.argv[1], providers=["CPUExecutionProvider"])
print(sess.get_inputs()[0].name)
PY
}
ARCFACE_IN="$(input_name "$ARCFACE_MODEL")"
SCRFD_IN="$(input_name "$SCRFD_MODEL")"
echo "== ArcFace == (input tensor: $ARCFACE_IN)"
run trtexec \
--onnx="$ARCFACE_MODEL" \
--fp16 \
--minShapes="$ARCFACE_IN":1x3x112x112 \
--optShapes="$ARCFACE_IN":${EMBED_BATCH}x3x112x112 \
--maxShapes="$ARCFACE_IN":${EMBED_BATCH}x3x112x112 \
--saveEngine="$OUT/arcface.$(basename "$ARCFACE_MODEL" .onnx).b${EMBED_BATCH}.fp16.engine" \
--useCudaGraph
echo
echo "== SCRFD == (input tensor: $SCRFD_IN)"
run trtexec \
--onnx="$SCRFD_MODEL" \
--fp16 \
--minShapes="$SCRFD_IN":1x3x640x640 \
--optShapes="$SCRFD_IN":1x3x640x640 \
--maxShapes="$SCRFD_IN":1x3x640x640 \
--saveEngine="$OUT/scrfd.$(basename "$SCRFD_MODEL" .onnx).640.fp16.engine" \
--useCudaGraph
if [[ -f "$SCENE_MODEL" ]]; then
echo
echo "== TransNetV2 (scene detector) =="
# Fixed 1x100x27x48x3 window. The raw-TRT scene detector backend loads this
# engine directly via --scene-detector-engine; the ORT-TRT EP builds its own.
# No --*Shapes here: TransNetV2's input is fully static (1x100x27x48x3
# with no dynamic dimensions), and TensorRT rejects explicit shape
# profiles for such a model — "Static model does not take explicit shapes
# since the shape of inference tensors will be determined by the model
# itself". The shape comes from the model.
run trtexec \
--onnx="$SCENE_MODEL" \
--fp16 \
--saveEngine="$OUT/transnetv2.100x27x48.fp16.engine" \
--useCudaGraph
else
echo
echo "== TransNetV2 skipped (no $SCENE_MODEL) =="
fi
echo
echo "Engines saved under: $OUT"
echo "Look for 'mean: ... ms' in each section for per-call latency."