SamplerSelfRefineVideo
Fixing wacky video motion without extra training
- latent
- SAMPLER
The node's own description is refreshingly honest about what you're getting: "Attempt to implement [the self-refine-video paper], for testing only, MAY NOT WORK AS INTENDED." This is Kijai's early port of a technique that made real noise in the video-gen community - a training-free way to fix the wobbly hands, morphing limbs, and generally "wacky" motion that shows up in default video generations, without a detection model and without retraining anything.
What it's actually trying to do
The paper it's based on describes itself as basically an automatic adetailer for video motion. Instead of one denoising pass and hoping the motion holds together, it runs a couple of extra iterations (roughly 50% more compute), pumping in more noise and denoising again - but guided, focusing that extra effort specifically on high-uncertainty areas where motion is unstable. The result gets steered toward a stable local minimum with coherent movement, rather than the visible glitches a single pass can produce. No training-free - er, no training required, and notably no separate detection model either; it's the base model calling itself extra times with guidance baked into the resampling.
When the technique first surfaced, the ComfyUI community's reaction was immediate interest - people asked for a native implementation within hours, and someone pointed out a real overlap with the cyclosampling already available in the res4lyf pack (sample → unsample → resample, potentially over multiple cycles) as a conceptually similar existing tool. Whether this KJNodes implementation and that overlap resolve identically isn't something to assume - this node is Kijai's own attempt at the paper's specific method, built fast, and it says so itself.
The inputs and outputs that matter
This is a SAMPLER-type node - it doesn't sample on its own, it produces a sampler object you wire into a custom-sampling node's sampler slot, same shape as any other advanced/custom sampler in the ecosystem.
certain_percentage(default 0.999) anduncertainty_threshold(default 0.2) - the two knobs that map onto the paper's core idea: deciding which regions of the video count as stable ("certain") versus unstable enough to deserve the extra refinement pass. Leave these at defaults first; they're tuned starting points, not values you should expect to need to touch for a first try.seed- standard reproducibility control, same as any sampler.verbose(default false) - turn on if you want the node talking to your console while it works, useful when you're trying to understand what it's doing on a test run.latent(optional) - an optional latent input alongsideinput_mode, which controls how that input is used.
Output: SAMPLER, feed it into your custom sampler node like any other.
Installing it
Ships with the pack:
- ComfyUI Manager - search KJNodes for ComfyUI, install, restart.
- Manual -
cd ComfyUI/custom_nodes && git clone https://github.com/kijai/ComfyUI-KJNodes, thenpip install -r ComfyUI-KJNodes/requirements.txt, restart.
No extra model downloads - it works with whatever video model and sampler chain you're already running.
Common issues & troubleshooting
It's slower and I'm not sure it's helping. That's expected and honestly baked into the technique - the whole method trades roughly 50% more compute for better motion coherence. If a given generation didn't have a motion problem to begin with, you're just paying the extra cost for nothing visible.
Results look worse, or it errors outright. Take the node's own self-description seriously: "MAY NOT WORK AS INTENDED." This is filed under KJNodes/samplers as a fresh, fast-turnaround implementation of a paper that had barely landed in the community's awareness - treat it as something to experiment with on throwaway generations, not something to build a production pipeline around yet.
I don't understand what certain_percentage vs uncertainty_threshold actually change. Neither did most of the community when the underlying technique first circulated - this is genuinely new ground, not an established parameter pair with a settled community consensus yet. Default values first, then nudge one at a time and compare, the same way you'd approach any unfamiliar sampler control.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| input_mode | COMBO | How to configure the step plan | |
| certain_percentage | FLOAT | 0.9990–1 | Percentage of certain pixels to consider the frame as certain and skip further refinement |
| uncertainty_threshold | FLOAT | 0.200–1 | Threshold of uncertainty to consider a pixel uncertain |
| verbose | BOOLEAN | false | Enable verbose logging during sampling |
| seed | INT | 00–18446744073709550000 | Seed for stochastic sampling |
| latentopt | LATENT | Optional latent input to get input shape for LTX2 audio/video separation |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| SAMPLER | SAMPLER | — |