Most “easy face swap” tutorials set you up to fail
FaceFusion 3.9.0 shipped 3 September 2026 (alphaface_256 swapper, hrffa landmarker – release notes). Colab notebooks and mystery one-click packs still dominate search results. Fine for a 20-second toy clip. Bad if you need privacy, repeatable jobs, or anything you can re-run next month.
This is a deploy guide, not Source→Target→Start. Official introduction is blunt: terminal install needs technical skill. If that is not you, use the Windows or macOS installers and stop here.
What you actually need before you clone
As of the FaceFusion FAQ: latest Linux, macOS, and Windows are supported. VRAM is the real gate – 8GB bare minimum, 12GB+ once face enhancer sits on top of the swapper.
| Resource | Minimum | Comfortable |
|---|---|---|
| GPU VRAM | 8GB (official FAQ) | 12GB+ |
| Disk | SSD with room for models + temp frames | Extra free space if you pick disk workflow-strategy |
| Python (conda) | 3.12 | 3.12 + pip 25.0 (install docs) |
| FFmpeg | Required on PATH | Windows docs pin Gyan.FFmpeg 7.0.2 via winget |
NVIDIA + CUDA: least friction on Windows/Linux. Elsewhere: DirectML (Windows AMD/iGPU), ROCm/MIGraphX (Linux AMD), default/CoreML (Apple Silicon), OpenVINO (Intel Arc) – all are first-class install.py targets as of 3.9.0.
Download source – only these URLs
Code: https://github.com/facefusion/facefusion (tag 3.9.0). Install steps: docs.facefusion.io/installation. Containers: https://github.com/facefusion/facefusion-docker.
Skip “FaceFusion Free” packs and unlocked NSFW builds. Third-party mirrors are a malware lottery; stay on the GitHub org and facefusion.io.
Install FaceFusion 3.9.0 step by step
Native conda when you want control. Docker when the host toolchain is a mess.
1. Platform packages
Windows (platform docs, versions as published for current install guides):
winget install -e --id Git.Git
winget install -e --id Anaconda.Miniconda3 --version py312_25.1.1-2 --override "/AddToPath=1"
winget install -e --id Gyan.FFmpeg --version 7.0.2
Linux / macOS: install Git, FFmpeg, and Miniconda (or full Anaconda) with your usual package manager, then continue from the conda steps. Windows is where the docs pin exact winget IDs; other OS prep is the same three ingredients without those pins.
2. Conda env
conda init --all
# restart the shell after init
conda create --name facefusion python=3.12 pip=25.0
conda activate facefusion
3. Accelerator (NVIDIA Windows example)
conda install nvidia/label/cuda-12.9.1::cuda-runtime nvidia/label/cudnn-9.10.0::cudnn
Intel Arc path uses the OpenVINO installer choice in the next step (see install docs for accelerator packages on your OS). Match runtime major to the install.py argument you pick below.
4. Clone + install.py
git clone https://github.com/facefusion/facefusion
cd facefusion
# optional pin:
# git checkout 3.9.0
python install.py cuda@12
# alternatives: default | cuda@13 | directml | openvino | migraphx | rocm
Argument is positional. Turns out installer.py maps cuda@12 → onnxruntime-gpu 1.24.4 and cuda@13 → 1.29.0 (default CPU stack lands on 1.29.0). Wrong pair often means CPU-only inference with no dramatic error. The script also strips older onnxruntime wheels so mixed installs do not linger.
5. Reload – the catch is easy to miss
conda deactivate
conda activate facefusion
python facefusion.py run --open-browser
Skip deactivate/activate and pip still “looks fine” while the UI dies with ModuleNotFoundError or AttributeError. Official installation step 6 is the reload for that reason.
Docker alternative
git clone https://github.com/facefusion/facefusion-docker.git
cd facefusion-docker
docker compose -f docker-compose.cuda.yml up
# CPU → http://localhost:7865
# CUDA → http://localhost:7870
# TensorRT → :7875 | ROCm → :7880
Use Docker for isolation on a dirty machine. Prefer native only if you already trust your CUDA stack and care about host I/O on long jobs.
First-time config that doesn’t waste an evening
–workflow-strategy (added in 3.8): memory keeps frames in RAM – faster, hungrier. disk spills to temp – slower, safer on long 4K runs. Temp resources live under .facefusion in the OS temp directory (FAQ). Check that path before a multi-hour job fills the volume.
Smoke test after models cache: python facefusion.py run --open-browser.
Verify the install works
python facefusion.py -v
You want 3.9.0 (or the tag you checked out). Then launch with python facefusion.py run --open-browser. First run pulls models into assets.
There’s a quiet moment after a clean install when the first model hash validates and the UI finally loads – that is when the tool stops feeling like a dependency maze and starts feeling like a machine you own.
Common install errors and fixes
Straight from official troubleshooting plus the VRAM/NSFW FAQ notes – not generic driver fluff.
- ModuleNotFoundError / “module has no attribute” – incomplete env. Re-run
python install.py ...inside the activated env, then deactivate/activate again. - No matching distribution found – OS or Python too old. Docs want a current OS and Python 3.12.
- Protobuf parsing failed – delete the broken file under
.assets/modelsand let it re-download. - Cannot allocate memory / CUDA OOM – lower execution threads (toward 1), set video memory strategy to strict, close other GPU apps. 8GB is the documented floor.
- Halts at 100% analysing – NSFW policy stop, not a crash (FAQ). Use consented, non-blocked material.
- ffmpeg not found – new shell after winget; confirm
ffmpeg -version. - conda is not activated – install.py expects the env active.
Upgrade from an older FaceFusion / uninstall
Upgrade (same major line):
conda activate facefusion
cd facefusion
git fetch --tags
git checkout 3.9.0
python install.py cuda@12 --force-reinstall
conda deactivate && conda activate facefusion
python facefusion.py -v
3.8→3.9 is usually pull + reinstall. If onnxruntime fights you, remove the env and recreate clean.
Uninstall / cleanup:
conda deactivate
conda env remove --name facefusion
# delete the cloned facefusion directory
# purge OS temp/.facefusion and leftover .assets if you want the disk back
Docker: docker compose ... down, then drop images/volumes you created.
Is local face-swap tooling always worth the CUDA tax versus a paid API? Depends whether your clips can leave the building – and whether you need the alphaface_256 path at all.
FAQ
Do I need cuda@12 or cuda@13 for FaceFusion 3.9.0?
Match the CUDA runtime you installed. Docs show python install.py cuda@12 next to the cuda-12.9.1 runtime package; cuda@13 ships a newer onnxruntime-gpu pin. Mismatch → silent CPU fallback.
Can I run face swap open source without an NVIDIA GPU?
Yes. default (CPU/CoreML on Mac), directml on Windows AMD/iGPU, openvino for Intel Arc, rocm/migraphx on Linux AMD. Expect much slower runs than a mid-range RTX. Practical trial: spin docker-compose.cpu.yml or the ROCm compose file so you never dirty the host – UI lands on the ports listed above (7865 CPU, 7880 ROCm).
Why did processing stop after analysis hit 100%?
People treat this like a hung encode. It is not. The built-in analyser enforces the project’s NSFW rules; the FAQ states that outright. Swap the media. Do not hunt a “disable filter” switch inside official builds – that hunt is how people land on third-party “unlocked” forks. If the job only looked frozen on a long disk-strategy run, also glance at temp growth under .facefusion before you assume the process died.
Next action: create the conda env with Python 3.12, clone tag 3.9.0, run the matching install.py, reload the env, confirm with python facefusion.py -v before you touch a source frame.