Skip to main content

MLX-UniFace: Blazing-fast face analysis on Apple Silicon with MLX backend

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mlx_uniface-1.0.0.tar.gz (79.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mlx_uniface-1.0.0-py3-none-any.whl (102.2 kB view details)

Uploaded Python 3

File details

Details for the file mlx_uniface-1.0.0.tar.gz.

File metadata

  • Download URL: mlx_uniface-1.0.0.tar.gz
  • Upload date:
  • Size: 79.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mlx_uniface-1.0.0.tar.gz
Algorithm Hash digest
SHA256 75fc5177f9c09c601ffb19267770c9fc526b0733b1da3be5589c3fb2810ef10e
MD5 e4eb3c0c50177db9f8cab9b1f77e475b
BLAKE2b-256 b59bddce5a38764a117cc90a38c6846fd3c6682c794a6b50737acdc1869ac6d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlx_uniface-1.0.0.tar.gz:

Publisher: publish.yml on CodeWithBehnam/mlx-uniface

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mlx_uniface-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: mlx_uniface-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 102.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mlx_uniface-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 42e5773e9b76db6cbe233161315e0572c3aed206cca7cd9138e3c8e5a8ca4e8a
MD5 d941046ec9a14b66fd8e3b074887d88f
BLAKE2b-256 bd9c7dbdf2944f3cbdbb7a6e406593bc69270cd5516b41ceddc0334b458be6a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlx_uniface-1.0.0-py3-none-any.whl:

Publisher: publish.yml on CodeWithBehnam/mlx-uniface

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page