Library / SDK
yakhyo/uniface avatar
yakhyo/uniface

UniFace: One Python API for Fifteen Face Analysis Tasks

UniFace: A Unified Face Analysis Library for Python | Detection, alignment, landmarks, face-mesh, recognition, parsing, gaze, attributes and anti-spoofing under one API.

1,711 stars232 forksPythonMIT

At a glance

What is it?
UniFace bundles detection, recognition, tracking, landmarks, parsing, matting, gaze, head pose, attributes, quality and liveness behind a single FaceAnalyzer call, with ONNX weights fetched and SHA-256 verified on first use. The convenience is real; the cost is a wide dependency surface and a model zoo you still have to choose from.
Who is it for?
Adopt UniFace if you need several face tasks in one Python process and would rather not maintain separate wrappers for RetinaFace, ArcFace and BiSeNet. Do not adopt it if you need a single narrow model behind a stable C ABI, or if you cannot accept a pip install that pulls in ONNX Runtime, OpenCV and FAISS.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The integration tax UniFace is trying to remove

Face pipelines in Python have a familiar shape. You pull a detector from one repository, an alignment model from a second, a recognition embedding model from a third, and each one ships its own preprocessing conventions, its own weight download logic and its own output tensor layout. The glue code is not hard, but it is repetitive and it drifts. UniFace targets exactly that seam. The README describes it as a unified library covering detection, recognition, tracking, landmarks, parsing, gaze estimation, attributes, quality, anti-spoofing, anonymization and a FAISS-backed vector store, and the core promise is that these live behind one API rather than one repository each. The audience is Python engineers building face features into an application: video analytics, identity checks, dataset curation, redaction tooling. It is not aimed at researchers who want to modify training code, because the material describes inference only, with ONNX Runtime as the execution backend and no mention of a training loop.

FaceAnalyzer and the lazy attribute contract

The central object is FaceAnalyzer. It runs detection, alignment and recognition in one call, and additional models are opt-in through a predictors list. The README example constructs FaceAnalyzer(predictors=[FairFace()]) and then iterates over analyzer.analyze(image), printing face.bbox, face.sex, face.age_group and face.embedding.shape. The important detail is the field contract: bbox, confidence, landmarks and embedding are always populated, while age, sex, race, emotion, quality and the face states remain None until you pass the predictor that fills them. That is a sensible design. It keeps the always-on path cheap and makes the cost of each extra model explicit at construction time rather than hidden behind a flag. It also means code that reads face.emotion without registering an emotion predictor will get None rather than an exception, so defensive checks belong in your own code. The model zoo spans six detectors (RetinaFace, SCRFD, CenterFace, YOLOv5-Face, YOLOv8-Face, BlazeFace), five recognition backbones (AdaFace, ArcFace, EdgeFace, MobileFace, SphereFace), three landmark families (2d106det at 106 points, PIPNet at 98 or 68, and a 468 or 478 point 3D face mesh), BiSeNet for 19-class parsing, XSeg masking, MODNet for trimap-free portrait matting, MobileGaze for gaze, a 6D rotation head pose estimator, AffectNet-7 and AffectNet-8 for emotion, FaceAttribNet for eyes, glasses, sunglasses and mask, eDifFIQA in T, S, M and L sizes for quality, and MiniFASNet for liveness. Tracking uses BYTETracker with persistent IDs across video frames. That is a lot of surface area, and the choice of which detector to pair with which recognizer is left to you.

Installation, extras and the first verified download

Installation is a pip extra split by accelerator. The README gives three commands: pip install "uniface[cpu]" for CPU and Apple Silicon, pip install "uniface[gpu]" for NVIDIA CUDA, and pip install --pre "uniface[cpu]" for the latest pre-release. Python 3.10 or newer is required. Weights are not bundled; the README states they download on first use and are verified by SHA-256. That verification step matters operationally. The first run of any predictor touches the network, so air-gapped deployments need a pre-seeding step that the supplied material does not describe. There is also no documented config key or environment variable in the material for redirecting the weight cache, so if you need weights on a read-only filesystem or behind a proxy, plan to inspect the installed package for the download path rather than relying on documented configuration. The pre-release channel exists and v4.0.0rc2 and v4.0.0rc3 both shipped before v4.0.0, which suggests the release cadence is active rather than dormant.

