A production-oriented FastAPI wrapper for the CatVTON Mask-Free virtual try-on model. Send a person image and a garment image, and receive a PNG of the person wearing the garment—without supplying a segmentation mask.
The service deliberately includes only the mask-free inference path. It does not load the original project's Gradio UI, Detectron2, DensePose, SCHP, or mask-based pipeline.
CatVTONPix2PixPipelineseed are used.
├── app/
│ ├── main.py # FastAPI app, request validation, model lifecycle
│ └── config.py # Environment-based settings
├── CatVTON/
│ ├── model/
│ │ ├── pipeline.py # Mask-free diffusion pipeline
│ │ └── attn_processor.py # CatVTON attention implementation
│ ├── utils.py # Image resize, padding, and latent utilities
│ └── LICENSE # Upstream CatVTON license
├── scripts/
│ └── download_models.py # Optional model-cache warm-up script
├── .env.example # Local configuration template
├── Dockerfile # Single-worker CUDA runtime image
└── requirements.txt # API and model runtime dependencies
Client
│ multipart/form-data: person image + garment image
▼
FastAPI ── validation ──> RGB decode + max-size check
│
│ one request at a time per process
▼
CatVTONPix2PixPipeline
├─ resize/crop person image to OUTPUT_WIDTH × OUTPUT_HEIGHT
├─ resize/pad garment image to the same canvas
├─ VAE encodes both images into latents
├─ CatVTON attention + DDIM diffusion denoising
└─ VAE decodes the generated try-on image
│
▼
PNG response + X-Inference-Seed header
At application startup, the service loads the base InstructPix2Pix components, Stable Diffusion VAE, and CatVTON Mask-Free attention checkpoint into one process-local pipeline. On a cache miss, Hugging Face downloads these assets into HF_HOME.
| Area | Technology |
|---|---|
| HTTP API | FastAPI, Uvicorn, python-multipart |
| ML runtime | PyTorch 2.4, Accelerate |
| Diffusion | Diffusers, DDIM scheduler, Stable Diffusion VAE |
| Model | CatVTON Mask-Free / InstructPix2Pix attention checkpoint |
| Images | Pillow, NumPy |
| Packaging | Docker, NVIDIA CUDA 12.1 + cuDNN 8 runtime |
POST /v1/try-on
Send multipart/form-data with the following fields:
| Field | Type | Required | Default | Constraints |
|---|---|---|---|---|
person_image | image file | Yes | — | Decodable image; at most MAX_UPLOAD_BYTES |
cloth_image | image file | Yes | — | Decodable image; at most MAX_UPLOAD_BYTES |
steps | integer | No | 50 | 1–100 |
guidance_scale | number | No | 2.5 | 0–10 |
seed | integer | No | 42 | 0–2147483647 |
A successful request returns 200 OK with Content-Type: image/png. The seed used is also returned in the X-Inference-Seed response header.
curl --request POST http://localhost:8000/v1/try-on \
--form person_image=@CatVTON/inputs/person.jpg \
--form cloth_image=@CatVTON/inputs/cloth.jpg \
--form steps=30 \
--form guidance_scale=2.5 \
--form seed=42 \
--output try-on.png
Common error responses are 413 for oversized uploads, 415 for a non-image content type, 422 for an invalid image or invalid form parameters, 500 for inference failures, and 503 when the model is not ready.
GET /healthz returns {"status":"ok"} only after the model is loaded; otherwise it returns 503. Use it for container readiness checks.
requirements.txt installs the CUDA 12.1 PyTorch wheelCPU execution is supported by the configuration, but image generation will be slow and is best treated as a smoke test.
git clone https://github.com/Mahir-Uddin0/catvton-backend
cd catvton
python3.10 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --host 0.0.0.0 --port 8000
The initial startup downloads the required Hugging Face models. To download them before starting the server—for example while building a reusable machine image—run:
python scripts/download_models.py
Then verify the server once its startup logs finish:
curl http://localhost:8000/healthz
Interactive API documentation is available at http://localhost:8000/docs.
Copy .env.example to .env for local development. Environment variables provided by the shell or deployment platform take precedence over values in .env.
| Variable | Default | Purpose |
|---|---|---|
DEVICE | auto | auto, cuda, or cpu. auto selects CUDA when available. |
MIXED_PRECISION | bf16 | bf16, fp16, or no. CPU always uses float32; CUDA falls back to fp16 if BF16 is unavailable. |
OUTPUT_WIDTH | 768 | Generated image width; must be a positive multiple of 8. |
OUTPUT_HEIGHT | 1024 | Generated image height; must be a positive multiple of 8. |
MAX_UPLOAD_BYTES | 10485760 | Maximum size, in bytes, accepted for each uploaded image. |
ALLOWED_ORIGINS | http://localhost:3000 | Comma-separated CORS origins allowed to call the API from a browser. |
HF_HOME | ~/.cache/huggingface | Directory for downloaded model weights and Hugging Face cache. Mount this as persistent storage in containers. |
CATVTON_ROOT | ./CatVTON | Location of the bundled CatVTON source; it must contain model/pipeline.py. |
BASE_MODEL_ID | timbrooks/instruct-pix2pix | Hugging Face base model identifier or compatible local path. |
ATTENTION_CHECKPOINT_ID | zhengchong/CatVTON-MaskFree | Hugging Face CatVTON attention checkpoint identifier or compatible local path. |
PORT | 8000 in Docker | Uvicorn port used by the Docker command. |
Example production-oriented configuration:
DEVICE=cuda
MIXED_PRECISION=bf16
ALLOWED_ORIGINS=https://app.example.com
OUTPUT_WIDTH=768
OUTPUT_HEIGHT=1024
MAX_UPLOAD_BYTES=10485760
HF_HOME=/cache/huggingface
Build the supplied CUDA image and expose the same port the container listens on:
docker build --tag catvton-api .
docker run --rm --gpus all \
--publish 8080:8080 \
--env PORT=8080 \
--env DEVICE=cuda \
--env ALLOWED_ORIGINS=https://app.example.com \
--volume catvton-hf-cache:/cache/huggingface \
catvton-api
The image starts one Uvicorn worker. Keep one worker per GPU/model replica; adding workers loads another full model copy and increases GPU memory use.
CatVTONPix2PixPipeline, avoiding segmentation/mask input and excluding heavyweight Detectron2, DensePose, SCHP, and Gradio dependencies from the serving runtime.asyncio.Lock permits only one active generation per process. This keeps GPU memory predictable and avoids overlapping model calls; scale horizontally for concurrent requests.HF_HOME if that location is mounted.Built-in protections are intentionally narrow: the service validates the advertised image MIME type, attempts to decode every upload with Pillow, limits each upload size, and restricts browser origins through ALLOWED_ORIGINS.
Before exposing the API publicly, add the following:
ALLOWED_ORIGINS value—never use a permissive origin unnecessarily.The current pipeline is created with skip_safety_check=True; it does not run the upstream safety checker. If content moderation is required, implement it explicitly before returning outputs and ensure the policy is appropriate for your users and jurisdiction.
torch.compile, attention optimizations, TensorRT/ONNX paths where supported, and pre-warmed model caches.33 commits
Python
90.5%
JavaScript
3.3%
Cuda
3.2%
C++
2.3%
A production-oriented FastAPI wrapper for the CatVTON Mask-Free virtual try-on model. Send a person image and a garment image, and receive a PNG of the person wearing the garment—without supplying a segmentation mask.
The service deliberately includes only the mask-free inference path. It does not load the original project's Gradio UI, Detectron2, DensePose, SCHP, or mask-based pipeline.
CatVTONPix2PixPipelineseed are used.
├── app/
│ ├── main.py # FastAPI app, request validation, model lifecycle
│ └── config.py # Environment-based settings
├── CatVTON/
│ ├── model/
│ │ ├── pipeline.py # Mask-free diffusion pipeline
│ │ └── attn_processor.py # CatVTON attention implementation
│ ├── utils.py # Image resize, padding, and latent utilities
│ └── LICENSE # Upstream CatVTON license
├── scripts/
│ └── download_models.py # Optional model-cache warm-up script
├── .env.example # Local configuration template
├── Dockerfile # Single-worker CUDA runtime image
└── requirements.txt # API and model runtime dependencies
Client
│ multipart/form-data: person image + garment image
▼
FastAPI ── validation ──> RGB decode + max-size check
│
│ one request at a time per process
▼
CatVTONPix2PixPipeline
├─ resize/crop person image to OUTPUT_WIDTH × OUTPUT_HEIGHT
├─ resize/pad garment image to the same canvas
├─ VAE encodes both images into latents
├─ CatVTON attention + DDIM diffusion denoising
└─ VAE decodes the generated try-on image
│
▼
PNG response + X-Inference-Seed header
At application startup, the service loads the base InstructPix2Pix components, Stable Diffusion VAE, and CatVTON Mask-Free attention checkpoint into one process-local pipeline. On a cache miss, Hugging Face downloads these assets into HF_HOME.
| Area | Technology |
|---|---|
| HTTP API | FastAPI, Uvicorn, python-multipart |
| ML runtime | PyTorch 2.4, Accelerate |
| Diffusion | Diffusers, DDIM scheduler, Stable Diffusion VAE |
| Model | CatVTON Mask-Free / InstructPix2Pix attention checkpoint |
| Images | Pillow, NumPy |
| Packaging | Docker, NVIDIA CUDA 12.1 + cuDNN 8 runtime |
POST /v1/try-on
Send multipart/form-data with the following fields:
| Field | Type | Required | Default | Constraints |
|---|---|---|---|---|
person_image | image file | Yes | — | Decodable image; at most MAX_UPLOAD_BYTES |
cloth_image | image file | Yes | — | Decodable image; at most MAX_UPLOAD_BYTES |
steps | integer | No | 50 | 1–100 |
guidance_scale | number | No | 2.5 | 0–10 |
seed | integer | No | 42 | 0–2147483647 |
A successful request returns 200 OK with Content-Type: image/png. The seed used is also returned in the X-Inference-Seed response header.
curl --request POST http://localhost:8000/v1/try-on \
--form person_image=@CatVTON/inputs/person.jpg \
--form cloth_image=@CatVTON/inputs/cloth.jpg \
--form steps=30 \
--form guidance_scale=2.5 \
--form seed=42 \
--output try-on.png
Common error responses are 413 for oversized uploads, 415 for a non-image content type, 422 for an invalid image or invalid form parameters, 500 for inference failures, and 503 when the model is not ready.
GET /healthz returns {"status":"ok"} only after the model is loaded; otherwise it returns 503. Use it for container readiness checks.
requirements.txt installs the CUDA 12.1 PyTorch wheelCPU execution is supported by the configuration, but image generation will be slow and is best treated as a smoke test.
git clone https://github.com/Mahir-Uddin0/catvton-backend
cd catvton
python3.10 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --host 0.0.0.0 --port 8000
The initial startup downloads the required Hugging Face models. To download them before starting the server—for example while building a reusable machine image—run:
python scripts/download_models.py
Then verify the server once its startup logs finish:
curl http://localhost:8000/healthz
Interactive API documentation is available at http://localhost:8000/docs.
Copy .env.example to .env for local development. Environment variables provided by the shell or deployment platform take precedence over values in .env.
| Variable | Default | Purpose |
|---|---|---|
DEVICE | auto | auto, cuda, or cpu. auto selects CUDA when available. |
MIXED_PRECISION | bf16 | bf16, fp16, or no. CPU always uses float32; CUDA falls back to fp16 if BF16 is unavailable. |
OUTPUT_WIDTH | 768 | Generated image width; must be a positive multiple of 8. |
OUTPUT_HEIGHT | 1024 | Generated image height; must be a positive multiple of 8. |
MAX_UPLOAD_BYTES | 10485760 | Maximum size, in bytes, accepted for each uploaded image. |
ALLOWED_ORIGINS | http://localhost:3000 | Comma-separated CORS origins allowed to call the API from a browser. |
HF_HOME | ~/.cache/huggingface | Directory for downloaded model weights and Hugging Face cache. Mount this as persistent storage in containers. |
CATVTON_ROOT | ./CatVTON | Location of the bundled CatVTON source; it must contain model/pipeline.py. |
BASE_MODEL_ID | timbrooks/instruct-pix2pix | Hugging Face base model identifier or compatible local path. |
ATTENTION_CHECKPOINT_ID | zhengchong/CatVTON-MaskFree | Hugging Face CatVTON attention checkpoint identifier or compatible local path. |
PORT | 8000 in Docker | Uvicorn port used by the Docker command. |
Example production-oriented configuration:
DEVICE=cuda
MIXED_PRECISION=bf16
ALLOWED_ORIGINS=https://app.example.com
OUTPUT_WIDTH=768
OUTPUT_HEIGHT=1024
MAX_UPLOAD_BYTES=10485760
HF_HOME=/cache/huggingface
Build the supplied CUDA image and expose the same port the container listens on:
docker build --tag catvton-api .
docker run --rm --gpus all \
--publish 8080:8080 \
--env PORT=8080 \
--env DEVICE=cuda \
--env ALLOWED_ORIGINS=https://app.example.com \
--volume catvton-hf-cache:/cache/huggingface \
catvton-api
The image starts one Uvicorn worker. Keep one worker per GPU/model replica; adding workers loads another full model copy and increases GPU memory use.
CatVTONPix2PixPipeline, avoiding segmentation/mask input and excluding heavyweight Detectron2, DensePose, SCHP, and Gradio dependencies from the serving runtime.asyncio.Lock permits only one active generation per process. This keeps GPU memory predictable and avoids overlapping model calls; scale horizontally for concurrent requests.HF_HOME if that location is mounted.Built-in protections are intentionally narrow: the service validates the advertised image MIME type, attempts to decode every upload with Pillow, limits each upload size, and restricts browser origins through ALLOWED_ORIGINS.
Before exposing the API publicly, add the following:
ALLOWED_ORIGINS value—never use a permissive origin unnecessarily.The current pipeline is created with skip_safety_check=True; it does not run the upstream safety checker. If content moderation is required, implement it explicitly before returning outputs and ensure the policy is appropriate for your users and jurisdiction.
torch.compile, attention optimizations, TensorRT/ONNX paths where supported, and pre-warmed model caches.33 commits
Python
90.5%
JavaScript
3.3%
Cuda
3.2%
C++
2.3%