## 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 `score` field will be `0.0` and `bbox` is the used crop. ### Installation (WSL2, Python venv) From `/home/hung/genealog-face`: ```bash python -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` **Dependencies:** - `fastapi`, `uvicorn` - Web framework - `insightface` - Face detection and recognition - `onnxruntime-gpu` - GPU-accelerated inference - `httpx` - Async HTTP client for image downloads - `tenacity` - Retry logic - `opencv-python-headless`, `numpy`, `Pillow` - Image processing GPU support assumes: - WSL2 with GPU enabled. - NVIDIA drivers installed on Windows. - `nvidia-smi` works inside WSL. The service uses `insightface` with `CUDAExecutionProvider` first, falling back to CPU if needed. ### Running the service Use the helper script (recommended): ```bash 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: ```bash 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: ```bash 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: 1. Open **Task Scheduler** → **Create Task…**. 2. **General** tab: - Name: `GenealogFaceService`. - Configure to run for your Windows user. 3. **Triggers** tab: - New → Begin the task: **At log on**. 4. **Actions** tab: - Program/script: `wsl.exe` - Arguments: ```text -d Ubuntu -- bash -lc "cd /home/hung/genealog-face && nohup ./run_face_service.sh >> face_service.log 2>&1" ``` 5. 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`.