DeSynth removes the SynthID invisible watermark from both OpenAI/Google generated images. (SynthID Bypass)
Python
45
6 commits
updated Jun 5, 2026
A tool & pipeline for removing OpenAI & Google's SynthID watermark from images.
This project is intended solely for research, education, and authorized evaluation.
Edge Mode:
Gaussian Mode (Default):

All scores are input image vs output via the included compare.py.
| metric | our method | competitor |
|---|---|---|
| PSNR | 28.75 dB | 20.21 dB |
| SSIM | 0.946 | 0.624 |
| SSIM (low-frequency) | 0.944 | 0.812 |
| SSIM (high-frequency) | 0.987 | 0.641 |
| MAE (lower is better) | 5.33 | 12.18 |
| Output resolution | 2752×1536 | 1501×835 |
| SynthID verdict | not found | not found |
| metric | gaussian (default) | edge mode |
|---|---|---|
| PSNR | 32.47 dB | 31.47 dB |
| SSIM | 0.956 | 0.948 |
| SSIM (low-frequency) | 0.959 | 0.955 |
| SSIM (high-frequency) | 0.991 | 0.984 |
| MAE | 3.82 | 4.08 |
| SynthID verdict | not found | not found |
flowchart TD
A["Original.png"]
B["Qwen-Image GGUF Q4<br>+ Lightning 4-step LoRA"]
B_note["2 Lightning steps\n(strength 0.25)"]
C["Frequency-domain restore<br>low_clean + high_orig"]
C_note["Gaussian split, sigma=1.95<br>low band from clean<br>high band from Original"]
D["[output]\nNAME_desynth_r1.95.png"]
A --> B
B -- "clean: no SynthID, blurry-ish" --> C
C --> D
B -.- B_note
C -.- C_note
classDef note fill:#f6f8fa,stroke:#d0d7de,color:#57606a;
class B_note,C_note note;
Download the two model files into the repo root:
| file | size | source |
|---|---|---|
qwen-image-2512-Q4_K_M.gguf | ~13 GB | Frederic75/Qwen-Image-2512-GGUF |
Qwen-Image-2512-Lightning-4steps-V1.0-fp32.safetensors | ~1.6 GB | lightx2v/Qwen-Image-2512-Lightning |
python desynth.py # processes original.png
python desynth.py path\to\image.png # processes any input
Output: out/<name>_desynth_s8_d0.250_p1_r1.95.png. Random seed per run by
default. First run downloads ~250 MB of VAE + configs from Hugging Face
and caches them.
| flag | default | when to use |
|---|---|---|
--seed N | random | reproducible runs |
--denoise X [X X] | 0.25 | sweep denoise |
--steps N | 8 | per-pass step count |
--passes N | 1 | iterate img2img |
--restore-sigma X | 1.95 | tune detail restore |
--restore-mode M | gaussian | edge for shape-coherent contours |
--unsharp X | 0.0 | post-restore sharpen; 0.2 is the perceptual sweet spot |
--no-restore | off | skip the frequency restore step |
--keep-intermediate | off | save the pre-restore clean output |
--transformer PATH | Q4_K_M | try a different GGUF quant |
python compare.py Original.png out\<output>.png
Prints PSNR, SSIM (full + low/high band), MAE, MSE, and per-channel histogram correlation.
| file | role |
|---|---|
desynth.py | main pipeline: img2img + restore in one call |
compare.py | similarity metrics between two images |
embeds_cache.pt | cached prompt embeddings (~430 KB) |
qwen-image-2512-Q4_K_M.gguf | Qwen-Image transformer, GGUF Q4 quant (~13 GB) |
Qwen-Image-2512-Lightning-4steps-V1.0-fp32.safetensors | 4-step Lightning distillation LoRA (~1.6 GB) |
Tested on Windows 10, RTX 5060 Ti 8 GB, 32 GB DDR4 RAM. Sequential CPU offload is required with < 12GB VRAM
Baseline workflow and watermark hypothesis from
00quebec/Synthid-Bypass.
This pipeline reimplements the core idea in plain Python without ComfyUI,
ControlNet, or the face-detail path, and replaces the heavier redraw with a
two-step minimum denoise + frequency-domain restore.
6 commits
Python
100.0%
DeSynth removes the SynthID invisible watermark from both OpenAI/Google generated images. (SynthID Bypass)
Python
45
6 commits
updated Jun 5, 2026
A tool & pipeline for removing OpenAI & Google's SynthID watermark from images.
This project is intended solely for research, education, and authorized evaluation.
Edge Mode:
Gaussian Mode (Default):

All scores are input image vs output via the included compare.py.
| metric | our method | competitor |
|---|---|---|
| PSNR | 28.75 dB | 20.21 dB |
| SSIM | 0.946 | 0.624 |
| SSIM (low-frequency) | 0.944 | 0.812 |
| SSIM (high-frequency) | 0.987 | 0.641 |
| MAE (lower is better) | 5.33 | 12.18 |
| Output resolution | 2752×1536 | 1501×835 |
| SynthID verdict | not found | not found |
| metric | gaussian (default) | edge mode |
|---|---|---|
| PSNR | 32.47 dB | 31.47 dB |
| SSIM | 0.956 | 0.948 |
| SSIM (low-frequency) | 0.959 | 0.955 |
| SSIM (high-frequency) | 0.991 | 0.984 |
| MAE | 3.82 | 4.08 |
| SynthID verdict | not found | not found |
flowchart TD
A["Original.png"]
B["Qwen-Image GGUF Q4<br>+ Lightning 4-step LoRA"]
B_note["2 Lightning steps\n(strength 0.25)"]
C["Frequency-domain restore<br>low_clean + high_orig"]
C_note["Gaussian split, sigma=1.95<br>low band from clean<br>high band from Original"]
D["[output]\nNAME_desynth_r1.95.png"]
A --> B
B -- "clean: no SynthID, blurry-ish" --> C
C --> D
B -.- B_note
C -.- C_note
classDef note fill:#f6f8fa,stroke:#d0d7de,color:#57606a;
class B_note,C_note note;
Download the two model files into the repo root:
| file | size | source |
|---|---|---|
qwen-image-2512-Q4_K_M.gguf | ~13 GB | Frederic75/Qwen-Image-2512-GGUF |
Qwen-Image-2512-Lightning-4steps-V1.0-fp32.safetensors | ~1.6 GB | lightx2v/Qwen-Image-2512-Lightning |
python desynth.py # processes original.png
python desynth.py path\to\image.png # processes any input
Output: out/<name>_desynth_s8_d0.250_p1_r1.95.png. Random seed per run by
default. First run downloads ~250 MB of VAE + configs from Hugging Face
and caches them.
| flag | default | when to use |
|---|---|---|
--seed N | random | reproducible runs |
--denoise X [X X] | 0.25 | sweep denoise |
--steps N | 8 | per-pass step count |
--passes N | 1 | iterate img2img |
--restore-sigma X | 1.95 | tune detail restore |
--restore-mode M | gaussian | edge for shape-coherent contours |
--unsharp X | 0.0 | post-restore sharpen; 0.2 is the perceptual sweet spot |
--no-restore | off | skip the frequency restore step |
--keep-intermediate | off | save the pre-restore clean output |
--transformer PATH | Q4_K_M | try a different GGUF quant |
python compare.py Original.png out\<output>.png
Prints PSNR, SSIM (full + low/high band), MAE, MSE, and per-channel histogram correlation.
| file | role |
|---|---|
desynth.py | main pipeline: img2img + restore in one call |
compare.py | similarity metrics between two images |
embeds_cache.pt | cached prompt embeddings (~430 KB) |
qwen-image-2512-Q4_K_M.gguf | Qwen-Image transformer, GGUF Q4 quant (~13 GB) |
Qwen-Image-2512-Lightning-4steps-V1.0-fp32.safetensors | 4-step Lightning distillation LoRA (~1.6 GB) |
Tested on Windows 10, RTX 5060 Ti 8 GB, 32 GB DDR4 RAM. Sequential CPU offload is required with < 12GB VRAM
Baseline workflow and watermark hypothesis from
00quebec/Synthid-Bypass.
This pipeline reimplements the core idea in plain Python without ComfyUI,
ControlNet, or the face-detail path, and replaces the heavier redraw with a
two-step minimum denoise + frequency-domain restore.
6 commits
Python
100.0%