inswapper (InsightFace face swap) → OpenVINO 16 / 8 / 4 bit

把 haofanwang/inswapper / InsightFace inswapper_128 的整條換臉流程轉成 OpenVINO IR,並用 NNCF 量化成 16-bit / 8-bit / 4-bit。 推論時不需要 PyTorch / onnxruntime,只要 openvino + opencv + numpy。

⚠️ 授權與使用範圍(請先讀) inswapper_128、ArcFace、RetinaFace 都是 InsightFace 訓練並發佈的模型, 依其官方授權僅限非商業研究用途(non-commercial research use only)。 本 repo 只做格式轉換與量化測試,請勿用於冒充他人、散布謠言或任何未經當事人同意的用途; 商用請先取得 InsightFace 官方授權。

這條流程用到三個模型

網路 用途 原始 ONNX
retinaface_10g 人臉偵測 + 5 點關鍵點 16.9 MB
arcface_w600k_r50 人臉辨識,輸出 512 維 embedding 174.4 MB
inswapper_128 換臉本體(target 128×128 + source 512 維 embedding → 換好的臉) 554.3 MB

三者都已轉成 OpenVIR,各有 fp16 / int8 / int4 三種版本(int4-mixed 只有 swapper 版本)。

模型清單(models/)

檔案 精度 大小 (xml+bin)
inswapper_fp16.* 16-bit FP16 276.9 MB
inswapper_int8.* 8-bit W8A8(NNCF PTQ + SmoothQuant) 139.1 MB
inswapper_int4.* 4-bit u4 權重(NNCF LWC) 69.7 MB
inswapper_int4_mixed.* 4-bit/8-bit 混合(75% 權重為 4-bit) 91.7 MB
retinaface_fp16.* / _int8.* / _int4.* 偵測 8.7 / 4.6 / 2.5 MB
arcface_fp16.* / _int8.* / _int4.* 辨識 87.5 / 44.2 / 22.3 MB
inswapper_emap.npy 512×512 的 embedding 投影矩陣(原模型最後一個 initializer) 1.0 MB

快速開始(單一 py 檔)

pip install openvino opencv-python numpy huggingface_hub
git clone https://huggingface.co/HelloSun/inswapper
cd inswapper
python inswapper_ov.py -s input/source_face_nasa_astronaut.jpg \
                       -t input/target_photo_nasa_astronaut.jpg \
                       -o result.jpg -m int8

模型會在第一次執行時自動從本 repo 下載並快取到 ~/.cache/inswapper_openvino (可用 INSWAPPER_OV_CACHE 改路徑;也可下載後用 --model-dir models 指定本機資料夾)。

# 最小可運作範例
import cv2
from inswapper_ov import FaceSwapperOpenVINO

swapper = FaceSwapperOpenVINO(precision='int8')       # fp16 / int8 / int4 / int4-mixed
out = swapper.swap('source.jpg', 'target.jpg', out='result.jpg')

命令列選項

選項 說明
-s, --source 提供臉孔的來源圖
-t, --target 要被換臉的目標圖
-o, --output 輸出路徑(預設 result.jpg)
-m, --model fp16(16-bit) / int8(8-bit) / int4(4-bit) / int4-mixed
-d, --device CPU / GPU / NPU / AUTO
--all-faces 目標圖中每一張臉都換
--face-index N 只換第 N 張臉(依置信度排序,預設 0 = 最大張)
--det-size W H 偵測輸入尺寸,預設 640 640
--model-dir 使用本機 models/ 資料夾,不連網
--num-threads CPU 執行緒數

Python API

from inswapper_ov import FaceSwapperOpenVINO

sw = FaceSwapperOpenVINO(precision='int4-mixed', device='CPU', det_size=(640, 640))

bboxes, kpss = sw.detect(img_bgr)          # 偵測
emb, kps    = sw.embedding(img_bgr)        # 512 維 embedding(ArcFace)
out         = sw.swap('src.jpg', 'tgt.jpg', all_faces=True)

實測結果(16 / 8 / 4 bit)

素材為 NASA 公有領域太空人肖像照片(見 samples/README.md), 以 ONNX Runtime FP32(完全相同的預處理與貼回程式碼)為參考基準:

face montage

精度 swapper 大小 臉部 PSNR ↑ 臉部 SSIM ↑ 全圖 PSNR ↑ embedding cos ↑ 單次換臉 ↑
ONNX Runtime FP32(參考) 554.3 MB – – – 1.000 8.08 s
fp16 (16-bit) 276.9 MB 56.29 dB 0.9994 71.02 dB 1.000 0.47 s
int8 (8-bit) 139.1 MB 19.28 dB 0.556 37.09 dB 0.979 0.09 s
int4-mixed (4-bit 主體) 91.7 MB 17.28 dB 0.672 37.70 dB 0.947 0.40 s
int4 (純 4-bit) 69.7 MB 14.79 dB 0.532 32.29 dB 0.947 0.43 s

(測試機:Xeon Platinum 8559C 16 vCPU、OpenVINO 2026.4.1、1280×1024 照片、單張臉。)

