Nodes/ComfyUI-FlashPortrait/FlashPortrait Feature Extractor
ComfyUI Node

FlashPortrait Feature Extractor

Turning a Driving Video Into a Face Script

By okdalto·Created 8 months ago·Updated 8 months ago· 25
FlashPortrait Feature Extractor
  • face_align_models
  • images
  • head_emo_features
  • fps
  • total_frames
source_fps25.00
context_size51
context_overlap30

Your reference image gives FlashPortrait the face. This node gives it the acting. The Feature Extractor reads the driving video you feed in, finds the face in every frame, and compresses head pose, eye movement, expression, and mouth motion into a single per-frame feature vector - the "script" the sampler later follows to animate your portrait. It's the quiet middle step, and the one beginners most often skip, because the nodes it sits between are so much more obvious.

Why this split matters

Here's the design decision that makes FlashPortrait work, straight from the paper: it's identity-agnostic. The extractor deliberately does not care whose face is in the driving video. It only pulls out motion and expression. The identity lives entirely in your reference image, which stays on the other side of the workflow. That separation is why the model can hold a face's likeness over hundreds of frames without it drifting into a zombie - the very thing its direct competitors visibly fail at (the release thread's top comment was literally about a rival turning the subject into a zombie by the end).

How it works

The node takes FACE_ALIGN_MODELS from the Loader (the onnx face-detection + landmark files and the PD-FGC model) and runs two passes over your frames: landmark detection and alignment, then expression extraction that produces eye, emotion, and mouth embeddings per frame. Each frame's embeddings get concatenated with a head-pose embedding into one head_emo vector. It also does two bits of bookkeeping you should know about:

  • Frames are trimmed so the count satisfies (N-1) % 4 == 0, which the Wan VAE's 4× temporal compression needs. A 53-frame clip silently becomes 49.
  • If your clip is shorter than context_size, it pads by repeating the last frame's features rather than erroring.

Note what it does not do: it extracts features for the whole video up front and hands the full stack to the sampler. The sliding-window stuff - where the "infinite length" actually happens - lives in the sampler, which re-walks these features in overlapping chunks.

The inputs and outputs that matter

  • images - your driving video frames. Hook up Load Video (or any node that outputs an IMAGE batch) and feed it frames here. This is the motion source; your actual portrait's face never touches this node.
  • source_fps - default 25. It just gets passed through to the output so whatever saves your video knows the playback rate, but get it roughly right.
  • context_size (51) and context_overlap (30) - these define the sliding-window stride (context_size − context_overlap). Keep them identical to the sampler's - both nodes take these inputs and they're describing the same window, so mismatched values mean the extractor and sampler are walking different chunks of the same video.
  • Outputs: head_emo_features (HEAD_EMO_FEAT) → the sampler's head_emo_features input. fps → downstream video nodes. total_frames → how many frames your animation will be, useful for setting up the save node.

Installing and running it

Same story as the rest of the pack: ComfyUI Manager (search "FlashPortrait") or git clone https://github.com/okdalto/ComfyUI-FlashPortrait into custom_nodes, install requirements.txt, restart. The extractor itself is the lightweight node of the three - the heavy memory lives in the Loader and the Sampler, so this one runs fast once the models are in.

A couple of practical notes: the extractor works on whatever you feed it, so a clean, single-face, well-lit driving clip gets you dramatically better expression capture than a chaotic one. And don't over-think it - for a first run, leave context_size and context_overlap at their defaults and just match the sampler to them. The defaults are the author's tested values, and the model's own config uses them too.

CategoryFlashPortrait

Inputs (5)

NameTypeDefaultDescription
face_align_modelsFACE_ALIGN_MODELS
imagesIMAGE
source_fpsFLOAT25.00
context_sizeINT51
context_overlapINT30

Outputs (3)

NameTypeDescription
head_emo_featuresHEAD_EMO_FEAT
fpsFLOAT
total_framesINT