diff --git a/.gitignore b/.gitignore index e1e30dd..3cf6c27 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Build build/ +build-*/ cmake-build-*/ CMakeCache.txt CMakeFiles/ diff --git a/experiments/dump_lvface_opencv5.sh b/experiments/dump_lvface_opencv5.sh new file mode 100755 index 0000000..8635fc0 --- /dev/null +++ b/experiments/dump_lvface_opencv5.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Fresh LVFace-B embedding dumps (HDF5) for all 9 X-Ray films with the current +# feature/opencv5 build, for the flood-fill GA optimisation. Plain front-half +# (decode -> campos -> detect -> align -> embed); no scene detection (histogram +# cuts is_cut are baked in for flood-fill). Hardware VAAPI decode, no MIGraphX, +# no crash. Serial -- ROCm GPU wedges at concurrency>2-3. +set -uo pipefail + +REPO="/home/dtourolle/Development/scene-actor-extraction" +cd "$REPO" + +ARC="models/LVFace-B_Glint360K.onnx" +BIN="build/dump_embeddings" +LUT="experiments/file-lut.json" +FILMS="experiments/manifests/films.json" +OUT="experiments/dumps/LVFace-B_Glint360K_opencv5" +mkdir -p "$OUT" + +# Persist MIOpen tuning so SCRFD/ArcFace kernel search is paid once, not per film. +export MIOPEN_USER_DB_PATH="$HOME/.cache/miopen-sae" +export MIOPEN_FIND_MODE=NORMAL +mkdir -p "$MIOPEN_USER_DB_PATH" + +mapfile -t SLUGS < <(python3 -c 'import json;[print(f["slug"]) for f in json.load(open("'"$FILMS"'"))]') + +echo "=== LVFace-B dumps (feature/opencv5) — $(date) ===" | tee "$OUT/dump.log" +for slug in "${SLUGS[@]}"; do + movie="$(python3 -c 'import json;print(json.load(open("'"$LUT"'"))["'"$slug"'"])')" + out="$OUT/dump_${slug}.h5" + echo "" | tee -a "$OUT/dump.log" + echo ">>> $slug" | tee -a "$OUT/dump.log" + if [ -f "$out" ]; then echo " exists, skip" | tee -a "$OUT/dump.log"; continue; fi + if [ ! -f "$movie" ]; then echo " SKIP missing: $movie" | tee -a "$OUT/dump.log"; continue; fi + # No --max-decode-fps cap: that cap existed only to stop LVFace dump truncation + # under PARALLEL load (3 concurrent dumps). This runner is serial, so the cap + # just halved throughput for nothing — measured 54s vs 27s per 300s of film, + # identical face counts. Uncapped ~9 min/film vs ~18 min capped. + "$BIN" --movie "$movie" --arcface "$ARC" --out "$out" --fps 1 \ + >"$OUT/${slug}.log" 2>&1 + rc=$? + if [ $rc -ne 0 ] || [ ! -f "$out" ]; then + echo " DUMP FAILED (rc=$rc) — see ${slug}.log" | tee -a "$OUT/dump.log" + else + stats=$(python3 -c 'import h5py,sys +f=h5py.File(sys.argv[1]) +n=f["frames/timestamp_sec"].shape[0] +faces=f["faces/embedding"].shape[0] +cuts=int(f["frames/is_cut"][:].sum()) +print(f"frames={n} faces={faces} cuts={cuts}")' "$out" 2>/dev/null) + echo " ok ($(du -h "$out" | cut -f1), $stats)" | tee -a "$OUT/dump.log" + fi +done +echo "" | tee -a "$OUT/dump.log" +echo "=== DONE — $(date) ===" | tee -a "$OUT/dump.log" diff --git a/experiments/run_xray_lvface_opencv5.sh b/experiments/run_xray_lvface_opencv5.sh new file mode 100755 index 0000000..85a4afd --- /dev/null +++ b/experiments/run_xray_lvface_opencv5.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# Re-benchmark the feature/opencv5 pipeline against Amazon X-Ray, all 9 films, LVFace-B. +# Full end-to-end scene_analyze (decode→detect→scene→embed→match→presence) — NOT a replay, +# because the framework changed enough that old embedding dumps no longer represent the front half. +# Outputs land in experiments/results/xray_opencv5_lvface/ (durable; /tmp gets wiped). +set -uo pipefail + +REPO="/home/dtourolle/Development/scene-actor-extraction" +cd "$REPO" + +ARC="models/LVFace-B_Glint360K.onnx" +GAL="experiments/galleries/gallery_LVFace-B_Glint360K.h5" +OUT="experiments/results/xray_opencv5_lvface" +mkdir -p "$OUT" + +BIN="build/scene_analyze" +LUT="experiments/file-lut.json" +FILMS="experiments/manifests/films.json" + +# film slugs and their xray dirs, from films.json +mapfile -t ROWS < <(python3 -c ' +import json +for f in json.load(open("'"$FILMS"'")): + print(f["slug"] + "\t" + f["xray"]) +') + +echo "=== X-Ray re-benchmark (feature/opencv5, LVFace-B) — $(date) ===" | tee "$OUT/run.log" + +for row in "${ROWS[@]}"; do + slug="${row%%$'\t'*}" + xray="${row#*$'\t'}" + movie="$(python3 -c 'import json,sys; print(json.load(open("'"$LUT"'"))["'"$slug"'"])')" + pred="$OUT/${slug}.json" + + echo "" | tee -a "$OUT/run.log" + echo ">>> $slug" | tee -a "$OUT/run.log" + if [ ! -f "$movie" ]; then + echo " SKIP: movie missing: $movie" | tee -a "$OUT/run.log" + continue + fi + + # Run the full pipeline (serial — ROCm GPU wedges at concurrency>2-3). + "$BIN" --movie "$movie" --arcface "$ARC" --gallery "$GAL" \ + --output "$pred" >"$OUT/${slug}.pipeline.log" 2>&1 + rc=$? + if [ $rc -ne 0 ] || [ ! -f "$pred" ]; then + echo " PIPELINE FAILED (rc=$rc) — see ${slug}.pipeline.log" | tee -a "$OUT/run.log" + continue + fi + echo " pipeline ok" | tee -a "$OUT/run.log" + + # Score against X-Ray, masked to gallery∩GT, 1s grid. + python scripts/validation/sample_eval.py \ + --pred "$pred" --xray "$xray" --gallery "$GAL" --step 1.0 \ + >"$OUT/${slug}.eval.txt" 2>&1 + tail -8 "$OUT/${slug}.eval.txt" | tee -a "$OUT/run.log" +done + +echo "" | tee -a "$OUT/run.log" +echo "=== DONE — $(date) ===" | tee -a "$OUT/run.log"