Configuration Reference
UFME is configured via a TOML file (default: config.toml) or environment variables. All thresholds are policy values — they are injected at startup as pure function parameters, never embedded in domain logic.
Optional pipeline stages (age, head pose, deepfake, face attributes, super-resolution) are enabled simply by placing the model file at the configured path. No additional configuration flag is required.
Thresholds
Section titled “Thresholds”Gate thresholds that control accept/reject decisions in the pipeline.
[thresholds]pad_spoof_score = 0.85 # PAD: spoof probability above this → rejected (HTTP 451)mad_morph_score = 0.75 # MAD: morph probability above this → rejected (HTTP 422)quality_min_score = 0.40 # Quality: score below this → rejected (HTTP 422)similarity = 0.45 # Recognition: minimum cosine similarity to report a hitdeepfake_fake_score = 0.50 # Deepfake: fake probability above this → rejected (optional stage)max_head_pose_yaw = 45.0 # Head pose: absolute yaw beyond this → rejected (degrees; optional stage)| Key | Default | Description |
|---|---|---|
thresholds.pad_spoof_score | 0.85 | Spoof probability (0–1). Faces above this are rejected before matching. |
thresholds.mad_morph_score | 0.75 | Morphing probability (0–1). Images above this are rejected at enrolment. |
thresholds.quality_min_score | 0.40 | Minimum quality score (0–1). Images below this are rejected. |
thresholds.similarity | 0.45 | Minimum cosine similarity for a candidate to be returned as a match. |
thresholds.deepfake_fake_score | 0.50 | Fake probability threshold for the optional deepfake detection stage. |
thresholds.max_head_pose_yaw | 45.0 | Maximum absolute yaw (degrees) for the optional head pose gate. Faces beyond this are profile shots, typically unprocessable. |
Model paths
Section titled “Model paths”Paths to ONNX model files. Optional stage models are wired into the pipeline only when the file exists at startup.
[model_paths]scrfd = "models/det_10g.onnx"adaface = "models/w600k_r50.onnx"pad = "models/MiniFASNetV2.onnx"mad = "models/mad_selfmad_hrnet_w18.onnx"quality = "models/ediffiqa_tiny.onnx"age = "models/genderage.onnx" # optional — age estimation stagedeepfake = "models/deepfake_vit_q.onnx" # optional — deepfake detection stagehead_pose = "models/head_pose_resnet18.onnx" # optional — head pose stage + yaw gatesuper_resolution = "models/realesrgan_x4plus.onnx" # optional — super-resolution pre-detect stage| Key | Default | Stage |
|---|---|---|
model_paths.scrfd | models/det_10g.onnx | Detection (required) |
model_paths.adaface | models/w600k_r50.onnx | Recognition (required) |
model_paths.pad | models/MiniFASNetV2.onnx | PAD (required) |
model_paths.mad | models/mad_selfmad_hrnet_w18.onnx | MAD (required) |
model_paths.quality | models/ediffiqa_tiny.onnx | Quality (required) |
model_paths.age | models/genderage.onnx | Age estimation (optional) |
model_paths.deepfake | models/deepfake_vit_q.onnx | Deepfake detection (optional) |
model_paths.head_pose | models/head_pose_resnet18.onnx | Head pose + yaw gate (optional) |
model_paths.super_resolution | models/realesrgan_x4plus.onnx | Super-resolution pre-detect (optional) |
To disable an optional stage, remove or rename the model file. To switch to mask-aware recognition, replace model_paths.adaface with the path to w600k_mbf.onnx.
FAISS index
Section titled “FAISS index”Controls vector search behaviour. Applies to both the local in-process store (development) and the Rust shard cluster (production).
[faiss]shard_count = 4nlist = 16384 # IVF Voronoi cells; ~sqrt(gallery_size)nprobe = 96 # cells probed per querypq_m = 64 # PQ subvectors (64 bytes/vector)pq_nbits = 8 # bits per PQ codelocal_k = 50 # candidates per shard before aggregationcandidate_k = 100 # candidates retained globally for rerankingdeadline_seconds = 0.2 # per-shard gRPC timeoutpartial_result_policy = "annotate" # "reject" | "annotate" | "degrade"compaction_interval_seconds = 3600| Key | Default | Description |
|---|---|---|
faiss.nlist | 16384 | IVF cell count — tune to approximately sqrt(gallery_size) |
faiss.nprobe | 96 | Search breadth — probes ~0.6% of cells at nlist=16384 |
faiss.pq_m | 64 | PQ sub-vectors — 64 bytes/vector (32x compression from 2,048) |
faiss.local_k | 50 | Candidates returned per shard before aggregation |
faiss.candidate_k | 100 | PQ candidates globally retained for exact reranking |
faiss.deadline_seconds | 0.2 | Per-shard gRPC call timeout in seconds |
faiss.partial_result_policy | annotate | How to handle partial shard failures: annotate adds a warning field, reject fails the request, degrade returns partial results silently |
Detection
Section titled “Detection”[detection]confidence_threshold = 0.5nms_threshold = 0.4input_size = [640, 640]Recognition
Section titled “Recognition”[recognition]embedding_dim = 512normalize = true # L2-normalise embeddings before storage and searchInference
Section titled “Inference”[inference]fp16_tensorrt = false # Use TensorRT FP16 when GPU is availableint8_quantisation = false # INT8 quantisation for edge/cost-constrained deploymentsbatch_size = 1 # ONNX Runtime batch size (8 gives ~3.2x speedup vs 1)Pipeline
Section titled “Pipeline”[pipeline]workers = 4 # concurrent pipeline worker coroutinesqueue_size = 128 # async queue depth between stagesServer
Section titled “Server”[server]host = "0.0.0.0"port = 8080log_level = "info" # debug | info | warning | errorEnvironment variable overrides
Section titled “Environment variable overrides”Any config key can be overridden with an environment variable using the pattern UFME_<SECTION>_<KEY> (single underscore, uppercase):
UFME_THRESHOLDS_QUALITY_MIN_SCORE=0.6UFME_THRESHOLDS_PAD_SPOOF_SCORE=0.90UFME_THRESHOLDS_MAX_HEAD_POSE_YAW=30.0UFME_THRESHOLDS_DEEPFAKE_FAKE_SCORE=0.65UFME_MODEL_PATHS_SUPER_RESOLUTION=models/realesrgan_x4plus.onnxUFME_SERVER_PORT=9090UFME_FAISS_NPROBE=128Environment variables take precedence over values in config.toml.