Nodes/ComfyUI-H3-FaceRefine/H3 Per-Frame Denoise
ComfyUI Node

H3 Per-Frame Denoise

Per-frame denoise, so one pass can fix a whole shot

By Carasibana·Created 13 days ago·Updated 13 days ago· 292
H3 Per-Frame Denoise
  • av_latent
  • transform
  • av_latent
  • report
strength_small_face1.00
strength_large_face0.35
scale_modeabsolute_px
face_px_small30
face_px_large120
gamma1.0
smooth_frames9

H3 Per-Frame Denoise varies denoise strength along the length of a clip inside a single sampling pass, scaling it inversely to face size. It exists because one denoise value cannot serve a shot where the subject walks from distant to close - and that's exactly the kind of shot the ComfyUI-H3-FaceRefine pack was built for.

Think about what the two ends need. A tiny face has no detail worth preserving; it wants a strong pass so H3 synthesizes a face where there was a smear. A large face has real, genuine detail, and a strong pass would rewrite it into something slightly wrong. One global denoise can't be both. This node reads the per-frame face size out of the tracker's transform, and scales the base denoise down as faces get bigger, leaving distant frames to take the full hit.

How it works

The sampler builds one sigma schedule for a whole clip, so every frame normally gets the same denoise. ComfyUI's noise_mask is the escape hatch: it scales denoising per latent position, and varied along the temporal axis it gives per-frame strength out of one sampling pass. The node computes face height per frame from the transform (crop height ÷ crop_factor), interpolates between strength_small_face and strength_large_face, applies a gamma curve, and smooths the resulting strength over smooth_frames - because an abrupt denoise change between neighbouring frames shows up as a texture pop.

Two placement details matter. It goes after MiniMaxH3NativeAudioLock, and it deliberately preserves that node's audio-side zeros in the noise mask - those are what keep the audio clean and drive lipsync. And the granularity is one latent frame, which is roughly 3.4 pixel frames; the strength curve is resampled to fit.

Inputs that matter

  • av_latent - from MiniMaxH3NativeAudioLock.
  • transform - from H3 Face Track + Crop; this is where face sizes come from.
  • strength_small_face (1.0) - multiplier where the face is smallest; 1.0 means the full denoise set on BasicScheduler.
  • strength_large_face (0.35) - multiplier where the face is largest; lower preserves the detail those frames already have.
  • scale_mode - absolute_px (default) keys off real face size in source pixels, which is safe across a batch: a clip that never has a small face just sits at the baseline. relative_to_clip normalises to that clip's own min/max so its smallest face always gets the full boost - use it when tuning one clip to its extremes.
  • face_px_small (30) / face_px_large (120) - the source-pixel face heights bracketing the ramp. Anything past 120px gets none of the boost.
  • gamma (1.0) - the curve; above 1 keeps strength high until the face is genuinely large.
  • smooth_frames (9) - time smoothing on the strength curve; be generous.

Outputs: av_latent (to SamplerCustomAdvanced's latent_image) and a report showing the strength ramp it computed.

The denoise numbers you should steal

H3 is flow matching with a large sigma shift, so SDXL-family denoise values do not transfer. At the default shift of 12, 0.25 - a normal FaceDetailer value - lands at an effective sigma of 0.800 and rewrites the frame. The rule of thumb from the table:

| denoise | effective sigma (shift 12) | |---|---| | 0.02 | 0.197 | | 0.05 | 0.387 | | 0.25 | 0.800 |

steps and denoise are independent on BasicScheduler, and you should not use SplitSigmas here - even its last split point on a short schedule is already at sigma 0.8. The example workflows ship a base of 0.45 which this node scales down on large-face frames. Tune base and multipliers together, and remember: if you bypass this node, drop the base a long way or every large face gets rewritten.

Install

It's part of the pack, so one clone and a restart:

cd ComfyUI/custom_nodes
git clone https://github.com/Carasibana/ComfyUI-H3-FaceRefine.git

Restart and it appears under MiniMax H3/Face Refine (ComfyUI Manager: search "ComfyUI-H3-FaceRefine"). It has no extra dependencies beyond the H3 stack you're already running - the node itself is just latent and transform math.

CategoryMiniMax H3/Face Refine

Inputs (9)

NameTypeDefaultDescription
av_latentLATENT
transformH3FACEXFORM
strength_small_faceFLOAT1.000–1Denoise multiplier where the face is SMALLEST. 1.0 = the full denoise set on BasicScheduler.
strength_large_faceFLOAT0.350–1Denoise multiplier where the face is LARGEST. Lower preserves the detail those frames already have.
scale_modeCOMBOabsolute_pxabsolute_px: strength is set by real face size in SOURCE pixels via face_px_small/large. Safe across a batch - a clip that never has a small face gets the baseline throughout. relative_to_clip: normalise to this clip's own min/max, so its smallest face always gets the full boost regardless of actual size. Use when tuning a single clip to its extremes.
face_px_smallFLOAT304–400Face height (SOURCE px) at or below which the full strength_small_face is applied. Genuinely tiny faces only.
face_px_largeFLOAT1208–800Face height (SOURCE px) at or above which strength_large_face is applied. Calibrated so a clip whose smallest face is ~90px gets only a mild boost - that size was already fine at the baseline denoise - and anything past 120px gets none.
gammaFLOAT1.00.2–4Curve on the interpolation. >1 keeps strength high until the face is genuinely large; <1 drops it off early.
smooth_framesINT91–61Smooth the strength curve over time. An abrupt change in denoise between neighbouring frames is visible as a texture pop, so this wants to be generous.

Outputs (2)

NameTypeDescription
av_latentLATENT
reportSTRING