Open-source project
Carasibana/ComfyUI-H3-FaceRefine avatar
Carasibana/ComfyUI-H3-FaceRefine

ComfyUI-H3-FaceRefine: re-rendering small faces in MiniMax H3 video

Refine and improve the quality of small faces in MiniMax H3 video. Per-frame face tracking, crop, refine with H3, stitch back.

390 stars31 forksPythonMIT

At a glance

What is it?
A ComfyUI custom node pack that detects faces per frame, crops them to fill a canvas, sends the crop through MiniMax H3 again, and composites the result back. It is aimed at one specific failure mode: heads that occupy too little of the frame for H3 to render well.
Who is it for?
Adopt it if your H3 clips have small, distant heads and you already run ComfyUI with a recent H3 build, a YOLO face detector in models/ultralytics/bbox/, and a single onnxruntime variant. Skip it if your faces already fill a reasonable part of the frame, since the crop-and-restitch cycle adds a full H3 pass per shot for no gain.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The head-size problem these nodes target

The README makes a narrow claim: MiniMax H3 renders faces poorly when the head occupies a small fraction of the frame, and this is a property of head-size-in-frame rather than of output resolution, so it persists at 720p and above. That distinction matters. If the defect were a resolution limit, upscaling the output or rendering at a higher resolution would fix it. The project's position is that it does not, because the model is being asked to spend very few pixels on the face regardless of how large the final frame is. The remedy is to change what the model is handed rather than how large the output is: track the face on every frame, crop to it so it fills a canvas, let H3 regenerate that crop, then composite the result back into the original video. The intended user is someone running ComfyUI with MiniMax H3 support, working on video where people appear at a distance (wide shots, group scenes, full-body framing) and finding the faces soft, mushy or unstable. The README credits Impact Pack's FaceDetailer as the model, adapted from stills to video, which tells you the still-image version of this idea is already familiar to ComfyUI users.

What actually happens between input video and output video

