FastAPI wrapper around FaceFusion v3.5.3 submodule with: - Sync and async (job-based) processing endpoints - FaceFusion bridge with manual key registration and Lock-serialized processing - Multi-target Dockerfile (CPU + CUDA GPU) - Docker Compose configs for dev, prod-cpu, and prod-gpu - Gitea CI/CD workflow with dual image builds - All 11 FaceFusion processors supported via options API Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
96 lines
3.4 KiB
Markdown
96 lines
3.4 KiB
Markdown
# CLAUDE.md
|
|
|
|
## Overview
|
|
|
|
FaceFusion API - A Python REST API wrapping FaceFusion v3.5.3 for face swapping, enhancement, lip sync, and other face/frame processing. Containerized with CUDA GPU support, deployed via Gitea CI/CD at `dev.pivoine.art`.
|
|
|
|
## Architecture
|
|
|
|
- **FastAPI** async web framework with single uvicorn worker (mandatory due to FaceFusion's global state)
|
|
- **FaceFusion** included as git submodule at `facefusion/` pinned to tag 3.5.3
|
|
- All FaceFusion processing serialized through `threading.Lock` in `facefusion_bridge.py`
|
|
- Background job queue in `worker.py` for async processing
|
|
|
|
### Key Integration Points
|
|
|
|
FaceFusion uses global mutable state (`state_manager`) and module-level ONNX inference pools. The bridge (`app/services/facefusion_bridge.py`) replicates the initialization side-effects of `program.py`:
|
|
1. Registers all job_keys and step_keys in `job_store`
|
|
2. Initializes state defaults via `state_manager.init_item()`
|
|
3. Initializes job filesystem via `job_manager.init_jobs()`
|
|
4. Symlinks `facefusion/.assets/models/` -> `/data/models/` for model persistence
|
|
|
|
### Project Structure
|
|
|
|
```
|
|
app/
|
|
main.py # FastAPI app, lifespan, sys.path setup
|
|
config.py # Pydantic BaseSettings (FF_ env prefix)
|
|
routers/ # API endpoint handlers
|
|
schemas/ # Pydantic request/response models
|
|
services/
|
|
facefusion_bridge.py # Core FaceFusion integration
|
|
worker.py # Background job queue
|
|
file_manager.py # File upload/output handling
|
|
```
|
|
|
|
## Common Commands
|
|
|
|
```bash
|
|
# Development
|
|
docker compose build
|
|
docker compose up
|
|
|
|
# Production (CPU VPS)
|
|
docker compose -f docker-compose.prod.yml up -d
|
|
|
|
# Production (GPU server)
|
|
docker compose -f docker-compose.gpu.yml up -d
|
|
|
|
# Test endpoints
|
|
curl http://localhost:8000/api/v1/health
|
|
curl http://localhost:8000/api/v1/system
|
|
curl -X POST http://localhost:8000/api/v1/models/download -H 'Content-Type: application/json' -d '["face_swapper"]'
|
|
|
|
# Sync face swap
|
|
curl -X POST http://localhost:8000/api/v1/process \
|
|
-F source=@source.jpg \
|
|
-F target=@target.jpg \
|
|
-o result.jpg
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
- `POST /api/v1/process` - Synchronous processing (returns file)
|
|
- `POST /api/v1/jobs` - Create async job
|
|
- `GET /api/v1/jobs/{id}` - Job status
|
|
- `GET /api/v1/jobs/{id}/result` - Download result
|
|
- `DELETE /api/v1/jobs/{id}` - Cancel/delete job
|
|
- `GET /api/v1/processors` - List processors
|
|
- `GET /api/v1/models` - List downloaded models
|
|
- `POST /api/v1/models/download` - Download models
|
|
- `GET /api/v1/health` - Health check
|
|
- `GET /api/v1/system` - System info (GPU, memory)
|
|
|
|
## Docker
|
|
|
|
- `VARIANT=cpu` (default): `python:3.12-slim` + `onnxruntime`
|
|
- `VARIANT=gpu`: `nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04` + `onnxruntime-gpu`
|
|
- Models persisted in `/data/models` Docker volume (not baked into image)
|
|
- Single worker mandatory (`--workers 1`)
|
|
|
|
## Environment Variables
|
|
|
|
All prefixed with `FF_`:
|
|
- `FF_EXECUTION_PROVIDERS` - JSON array, e.g. `["cuda","cpu"]`
|
|
- `FF_EXECUTION_THREAD_COUNT` - Default 4
|
|
- `FF_VIDEO_MEMORY_STRATEGY` - strict/moderate/tolerant
|
|
- `FF_MODELS_DIR` - Model storage path
|
|
- `FF_MAX_UPLOAD_SIZE_MB` - Upload limit (default 500)
|
|
|
|
## Important Notes
|
|
|
|
- Never run with multiple uvicorn workers - FaceFusion global state will corrupt
|
|
- Models are 100MB-1GB each; pre-download via `/api/v1/models/download` before processing
|
|
- The `facefusion/` submodule must not be modified - use symlinks for model paths
|
|
- Git operations: always push with the valknarthing ssh key
|