Where the unified abstraction leaks

A single API over fifteen tasks has to pick a lowest common denominator, and the README shows where. The FaceAnalyzer example returns a per-face object with a fixed set of fields, which suits detection and attributes but fits poorly for tasks whose natural output is not per-face: portrait matting produces an alpha matte for the whole image, parsing produces a per-pixel label map, and the FAISS vector store is a collection-level index rather than a per-face result. The material presents those as separate modules with their own docs pages rather than as FaceAnalyzer outputs, which is honest, but it means the unified surface is really a unified import path plus a unified weight-download mechanism, not a unified result type. The other leak is model selection. Fifteen tasks times multiple backbones is a combinatorial space, and the README's task table tells you which models exist without telling you which pairing is sensible. Picking BlazeFace for a recognition pipeline that needs tight alignment crops, or a 478-point mesh when 68 landmarks suffice, is on you. The library will not stop you. Versioning is the third consideration: the jump to 4.0.0 with two release candidates in the preceding week indicates the API is still moving, so pinning an exact version is the safer posture for anything in production.

UniFace against assembling the individual repositories

The obvious alternative is not another unified library but the underlying projects themselves: RetinaFace or SCRFD for detection, ArcFace or AdaFace for recognition, BiSeNet for parsing, MODNet for matting, each installed from its own repository. That approach wins on control. You get the upstream training code, the upstream issue tracker, and the ability to patch a preprocessing step without forking a wrapper. It also lets you ship only the dependencies one model needs, which matters if you are building a container image and every megabyte counts. UniFace wins on the opposite axis: one install, one weight-verification path, one place to look when a tensor shape is wrong, and consistent handling of device selection across CPU, Apple Silicon and CUDA. The practical difference shows up at integration time. With separate repositories you write the glue between detector crops and recognizer inputs yourself, and you own that glue forever. With UniFace you accept the library's glue and its release cadence. Neither is strictly better; the question is whether you would rather maintain three wrappers or track one dependency's breaking changes.

Maintenance cost, licensing and what to check first

UniFace is MIT licensed, which is permissive and places few obligations on how you redistribute it. That covers the library code. It does not automatically cover the pretrained weights, which come from separate upstream projects with their own terms, and the supplied material does not state the licence of any individual checkpoint. If you are shipping a commercial product, verify the terms for each model you actually load rather than assuming the MIT badge on the repository extends to ArcFace or FairFace weights. On maintenance, the practical costs are the ONNX Runtime and OpenCV dependency chain, the FAISS dependency if you use the vector store, and the weight download on first use in every fresh environment. The repository is not archived and the most recent push is dated 2026-09-09, so the project is active. For an evaluation, install uniface[cpu], run the README's FaceAnalyzer snippet on a handful of your own photographs, then add one predictor at a time and confirm each weight file downloads and verifies. That sequence surfaces the two failure modes that matter most: a network path that blocks the weight host, and a predictor whose output fields you assumed were populated when they are still None.

Editorial conclusion

Adopt UniFace if you need several face tasks in one Python process and would rather not maintain separate wrappers for RetinaFace, ArcFace and BiSeNet. Do not adopt it if you need a single narrow model behind a stable C ABI, or if you cannot accept a pip install that pulls in ONNX Runtime, OpenCV and FAISS. Before committing, install uniface[cpu], run FaceAnalyzer on your own images, and check that the weights for the predictors you actually use download and verify cleanly behind your network.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. yakhyo/uniface on GitHub
Community notes

Community notes