Overview
UniFace is designed as a modular, production-ready face analysis library. This page explains the architecture and design principles.
Architecture
UniFace follows a modular architecture where each face analysis task is handled by a dedicated module:
graph TB
subgraph Input
IMG[Image/Frame]
end
subgraph Detection
DET[RetinaFace / SCRFD / YOLOv5Face / YOLOv8Face]
end
subgraph Analysis
REC[Recognition]
LMK[Landmarks]
ATTR[Attributes]
GAZE[Gaze]
HPOSE[Head Pose]
PARSE[Parsing]
SPOOF[Anti-Spoofing]
QUAL[Quality]
MATT[Matting]
PRIV[Privacy]
end
subgraph Tracking
TRK[BYTETracker]
end
subgraph Stores
IDX[FAISS Vector Store]
end
subgraph Output
FACE[Face Objects]
end
IMG --> DET
IMG --> MATT
DET --> REC
DET --> LMK
DET --> ATTR
DET --> GAZE
DET --> HPOSE
DET --> PARSE
DET --> SPOOF
DET --> QUAL
DET --> PRIV
DET --> TRK
REC --> IDX
REC --> FACE
LMK --> FACE
ATTR --> FACE
TRK --> FACE
Design Principles
1. Cross-Platform Inference
UniFace gives you consistent, hardware-accelerated face analysis across macOS, Linux, and Windows from a single API. The optimal hardware backend is selected automatically; models run on ONNX Runtime, with PyTorch for a few optional ones.
- Cross-platform: Same models work on macOS, Linux, Windows
- Hardware acceleration: Automatic selection of optimal provider
- Production-ready: No Python-only dependencies for inference
2. Minimal Dependencies
Core dependencies are kept minimal:
numpy # Array operations
opencv-python # Image processing
scikit-image # Geometric transforms (face alignment)
scipy # Scientific computing
requests # Model download
tqdm # Progress bars
ONNX Runtime is installed separately via the uniface[cpu] or uniface[gpu] extra (see Installation).
3. Simple API
Direct class instantiation:
4. Type Safety
Full type hints throughout:
Module Structure
uniface/
├── detection/ # Face detection (RetinaFace, SCRFD, YOLOv5Face, YOLOv8Face)
├── recognition/ # Face recognition (AdaFace, ArcFace, EdgeFace, MobileFace, SphereFace)
├── tracking/ # Multi-object tracking (BYTETracker)
├── landmark/ # Dense landmarks (Landmark106 = 106 pts, PIPNet = 98 / 68 pts)
├── attribute/ # Age, gender, emotion, race
├── parsing/ # Face semantic segmentation
├── matting/ # Portrait matting (MODNet)
├── gaze/ # Gaze estimation
├── headpose/ # Head pose estimation
├── spoofing/ # Anti-spoofing (MiniFASNet)
├── quality/ # Face image quality assessment (eDifFIQA)
├── privacy/ # Face anonymization
├── stores/ # Vector stores (FAISS)
├── types.py # Dataclasses (Face, GazeResult, HeadPoseResult, etc.)
├── constants.py # Model weights and URLs
├── model_store.py # Model download and caching
├── onnx_utils.py # ONNX Runtime utilities
└── draw.py # Drawing utilities
Workflow
A typical face analysis workflow:
import cv2
from uniface.attribute import AgeGender
from uniface.detection import RetinaFace
from uniface.recognition import ArcFace
# 1. Initialize models
detector = RetinaFace()
recognizer = ArcFace()
age_gender = AgeGender()
# 2. Load image
image = cv2.imread("photo.jpg")
# 3. Detect faces
faces = detector.detect(image)
# 4. Analyze each face
for face in faces:
# Recognition embedding
embedding = recognizer.get_normalized_embedding(image, face.landmarks)
# Attributes
attrs = age_gender.predict(image, face)
print(f"Face: {attrs.sex}, {attrs.age} years")
FaceAnalyzer
For convenience, FaceAnalyzer combines multiple modules:
from uniface.analyzer import FaceAnalyzer
from uniface.attribute import AgeGender, FairFace
from uniface.detection import RetinaFace
from uniface.recognition import ArcFace
detector = RetinaFace()
recognizer = ArcFace()
age_gender = AgeGender()
fairface = FairFace()
analyzer = FaceAnalyzer(
detector,
recognizer=recognizer,
attributes=[age_gender, fairface],
)
faces = analyzer.analyze(image)
for face in faces:
print(f"Age: {face.age}, Gender: {face.sex}")
print(f"Embedding: {face.embedding.shape}")
Model Lifecycle
- First use: Model is downloaded from GitHub releases
- Cached: Stored in
~/.uniface/models/(configurable viaset_cache_dir()orUNIFACE_CACHE_DIR) - Verified: SHA-256 checksum validation
- Loaded: ONNX Runtime session created
- Inference: Hardware-accelerated execution
# Models auto-download on first use
detector = RetinaFace() # Downloads if not cached
# Optionally configure cache location
from uniface.model_store import get_cache_dir, set_cache_dir
set_cache_dir('/data/models')
print(get_cache_dir()) # /data/models
# Or manually pre-download
from uniface.model_store import verify_model_weights
from uniface.constants import RetinaFaceWeights
path = verify_model_weights(RetinaFaceWeights.MNET_V2)
Next Steps
- Inputs & Outputs - Understand data types
- Execution Providers - Hardware acceleration
- Detection Module - Start with face detection
- Image Pipeline Recipe - Complete workflow