Remove Invisible Watermark / SynthID (RAIW)
The watermark you can't see — and the one node in this pack that needs a GPU
- image
- image
Every image out of Nano Banana, ImageFX, or the Gemini API carries a SynthID watermark baked into the pixels. You can't see it; Google's detectors can. This node is the heavy artillery of the Remove AI Watermarks pack: instead of patching a visible mark, it regenerates the whole image just enough to scramble the embedded signal away, then rebuilds the details.
That makes it the one node here that isn't a free lunch. The visible-mark nodes are cv2 and CPU-only; this one runs a real diffusion stack, needs a GPU, downloads multi-GB models on first use, and takes a while per image. If you just want a corner sparkle gone, you want the other nodes. This exists for the case where the provenance is invisible - and you've decided you have a reason to strip it. That decision is genuinely contested (some read SynthID as provenance protection, some as vendor lock-in), so it's worth being sure about your own before you run it.
How it works
The technique is the one the community has known about since the first open-source edit models: re-diffuse the image. The default controlnet pipeline runs the image through an SDXL regeneration pass at low strength - enough to "re-noise" the pixels and destroy the pixel-space watermark, not enough to change what you see - while a canny ControlNet holds the edges, faces, and text structure in place. Structure preserved, watermark scrambled. The sdxl pipeline is the plain regeneration pass without the ControlNet stabilizer, which is more destructive but sometimes needed on tricky inputs. humanize and unsharp inputs then claw back any softness, and adaptive_polish (default on) runs a final detail pass.
Inputs that matter
- pipeline -
controlnet(default) orsdxl. - strength - the core dial, 0–1. Here's the trap: ComfyUI tensors carry no file metadata, so the vendor-adaptive default can't kick in and falls back to the unknown-vendor value (0.30). Leave it at 0 and you get that. Set it above 0 to take control. Higher = more watermark removed, but also more drift from the original.
- steps (default 30) and seed (default 0) - standard sampling controls.
- controlnet_scale (default 1.0) - how hard the ControlNet holds structure. Dial it down if the result looks over-constrained.
- max_resolution / min_resolution - cap or floor for the regeneration resolution; watch your VRAM.
- upscaler -
lanczos(default) oresrgan(needs the optional esrgan extra).
One output: image. That's it - there's no local detector, so nothing reports "success" at the end.
Install
Same pack install as the others, plus the GPU extra:
cd ComfyUI/custom_nodes
git clone https://github.com/wiltodelta/ComfyUI-remove-ai-watermarks
pip install -r ComfyUI-remove-ai-watermarks/requirements.txt
pip install "remove-ai-watermarks[gpu]"
The [gpu] extra pulls the diffusion stack (torch, diffusers) and it's multi-GB; model weights download on first use. In practice the profiles are CUDA-only, so don't plan on running this on CPU. The esrgan upscaler is another optional extra if you want it.
Verifying and troubleshooting
The README is upfront that there is no local SynthID detector - verify with Google's own "Verify with SynthID" in the Gemini app. If the detector still fires, raise strength a notch; if the image is drifting too far from the original, lower it and lean on controlnet_scale instead. And mind the memory: this is a diffusion run per frame, so a batch of large images can blow through VRAM fast - clamp max_resolution before you queue up a folder.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| pipeline | COMBO | qwen-zimage | 4 options: qwen-zimage, sdxl-zimage, chroma-zimage, auto |
| strength | FLOAT | 0.000–1 | — |
| seedopt | INT | 00–18446744073709550000 | — |
| controlnet_scaleopt | FLOAT | 1.000–2 | — |
| humanizeopt | FLOAT | 0.00–10 | — |
| unsharpopt | FLOAT | 0.00–3 | — |
| max_resolutionopt | INT | 00–8192 | — |
| adaptive_polishopt | COMBO | profile default | 3 options: profile default, on, off |
| cpu_offloadopt | BOOLEAN | false | — |
| tileopt | BOOLEAN | false | — |
| tile_sizeopt | INT | 1024256–4096 | — |
| tile_overlapopt | INT | 1280–1024 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |