Nodes/ComfyUI-SyncReward/SyncReward Select Best
ComfyUI Node

SyncReward Select Best

Automated Seed-Hunting for the One Axis You Can't Eyeball

By hiroki-abe-58·Created 2 days ago·Updated about 16 hours ago· 0
SyncReward Select Best
  • model
  • video_1
  • video_2
  • video_3
  • video_4
  • video_5
  • video_6
  • best_video
  • best_index
  • best_reward
  • scores
◄encode_batch_size18►

Seed hunting is the load-bearing habit of video generation right now. LTX-2.3 still has prompt-adherence problems, so the community answer isn't better prompts - it's generating four candidates on four seeds and picking the one that worked. But that covers only the parts you can see. The sound is where it falls apart, because nobody watches four clips with headphones to check whether the footsteps land on the footsteps.

SyncReward Select Best automates that one axis. Feed it two to six candidate videos, it scores each for audio-visual synchronization and hands back the winner plus every score so you can see the field.

What goes in, what comes out

model comes from the Loader. video_1 and video_2 are required; video_3 through video_6 are optional and you leave them unconnected when you have fewer candidates. There's an encode_batch_size (default 18) that does the same thing here as in the Score node - VRAM dial, 9.8 GiB at 18, 6.7 GiB at 1.

Four outputs. best_video is a VIDEO and it's the whole point - wire it straight into Save Video and the losing candidates never touch disk. best_index is an INT telling you which input won (1 means video_1), which is handy when you want to log which seed to trust. best_reward is the winning FLOAT. And scores is a JSON STRING with every candidate's reward rounded to four decimals, so you can actually see whether the winner won by a mile or by nothing.

Under the hood it scores the candidates one after another through the same resident model, with a progress bar. Ties go to the lower-numbered input, so identical candidates always return the first.

The honest part

This node ships with its own warning label, and the author earned it. Reading LIMITATIONS.md first is the difference between a useful tool and a random number generator with a nice UI.

Rewards that differ by less than about 0.1 are noise. That's the spread you get from changes that provably shouldn't matter - the same clip re-encoded at a decent quality, gain nudged down 12 dB. So when scores shows 1.412 against 1.401, you have learned nothing. On benchmark clips where humans rated the pair close together, the reward orders them the way the humans did only about 69% of the time. On pairs humans rated far apart it's much better (0.94 and up), which matches your intuition: it's a coarse signal.

Two more traps worth internalising. Candidates encoded differently - different resolution, bitrate or frame rate - get partly chosen by that, not by synchronization; half resolution alone drops a score by about 0.14. And a candidate with no sound, with noise, or with someone else's audio can still win outright. The model was trained to predict how humans rate sync, and it's imperfect at flagging outright wrongness.

The best-of-N numbers are the ones I'd tape to the monitor. On the official benchmark, asking for the best of 2 picks a human-best clip 83.6% of the time. Best of 4, 76.4%. Best of 6, 71.4%. Adding candidates makes the task harder faster than it makes the tool better - so if you're running six variants, treat the pick as a strong hint, not a verdict. And note the caveat: those numbers come from random groups of clips from different prompts and generators, not several seeds of one prompt - your case, and the harder one, because the candidates are closer together.

My honest read: reach for it when your candidates are otherwise tied on everything you can check by eye, and you just don't want to listen to all four. It's not a replacement for watching the winner.

Wiring it up

The shape that makes sense is Load Video nodes for each candidate feeding video_1..video_6, best_video into Save Video, and scores into a Show Text node you leave open while you work out how much to trust it on your own material. Do that for a dozen batches and you'll get a feel for what gap size means on your generator - because the per-generator numbers vary noticeably (the pack's own benchmark puts Spearman at 0.60 for Seedance clips and 0.79 for LTX-2.3).

Install

cd ComfyUI/custom_nodes
git clone https://github.com/hiroki-abe-58/ComfyUI-SyncReward
python -m pip install -r ComfyUI-SyncReward/requirements.txt
python custom_nodes/ComfyUI-SyncReward/tools/download_models.py --models-dir ComfyUI/models/syncreward

Or search "SyncReward" in ComfyUI Manager. The ~15 GB of weights land in models/syncreward/; transformers>=5.1.0 is a hard floor because the PE-AV encoder doesn't exist in earlier versions. Restart ComfyUI afterwards - nodes only appear after a restart, and the Loader's dropdowns will be empty until the download finishes.

Where it goes sideways

Every candidate needs an audio track. A silent one doesn't error out here, it just gets scored badly and might still win, so make sure your Load Videos are pointing at files with sound.

Speed is multiplicative: six candidates is six scoring passes, roughly 1.6–2 s each on a 5090 after the load. Fine. But watch VRAM if this sits next to a video model - dropping encode_batch_size to 1 helps, and its 0.008 wobble is far below the noise floor.

Categoryvideo/syncreward

Inputs (8)

NameTypeDefaultDescription
modelSYNCREWARD_MODEL—
video_1VIDEO—
video_2VIDEO—
encode_batch_sizeINT181–36—
video_3optVIDEO—
video_4optVIDEO—
video_5optVIDEO—
video_6optVIDEO—

Outputs (4)

NameTypeDescription
best_videoVIDEO—
best_indexINT—
best_rewardFLOAT—
scoresSTRING—