FunPack Identity Transfer
Carrying a face into a video clip without a LoRA
- model
- vae
- positive
- negative
- latent
- image
- model
- positive
- negative
- status
Keeping a face consistent across an image is basically a solved problem: IP-Adapter FaceID, InstantID and PuLID all lean on InsightFace's ArcFace embeddings and get you close. Keeping that same face across a moving clip is a different story, and the usual answer is "train a LoRA of the person and hope the motion doesn't break it." FunPack Identity Transfer is the zero-training attempt: push a reference face into the clip as extra tokens the model attends to, and optionally nudge it with ArcFace text tokens on top.
Fair warning before the how-to: the pack's own changelog files identity transfer as experimental - built and run, not proven over many runs - and the node's description names LTX, which this pack marks untested. This is a lab bench, not a product. Treat a good result as a bonus.
How the reference gets in
You wire a picture, and the node resizes it to the clip's latent frame, encodes it with the picture VAE, and appends those latents as separate tokens. The model attends to them like anything else in the sequence. source_id sets a source-phase marker on those tokens - the trainer used 2 - so the model can tell "reference" rows from "the clip I'm generating" rows. Setting it to 0 turns that rotation off and leaves the tokens in place, which is a diagnostic, not a setting you'd ship.
If you also point identity_projector at an ArcFace projector .safetensors (it's picked from models/loras), the node detects the face, runs it through ArcFace, and maps that embedding to text tokens with a small network. id_strength multiplies those tokens - the tooltip is refreshingly blunt that this is "a weak channel: 5-20 to test", so don't expect 1.0 to do much.
Worth noting what the author claims about the split: the overlap tokens "carry most of the identity" and ArcFace is the extra. If your projector isn't installed or the face won't detect, you're not left with nothing.
Inputs and outputs
Required: model, vae (the picture VAE that encodes the reference), positive, negative, and latent - the clip's starting latent, because the reference gets sized to its frame. That last one is load-bearing: this node needs a video latent, with frames, height and width. A 2-D image latent raises an error rather than doing something creative.
Optional: image (no image = no identity transfer, full pass-through), identity_projector, source_id, phase_scale (0–4, a multiplier on the phase marker), id_strength, and arcface_mode - auto_adjust retries face detection zoomed out and up, as_is only looks at the image as given, disable skips ArcFace entirely.
Outputs are model, positive, negative and status. Wire the model into the sampler and the conditionings where they were going. Read the status: it narrates honestly, something like "reference tokens appended (source phase 2)" or "ArcFace found no face: overlap tokens only" - which is your cue to try a cleaner, more frontal reference.
Because there's no image, wiring this node into a graph and never using it costs you nothing: everything comes out untouched. That's a nice property for a node you're still evaluating.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/olivv-cs/ComfyUI-FunPack
pip install -r ComfyUI-FunPack/requirements.txt
Or install through ComfyUI Manager by searching ComfyUI-FunPack; restart afterwards. The pack uses your existing torch. If you plan on using the ArcFace path, put the projector .safetensors in models/loras - that's the folder the dropdown lists, which surprises people every time.
Where it goes wrong
The realistic failure isn't an exception, it's a clip that looks like your reference for two seconds and then drifts into a cousin. That's the state of identity in video generally, not a bug in this node. Push id_strength up and you'll trade drift for a face that looks pasted on; there's no magic value, and the honest answer is that you're balancing two failure modes.
Then the structural traps: a non-video latent (error), a reference that's too small or too stylized for detection (status tells you), and the pack-level one - if the identity transfer module fails to load, FunPack skips it and says so beside Generate rather than killing the run. One quirk the changelog calls out: the Reference 1 picture stays on screen and silently does nothing until the module is back.
And the boring regulatory one, since it applies to this pack as a whole: MiniMax H3's weights exclude the US, EU, UK and South Korea from their licence territory. If you're in one of those places, the thing stopping your video project isn't the node.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| vae | VAE | The picture VAE, to encode the reference. | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| latent | LATENT | The clip's starting latent: the reference is sized to its frame. | |
| imageopt | IMAGE | The reference face. None = no identity transfer. | |
| identity_projectoropt | COMBO | None | ArcFace projector .safetensors (models/loras). None = the overlap tokens only (they carry most of the identity). |
| source_idopt | FLOAT | 20–8 | Source-phase id for the reference tokens (the trainer used 2). 0 turns the rotation off, leaving the tokens in. |
| phase_scaleopt | FLOAT | 1.00–4 | — |
| id_strengthopt | FLOAT | 1.00–50 | Multiplies the ArcFace tokens. A weak channel: 5-20 to test. |
| arcface_modeopt | COMBO | auto_adjust | auto_adjust retries detection zoomed out/up; as_is detects on the image only; disable skips ArcFace. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |
| positive | CONDITIONING | — |
| negative | CONDITIONING | — |
| status | STRING | — |