Bernini Inpaint Condition
Repaint video without a mask (or with one)
- positive
- negative
- vae
- source_video
- mask
- positive
- negative
- latent
Bernini's whole pitch is maskless editing: you describe the change and it edits the video. But "maskless" describes the model's conditioning, not the workflow - somebody still has to get your source video into the graph as the thing being edited, and turn the mask you do want (or don't want) into the right latent. That's this node's job.
Bernini Inpaint Condition does three things in one place: it VAE-encodes your source video into the starting latent, it sets up the conditioning for positive and negative, and - the bit that sounds like a contradiction - it optionally applies a mask. Omit the mask and you get a global repaint: the whole clip is regenerated from the source latent with Bernini's instruction conditioning. Add a mask and you get local repainting, where white is repainted and black is preserved.
That's a genuinely useful shape for video, because Bernini has no first-frame/last-frame mode - it's not a tool for "animate this still." Its thing is editing footage that already exists, and this node is the adapter that makes that footage the input.
The inputs that matter
- positive / negative - the conditioning you'd build with CLIP Text Encode. The node copies them and attaches the source-video context.
- vae - the Bernini VAE. It's used to encode
source_videointo the latent that sampling starts from. - source_video - the clip you're editing, as an
IMAGEbatch of frames. - width / height / length - target geometry. Defaults are 832×480×81 frames, and
lengthmust be4*n + 1(it validates and errors otherwise). - batch_size - for running multiple source videos at once.
- source_as_context - default off. When on, the aligned source video is also appended as Bernini context tokens, so the model sees the source twice: once as the starting latent, once as reference context. Costs more compute; helps keep identity stable.
- mask (optional) - white repainted, black preserved. Omit for global repaint.
Outputs: positive, negative, and latent - wire all three to your sampler. The latent carries a noise_mask when a mask was supplied.
How to install
Same pack as everything here - ComfyUI Turing Utils, "comfyui-svdint4" in Manager:
cd ComfyUI/custom_nodes
git clone https://github.com/wjie98/comfyui-svdint4
cd comfyui-svdint4
python -m pip install -v --no-build-isolation -e ./kernel
Kernel build is manual, restart after. No extra model downloads for this node itself - the Bernini weights come from ByteDance's repos via your normal model loaders.
Where people get burned
The classic mistake is feeding a frame count that isn't 4*n+1 and getting a hard error instead of an explanation - trim or pad upstream first. Second: the mask must match the source video's frame count and dimensions, and it's a per-frame mask, not a single 2D image. And third, the source_as_context temptation: it roughly doubles the conditioning cost, so don't flip it on because it sounds better. If global repaint looks stable without it, leave it off and spend the VRAM on a longer clip.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| vae | VAE | — | |
| source_video | IMAGE | — | |
| width | INT | 83216–8192 | — |
| height | INT | 48016–8192 | — |
| length | INT | 811–8192 | — |
| batch_size | INT | 11–4096 | — |
| source_as_context | BOOLEAN | false | Also append the aligned source video as Bernini context tokens. |
| maskopt | MASK | White is repainted and black is preserved. Omit for global repaint. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| positive | CONDITIONING | — |
| negative | CONDITIONING | — |
| latent | LATENT | — |