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

> 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.

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

- Repository: https://github.com/Carasibana/ComfyUI-H3-FaceRefine
- Stars: 463 · Forks: 39
- Language: Python
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/carasibana-comfyui-h3-facerefine

## 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.

## 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.

## FAQ

### What problem does ComfyUI-H3-FaceRefine solve?

MiniMax H3 renders faces poorly when the head occupies a small fraction of the frame, which is a property of head-size-in-frame rather than output resolution, so it persists at 720p and above. The nodes detect the face every frame, crop so it fills the canvas, let H3 regenerate it and composite the result back.

### What changed in ComfyUI-H3-FaceRefine 1.1.2?

The tracker no longer hops to another person when it loses the subject. It only carries the subject onto a face within reach, unresolved frames get an interpolated crop and a faded composite so they keep their original pixels, a lost: line in the report counts them and preview draws them red, and fallback_detector now uses the body nearest the subject's expected head position.

### Do my old ComfyUI-H3-FaceRefine workflows still load?

Workflows saved against 1.0.0 do not, because H3 Per-Frame Denoise now takes and returns MODEL and model is a required input. The failure message is Required input is missing: model, fixed by routing the model through the node and taking its model output onward to the guider. Version 1.1.2 requires no rewiring at all.

### How do I choose which face ComfyUI-H3-FaceRefine follows?

The select input has nine modes: largest_face, smallest_face, left_most, right_most, top_most, bottom_most, centre_most, closest_to_xy and detector_score, with the direction in the name. Version 1.0's largest and most_central migrate automatically. There is also a Pick faces interface on H3 Load Video + Face Select for choosing the subject per shot by eye.

### What do I have to install for ComfyUI-H3-FaceRefine?

Clone into ComfyUI/custom_nodes/ and restart. ultralytics, scipy, insightface and scenedetect 0.7 or newer install automatically, and you must supply your own face detector such as face_yolov8m.pt in models/ultralytics/bbox/, or an anime face model. H3's own nodes are core, so you need a recent enough ComfyUI build.

### Why does ComfyUI-H3-FaceRefine not declare onnxruntime or dghs-imgutils?

Both are left out because they shadow what ComfyUI already has. dghs-imgutils pins numpy below 2 and pulls opencv-contrib-python, replacing ComfyUI's OpenCV build. Declaring onnxruntime-gpu next to an existing onnxruntime makes the CPU package shadow it, so CUDAExecutionProvider disappears and identity matching silently falls back to CPU. Install one variant, not both.

## Sources

- [Carasibana/ComfyUI-H3-FaceRefine on GitHub](https://github.com/Carasibana/ComfyUI-H3-FaceRefine)
- [Issues](https://github.com/Carasibana/ComfyUI-H3-FaceRefine/issues)
- [License: MIT](https://github.com/Carasibana/ComfyUI-H3-FaceRefine/blob/main/LICENSE)
- [README](https://github.com/Carasibana/ComfyUI-H3-FaceRefine/blob/main/README.md)
- [Releases](https://github.com/Carasibana/ComfyUI-H3-FaceRefine/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/carasibana-comfyui-h3-facerefine
