Nodes/ComfyUI-PuLID-Flux-GR/GR Apply PuLID Flux
ComfyUI Node

GR Apply PuLID Flux

The node that actually puts the face in

By GraftingRayman·Created 2 years ago·Updated 2 months ago· 60
GR Apply PuLID Flux
  • model
  • pulid_flux
  • eva_clip
  • face_analysis
  • image
  • attn_mask
  • prior_image
  • MODEL
weight1.00
start_at0.000
end_at1.000
use_face_number
face_numberNone
blur0.01
face_select
fusion
fusion_weight_max1.0
fusion_weight_min0.0
train_step1000
use_graytrue

This is the node where PuLID actually happens. The other three in the ComfyUI-PuLID-Flux-GR pack are just its groceries: one loads the PuLID model, one loads a face detector, one loads a CLIP model. GR Apply PuLID Flux takes the reference photo and your Flux checkpoint and hands back a patched model that will draw your subject's face into whatever you prompt.

If you've ever used PuLID for Flux, you know the drill - ByteDance's identity adapter won the Flux era of face customization because it shipped a port before InstantID ever did, and because its contrastive-alignment training meant you got the face without wrecking prompt adherence. This GR variant is GraftingRayman's enhanced fork of the standard balazik node, and it's the pack that showed up in that 663-upvote "PuLID Face ID with Multiple ControlNets" workflow from early 2025. The author's own pitch, posted when someone was stuck on an older node: "you can try my repo… had to fix some long standing issues." That's about right.

How it works

Give it a photo and it builds a combined identity embedding out of two halves: an InsightFace ArcFace embedding (the biometric "who" - facial geometry, not appearance) and EVA-CLIP visual features from the face crop. Both run through PuLID's IDFormer encoder, and the result is injected into Flux via perceiver cross-attention patched into the model's forward pass - only between start_at and end_at in the denoising schedule, so you can let the composition settle first. If it can't find a face in your image, it logs a warning and returns the model untouched, which is how it tells you you've fed it a bad reference.

The inputs that actually matter

The first five are fixed: model (your Flux checkpoint), pulid_flux, eva_clip, face_analysis (all three loaded by this pack's loader nodes), and image - the reference face. Then:

  • weight (default 1.0, range -1 to 5): how hard the identity is pushed. 0.8–1.2 is the sane zone; crank toward 2+ and likeness hardens but the image gets a bit plasticky. The official repo quotes 16GB VRAM for Flux, and on less than that watch out for OOMs here.
  • start_at / end_at (0 to 1): the denoising window the patch is active for. Defaults are the full range; you'll often nudge start_at up to 0.1–0.2 so structure forms before the face locks in.
  • face_select: center_face, largest_face, smallest_face, most_prominent, or normal. This is where the GR fork earns its keep - feed it a group photo and pick which face you want. With normal you also get use_face_number + face_number to index a specific person, and blur to skip blurred faces in a batch.
  • fusion (default mean): only matters when you feed multiple reference images. mean, concat, max, and the fancier auto_weight / train_weight (the latter runs a tiny online-training pass over train_step iterations to weight each face). For one photo, leave it.
  • use_gray (default on): masks out hair and background from the face crop before CLIP encodes it, so only the actual face features condition the model. Usually leave it on.

Optional inputs: prior_image, which you can concatenate as extra conditioning to hold composition; and attn_mask, which is accepted but masking support is unfinished in the code - don't build a workflow that depends on it.

The single output is MODEL, wired straight into your KSampler.

Installing it

You're installing the whole pack either way - via ComfyUI Manager (search "ComfyUI-PuLID-Flux-GR"), or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/GraftingRayman/ComfyUI-PuLID-Flux-GR
cd ComfyUI-PuLID-Flux-GR
pip install -r requirements.txt

Portable installs have to aim pip at their own Python: ComfyUI\python_embeded\python.exe -m pip install -r ...\requirements.txt. The requirements list is heavy (insightface, onnxruntime, onnxruntime-gpu, facexlib, timm, filterpy), and the onnx stack is the known trap - the classic community failure was onnxruntime 1.16+ breaking insightface, fixed by pinning onnx==1.14.0 and onnxruntime-gpu==1.15.0. The other telltale error, "Two devices issue on several passes," also points back at a mismatched onnx install, not at this node.

The pack's repo was renamed in January 2025 specifically so it wouldn't collide with older PuLID installs - if you've got another ComfyUI-PuLID-Flux* folder, don't keep both.

Realistic expectations

PuLID gets you a convincing, on-model face from one photo, and it stops a step short of a perfect likeness. The community recipe is PuLID for structure, then ACE++ or Flux Fill to close the last few percent. Also keep the license footnote in mind: the PuLID weights are Apache 2.0, but the InsightFace antelopev2 models underneath are non-commercial - relevant if this leaves the hobby box. And the face_select "normal" option picks, in the author's own words, "usually the face to the far right of the image, but don't count on that."

Categorypulid

Inputs (19)

NameTypeDefaultDescription
modelMODEL
pulid_fluxPULIDFLUX
eva_clipEVA_CLIP
face_analysisFACEANALYSIS
imageIMAGE
weightFLOAT1.00-1–5
start_atFLOAT0.0000–1
end_atFLOAT1.0000–1
use_face_numberBOOLEAN
face_numberINTNone0–15
blurFLOAT0.010.01–1
face_selectCOMBO5 options: center_face, largest_face, smallest_face, most_prominent, normal
fusionCOMBO7 options: mean, concat, max, norm_id, max_token, auto_weight, +1
fusion_weight_maxFLOAT1.00–20
fusion_weight_minFLOAT0.00–20
train_stepINT10000–20000
use_grayBOOLEANtrue
attn_maskoptMASK
prior_imageoptIMAGE

Outputs (1)

NameTypeDescription
MODELMODEL