怎麼選

  1. fp16(16-bit):與原模型幾乎一模一樣(56 dB),又快 17×,大多數情況請用這個。
  2. int8(8-bit):CPU 上最快(0.09 s),模型只有原版 1/4;臉部會有細微雜訊, 但辨識度完全沒問題。注意:校準資料一定要用真實人臉(見下方匯出說明), 用隨機雜訊校準會讓 ArcFace embedding 偏移到 cosine 0.78(會換到錯的人)。
  3. int4-mixed(4-bit 主體):視覺品質比純 4-bit 好很多,幾乎達到 int8 的水準, 模型 91.7 MB(FP32 的 1/6)。要在 4-bit 路線上兼顧品質就用這個。
  4. int4(純 4-bit):最小(69.7 MB),但 swapper 是類 GAN 網路, 4-bit 誤差會讓膚色嚴重偏色(見 montage 右下),不建議實際使用。

INT4 在 CPU 上不會比 INT8 快(0.43 s vs 0.09 s):CPU plugin 會在 runtime 把 u4 權重 解壓回 FP32/FP16 再計算。INT4 的收益是模型體積,不是速度。

Intel GPU / NPU

python inswapper_ov.py -s src.jpg -t tgt.jpg -o out.jpg -m int8 -d GPU

這三個 IR 都是標準 OpenVINO IR,不綁 plugin,CPU / GPU / NPU / AUTO / HETERO 都能跑。 GPU 上推薦 int8(plugin 對 INT8 卷積最佳化)與 fp16; int4 在 GPU 上也不會有 4-bit 卷積加速,權重同樣是 runtime 解壓。 要產生針對 GPU plugin 調校的 INT8 模型:

python export_openvino_inswapper.py --onnx-dir onnx --target-device gpu \
    --models inswapper --precisions int8 --calib-dir calib

本 repo 的數據是在沒有 GPU 的機器上量測的(available_devices = ['CPU']), GPU 的說明依 OpenVINO plugin 能力整理,非本機實測。

從原始 ONNX 重新轉換/量化

# 1) 先取得三個 ONNX(見 README 的來源)
# 2) 用真實人臉照片產生 NNCF 校準張量(強烈建議,否則 INT8 embedding 會偏移)
python make_calib_data.py --images "input/*.jpg" --samples 24 --out-dir calib

# 3) 轉換 + 量化(fp16 / int8 / int4 一次產出)
python export_openvino_inswapper.py --onnx-dir onnx --out-dir models --calib-dir calib

# 只做純 4-bit 或混合精度 4/8-bit
python export_openvino_inswapper.py --onnx-dir onnx --out-dir models \
    --models inswapper --precisions int4 --int4-ratio 0.75

轉換管線裡處理了三個「不處理就會出包」的點:

  1. NNCF 的 compress_weights(mode='int4_*') 預設只壓 MatMul,卷積會靜默退回 INT8 → enable_int4_for_convolutions() 擴充 _get_ratio_defining_params,讓 Conv 也用 4-bit。 swapper 裡的 Gemm 會自動被壓,Conv 則需要這個 patch。
  2. NNCF 的 CPU hardware config 只允許 8/16-bit 權重 → enable_int4_weights_in_cpu_hw_config() 把 q4_w 加進 Convolution/MatMul 的 qspace,才會產生真正的 u4 常數。 (--target-device gpu 時 NNCF 本身就允許 4-bit,不需 patch。)
  3. openvino.convert_model() 預設把權重壓成 FP16(舊版 Model Converter 的行為) → convert_onnx_fp32() 以 compress_to_fp16=False 轉換,量化才從真正的 FP32 出發。

另外,emap(embedding 投影矩陣)在推論時需要,但它是 ONNX 最後一個 initializer, 已匯出成 models/inswapper_emap.npy,執行期就不必安裝 onnx 了。

重新產生 samples/

python make_sample.py --onnx-dir onnx --models-dir models --out-dir samples

疑難排解

症狀 原因 / 解決
換錯人 / 換到奇怪的人 ArcFace 精度太低或校準資料是隨機雜訊;用 --model-dir 指定本機 IR,並用 int8 以上
臉部出現彩色斑塊 用了純 int4,改用 int4-mixed 或 int8 / fp16
No face detected 把 --det-size 調大(例如 1024 1024),或換張臉比較大的圖
想對影片換臉 逐影格呼叫 sw.swap(...),參考下方「影片」範例
OpenVINO 對 FP32 graph 預設 bf16 inswapper_ov.py 已固定 INFERENCE_PRECISION_HINT=f32;自己呼叫 ov.Core().compile_model 時記得傳入

影片換臉(逐影格)

import cv2
from inswapper_ov import FaceSwapperOpenVINO
sw = FaceSwapperOpenVINO(precision='int8')
cap, out = cv2.VideoCapture('in.mp4'), cv2.VideoWriter('out.mp4', cv2.VideoWriter_fourcc(*'mp4v'), 25, (1920, 1080))
while True:
    ok, frame = cap.read()
    if not ok: break
    out.write(sw.swap('src.jpg', frame, verbose=False))
out.release()

來源與授權

項目 來源 授權
換臉程式 haofanwang/inswapper Apache-2.0
inswapper_128 deepinsight/insightface 非商業研究用途
arcface_w600k_r50、retinaface_10g InsightFace(buffalo_l 系列) 非商業研究用途
量化 OpenVINO NNCF Apache-2.0
測試照片 NASA Johnson Space Center(公有領域) Public Domain
inswapper_ov.py / 匯出腳本 / 本說明 本專案 Apache-2.0

本 repo 的 inswapper_ov.py 內含從 InsightFace 移植的 estimate_norm / RetinaFace 後處理 / 換臉貼回(paste_back)邏輯,以確保 OpenVINO 版本與原版逐像素一致。

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support