MiniMax H3 Face Refine Quality Gate / 候选质量门 (Advanced)
An automatic 'don't ship the worse face' check before export
- base_frames
- candidate_frames
- changed_mask
- face_plan
- safe_candidate_frames
- accepted_change_mask
- rejected_frame_mask
- accepted_frame_count
- rejected_frame_count
- report_json
This is the node that stops you from exporting a face that got worse. Face refine is not a guaranteed win - the second pass can melt a face, swap identity, or introduce flicker, and if you're batch-processing a video you might not notice until it's rendered. The Quality Gate sits between your stitch candidate and your export, and it rejects obvious regressions frame-by-frame using conservative proxy thresholds. Rejected frames quietly return to the original source. It's not AI taste - it's a tripwire for the failure modes you can actually measure.
What it measures, per frame: source-relative structure (SSIM), the face-region change magnitude, measured sharpness, and temporal residual (how much the candidate jumps relative to its neighbors). Every one of those must pass for the frame to be accepted, and accepted frames must come in a continuous run of at least minimum_accept_run (3) - a single good frame surrounded by rejects doesn't count, because isolated good frames are where flicker lives. edge_fade_frames (2) feathers the boundary between accepted and rejected runs so the output doesn't hard-cut.
Inputs: base_frames, candidate_frames, changed_mask (so it only scores what actually changed), and face_plan.
The dials you'd actually move:
min_structure_ssim(0.82) - if the candidate's structure diverges too far from source, it's probably a different face. Lower = more permissive.min_sharpness_ratio(1.02) /max_sharpness_ratio(2) - the candidate must be sharper than source, but not suspiciously sharper (oversharpening is a refine artifact).max_face_mean_abs_delta(0.06) - normalized face-region change cap. This is your identity guard.max_residual_temporal_jitter(0.05) - temporal consistency guard.
Outputs: safe_candidate_frames (the mixture: accepted refined frames + source where rejected), accepted_change_mask, rejected_frame_mask, accepted_frame_count, rejected_frame_count, and report_json so you can see why frames were rejected.
Now the honesty clause, and it's important: passing this gate is not identity proof or quality proof. These are conservative proxy thresholds. The description says it plainly - the result still requires full-video human review. What the gate is genuinely good at: catching the obvious regression automatically so you don't ship it, and giving you a count of how many frames your refine actually improved versus bailed on. If rejected_frame_count is high, that's not a gate failure, that's information - your denoise curve is too hot, or the crop geometry is off.
Install: ComfyUI Manager → "MiniMax H3 Audio T8", or:
cd ComfyUI/custom_nodes
git clone https://github.com/T8mars/comfyui-minimax-h3-audio-T8
Restart after. No forced pip deps, no model downloads - it's all image statistics on the frames you already have.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| base_frames | IMAGE | — | |
| candidate_frames | IMAGE | — | |
| changed_mask | MASK | — | |
| face_plan | H3_T8_FACE_REFINE_PARITY_PLAN | — | |
| min_structure_ssim | FLOAT | 0.820–1 | — |
| min_sharpness_ratio | FLOAT | 1.020–10 | — |
| max_sharpness_ratio | FLOAT | 2.000–20 | — |
| max_face_mean_abs_delta | FLOAT | 0.0600–1 | — |
| max_residual_temporal_jitter | FLOAT | 0.0500–1 | — |
| minimum_accept_run | INT | 31–121 | — |
| edge_fade_frames | INT | 20–60 | — |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| safe_candidate_frames | IMAGE | — |
| accepted_change_mask | MASK | — |
| rejected_frame_mask | MASK | — |
| accepted_frame_count | INT | — |
| rejected_frame_count | INT | — |
| report_json | STRING | — |