手机也能跑实时人脸替换:Deep-Live-Cam 跨平台部署与调优实战记录
【免费下载链接】Deep-Live-Camreal time face swap and one-click video deepfake with only a single image项目地址: https://gitcode.com/GitHub_Trending/de/Deep-Live-Cam
Deep-Live-Cam 凭一张照片就能实时换脸,还能直接驱动摄像头做直播。这篇文章拆解它的三段式推理管线和 ONNX 图改写技巧,并把 Termux 与 Apple Silicon 两条路都跑通——附你会踩的坑。
为什么折腾:200ms 的差距让你想往手机上搬
PC 上的体验已经很顺滑了:一张照片、点下 Live,摄像头预览里的脸就被实时替换。但这套东西绑在桌面上——你人在户外、手机就在手边,却没法用。
差距没网上传的夸张,但足够硌人。在中端 Android 上纯 CPU 跑,单帧人脸检测就要 30-50ms,完整管线(检测+替换+融合)叠到 150-300ms;桌面独显跑同样的活是 30-80ms。2-5 倍的差,体感就是"有点卡"和"流畅"的区别。
| 指标 | 移动端中端(CPU) | PC 桌面(GPU) | 差距 |
|---|---|---|---|
| 人脸检测单帧 | 30-50 ms | 5-10 ms | 3-10 倍 |
| 完整管线延迟 | 150-300 ms | 30-80 ms | 2-5 倍 |
| 内存占用 | 1-2 GB | 4-8 GB | 2-4 倍 |
| 可持续运行 | 30-60 分钟 | 不限 | — |
所以目标不是"跑起来",而是"跑得顺"。下面先说它怎么把这笔账算平的,再给你自己的搬运动手路径。
拆管线:检测、替换、贴回三关
移动端人脸替换的全部管线代码其实不长,一帧画面要闯三关:
- 检测:modules/face_analyser.py 跑 RetinaFace(buffalo_l,640×640 输入)拿到人脸框和关键点,识别模型同时产出身份 embedding。
- 替换:modules/processors/frame/face_swapper.py 把目标脸裁成 128×128 喂给 inswapper_128,吐出换好的脸块。
- 融合:用羽化椭圆掩码把脸块贴回原帧,需要时再过一道 GFPGAN 超分(modules/processors/frame/face_enhancer.py)。
真正的看点不在三关本身,而在每一关被派给了哪块硬件。
ONNX 当通用货币
全项目模型层统一说 ONNX,同一个 .onnx 文件在不同芯片上交不同的执行提供器。启动时这段代码做一次"谁在谁上"的择优:
# modules/core.py:按优先级挑加速器,都不行就退回 CPU available = encode_execution_providers(onnxruntime.get_available_providers()) for pref in ('cuda', 'rocm', 'coreml', 'openvino', 'dml'): if pref in available: return pref return 'cpu'启动 banner 会打印最终选中的加速器——这条日志就是后面排查卡顿的第一检查点。
给 Apple Silicon 动图的"手术"
ONNX 是通用货币,但 CoreML 后端认账的算子有限:不认识的算子(Pad(reflect)、Split、标量 Gather)会让模型被切段,结果在 CPU 和神经引擎之间来回搬运。项目专门写了 modules/onnx_optimize.py,加载时跑四遍图改写,落盘缓存:
# modules/onnx_optimize.py:每个模型改写一次,_coreml 后缀缓存 model = onnx.load(model_path) if _fold_shape_gather(model, input_shape): # Shape→Gather 动态链折成常量 changed = True if _decompose_reflect_pad(model): # Pad(reflect) 拆成 Slice+Concat changed = True onnx.save(model, optimized_path) # 存改写后的模型改写之后 inswapper 整个模型能在神经引擎上单分区跑完,不用把中间结果甩给 CPU。
检测和替换,走两条"车道"
更妙的地方在调度:Apple Silicon 上,检测模型被刻意分到CPUAndGPU(GPU 上约 4ms),让更重的替换模型独占神经引擎——两次推理用不同的硬件单元并行推进,下一帧的检测在当前帧替换结束前就提前开跑:
# modules/processors/frame/core.py:检测与替换流水重叠 pending_detect = detect_executor.submit(get_one_face, frame.copy()) ... target_face = pending_detect.result() # 取本帧检测结果 pending_detect = detect_executor.submit(get_one_face, frame.copy()) # 提前探下一帧这套组合拳下来,M3 Max 上的人脸检测从 21ms 压到 4ms——移动端人脸替换的"卡"感,就是从这里被拿掉的。
跑通:Termux 与 Apple Silicon 两条路
Android(Termux)路线
pkg install python clang ffmpeg -y git clone --depth 1 https://gitcode.com/GitHub_Trending/de/Deep-Live-Cam cd Deep-Live-Cam python -m venv venv && source venv/bin/activate pip install --upgrade pip && pip install -r requirements.txt✅ 预期看到:依赖装完无报错,opencv 与 onnxruntime 均为纯 CPU 构建。
⚠️ 坑一:Termux 摄像头权限不默认授予,先执行termux-setup-camera(弹窗授权)再重启 Termux,否则开摄像头直接黑屏。
⚠️ 坑二:把 models/instructions.txt 列出的 inswapper_128 与 GFPGANv1.4 两个模型文件放进models/目录;首次运行还会自动拉取约 300MB,网络不稳就卡死在加载页。
python run.py --execution-provider cpu --live-mirror✅ 预期看到:GUI 弹出,点 Live 后 10-30 秒内实时窗口出现自己的脸。
Apple Silicon 路线
brew install python@3.14 python-tk@3.14 python3.14 -m venv venv && source venv/bin/activate pip install -r requirements.txt⚠️ 坑:如果之前装过 onnxruntime-silicon 分支包,先pip uninstall onnxruntime-silicon——它会遮蔽官方包,导致 CoreML 提供器消失。
python3.14 run.py --execution-provider coreml✅ 预期看到:banner 打印accelerator: CoreML (Apple Neural Engine)。若显示accelerator: CPU,回去检查 onnxruntime 装的是哪个版本。
| 执行提供器 | 适用硬件 | 启动参数 |
|---|---|---|
| coreml | Apple M1-M5 | --execution-provider coreml |
| cuda | NVIDIA GPU | --execution-provider cuda |
| openvino | Intel GPU/NPU | --execution-provider openvino |
| directml | Windows AMD/Intel | --execution-provider directml |
| cpu | 全平台兜底 | 默认 |
卡了怎么办:按掉帧顺序排一遍
能跑之后别急着庆祝,移动端人脸替换通常是"勉强能看"。卡了,按下面顺序排查:
1. banner 显示 CPU。最常见原因:对应的 onnxruntime 构建没装对,静默回退 CPU 了。跑python -c "import onnxruntime as o; print(o.get_available_providers())"确认提供器列表里有没有你要的那个。
2. 前几秒慢,随后变顺。那是模型加载 + 内核预热,外加 FP16 / CUDA graph 会话初始化,属正常现象。
3. 脸边缘抖、闪。贴回掩码每帧重建,关键点微小漂移被放大。项目在 face_swapper.py 里做了掩码缓存:脸几乎静止时直接复用上一帧的数组(_poisson_cached_mask),GUI 里还可以开 Poisson blend 平滑接缝。
4. 视频批处理太慢。老路径把每帧写成 PNG 再读回,磁盘 IO 才是真瓶颈。现在默认走 FFmpeg 管道管线,原始帧直接进内存、处理完直喂编码器:
# modules/processors/frame/core.py:读写都走管道,零磁盘 reader_cmd = ['ffmpeg', '-i', target_path, '-f', 'rawvideo', '-pix_fmt', 'bgr24', '-'] writer_cmd = ['ffmpeg', '-f', 'rawvideo', '-s', f'{width}x{height}', '-c:v', encoder, '-y', temp_output_path] raw = reader.stdout.read(frame_size) # 解码出当前帧 writer.stdin.write(frame.tobytes()) # 换完写回5. 线程与内存上限。线程数由 core.py 的suggest_execution_threads自动建议(DML/OpenVINO 给 1、CUDA 给 2、纯 CPU 给核心数-2);--max-memory参数用setrlimit硬限进程内存,4GB 内存的机器上不容易被系统杀进程。
各设备优化后的效果,供你对号入座:
| 设备 | 芯片 | 实时帧率 | 内存 |
|---|---|---|---|
| iPhone 13 | A15 | 22-25 fps | 1.2-1.5 GB |
| Samsung S21 | 骁龙 888 | 18-22 fps | 1.5-1.8 GB |
| Pixel 6 | Tensor G2 | 15-18 fps | 1.3-1.6 GB |
| iPad Pro (M1) | M1 | 28-32 fps | 1.8-2.2 GB |
能拿去干什么,红线划在哪
跑得顺之后,玩法组合其实不少:
- 直播面部特效:OBS 捕获实时窗口,作为虚拟相机推流;画面里多人时,用 face mapping 给每张大脸绑定不同来源脸。
- 老电影换脸:视频模式整片批处理,把片里所有面孔换成你的来源图,输出存到以目标命名的目录。
- 旧照与短片活化:单张照片或短片走图片/视频模式,配上 GFPGAN 增强,输出细节能看。
技术有技术的好玩,红线得先划清楚:
- 换到真人脸上,先拿到本人同意,没有商量余地。
- 发布内容必须明确标注是 AI 生成。
- 用于诽谤、诈骗、色情内容属于违法,后果自负。
- 项目自带 NSFW 过滤,别想着绕过它。
收尾
从 Termux 到 M3,一条移动端实时人脸替换管线你已经完整跑通,也看清了 2-5 倍性能差花在哪、又被哪些招数找了回来。下一步建议拿你手边最慢的设备,把 banner、帧率、内存三样自己记一份基线,再逐个参数动刀看变化。说到底,这个项目最值钱的东西是:换脸不过是 ONNX、几百行管线代码和几处硬件癖好的副产品。
【免费下载链接】Deep-Live-Camreal time face swap and one-click video deepfake with only a single image项目地址: https://gitcode.com/GitHub_Trending/de/Deep-Live-Cam
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考