Nodes/Temporal Face Detailer/Temporal Face Detailer (SDXL video)
ComfyUI Node

Temporal Face Detailer (SDXL video)

Fix video faces without the flicker — a FaceDetailer that actually tracks

By nikythebikky·Created 2 months ago·Updated 2 months ago· 0
Temporal Face Detailer (SDXL video)
  • image
  • model
  • clip
  • vae
  • positive
  • negative
  • lora_stack
  • reference_image
  • image
  • face_masks
  • debug_overlay
  • face_tracks
positive_textdetailed face, sharp eyes, high quality skin texture
negative_textblurry, deformed, low quality
detectorinsightface
det_threshold0.50
min_face_size24
max_faces4
detector_devicecuda
iou_threshold0.25
max_track_gap10
min_track_length2
crop_factor1.7
crop_smoothing0.80
crop_anchorlandmarks
align_rotationfalse
guide_size768
max_size1024
seed0
steps20
cfg7.0
sampler_name
scheduler
denoise0.35
denoise_max0.00
noise_modefixed_per_track
detail_modeimg2img
mask_dilation8
feather15
temporal_strength1.00
flow_strength0.50
latent_blend0.00
flow_bidirectionaltrue
flow_backendfarneback
color_match0.50
chunk_size4
detail_every1
track_prompts
reference_strength0.35

If you've ever run Impact Pack's FaceDetailer on every frame of a video, you already know why this node exists. Each frame gets a fresh img2img pass with fresh noise, the face sharpens up nicely - and then morphs, shimmers, or straight-up changes identity a few frames later. Per-frame detailing fixes faces and creates flicker in the same gesture.

Temporal Face Detailer is the video-grade version of that loop. It detects and tracks faces across the whole frame batch, re-details each tracked face with a fixed seed and stabilized crops, and blends the results with optical flow, so you get the detail pass without the strobe light. One node does the entire pipeline: detect → track → detail → smooth → paste back. It's SDXL-only - you feed it a normal checkpoint's MODEL, CLIP, and VAE, and frames from a video loader like VideoHelperSuite's Load Video (Upload).

How it works

The anti-flicker magic is layered, and worth knowing - every lever is a widget on this node:

  1. Tracked, stabilized crops. Faces are linked into identity tracks frame-to-frame (greedy association on IoU + center distance, with a constant-velocity prediction). Each track's crop is centered on the facial-landmark centroid instead of the wobbly detection box (crop_anchor: landmarks), and the window is smoothed over time - the sampled region barely moves, so neither does the result.
  2. Fixed per-track seed and noise. Every frame in a track is sampled from the same noise - the source literally replicates one noise tensor across the track's frames. Single biggest identity-stability lever, and on by default (noise_mode: fixed_per_track).
  3. Moderate denoise. Default 0.35, and the README's 0.3–0.45 sweet spot is right. denoise_max adds adaptive denoise: steady frames stay locked at the base value while high-motion frames ramp up, where correction is most needed and flicker is masked by the motion anyway.
  4. Flow-guided temporal blending in pixel space (flow_strength) and optionally latent space (latent_blend). Optical flow from the originals warps the running result onto each new frame, occlusion-aware so motion doesn't smear. Latent blending smooths in the VAE's semantic space and lets you raise denoise before flicker shows.
  5. Color match + feathered paste-back. Each crop's exposure is pinned to its source (no brightness pulsing), and only the face region is composited back, so backgrounds stay pixel-exact.

The inputs that matter

Wire image, model, clip, vae, type a positive/negative prompt (the widgets are fine - positive/negative conditioning inputs override them if you prefer encode nodes), and hit go. Defaults are genuinely good for a first pass. The ones you'll actually touch:

  • denoise - the main quality-vs-consistency knob.
  • noise_mode - leave it on fixed_per_track.
  • detector - insightface for realistic faces, a yolo:... anime model for stylized ones.
  • reference_image - a clean face photo to anchor identity against (see below).
  • chunk_size - lower it (default 4) if you OOM.
  • detail_every - set 2–4 on long clips; it samples keyframes and flow-propagates the rest for a big speedup.

Outputs: image goes to Video Combine (the final video), face_masks to a preview/save, debug_overlay to a second Video Combine if you want to inspect tracking, and face_tracks to Face Track Preview or a second-pass detail.

Installing it

ComfyUI Manager - search "Temporal Face Detailer" - or the manual way:

cd ComfyUI/custom_nodes
git clone https://github.com/nikythebikky/ComfyUI-Temporal-Face-Detailer
pip install -r ComfyUI-Temporal-Face-Detailer/requirements.txt

Then restart. The heavy lift is insightface (RetinaFace) plus onnxruntime - swap for onnxruntime-gpu to run detection on CUDA. InsightFace's models auto-download into models/insightface, shared with ReActor and friends; if it isn't installed, the nodes fall back to OpenCV YuNet, then to a Haar cascade.

Where people get burned

