Get Face Expression
Get Face Expression — the node that pulls the face's motion out of a video
- face_toolkits
- images
- landmarks
- expression
HelloMeme is a talking-head/face-reenactment pack: you give it one reference photo and a "driving" face, and it makes the photo perform the driving face's motions. The tricky part is how that motion gets into the diffusion model at all. That's this node's job. It reads an image or video of a face and returns a compact EXPRESSION object - the eye, brow, mouth, and cheek movement that HelloMeme Image Pipeline and HelloMeme Video Pipeline use as conditioning.
Think of it as the expression half of the driving signal. The other half (head rotation and position) is handled by GetHeadPose; the two always run side by side, both fed by the same landmarks.
How it works
Under the hood it doesn't do any diffusion. It hands your frames plus their landmarks to the face-analysis models inside the FACE_TOOLKITS object - the ARKit blendshape predictor and the 3DMM head-model predictor that HMFaceToolkitsLoader loads at the start of the graph. Those produce the expression parameters, wrapped into the EXPRESSION tensor your pipeline nodes consume.
It can't run alone. It needs landmarks from GetFaceLandmarks, which in turn needs face_toolkits from the loader. The chain is always: Load Face Toolkits → Get Face Landmarks → GetHeadPose + GetExpression.
The inputs and output that matter
face_toolkits- the toolkit bundle fromHMFaceToolkitsLoader. Non-negotiable.images- one reference image or a batch of driving frames. Feed it a single frame if you want a static reference expression, or the whole driving clip if you want the drive.landmarks- theFACELANDMARKS222output fromGetFaceLandmarks, computed on the same frames. Mismatched frames give garbage.
Output: expression, an EXPRESSION object. It has two natural homes - the ref_expression socket (what the reference face is doing) and drive_expression (what you want it to do). Most workflows run one instance of the node per source: once on the reference image, once on the driving video.
There's a sibling called Get Face Expression V2 (GetExpression2) that does the same job with a different motion extractor - see its article before you assume which to use.
Installing it
This node ships with the whole HelloMeme pack, so install once and you get all nine nodes. Easiest route is ComfyUI Manager - search for the keyword hellomeme-api (that's the pack's Manager keyword, straight from the README) and hit install. Or clone it manually:
cd ComfyUI/custom_nodes
git clone https://github.com/HelloVision/ComfyUI_HelloMeme
# restart ComfyUI
The pack's requirements.txt is heavy - transformers, diffusers, accelerate, onnxruntime, opencv-python, peft, modelscope and friends. Manager installs them automatically; with a manual clone you'll want a ComfyUI Python environment that already has the diffusers stack. The first run also silently downloads the face toolkits and the HM model modules from HuggingFace (or ModelScope, if you flip deployment), so give the first load time.
Common issues
- A frame with no detectable face kills the run. The landmark node asserts if any frame lacks a face, and this node inherits that. If your driving clip has a face leaving the frame, trim it or use a cleaner clip.
- Wrong landmarks. If
imagesandlandmarkscome from different sources, expression output is nonsense. Keep the node on the same frames you ranGetFaceLandmarkson. - Wobbly, "morphy" output. Community reports of too much morphing and body movement trace back to the driving source as often as the pipeline. A clean, front-on driving face with the reference cropped so the face fills the frame (the pack's own guidance: face proportion in the reference image significantly affects quality) fixes more than tweaking settings does.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| face_toolkits | FACE_TOOLKITS | — | |
| images | IMAGE | — | |
| landmarks | FACELANDMARKS222 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| expression | EXPRESSION | — |