A ComfyUI pipeline that swaps a person's head/face/hair onto an existing photo while preserving the original pose, framing, and background — using text-prompted segmentation (SAM3) + a LoRA-trained identity model on Krea2 Turbo, with a low-denoise inpaint-and-stitch step for a clean, seamless result.
No manual masking required — you describe the target in plain text ("head, face, neck, and hair of womant") and the workflow does the rest.
What it does - Face Swap (Very Automated) and Headswap (Requires Some Tweaking if Input image looks a lot different than character lora)
1. Takes a single input photo (any pose). Works best with only 1 person in the photo.
2. Uses SAM3 with a text prompt to auto-segment the target head/face/neck region — works even with multiple people in frame if you specify "left"/"right"/"man"/"woman." can work with a man and woman in the same photo, but gets confused if it's 2 women or 2 men.
3. Crops tightly around that region (**Inpaint Crop**) so the diffusion model only has to work on the relevant area.
4. Encodes the crop and applies a noise mask that locks in the original pose and scale.
5. Runs it through Krea2 Turbo with your trained Character identity LoRA, at a low denoise strength — swapping identity while keeping composition intact.
6. Stitches the refined region back into the untouched original image, so background, body, and lighting are preserved exactly.
Requirements
Models (place in the usual ComfyUI model folders):
| Type | File | Used for |
|---|---|---|
| UNet | krea2_turbo_int8_convrot.safetensors | Base diffusion model | (Could use others)
| CLIP | qwen3vl_4b_fp8_scaled.safetensors | Text conditioning |
| VAE | qwen_image_vae.safetensors | Encode/decode |
| Checkpoint | sam3.1_multiplex_fp16.safetensors | Segmentation |
| LoRA | your trained identity LoRA (e.g. cy_krea2_lora_step_700_comfyui.safetensors) | The face you're swapping in |
Custom nodes:
- SAM3 nodes SAM3_Detect)
- Inpaint Crop/Stitch nodes InpaintCropImproved, InpaintStitchImproved)
- Standard ComfyUI core nodes (KSampler, VAE Encode/Decode, LoRA Loader, etc.)
Hardware: tested at int8/fp8 precision — should run on consumer GPUs with ~8GB+ VRAM. (I tested on 8 gigs vram. 32 gigs ram.
---
How to use
1. Load your photo into the "Load Your Photo" node.
2. In the SAM3 Prompt node, describe the target: e.g. head, face, neck, and hair of woman, looking forward. If there's more than one person in frame, specify which one: "man to the left" or "woman to the right".
3. In the Identity Prompt node, use your LoRA's trigger word plus the same description: [trigger word], head, face, neck, and hair of woman, looking forward.
4. Check the DEBUG mask preview — confirm the mask actually covers the head and isn't blank.
5. Run the full workflow. Final output saves as krea2_single_final.
### Tuning tips (from the original build notes)
- Denoise (KSampler): 0.2–0.5 is the sweet spot. Lower keeps positioning locked; above ~0.5 the model starts taking more creative liberties with pose/composition.
- Mask tightness (Grow Mask "expand"): if the head looks cut off, increase expand up to ~5. If the mask is bleeding into other areas (hair into background, etc.), use a negative value to shrink it.
- SAM3 prompt specificity: always state gender/position when more than one person is in the photo — this is what determines which head actually gets swapped.
---
## Known issues ##
### "Left/right" in the SAM3 prompt doesn't work for two people of the same class
SAM3's text detection matches by class description ("woman," "man"), not real spatial position. "woman on the left" correctly isolates one person when the other person is a man — but that's because gender did the filtering, not the position. With two women in frame, both match "woman" and get merged into a single mask. Best to crop input image to one person.
### Skin tone mismatch at the seam when source and target skin tones differ a lot (e.g. LoRA identity is a different ethnicity than the source photo)
GrowMask expand (node 5) and mask_blend_pixels on the Inpaint Crop node (node 8) aren't a simple on/off fix — they're a dial between two opposite failure modes:
- Too low → abrupt/incomplete: the mask undersizes the actual face, so original skin tone snaps back in visibly at the edges.
- Too high → over-blended: the feather zone gets wide enough to visibly average the two skin tones into a muddy gradient instead of a clean edge.
There's a sweet spot in between, and it shifts per-photo depending on how much contrast there is between the original and target skin tone, and how tight the crop is around the neck/collar. The bigger the skin-tone contrast, the tighter/smaller both values generally need to be — heavy blending forgives a small mismatch but exaggerates a large one.
Recommended process:
1. Start with GrowMask expand ~5–8 and mask_blend_pixels ~10–15 as a baseline.
2. Run once, check the result specifically at the jaw/neck seam.
3. If you still see a ring of the original skin tone bleeding through → increase expand a few pixels at a time (coverage problem, not a blend problem).
4. If the seam is fully covered but looks like a muddy gradient between the two tones → reduce mask_blend_pixels a few pixels at a time (feather problem, not a coverage problem).
5. Re-check the DEBUG mask preview after each change.
Also note: these settings only affect the seam right at the edge of whatever SAM3 segmented (head/face/hair/neck). Skin visible outside that mask — shoulders, chest, arms — is never touched by the workflow at all, since it was never part of the detected region to begin with. No amount of mask tuning reaches it. If your source photos show visible body below the neckline and you need that to match too, either broaden the SAM3 prompt to include it (e.g. "head, face, neck, upper chest, and shoulders") or favor tighter headshot/bust-crop source photos, which sidesteps the issue entirely and is the more common convention for head-swap workflows.
### The mask debug image doesn't update when I just change the seed
This is expected — not a bug. ComfyUI caches each node's output and skips re-running a node if its inputs haven't changed. Randomizing the seed only affects the KSampler; it doesn't touch the image, SAM3 prompt, threshold, or mask expand value, so the SAM3 detect → mask debug chain is correctly skipped and reused from cache.
It'll only regenerate if you change: the input photo, the SAM3 prompt text, the threshold, or the Tighten Mask expand value. To force a fresh pass anyway, right-click the SAM3 Detect node and use its "Run" option, or nudge the prompt text and change it back.
If you don't want the mask to save every time , just bypass that n ode, it's for easy visual testing of the sam3 masking.
---
## Usage policy
This workflow is shared for creative, VFX, and consensual-use cases (character work, restoration, avatars, etc.). Do not use it to depict real people without their consent, and do not use it to create non-consensual intimate or explicit imagery. Users are responsible for complying with applicable laws and the terms of any platform they upload results to.
---
## Credits
Built by [https://civarchive.com/user/anonameguyman1234252]. Uses SAM3, Krea2 Turbo, and Qwen3-VL. Trained identity LoRA is user-supplied.






