diff --git a/docs/installation.md b/docs/installation.md index 87ae329..dbfb587 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -77,9 +77,11 @@ uv tool install --force "remove-ai-watermarks[qwen-zimage]" Both remaining profiles run a Z-Image face stage on the DiffSynth runtime, so both need this extra. The third profile, `chroma-zimage`, uses diffusers' ChromaImg2ImgPipeline instead of DiffSynth for its global stage but inherits -the same face stage, so it needs this extra too. It includes the `diffusion` -dependencies; `diffusion` on its own covers the torch and diffusers imports -but not the face stage, so it is not enough to run a removal. +the same face stage, so it needs this extra too. The extra also installs +SentencePiece for Chroma1-HD's binary `spiece.model`; without that backend, +Transformers cannot construct the Chroma tokenizer. It includes the `diffusion` +dependencies; `diffusion` on its own covers the torch and diffusers imports but +not the face stage or Chroma tokenizer, so it is not enough to run a removal. **An NVIDIA GPU is required.** `qwen-zimage`, `sdxl-zimage` and `chroma-zimage` are CUDA-only, and @@ -117,7 +119,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, all CUDA-only profiles | `diffusion`, DiffSynth | Yes | +| `qwen-zimage` | Invisible image-watermark removal, all CUDA-only profiles | `diffusion`, DiffSynth, SentencePiece | Yes | | `text-restoration` | Opt-in verified profile-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/pyproject.toml b/pyproject.toml index bd4522c..068c08e 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.37.0" +version = "0.37.1" description = "AI watermark remover for visible, invisible, and provenance marks in images and video" readme = "README.md" requires-python = ">=3.11,<3.15" @@ -118,6 +118,9 @@ diffusion = [ qwen-zimage = [ "remove-ai-watermarks[diffusion]", "diffsynth>=2.0.17,<3", + # Chroma1-HD ships a binary spiece.model. Without the matching backend, + # Transformers falls through to tiktoken, which cannot parse that file. + "sentencepiece>=0.2.2,<0.3", "torchvision>=0.20.0", ] # Opt-in verified-text reconstruction over qwen-zimage. LaMa removes the changed diff --git a/src/remove_ai_watermarks/__init__.py b/src/remove_ai_watermarks/__init__.py index 9971d99..b4320ef 100644 --- a/src/remove_ai_watermarks/__init__.py +++ b/src/remove_ai_watermarks/__init__.py @@ -33,7 +33,7 @@ _os.environ.setdefault("TRANSFORMERS_VERBOSITY", "error") _warnings.filterwarnings("ignore", message=r".*ImageProcessorFast.*") -__version__ = "0.37.0" +__version__ = "0.37.1" __all__ = [ "BatchSummary", diff --git a/tests/test_packaging.py b/tests/test_packaging.py index 50c28e2..d8ab405 100644 --- a/tests/test_packaging.py +++ b/tests/test_packaging.py @@ -81,6 +81,10 @@ def test_classify_extra_owns_the_photo_heads() -> None: assert {"torch", "transformers", "huggingface-hub", "tokenizers"} <= names +def test_qwen_zimage_extra_owns_every_profile_tokenizer_backend() -> None: + assert "sentencepiece" in _requirement_names("qwen-zimage") + + def test_production_all_does_not_include_development_tools(): assert { "pyright", diff --git a/uv.lock b/uv.lock index c007e32..ab0ef70 100644 --- a/uv.lock +++ b/uv.lock @@ -3311,7 +3311,7 @@ wheels = [ [[package]] name = "remove-ai-watermarks" -version = "0.37.0" +version = "0.37.1" source = { editable = "." } dependencies = [ { name = "c2pa-python" }, @@ -3336,6 +3336,7 @@ all = [ { name = "pillow-heif" }, { name = "pywavelets" }, { name = "safetensors" }, + { name = "sentencepiece" }, { name = "tokenizers" }, { name = "torch" }, { name = "torchvision" }, @@ -3412,6 +3413,7 @@ qwen-zimage = [ { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.13'" }, { name = "opencv-python-headless" }, { name = "safetensors" }, + { name = "sentencepiece" }, { name = "tokenizers" }, { name = "torch" }, { name = "torchvision" }, @@ -3432,6 +3434,7 @@ text-restoration = [ { name = "onnxruntime" }, { name = "opencv-python-headless" }, { name = "safetensors" }, + { name = "sentencepiece" }, { name = "tokenizers" }, { name = "torch" }, { name = "torchvision" }, @@ -3500,6 +3503,7 @@ requires-dist = [ { name = "remove-ai-watermarks", extras = ["visible"], marker = "extra == 'video'" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.4.0" }, { name = "safetensors", marker = "extra == 'diffusion'" }, + { name = "sentencepiece", marker = "extra == 'qwen-zimage'", specifier = ">=0.2.2,<0.3" }, { name = "tokenizers", marker = "extra == 'classify'", specifier = ">=0.22,<0.23" }, { name = "tokenizers", marker = "extra == 'diffusion'", specifier = ">=0.22,<0.23" }, { name = "torch", marker = "extra == 'classify'", specifier = ">=2.0.0" },