The pipeline is a loop over frames with a re-generation step in the middle. A detector (the README's example is face_yolov8m.pt, expected in models/ultralytics/bbox/) finds faces on each frame. A selection rule picks which one is the subject. The crop is normalized so the face fills a canvas, and that crop sequence goes to H3 for refinement. The refined crops are then stitched back into the original frames. Two design details in 1.1.0 change how stable this is. First, hard cuts are detected so that the subject is chosen once per shot and the smoothing, interpolation and composite fade all run per shot rather than being dragged across a join; the README explains that a cut renumbers every face and breaks continuity, which is why cut detection is not cosmetic here. Second, the auto canvas modes clamp up to a minimum of 512x512, because the canvas is sized from the largest crop and the crop is bounded by the source frame, so on a small face in a low-resolution clip the canvas used to shrink to a couple of hundred pixels, handing H3 the same small face it renders badly. That clamp is the honest part of the design: the failure mode was self-inflicted and is now bounded. The README also points at the crop-in and crop-out GIFs as the things to watch for temporal behaviour, noting that the box has to sit still on a moving subject or the refined face boils. That is the real risk in this architecture, and the project says so rather than hiding it.

Installation and the detector you must supply

Installation is a clone into the custom nodes directory:

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

Restart ComfyUI and the nodes appear under MiniMax H3/Face Refine. H3's own nodes are core in comfy_extras/nodes_minimax_h3.py, so no add-on is needed for the base model support, only a build recent enough to include them. Python packages (ultralytics, scipy, insightface, scenedetect) install automatically from requirements.txt or pyproject.toml. The one thing you must supply yourself is a face detector, for example face_yolov8m.pt placed in models/ultralytics/bbox/. The README notes that for anime you should use an anime face model instead, and that the nodes find the file there on their own while the example workflows additionally need folder registration, because their stored detector values carry a bbox\ prefix. That is a small but real distinction: a node that works and a workflow that loads are two different states. Running the shipped templates also requires ComfyUI-VideoHelperSuite for saving via VHS_VideoCombine (and for loading in the Auto Select template), plus ComfyUI-H3-NativeAudioLock, which supplies MiniMaxH3NativeAudioLock to drive lipsync. Two further nodes ship muted.

The onnxruntime trap and the 1.0.0 model rewiring

Two upgrade hazards are worth stating plainly. The first is onnxruntime. insightface needs it, and the pack deliberately does not pin a variant. If you install onnxruntime-gpu alongside an existing onnxruntime, the CPU-only package shadows it, CUDAExecutionProvider disappears, and identity matching silently runs on CPU. The word silently is the problem: nothing errors, the run just gets slower and you may not notice until you wonder why a clip took so long. The README gives the check: python -c "import onnxruntime; print(onnxruntime.get_available_providers())". Install one or the other, not both. The second hazard is the 1.1.0 change to H3 Per-Frame Denoise, which now takes and returns MODEL because a per-frame mask needs two changes to the model rather than the latent. The node must sit in the model path and its model output has to reach the guider. Because model is a required input, a workflow saved against 1.0.0 fails validation with Required input is missing: model until you route the model through the node and take its output onward. The README states that nothing else in the release requires rewiring, which is a useful scope statement: the break is one edge in the graph, not a rebuild. The same release renamed the two strength widgets to denoise_multiplier_small_face and denoise_multiplier_large_face, which the README says is what they always were.

Cut detection, the soft dependency, and what happens without it

PySceneDetect (scenedetect>=0.7) backs cut_detection = auto (pyscenedetect) on both H3 Load Video + Face Select and H3 Face Track + Crop, and it installs automatically with the pack. The threshold is PySceneDetect's own adaptive default of 3.0, exposed as cut_threshold. The implementation detail that matters is that it is fed frame by frame from the decode pass that is already running, so it costs no second decode of the video. That is a sensible way to add a dependency: the expensive part (decoding) is shared. It is also a soft dependency in practice. If it is missing or fails to import, the run does not stop; the video is treated as a single shot and the report says cut detection unavailable, treating the video as one shot. That is the right failure direction for a node pack, but it does mean a clip with many cuts, run without PySceneDetect, will have the subject selection and smoothing dragged across joins, which is exactly the boiling the README warns about. If your source is a fast-cut edit, check that scenedetect imported before blaming the tracker.

Where this is the wrong tool

The clearest limitation is structural: the method only helps when the face is small in frame. If your subject already fills a reasonable portion of the frame, the crop is close to the original framing, H3 is being handed roughly what it already had, and you have paid for an extra H3 pass per shot plus the compositing step for no visible gain. The second limitation is temporal. The README is explicit that the box has to sit still on a moving subject or the refined face boils, and that the crop-in and crop-out sequences are what to watch for temporal behaviour. That means fast motion, occlusion, or a subject who turns away and back can produce a refined face that flickers or drifts relative to the surrounding frame, and cut detection only addresses the joins, not within-shot instability. Third, identity matching depends on insightface and onnxruntime, and the README's note about CPU fallback means a misconfigured environment degrades quietly rather than failing loudly. Fourth, the auto canvas clamp to 512x512 is a floor, not a guarantee: on a very small face in a low-resolution clip, 512x512 may still be a modest canvas for H3, and manual mode will take whatever you type, including something too small. Finally, the example workflows pull in VideoHelperSuite and ComfyUI-H3-NativeAudioLock, so the templates are not a two-minute test of this pack alone.

How it differs from FaceDetailer and from plain upscaling

The README states the lineage directly: the pack is modelled on Impact Pack's FaceDetailer, adapted from stills to video. The difference in approach is what that adaptation buys and costs. FaceDetailer operates on a still image, where a per-frame crop is the whole problem and there is no notion of continuity between crops. Here, the crop sequence is the unit of work: cut detection, per-shot subject selection, smoothing, interpolation and composite fade all exist because frame N and frame N+1 must agree about where the face is and what it looks like. That is more machinery than the still version, and it is the machinery most likely to misbehave on a moving subject. The alternative that is not FaceDetailer is simply upscaling or re-rendering the whole frame at higher resolution. The README's own claim rules that out for this defect: head-size-in-frame persists at 720p and above, so a bigger frame does not give H3 more pixels on the face in a way that fixes the render. If that claim holds for your footage, upscaling is the wrong lever and cropping is the right one. If it does not hold, this pack is unnecessary complexity.

Maintenance, licence and what to verify first

The licence is MIT, which is permissive and imposes no copyleft obligation on your own graphs or derivative work; as always, read the licence text itself rather than treating a one-line summary as advice. The pack depends on fast-moving external pieces: ComfyUI core H3 nodes, ultralytics, insightface, onnxruntime, scenedetect and, for the templates, VideoHelperSuite and ComfyUI-H3-NativeAudioLock. The 1.1.0 release already broke saved workflows once by making model a required input on H3 Per-Frame Denoise, and the README's migration note for the select list (largest becomes largest_face, most_central becomes centre_most, applied on load) shows the project does handle renames rather than leaving them to users. The practical upgrade cost is therefore low but not zero: expect to re-check model routing after any release that touches the denoise node. Before adopting, verify the detector path, verify that only one onnxruntime variant is installed, and confirm your ComfyUI build actually contains comfy_extras/nodes_minimax_h3.py. If you run 1.0.0 graphs, rewire the model edge first; that is the single change that will stop a graph from queueing.

Editorial conclusion

Adopt it if your H3 clips have small, distant heads and you already run ComfyUI with a recent H3 build, a YOLO face detector in models/ultralytics/bbox/, and a single onnxruntime variant. Skip it if your faces already fill a reasonable part of the frame, since the crop-and-restitch cycle adds a full H3 pass per shot for no gain. Before committing, verify three things: that onnxruntime.get_available_providers() lists CUDAExecutionProvider if you expect GPU identity matching, that the detector file is where the nodes look for it, and that a 1.0.0 workflow is rewired so MODEL passes through H3 Per-Frame Denoise to the guider.

Official sources

  1. Carasibana/ComfyUI-H3-FaceRefine on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Community notes

Community notes