Anime faces. Realistic-face detectors miss or jitter on stylized characters, and unstable detection is a root cause of flicker no downstream blending can fix. Install ultralytics and drop face_yolov8m_anime.pt (same weights Impact Pack uses) into models/ultralytics/bbox/, then pick yolo:bbox/face_yolov8m_anime.pt. The README's recipe for WAN Animate post-pass: keep denoise low (~0.15), add latent_blend 0.4, anchor with a reference_image, use raft_small flow on fast motion.

Identity drift over a long clip. Temporal blending keeps frames consistent with each other, but the whole sequence can drift away from who it should be. Connect a reference face to reference_image - it nudges each frame's init latent toward the reference (scaled by reference_strength × denoise, so it won't ghost at low denoise) and color-anchors the face region. For strong identity, patch the model with IPAdapter FaceID upstream and feed the patched model in.

Turing GPUs. Tested on a 22 GB 2080 Ti, the pack explicitly warns: don't enable SageAttention on Turing - it silently produces NaN/black frames. fp16/bf16 only, no fp8 needed.

Flicker you can't kill. Check debug_overlay first - if the boxes themselves flicker or drop out, no smoothing fixes the root cause. Switch detectors before you touch denoise.

CategoryTemporalFaceDetailer

Inputs (45)

NameTypeDefaultDescription
imageIMAGEvideo frame batch
modelMODEL
clipCLIP
vaeVAE
positive_textSTRINGdetailed face, sharp eyes, high quality skin texture
negative_textSTRINGblurry, deformed, low quality
detectorCOMBOinsightfaceyolo:* entries are ultralytics models found in models/ultralytics — use an anime face model (e.g. bbox/face_yolov8m_anime.pt) for stylized characters
det_thresholdFLOAT0.500.05–1
min_face_sizeINT248–1024
max_facesINT41–16
detector_deviceCOMBOcuda2 options: cuda, cpu
iou_thresholdFLOAT0.250.05–0.95min overlap to link a detection to a track
max_track_gapINT100–120frames a face may vanish (occlusion) before its track ends; gaps are interpolated
min_track_lengthINT21–120
crop_factorFLOAT1.71–4
crop_smoothingFLOAT0.800–1temporal smoothing of the crop window (anti-jitter)
crop_anchorCOMBOlandmarkslandmarks centers the crop on the facial-landmark centroid (far more stable than the detection box); falls back to bbox when the detector yields no landmarks
align_rotationBOOLEANfalserotation-register crops so the eye line is horizontal in every sampled crop (similarity transform, inverse-warped on paste-back); needs a landmark-capable detector
guide_sizeINT768256–2048resolution faces are resampled at
max_sizeINT1024256–2048
seedINT00–18446744073709550000
stepsINT201–100
cfgFLOAT7.00–30
sampler_nameCOMBO44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBO9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
denoiseFLOAT0.350–1main quality/consistency lever: higher = more detail but more flicker (0.3-0.45 recommended)
denoise_maxFLOAT0.000–1adaptive denoise: when above 'denoise', steady frames keep the low base value while high-motion frames ramp toward this. 0 = off (single global denoise)
noise_modeCOMBOfixed_per_trackfixed_per_track reuses the same seed and noise on every frame of a track — the biggest identity-stability lever
detail_modeCOMBOimg2imginpaint restricts sampling to the face mask in latent space; img2img resamples the whole crop (mask still limits the paste-back)
mask_dilationINT80–128
featherINT150–128
temporal_strengthFLOAT1.000–1master anti-flicker strength; scales flow blend + color match
flow_strengthFLOAT0.500–1optical-flow-guided temporal blend of detailed crops (pixel space)
latent_blendFLOAT0.000–1flow-guided temporal blend in LATENT space before decode — smooths in the VAE's semantic space, letting you raise denoise with less flicker. Try 0.3-0.5 with denoise 0.25+; 0 = off
flow_bidirectionalBOOLEANtrue
flow_backendCOMBOfarnebackraft_small/raft_large (torchvision) give much cleaner flow on fast motion at some VRAM/time cost; auto-falls back to farneback on any failure
color_matchFLOAT0.500–1match each detailed crop's color to its source (stops brightness pulsing)
chunk_sizeINT41–64crops sampled per batch; lower if you hit OOM
detail_everyINT11–30keyframe mode: sample every Nth frame, flow-propagate the rest (speed on long clips)
positiveoptCONDITIONINGoverrides positive_text
negativeoptCONDITIONINGoverrides negative_text
lora_stackoptLORA_STACK
track_promptsoptSTRINGper-track positive prompt overrides, one per line: 'track_id: prompt' (see the debug overlay for IDs)
reference_imageoptIMAGEidentity anchor: a reference face image the detailed faces are biased toward (init-latent nudge + color anchoring). For strong identity conditioning also patch the MODEL with IPAdapter FaceID upstream — crops are sampled with whatever model you feed in, so it composes
reference_strengthoptFLOAT0.350–1how hard to pull toward reference_image (no effect unless it is connected)

Outputs (4)

NameTypeDescription
imageIMAGE
face_masksMASK
debug_overlayIMAGE
face_tracksFACE_TRACKS