SyncReward Shift Audio
The Node That Proves the Score Is Not a Timing Detector
- video
- video
Sometimes a utility node tells you more than the headline node does. SyncReward Shift Audio slides a video's soundtrack forward or backward in time and leaves the picture and the duration alone. Its stated purpose is making deliberately out-of-sync test clips. Its actual value, if you ask me, is that it lets you measure how blunt the SyncReward score is before you bet a selection pipeline on it - and the answer is very blunt, which is the single most useful thing you can learn about this pack in five minutes.
How it works
One audio-shift, done properly. The node takes the video's audio waveform, converts offset_ms into a sample count at the file's own sample rate, and prepends silence (positive offset) or trims from the front and pads the tail with silence (negative offset), cutting anything that runs past the end. Length in, length out. Picture untouched.
Two inputs: video, which needs an audio track, and offset_ms, a FLOAT from −5000 to 5000 with a step of 10, defaulting to 250 - a quarter second late, right around where a person starts to notice. Positive means the sound arrives after the picture. One output, video, so it drops in anywhere a VIDEO flows.
The frames it emits are the same 8-bit values the scorer reads, so a shifted copy differs from its original only in the audio. Any score difference you see is the shift and nothing else.
The five-minute experiment you should actually run
Take one clip you're happy with. Score it. Then run the same clip through Shift Audio at 250, 500 and 1000 ms, positive and negative, and score each. You're going to find that the reward barely moves.
That's not a bug in this node, and it isn't my opinion - the pack's own README publishes the sweep on the ten demo clips, mean reward unshifted 1.023, then 0.993 at −1000 ms, 1.033 at −100 ms, 0.991 at +1000 ms, 0.951 at +2000 ms and 0.879 at +3000 ms. A full second of desync costing a hundredth of a point. The wider test in LIMITATIONS.md is worse: on 70 well-synced benchmark clips, shifting 0.2 s or 0.5 s either way doesn't register at all as a drop, and in the ten-clip sweep the unshifted clip had the highest reward in only 4 out of 10.
So the moment you need the model to tell you "this audio is 300 ms late," it can't. It was trained on human ratings of generated clips, and humans rating generated clips are apparently forgiving about sub-second misalignment compared to the audio being absent or unrelated. That's the model's shape, and knowing it will save you from building a QC gate that passes everything.
So what is it good for?
Three real uses, in descending order of how often I'd reach for it.
First, calibration. Shift-and-rescore is the cheapest way to find the reward gap that actually corresponds to a difference you can see and hear on your own generator. Every generator behaves differently - the pack's benchmark puts the sync-vs-human Spearman at 0.60 for Seedance and 0.79 for LTX-2.3 - so your noise floor isn't necessarily 0.1 on your material.
Second, test clips. If your workflow branches on sync quality, you need known-bad inputs, and this makes them from good ones without touching a second model. A two-up of a clip and its audio-late twin also shows a human the failure mode in a way no number does.
What it is not for: fixing sync. Sliding a whole track by a constant doesn't rescue real drift, which is non-constant and usually the generator's fault. Diagnose, then regenerate.
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, restart ComfyUI. Worth saying plainly: this node needs no model at all - it's pure waveform arithmetic. You can clone the pack just for it and skip the 15 GB download entirely, which is the only reason I'd ever recommend installing this pack without the weights.
Gotchas
Feed it a video with no audio track and it raises rather than silently inventing silence - good, but it means the node is useless on a silent Wan render, which is exactly when you might think to try it. Route your foley in first if that's your situation.
The step size is 10 ms, so you can't dial a single-sample offset, and the range caps at ±5 s. Both are fine for the job.
And be careful about what you're comparing. Because the reward is so insensitive here, two shifted clips scoring 1.01 and 0.99 is not evidence of anything - that's inside the noise band the author measured. If your experiment produces differences that small, the honest conclusion is "the score doesn't care," not "0.99 is worse."
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| video | VIDEO | A video that has an audio track | |
| offset_ms | FLOAT | 250-5000–5000 | Positive = audio later than the picture |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |