Arc2Face Generator
The Arc2Face Generator
- face_embedding
- unet
- encoder
- IMAGE
This is the payoff node. The Face Extractor gave you a 512-number face vector, the two loaders gave you the model, and the Arc2Face Generator turns all of it into an actual image of that person. It's text-to-image in the technical sense - a diffusers StableDiffusionPipeline running - but the "text" is a face, and that difference is the whole point of the pack.
Arc2Face is an SD1.5 UNet fine-tuned on millions of face photos conditioned on ArcFace embeddings. Here's how the conditioning actually works: the pipeline encodes a fixed prompt, "photo of a id person", then injects your embedding at the position of the word "id" and runs the whole thing through the custom text encoder. That's the project_face_embs function in the pack. And because the model was trained this way, there's deliberately no positive prompt - the author tested positive text and found it ruined outputs. The embedding is the identity, the negative prompt just keeps it clean.
The wiring
Three sockets come from other nodes, and this is the whole reason the pack has loaders:
- face_embedding -
FACE_EMBEDDINGout of the Face Extractor. - unet -
ARC2FACE_UNETout of the UNet Loader. - encoder -
ARC2FACE_ENCODERout of the Encoder Loader.
If any of those three is missing, the node has nothing to work with.
The knobs that matter
- num_inference_steps - 30 default. It's an SD1.5-class model, so 25–35 is the sane range; more steps buy you almost nothing.
- guidance_scale - 2.7 default. Keep it low. This isn't a CFG-hungry model - crank it and faces start burning. The default negative prompt ("ugly, deformed, noisy, blurry, low contrast, split image") is genuinely worth keeping.
- num_images - 1–4 per run; nice for picking a keeper.
- width / height - 512 default, in steps of 64. The README is blunt: the model works best near 512×512. Generate small and upscale afterwards rather than asking it for 1024 directly.
- seed -
-1means random, so you can leave it alone unless you're hunting a specific frame.
Output
IMAGE - one or a batch of portraits, depending on num_images. Straight into any Save Image or Preview Image node.
Install and the first-run surprise
cd ComfyUI/custom_nodes
git clone https://github.com/caleboleary/ComfyUI-Arc2Face.git
pip install -r requirements.txt
The generator builds its pipeline on the botp/stable-diffusion-v1-5 base from Hugging Face, swapping in the Arc2Face UNet and encoder and replacing the scheduler with DPM-Solver++. So the first generation downloads the whole SD1.5 base - network access and a few gigabytes, mid-run, with no progress bar in ComfyUI. It looks hung. It isn't. Let it finish once and it's cached.
Honest expectations
Community reaction at release was "works pretty well overall" plus "don't expect miracles." That's the accurate review. Arc2Face is excellent at close-crop faces from an embedding - arguably the best tool in the space for turning a pure embedding back into a face, which is a genuinely rare capability. It does not control pose, expression, or composition; those come from the Img2Img generator. And by 2026, character-consistency work has largely moved to adapters and instruction-driven editing - if you're doing a full character across many scenes, this pack isn't that. For "I have photos of this face and want it rendered," it's still exactly right.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| face_embedding | FACE_EMBEDDING | — | |
| unet | ARC2FACE_UNET | — | |
| encoder | ARC2FACE_ENCODER | — | |
| negative_prompt | STRING | ugly, deformed, noisy, blurry, low contrast, split image | — |
| num_inference_steps | INT | 301–100 | — |
| guidance_scale | FLOAT | 2.70.1–30 | — |
| num_images | INT | 11–4 | — |
| width | INT | 51264–2048 | — |
| height | INT | 51264–2048 | — |
| seed | INT | -1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |