diff --git a/README.md b/README.md index 781af94..54a3ea9 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,8 @@ ControlNet, followed by SAM-masked Z-Image repair of any detected face. The alternative, `sdxl-zimage`, swaps the global stage for SDXL and keeps the same face stage. A third profile, `chroma-zimage`, uses the Apache-2.0 Chroma1 global pass with its own flat vendor floors; see `docs/chroma1-engine-research.md` for the -calibration. All are CUDA only. +calibration. `--pipeline auto` picks chroma-zimage for OpenAI and Microsoft +provenance and qwen-zimage otherwise. All are CUDA only. ```bash uv tool install --force "remove-ai-watermarks[qwen-zimage]" diff --git a/docs/cli.md b/docs/cli.md index 63d725f..be1796c 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -410,8 +410,10 @@ The same option exists on `all` and `batch`, and as | --- | --- | | `qwen-zimage` | Default. Qwen-Image-2512 global pass plus a SAM-masked Z-Image face stage | | `sdxl-zimage` | The same recipe and face stage on an SDXL global pass, at a higher denoise | +| `chroma-zimage` | The same face stage on an Apache-2.0 Chroma1 global pass, with lower OpenAI and Microsoft floors and higher Google and Meta floors | +| `auto` | Pick the engine from provenance: chroma-zimage for OpenAI and Microsoft, qwen-zimage for Google, Meta, and unknown | -**Both are CUDA-only.** There is no CPU or MPS profile for invisible-watermark +**All four are CUDA-only.** There is no CPU or MPS profile for invisible-watermark removal. The former `controlnet`, `sdxl`, `qwen` and `default` profiles were removed rather than kept as a CPU path: none of them matched this recipe's face preservation, so offering them implied a quality the library no longer delivers. Passing a retired diff --git a/docs/installation.md b/docs/installation.md index bd8cf8c..10dff15 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -115,7 +115,7 @@ application actually uses: | `diffusion` | Torch and Diffusers runtime; video SynthID regeneration | `pixels`, Torch, Diffusers | Yes | | `migan` | MI-GAN ONNX fill backend | `visible`, ONNX Runtime | Model download, no Torch | | `lama` | big-LaMa ONNX fill backend | `visible`, ONNX Runtime | Model download, no Torch | -| `qwen-zimage` | Invisible image-watermark removal, both CUDA-only profiles | `diffusion`, DiffSynth | Yes | +| `qwen-zimage` | Invisible image-watermark removal, all CUDA-only profiles | `diffusion`, DiffSynth | Yes | | `text-restoration` | Opt-in verified Qwen-VAE glyph restoration | `qwen-zimage`, `lama` | Yes | | `text-draft` | Draft OCR proposals for operator verification | PaddleOCR, PaddlePaddle | Model download, no Torch | | `all` | Every production feature available on the active Python | All compatible rows above | Yes | diff --git a/docs/known-limitations.md b/docs/known-limitations.md index e38da7e..f1b9cd1 100644 --- a/docs/known-limitations.md +++ b/docs/known-limitations.md @@ -73,10 +73,12 @@ as SynthID lives in the pixels everywhere, including inside the glyphs, so frozen text regions would keep the watermark ([text protection research](text-protection-research.md)). -`qwen-zimage` is the default profile and `sdxl-zimage` the only alternative. -Both are CUDA only and differ only in the global regeneration model: each -conditions that stage on a canny edge map, which preserves structure but not -identity or exact texture, and each then runs the same face stage. +`qwen-zimage` is the default profile. `sdxl-zimage` and `chroma-zimage` keep +the same face stage and swap the global model. `auto` picks chroma-zimage for +OpenAI and Microsoft provenance and qwen-zimage otherwise. All are CUDA only. +Qwen and SDXL condition the global stage on a canny edge map, which preserves +structure but not identity or exact texture. Chroma1 is a plain strength pass +without Canny. Existing face evaluations favor `qwen-zimage`, but there is no blanket fidelity ordering across content types. A fixed-seed, three-scene text comparison at the profile defaults found no stable winner: SDXL won one poster, Qwen won one, and @@ -235,6 +237,8 @@ are certified at a fixed seed. The live resolver is | --- | --- | | `qwen-zimage` | CUDA only, large model stack, and limited broad certification across seeds and content. | | `sdxl-zimage` | CUDA only. Its strength ladder is flat per vendor, not a resolution curve, because flat values are what was measured. | +| `chroma-zimage` | CUDA only. Higher Google and Meta floors than qwen; Google face content uses 0.125 instead of 0.40. | +| `auto` | CUDA only. Routes OpenAI and Microsoft to chroma-zimage and everything else to qwen-zimage. | Only manually verified `vae-glyphs` is an optional production stage, and it is experimental rather than a default. diff --git a/docs/module-internals.md b/docs/module-internals.md index c849778..aae8984 100644 --- a/docs/module-internals.md +++ b/docs/module-internals.md @@ -942,10 +942,12 @@ is the source of truth for: - the SDXL global-stage checkpoint id (`SDXL_MODEL_ID`) and the Canny ControlNet id; - strength resolution for every profile. -The current profiles are `qwen-zimage` (the default), `sdxl-zimage`, and -`chroma-zimage`, and all three are CUDA-only. `controlnet`, `sdxl`, `qwen` and -`default` were removed rather than kept as a CPU path, and are rejected rather -than aliased onward. There is no content-dependent automatic router. +The current profiles are `qwen-zimage` (the default), `sdxl-zimage`, +`chroma-zimage`, and `auto`, and all four are CUDA-only. `controlnet`, `sdxl`, +`qwen` and `default` were removed rather than kept as a CPU path, and are +rejected rather than aliased onward. `auto` is a per-cohort engine router: +chroma-zimage for OpenAI and Microsoft, qwen-zimage for Google, Meta, and +unknown. It is not a content-class split inside one engine. `qwen-zimage` normally resolves global denoise from image area for unknown content. Measured provider cohorts bypass that curve with flat operating points. The values, diff --git a/docs/python-api.md b/docs/python-api.md index 59e6955..2c56dd3 100644 --- a/docs/python-api.md +++ b/docs/python-api.md @@ -596,7 +596,7 @@ from pathlib import Path from remove_ai_watermarks.invisible_engine import InvisibleEngine engine = InvisibleEngine( - pipeline="qwen-zimage", # the default; also "sdxl-zimage" or "chroma-zimage" + pipeline="qwen-zimage", # the default; also "sdxl-zimage", "chroma-zimage", or "auto" device=None, cpu_offload=False, ) @@ -628,8 +628,10 @@ Qwen: engine = InvisibleEngine(pipeline="sdxl-zimage") ``` -The `qwen-zimage` extra is required for all three profiles: each runs the same -DiffSynth Z-Image face stage. +The `qwen-zimage` extra is required for every profile, including `auto`: each +concrete engine runs the same DiffSynth Z-Image face stage. `pipeline="auto"` +selects chroma-zimage for OpenAI and Microsoft provenance and qwen-zimage +otherwise, after the vendor is known and before strength resolution. The opt-in verified-text stage uses the same `text_manifest` argument as the CLI: diff --git a/docs/supported-signals.md b/docs/supported-signals.md index f6d5274..3ad6cbe 100644 --- a/docs/supported-signals.md +++ b/docs/supported-signals.md @@ -131,10 +131,12 @@ The `invisible` command uses diffusion regeneration. It targets watermark patterns by changing the image rather than decoding and deleting a known payload. -Current pipeline values, both CUDA-only: +Current pipeline values, all CUDA-only: - `qwen-zimage`, the default; -- `sdxl-zimage`, the same recipe and the same face stage on an SDXL global pass. +- `sdxl-zimage`, the same recipe and the same face stage on an SDXL global pass; +- `chroma-zimage`, the same face stage on a Chroma1 global pass; +- `auto`, chroma-zimage for OpenAI and Microsoft provenance, otherwise qwen-zimage. The `controlnet`, `sdxl`, `qwen` and `default` values were removed. A retired name is rejected at parse time rather than remapped onto a surviving profile. diff --git a/docs/synthid.md b/docs/synthid.md index a20d385..c4a9108 100644 --- a/docs/synthid.md +++ b/docs/synthid.md @@ -461,9 +461,9 @@ conditioning, never by copying original pixels.** > **Superseded in 0.24.0.** The `controlnet`, `sdxl`, `qwen` and `default` profiles > were removed, and a retired name is now rejected at parse time rather than routed -> onward. `--pipeline` accepts only `qwen-zimage` (the default) and `sdxl-zimage`; -> both are CUDA-only, both condition their global stage on a canny edge map, and both -> run the same Z-Image face stage. The bullets below are a record of what was measured +> onward. Current `--pipeline` values are `qwen-zimage` (the default), +> `sdxl-zimage`, `chroma-zimage`, and `auto`; all are CUDA-only and share the +> Z-Image face stage. The bullets below are a record of what was measured > on the removed profiles, kept because the oracle verdicts are still the evidence the > current design rests on. diff --git a/pyproject.toml b/pyproject.toml index 9a2a4cc..024520c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ # on it, including the ComfyUI node package. The console script below carries # the same weight, since users have it on PATH. name = "remove-ai-watermarks" -version = "0.35.1" +version = "0.36.0" description = "AI watermark remover for visible, invisible, and provenance marks in images and video" readme = "README.md" requires-python = ">=3.11,<3.15" diff --git a/src/remove_ai_watermarks/__init__.py b/src/remove_ai_watermarks/__init__.py index a2d5b7c..e3608e5 100644 --- a/src/remove_ai_watermarks/__init__.py +++ b/src/remove_ai_watermarks/__init__.py @@ -32,7 +32,7 @@ _os.environ.setdefault("TRANSFORMERS_VERBOSITY", "error") _warnings.filterwarnings("ignore", message=r".*ImageProcessorFast.*") -__version__ = "0.35.1" +__version__ = "0.36.0" __all__ = [ "BatchSummary", diff --git a/uv.lock b/uv.lock index ef37e15..3fcda2e 100644 --- a/uv.lock +++ b/uv.lock @@ -3169,7 +3169,7 @@ wheels = [ [[package]] name = "remove-ai-watermarks" -version = "0.35.1" +version = "0.36.0" source = { editable = "." } dependencies = [ { name = "c2pa-python" },