Skip to main content

MLX-UniFace: Blazing-Fast Face Analysis on Apple Silicon

License Python PyPI Apple Silicon

MLX-UniFace is a high-performance face analysis library optimized for Apple Silicon. It provides face detection, recognition, landmark detection, and attribute analysis with native MLX acceleration.

This is a fork of yakhyo/uniface with added MLX backend support for Apple Silicon Macs.

alt text

Why MLX-UniFace?

Feature MLX-UniFace Original UniFace
Apple Silicon Native Yes (MLX) ONNX via CoreML
Unified Memory Yes No
Backend MLX + ONNX fallback ONNX only
M1/M2/M3/M4 Optimized Yes Partial

Performance Benefits on Apple Silicon

  • Unified Memory: No CPU-GPU data transfer overhead
  • Native Acceleration: Optimized for Apple's Neural Engine and GPU
  • Lazy Evaluation: Automatic graph optimization
  • Numerical Parity: Identical results to ONNX (correlation = 1.0)

Installation

For Apple Silicon (Recommended)

pip install mlx-uniface

With MLX Backend (Explicit)

pip install mlx-uniface[mlx]

With ONNX Fallback

pip install mlx-uniface[onnx]

Install from Source

git clone https://github.com/CodeWithBehnam/mlx-uniface.git
cd mlx-uniface
pip install -e ".[mlx]"

Quick Start

Face Detection

import cv2
from uniface import RetinaFace

# Automatically uses MLX on Apple Silicon
detector = RetinaFace()

image = cv2.imread("image.jpg")
faces = detector.detect(image)

for face in faces:
    bbox = face['bbox']  # [x1, y1, x2, y2]
    confidence = face['confidence']
    landmarks = face['landmarks']  # 5-point landmarks
    print(f"Face detected with confidence: {confidence:.2f}")

Face Recognition

from uniface import ArcFace, RetinaFace
from uniface import compute_similarity

detector = RetinaFace()
recognizer = ArcFace()

# Detect and extract embeddings
faces1 = detector.detect(image1)
faces2 = detector.detect(image2)

embedding1 = recognizer.get_normalized_embedding(image1, faces1[0]['landmarks'])
embedding2 = recognizer.get_normalized_embedding(image2, faces2[0]['landmarks'])

# Compare faces
similarity = compute_similarity(embedding1, embedding2)
print(f"Similarity: {similarity:.4f}")

Age & Gender Detection

from uniface import RetinaFace, AgeGender

detector = RetinaFace()
age_gender = AgeGender()

faces = detector.detect(image)
gender, age = age_gender.predict(image, faces[0]['bbox'])
print(f"{'Female' if gender == 0 else 'Male'}, {age} years old")

Supported Models

Detection

Model Variants MLX ONNX
RetinaFace MobileNet 0.25/0.5/v1/v2, ResNet18/34 ✅ ✅
SCRFD 500M, 10G ✅ ✅
YOLOv5Face S, M ✅ ✅

Recognition

Model Variants MLX ONNX
ArcFace MobileNet, ResNet ✅ ✅
MobileFace v1, v2, v3 ✅ ✅
SphereFace Sphere20 ✅ ✅

Attributes

Model Output MLX ONNX
Landmark106 106-point landmarks ✅ ✅
AgeGender Age + Gender ✅ ✅
Emotion 7/8 emotions ✅ ✅

Backend Selection

MLX-UniFace automatically selects the best backend:

  1. Apple Silicon + MLX installed → Uses MLX (fastest)
  2. Otherwise → Uses ONNX Runtime

Force a Specific Backend

import os
os.environ['UNIFACE_BACKEND'] = 'mlx'   # Force MLX
os.environ['UNIFACE_BACKEND'] = 'onnx'  # Force ONNX

from uniface import RetinaFace
detector = RetinaFace()  # Uses the specified backend

Check Current Backend

from uniface.backend import get_backend, Backend

backend = get_backend()
print(f"Using: {backend}")  # Backend.MLX or Backend.ONNX

Benchmarks

Run benchmarks on your hardware:

# Quick benchmark
python scripts/test_mlx_detection.py

# Full benchmark with visualization
jupyter notebook notebooks/benchmark_mlx_vs_onnx.ipynb

Numerical Parity Verification

python scripts/verify_numerical_parity.py

Output:

✓ SUCCESS: MLX and ONNX outputs match within tolerance!
  All outputs have correlation > 0.999

Development

Setup

git clone https://github.com/CodeWithBehnam/mlx-uniface.git
cd mlx-uniface
pip install -e ".[dev]"

Run Tests

pytest

Code Formatting

ruff format .
ruff check . --fix

Project Structure

mlx-uniface/
├── uniface/
│   ├── detection/       # Face detection (RetinaFace, SCRFD, YOLOv5)
│   │   ├── retinaface.py      # ONNX implementation
│   │   ├── retinaface_mlx.py  # MLX implementation
│   │   └── ...
│   ├── recognition/     # Face recognition (ArcFace, MobileFace)
│   ├── landmark/        # 106-point landmarks
│   ├── attribute/       # Age, Gender, Emotion
│   ├── nn/              # MLX neural network modules
│   │   ├── backbone.py  # MobileNetV1/V2
│   │   ├── conv.py      # Conv layers with fused BatchNorm
│   │   ├── fpn.py       # Feature Pyramid Network
│   │   └── head.py      # Detection heads
│   ├── backend.py       # Backend auto-selection
│   ├── mlx_utils.py     # MLX utilities
│   └── onnx_utils.py    # ONNX utilities
├── scripts/
│   ├── convert_onnx_to_mlx.py    # Weight conversion
│   ├── verify_numerical_parity.py # Accuracy validation
│   └── test_mlx_detection.py      # End-to-end tests
├── notebooks/
│   └── benchmark_mlx_vs_onnx.ipynb
└── weights_mlx/         # Pre-converted MLX weights

Credits


License

MIT License - see LICENSE for details.


Contributing

Contributions are welcome! Please open an issue or submit a pull request.

Metadata

Release files for mlx-uniface 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mlx-uniface 1.0.0
File Size Uploaded Provenance
mlx_uniface-1.0.0.tar.gz 79.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mlx-uniface 1.0.0
File Interpreter ABI Platform
mlx_uniface-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 181.2 kB

Release files / mlx_uniface-1.0.0.tar.gz

Download URL mlx_uniface-1.0.0.tar.gz
Size 79.0 kB
Tags Source
SHA-256 checksum
How to use checksums
75fc5177f9c09c601ffb19267770c9fc526b0733b1da3be5589c3fb2810ef10e
BLAKE2b-256 checksum
How to use checksums
b59bddce5a38764a117cc90a38c6846fd3c6682c794a6b50737acdc1869ac6d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 9, 2025.

Transparency log

Release files / mlx_uniface-1.0.0-py3-none-any.whl

Download URL mlx_uniface-1.0.0-py3-none-any.whl
Size 102.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
42e5773e9b76db6cbe233161315e0572c3aed206cca7cd9138e3c8e5a8ca4e8a
BLAKE2b-256 checksum
How to use checksums
bd9c7dbdf2944f3cbdbb7a6e406593bc69270cd5516b41ceddc0334b458be6a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 9, 2025.

Transparency log

Security for mlx-uniface 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for mlx_uniface-1.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 9, 2025.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page