GR Apply PuLID Flux
The node that actually puts the face in
- model
- pulid_flux
- eva_clip
- face_analysis
- image
- attn_mask
- prior_image
- MODEL
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 nudgestart_atup to 0.1–0.2 so structure forms before the face locks in.face_select:center_face,largest_face,smallest_face,most_prominent, ornormal. This is where the GR fork earns its keep - feed it a group photo and pick which face you want. Withnormalyou also getuse_face_number+face_numberto index a specific person, andblurto skip blurred faces in a batch.fusion(defaultmean): only matters when you feed multiple reference images.mean,concat,max, and the fancierauto_weight/train_weight(the latter runs a tiny online-training pass overtrain_stepiterations 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."
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| pulid_flux | PULIDFLUX | — | |
| eva_clip | EVA_CLIP | — | |
| face_analysis | FACEANALYSIS | — | |
| image | IMAGE | — | |
| weight | FLOAT | 1.00-1–5 | — |
| start_at | FLOAT | 0.0000–1 | — |
| end_at | FLOAT | 1.0000–1 | — |
| use_face_number | BOOLEAN | — | |
| face_number | INT | None0–15 | — |
| blur | FLOAT | 0.010.01–1 | — |
| face_select | COMBO | 5 options: center_face, largest_face, smallest_face, most_prominent, normal | |
| fusion | COMBO | 7 options: mean, concat, max, norm_id, max_token, auto_weight, +1 | |
| fusion_weight_max | FLOAT | 1.00–20 | — |
| fusion_weight_min | FLOAT | 0.00–20 | — |
| train_step | INT | 10000–20000 | — |
| use_gray | BOOLEAN | true | — |
| attn_maskopt | MASK | — | |
| prior_imageopt | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |