Answer M1: tract loads both face graphs once their dims are pinned

Neither InsightFace export parses as shipped -- SCRFD fails at its input
node, ArcFace at the first Conv -- which is the same wall dr-segment hit
on YOLO's dynamic export. Both load cleanly with the input dims frozen,
so the pure-Rust runtime holds for the face pipeline too.

tools/fix-face-model-shapes.sh does the freezing, and exists so the
artefact is reproducible rather than a binary someone once produced. It
takes two forms because the two graphs need different ones: ArcFace's
batch is a named dim_param, SCRFD's H and W are dynamic but unnamed.

Also notes YuNet loading with no intervention, which matters for the
licence question in faces.md 2.3.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-26 19:51:02 +02:00
co-authored by Claude Opus 5
parent ec740115b6
commit 72410f39c6
9 changed files with 435 additions and 1 deletions
+43
View File
@@ -0,0 +1,43 @@
[package]
name = "dr-face"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
[dependencies]
thiserror.workspace = true
log.workspace = true
# Inference. `ort` is the API; **tract is the engine** — see the workspace
# manifest, and docs/faces.md §3, for why the C++ ONNX Runtime is not linked.
ort = { workspace = true, optional = true }
ort-tract = { workspace = true, optional = true }
ndarray = { workspace = true, optional = true }
[dev-dependencies]
zune-jpeg.workspace = true
env_logger.workspace = true
# The M1 probe drives `ort` directly so it can print the raw load error.
ort = { workspace = true }
ort-tract = { workspace = true }
[[example]]
name = "probe"
required-features = ["inference"]
[features]
# Nothing on by default, and in particular **no `embedded-model`**: the weights
# are not a build input and never become one (docs/faces.md §2.2). A feature
# flag that *could* embed them is a flag someone eventually sets in a packaging
# script, and the InsightFace grant does not survive that.
default = []
# The ONNX runtime, and the two stages that need it.
#
# Separable because the accuracy of this subsystem lives in `calibrate` and
# `cluster`, which are arithmetic over embeddings with no model in them. They
# must be testable against synthetic embeddings on a machine with no weights on
# it — a test suite that needs a research-licensed download is a test suite
# that does not run in CI.
inference = ["dep:ort", "dep:ort-tract", "dep:ndarray"]