4.6 KiB
Genealog Face Service
FastAPI-based face embedding microservice using InsightFace + ONNX Runtime GPU. This service generates face embeddings from images and is designed to be called from the genealog-api backend via HTTP.
Endpoints
GET /healthz– basic health check and model info.POST /embed-avatar– JSON body:{ "image_url": "https://..." }, returns a single best face embedding for an avatar image.POST /embed-image– JSON body:{ "image_url": "https://..." }, returns all detected faces and embeddings.
All embeddings are normalized float vectors suitable for cosine-similarity comparison. Face matching/comparison is handled by the calling service (genealog-api).
Features
- Async HTTP downloads with retry logic (httpx + tenacity)
- Image validation: size limits (20MB max), dimension limits (32px-8192px), decompression bomb protection
- Robust image decoding: handles all color modes (RGB, RGBA, L, LA, PA, CMYK, I, F), EXIF orientation correction
- Face detection fallback: If no face is detected in
/embed-avatar, falls back to center crop embedding - Embedding validation: Checks for NaN/Inf values before returning
- Modular structure: Clean separation of concerns (config, models, face processing, image handling, routes)
/embed-avatar notes:
- Images are decoded with Pillow and EXIF orientation is applied (e.g. iPhone photos) before running detection.
- If no face is detected, the service will fall back to a center square crop and run the recognition model directly to still produce an embedding. In this case, the
scorefield will be0.0andbboxis the used crop.
Installation (WSL2, Python venv)
From /home/hung/genealog-face:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Dependencies:
fastapi,uvicorn- Web frameworkinsightface- Face detection and recognitiononnxruntime-gpu- GPU-accelerated inferencehttpx- Async HTTP client for image downloadstenacity- Retry logicopencv-python-headless,numpy,Pillow- Image processing
GPU support assumes:
- WSL2 with GPU enabled.
- NVIDIA drivers installed on Windows.
nvidia-smiworks inside WSL.
The service uses insightface with CUDAExecutionProvider first, falling back to CPU if needed.
Running the service
Use the helper script (recommended):
cd /home/hung/genealog-face
./run_face_service.sh
Defaults:
- Host:
0.0.0.0 - Port:
18081 - Model:
buffalo_l - Detection size:
1024 - Workers:
nproc(all CPU cores detected)
You can override via environment variables:
PORT=18081 \
FACE_MODEL_NAME=buffalo_l \
FACE_DET_SIZE=1024 \
MAX_DOWNLOAD_SIZE=20971520 \
MAX_IMAGE_DIMENSION=8192 \
DOWNLOAD_TIMEOUT=15.0 \
MAX_RETRIES=3 \
UVICORN_WORKERS=20 \
./run_face_service.sh
To run in the background:
nohup ./run_face_service.sh > face_service.log 2>&1 &
Logs are written to face_service.log in the repo root.
Project Structure
genealog-face/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI app, lifespan handler, health endpoint
│ ├── config.py # Environment variables and constants
│ ├── models.py # Pydantic request/response models
│ ├── face.py # FaceAnalysis loading, embedding logic
│ ├── image.py # Image download, decode, validation
│ └── routes/
│ ├── __init__.py
│ └── embed.py # /embed-avatar, /embed-image endpoints
├── .gitignore
├── requirements.txt
├── run_face_service.sh
└── README.md
Integration with genealog-api (Docker)
The genealog-api service expects this face service to be reachable at:
FACE_SERVICE_URL: http://host.docker.internal:18081
You only need to ensure the service is running in WSL on port 18081 before starting the Docker stack.
Autostart on Windows reboot (via WSL2)
You can have Windows start this service automatically at logon using Task Scheduler:
- Open Task Scheduler → Create Task….
- General tab:
- Name:
GenealogFaceService. - Configure to run for your Windows user.
- Name:
- Triggers tab:
- New → Begin the task: At log on.
- Actions tab:
- Program/script:
wsl.exe - Arguments:
-d Ubuntu -- bash -lc "cd /home/hung/genealog-face && nohup ./run_face_service.sh >> face_service.log 2>&1"
- Program/script:
- Save the task (provide credentials if prompted).
After this, logging into Windows will start WSL and launch the face service in the background, ready to be used by genealog-api.