Skip to content

Repository files navigation

Inswapper Face Swapping | RunPod Serverless Worker

This is the source code for a RunPod Serverless worker for face swapping using FaceFusion swapper models (including inswapper) with InsightFace face detection.

Tests Python License Worker Version RunPod

Model

The worker uses the inswapper_128.onnx model by InsightFace.

Face Swapper Models

The worker supports 13 different face swap models with varying quality/speed trade-offs.

Available Models

Embedding-projected models:

  • inswapper_128 (default) - Original balanced quality/speed model
  • inswapper_128_fp16 - Faster FP16 version

Embedding models (use crossface converters):

  • simswap_256 - High quality with ImageNet normalization
  • simswap_unofficial_512 - Highest quality (slower)
  • ghost_1_256, ghost_2_256, ghost_3_256 - Ghost model variants
  • hififace_unofficial_256 - High fidelity variant
  • hyperswap_1a_256, hyperswap_1b_256, hyperswap_1c_256 - Hyperswap FP16 variants

Source-face models (warp source image to template):

  • blendswap_256 - Blend-focused model (uses source face image)
  • uniface_256 - Universal face model (uses source face image)

Model Selection Examples

Highest quality swap:

{
  "source_image": "base64...",
  "target_image": "base64...",
  "face_swapper_model": "simswap_unofficial_512",
  "face_swapper_resolution": "1024x1024"
}

Fast inference:

{
  "source_image": "base64...",
  "target_image": "base64...",
  "face_swapper_model": "inswapper_128_fp16",
  "face_swapper_resolution": "256x256"
}

Subtle blend with face selector filtering:

{
  "source_image": "base64...",
  "target_image": "base64...",
  "face_swapper_model": "uniface_256",
  "face_swapper_weight": 0.7,
  "face_selector_mode": "one",
  "face_selector_order": "large-small",
  "face_selector_gender": "female"
}

Parameters

Model selection:

  • face_swapper_model (string, optional, default: "inswapper_128"): Model to use
  • face_swapper_resolution (string, optional): Resolution for inference (auto-selects if not specified)
  • face_swapper_weight (number, optional, default: 1.0): Blend weight (0.0-1.0)

Face mask controls:

  • face_mask_blur (number, optional, default: 0.3): Softness of face mask edges (0.0-1.0)
  • face_mask_padding (string, optional, default: "0,0,0,0"): Mask inset as "top,right,bottom,left" percentages

Face selector:

  • face_selector_mode (string, optional, default: "many"): "many" or "one"
  • face_selector_order (string, optional, default: "left-right"): Sort order for detected faces
  • face_selector_gender (string, optional): Filter by "male" or "female"
  • face_selector_age_start (integer, optional): Minimum target face age
  • face_selector_age_end (integer, optional): Maximum target face age

See Face Swapper Models API Documentation for complete reference.

Examples

Each model has its own examples/ subdirectory with runnable Python scripts. The inswapper_128/ directory contains the full set of face indexing scenarios; all other model directories contain all_1_source_into_all_1_target.py with model-appropriate defaults.

examples/
├── util.py                              # shared request helpers
├── inswapper_128/                       # default model (all 8 scenarios)
│   ├── all_1_source_into_all_1_target.py
│   ├── all_1_source_into_first_1_targets.py
│   ├── all_1_source_into_matching_min_face_size_target.py
│   ├── all_1_source_single_into_index_in_3_targets.py
│   ├── all_2_source_into_all_2_targets.py
│   ├── all_2_source_into_first_2_targets.py
│   ├── all_2_source_into_specific_2_targets.py
│   ├── first_2_source_into_all_2_targets.py
│   └── specific_2_source_into_specific_2_targets.py
├── inswapper_128_fp16/                  # fast FP16
│   └── all_1_source_into_all_1_target.py
├── simswap_256/                         # high quality
│   └── all_1_source_into_all_1_target.py
├── simswap_unofficial_512/              # highest quality
│   └── all_1_source_into_all_1_target.py
├── blendswap_256/                       # blend-focused
│   └── all_1_source_into_all_1_target.py
├── uniface_256/                         # universal + blend demo
│   ├── all_1_source_into_all_1_target.py
│   └── all_1_source_into_all_1_target_blend.py
├── ghost_1_256/
│   └── all_1_source_into_all_1_target.py
├── ghost_2_256/
│   └── all_1_source_into_all_1_target.py
├── ghost_3_256/
│   └── all_1_source_into_all_1_target.py
├── hififace_unofficial_256/
│   └── all_1_source_into_all_1_target.py
├── hyperswap_1a_256/
│   └── all_1_source_into_all_1_target.py
├── hyperswap_1b_256/
│   └── all_1_source_into_all_1_target.py
└── hyperswap_1c_256/
    └── all_1_source_into_all_1_target.py

Create a .env file in examples/ with your RunPod API key and endpoint ID, then run any script from the examples/ directory:

cp examples/.env.example examples/.env
# edit examples/.env with your RunPod credentials
cd examples
python3 inswapper_128/all_1_source_into_all_1_target.py
python3 simswap_unofficial_512/all_1_source_into_all_1_target.py

Testing

  1. Local Testing
  2. RunPod Testing

Building the Docker image that will be used by the Serverless Worker

Building the Docker image

RunPod API Endpoint

You can send requests to your RunPod API Endpoint using the /run or /runsync endpoints.

Requests sent to the /run endpoint will be handled asynchronously, and are non-blocking operations. Your first response status will always be IN_QUEUE. You need to send subsequent requests to the /status endpoint to get further status updates, and eventually the COMPLETED status will be returned if your request is successful.

Requests sent to the /runsync endpoint will be handled synchronously and are blocking operations. If they are processed by a worker within 90 seconds, the result will be returned in the response, but if the processing time exceeds 90 seconds, you will need to handle the response and request status updates from the /status endpoint until you receive the COMPLETED status which indicates that your request was successful.

RunPod API Examples

Endpoint Status Codes

Status Description
IN_QUEUE Request is in the queue waiting to be picked up by a worker. You can call the /status endpoint to check for status updates.
IN_PROGRESS Request is currently being processed by a worker. You can call the /status endpoint to check for status updates.
FAILED The request failed, most likely due to encountering an error.
CANCELLED The request was cancelled. This usually happens when you call the /cancel endpoint to cancel the request.
TIMED_OUT The request timed out. This usually happens when your handler throws some kind of exception that does return a valid response.
COMPLETED The request completed successfully and the output is available in the output field of the response.

Serverless Handler

The serverless handler (handler.py) is a Python script that handles the API requests to your Endpoint using the runpod Python library. It defines a function handler(event) that takes an API request (event), runs the inference using the inswapper model (and CodeFormer where applicable) with the input, and returns the output in the JSON response.

Acknowledgements

Additional Resources

Community and Contributing

Pull requests and issues on GitHub are welcome. Bug fixes and new features are encouraged.

Appreciate my work?

Buy Me A Coffee

About

RunPod Serverless Worker for GPU-accelerated face swapping with 13 models, CodeFormer restoration, and VRAM-safe serial queue. Powered by insightface and FaceFusion.

Topics

Resources

Stars

29 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages