ComfyUI Node

Arc2Face Generator

The Arc2Face Generator

By caleboleary·Created 2 years ago·Updated 2 years ago· 53
Arc2Face Generator
  • face_embedding
  • unet
  • encoder
  • IMAGE
negative_promptugly, deformed, noisy, blurry, low contrast, split image
num_inference_steps30
guidance_scale2.7
num_images1
width512
height512
seed-1

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_EMBEDDING out of the Face Extractor.
  • unet - ARC2FACE_UNET out of the UNet Loader.
  • encoder - ARC2FACE_ENCODER out 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 - -1 means 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.

CategoryArc2Face

Inputs (10)

NameTypeDefaultDescription
face_embeddingFACE_EMBEDDING
unetARC2FACE_UNET
encoderARC2FACE_ENCODER
negative_promptSTRINGugly, deformed, noisy, blurry, low contrast, split image
num_inference_stepsINT301–100
guidance_scaleFLOAT2.70.1–30
num_imagesINT11–4
widthINT51264–2048
heightINT51264–2048
seedINT-1

Outputs (1)

NameTypeDescription
IMAGEIMAGE