From c9e04716e04f6b4b1530e43740e3c504dd98cf95 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 23 Aug 2025 11:41:12 +1000 Subject: [PATCH 1/2] feat(app): vendor in `invisible-watermark` Fixes errors like `AttributeError: module 'cv2.ximgproc' has no attribute 'thinning'` which occur because there is a conflict between our own `opencv-contrib-python` dependency and the `invisible-watermark` library's `opencv-python`. --- .../backend/image_util/imwatermark/vendor.py | 304 ++++++++++++++++++ .../backend/image_util/invisible_watermark.py | 5 +- pyproject.toml | 3 +- 3 files changed, 307 insertions(+), 5 deletions(-) create mode 100644 invokeai/backend/image_util/imwatermark/vendor.py diff --git a/invokeai/backend/image_util/imwatermark/vendor.py b/invokeai/backend/image_util/imwatermark/vendor.py new file mode 100644 index 00000000000..ef06274ff73 --- /dev/null +++ b/invokeai/backend/image_util/imwatermark/vendor.py @@ -0,0 +1,304 @@ +# This file is vendored from https://github.com/ShieldMnt/invisible-watermark +# +# `invisible-watermark` is MIT licensed as of August 23, 2025, when the code was copied into this repo. +# +# Why we vendored it in: +# `invisible-watermark` has a dependency on `opencv-python`, which conflicts with Invoke's dependency on +# `opencv-contrib-python`. It's easier to copy the code over than complicate the installation process by +# requiring an extra post-install step of removing `opencv-python` and installing `opencv-contrib-python`. + +import struct +import uuid +import base64 +import cv2 +import numpy as np +import pywt + + +class WatermarkEncoder(object): + def __init__(self, content=b""): + seq = np.array([n for n in content], dtype=np.uint8) + self._watermarks = list(np.unpackbits(seq)) + self._wmLen = len(self._watermarks) + self._wmType = "bytes" + + def set_by_ipv4(self, addr): + bits = [] + ips = addr.split(".") + for ip in ips: + bits += list(np.unpackbits(np.array([ip % 255], dtype=np.uint8))) + self._watermarks = bits + self._wmLen = len(self._watermarks) + self._wmType = "ipv4" + assert self._wmLen == 32 + + def set_by_uuid(self, uid): + u = uuid.UUID(uid) + self._wmType = "uuid" + seq = np.array([n for n in u.bytes], dtype=np.uint8) + self._watermarks = list(np.unpackbits(seq)) + self._wmLen = len(self._watermarks) + + def set_by_bytes(self, content): + self._wmType = "bytes" + seq = np.array([n for n in content], dtype=np.uint8) + self._watermarks = list(np.unpackbits(seq)) + self._wmLen = len(self._watermarks) + + def set_by_b16(self, b16): + content = base64.b16decode(b16) + self.set_by_bytes(content) + self._wmType = "b16" + + def set_by_bits(self, bits=[]): + self._watermarks = [int(bit) % 2 for bit in bits] + self._wmLen = len(self._watermarks) + self._wmType = "bits" + + def set_watermark(self, wmType="bytes", content=""): + if wmType == "ipv4": + self.set_by_ipv4(content) + elif wmType == "uuid": + self.set_by_uuid(content) + elif wmType == "bits": + self.set_by_bits(content) + elif wmType == "bytes": + self.set_by_bytes(content) + elif wmType == "b16": + self.set_by_b16(content) + else: + raise NameError("%s is not supported" % wmType) + + def get_length(self): + return self._wmLen + + # @classmethod + # def loadModel(cls): + # RivaWatermark.loadModel() + + def encode(self, cv2Image, method="dwtDct", **configs): + (r, c, channels) = cv2Image.shape + if r * c < 256 * 256: + raise RuntimeError("image too small, should be larger than 256x256") + + if method == "dwtDct": + embed = EmbedMaxDct(self._watermarks, wmLen=self._wmLen, **configs) + return embed.encode(cv2Image) + # elif method == 'dwtDctSvd': + # embed = EmbedDwtDctSvd(self._watermarks, wmLen=self._wmLen, **configs) + # return embed.encode(cv2Image) + # elif method == 'rivaGan': + # embed = RivaWatermark(self._watermarks, self._wmLen) + # return embed.encode(cv2Image) + else: + raise NameError("%s is not supported" % method) + + +class WatermarkDecoder(object): + def __init__(self, wm_type="bytes", length=0): + self._wmType = wm_type + if wm_type == "ipv4": + self._wmLen = 32 + elif wm_type == "uuid": + self._wmLen = 128 + elif wm_type == "bytes": + self._wmLen = length + elif wm_type == "bits": + self._wmLen = length + elif wm_type == "b16": + self._wmLen = length + else: + raise NameError("%s is unsupported" % wm_type) + + def reconstruct_ipv4(self, bits): + ips = [str(ip) for ip in list(np.packbits(bits))] + return ".".join(ips) + + def reconstruct_uuid(self, bits): + nums = np.packbits(bits) + bstr = b"" + for i in range(16): + bstr += struct.pack(">B", nums[i]) + + return str(uuid.UUID(bytes=bstr)) + + def reconstruct_bits(self, bits): + # return ''.join([str(b) for b in bits]) + return bits + + def reconstruct_b16(self, bits): + bstr = self.reconstruct_bytes(bits) + return base64.b16encode(bstr) + + def reconstruct_bytes(self, bits): + nums = np.packbits(bits) + bstr = b"" + for i in range(self._wmLen // 8): + bstr += struct.pack(">B", nums[i]) + return bstr + + def reconstruct(self, bits): + if len(bits) != self._wmLen: + raise RuntimeError("bits are not matched with watermark length") + + if self._wmType == "ipv4": + return self.reconstruct_ipv4(bits) + elif self._wmType == "uuid": + return self.reconstruct_uuid(bits) + elif self._wmType == "bits": + return self.reconstruct_bits(bits) + elif self._wmType == "b16": + return self.reconstruct_b16(bits) + else: + return self.reconstruct_bytes(bits) + + def decode(self, cv2Image, method="dwtDct", **configs): + (r, c, channels) = cv2Image.shape + if r * c < 256 * 256: + raise RuntimeError("image too small, should be larger than 256x256") + + bits = [] + if method == "dwtDct": + embed = EmbedMaxDct(watermarks=[], wmLen=self._wmLen, **configs) + bits = embed.decode(cv2Image) + # elif method == 'dwtDctSvd': + # embed = EmbedDwtDctSvd(watermarks=[], wmLen=self._wmLen, **configs) + # bits = embed.decode(cv2Image) + # elif method == 'rivaGan': + # embed = RivaWatermark(watermarks=[], wmLen=self._wmLen, **configs) + # bits = embed.decode(cv2Image) + else: + raise NameError("%s is not supported" % method) + return self.reconstruct(bits) + + # @classmethod + # def loadModel(cls): + # RivaWatermark.loadModel() + + +class EmbedMaxDct(object): + def __init__(self, watermarks=[], wmLen=8, scales=[0, 36, 36], block=4): + self._watermarks = watermarks + self._wmLen = wmLen + self._scales = scales + self._block = block + + def encode(self, bgr): + (row, col, channels) = bgr.shape + + yuv = cv2.cvtColor(bgr, cv2.COLOR_BGR2YUV) + + for channel in range(2): + if self._scales[channel] <= 0: + continue + + ca1, (h1, v1, d1) = pywt.dwt2(yuv[: row // 4 * 4, : col // 4 * 4, channel], "haar") + self.encode_frame(ca1, self._scales[channel]) + + yuv[: row // 4 * 4, : col // 4 * 4, channel] = pywt.idwt2((ca1, (v1, h1, d1)), "haar") + + bgr_encoded = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR) + return bgr_encoded + + def decode(self, bgr): + (row, col, channels) = bgr.shape + + yuv = cv2.cvtColor(bgr, cv2.COLOR_BGR2YUV) + + scores = [[] for i in range(self._wmLen)] + for channel in range(2): + if self._scales[channel] <= 0: + continue + + ca1, (h1, v1, d1) = pywt.dwt2(yuv[: row // 4 * 4, : col // 4 * 4, channel], "haar") + + scores = self.decode_frame(ca1, self._scales[channel], scores) + + avgScores = list(map(lambda l: np.array(l).mean(), scores)) + + bits = np.array(avgScores) * 255 > 127 + return bits + + def decode_frame(self, frame, scale, scores): + (row, col) = frame.shape + num = 0 + + for i in range(row // self._block): + for j in range(col // self._block): + block = frame[ + i * self._block : i * self._block + self._block, j * self._block : j * self._block + self._block + ] + + score = self.infer_dct_matrix(block, scale) + # score = self.infer_dct_svd(block, scale) + wmBit = num % self._wmLen + scores[wmBit].append(score) + num = num + 1 + + return scores + + def diffuse_dct_svd(self, block, wmBit, scale): + u, s, v = np.linalg.svd(cv2.dct(block)) + + s[0] = (s[0] // scale + 0.25 + 0.5 * wmBit) * scale + return cv2.idct(np.dot(u, np.dot(np.diag(s), v))) + + def infer_dct_svd(self, block, scale): + u, s, v = np.linalg.svd(cv2.dct(block)) + + score = 0 + score = int((s[0] % scale) > scale * 0.5) + return score + if score >= 0.5: + return 1.0 + else: + return 0.0 + + def diffuse_dct_matrix(self, block, wmBit, scale): + pos = np.argmax(abs(block.flatten()[1:])) + 1 + i, j = pos // self._block, pos % self._block + val = block[i][j] + if val >= 0.0: + block[i][j] = (val // scale + 0.25 + 0.5 * wmBit) * scale + else: + val = abs(val) + block[i][j] = -1.0 * (val // scale + 0.25 + 0.5 * wmBit) * scale + return block + + def infer_dct_matrix(self, block, scale): + pos = np.argmax(abs(block.flatten()[1:])) + 1 + i, j = pos // self._block, pos % self._block + + val = block[i][j] + if val < 0: + val = abs(val) + + if (val % scale) > 0.5 * scale: + return 1 + else: + return 0 + + def encode_frame(self, frame, scale): + """ + frame is a matrix (M, N) + + we get K (watermark bits size) blocks (self._block x self._block) + + For i-th block, we encode watermark[i] bit into it + """ + (row, col) = frame.shape + num = 0 + for i in range(row // self._block): + for j in range(col // self._block): + block = frame[ + i * self._block : i * self._block + self._block, j * self._block : j * self._block + self._block + ] + wmBit = self._watermarks[(num % self._wmLen)] + + diffusedBlock = self.diffuse_dct_matrix(block, wmBit, scale) + # diffusedBlock = self.diffuse_dct_svd(block, wmBit, scale) + frame[ + i * self._block : i * self._block + self._block, j * self._block : j * self._block + self._block + ] = diffusedBlock + + num = num + 1 diff --git a/invokeai/backend/image_util/invisible_watermark.py b/invokeai/backend/image_util/invisible_watermark.py index 84342e442fc..5b0b2dbb5b1 100644 --- a/invokeai/backend/image_util/invisible_watermark.py +++ b/invokeai/backend/image_util/invisible_watermark.py @@ -6,13 +6,10 @@ import cv2 import numpy as np -from imwatermark import WatermarkEncoder from PIL import Image import invokeai.backend.util.logging as logger -from invokeai.app.services.config.config_default import get_config - -config = get_config() +from invokeai.backend.image_util.imwatermark.vendor import WatermarkEncoder class InvisibleWatermark: diff --git a/pyproject.toml b/pyproject.toml index d16d86106ee..215152014bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,6 @@ dependencies = [ "compel==2.1.1", "diffusers[torch]==0.33.0", "gguf", - "invisible-watermark==0.2.0", # needed to install SDXL base and refiner using their repo_ids "mediapipe==0.10.14", # needed for "mediapipeface" controlnet model "numpy<2.0.0", "onnx==1.16.1", @@ -74,6 +73,7 @@ dependencies = [ "python-multipart", "requests", "semver~=3.0.1", + "PyWavelets", ] [project.optional-dependencies] @@ -234,6 +234,7 @@ exclude = [ "invokeai/backend/image_util/mlsd/", # External code "invokeai/backend/image_util/normal_bae/", # External code "invokeai/backend/image_util/pidi/", # External code + "invokeai/backend/image_util/imwatermark/", # External code ] [tool.ruff.lint] From 8a4f4f94477b380e9f34d42487bad6ee8e183d18 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 23 Aug 2025 11:52:01 +1000 Subject: [PATCH 2/2] chore: uv lock --- uv.lock | 75 +++++++++++++++------------------------------------------ 1 file changed, 20 insertions(+), 55 deletions(-) diff --git a/uv.lock b/uv.lock index 9ec4700c7fb..1bae4114f34 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 2 +revision = 3 requires-python = ">=3.10, <3.13" resolution-markers = [ "python_full_version >= '3.12' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra != 'extra-8-invokeai-cpu' and extra != 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm'", @@ -167,11 +167,11 @@ name = "bitsandbytes" version = "0.46.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, - { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra != 'extra-8-invokeai-cpu' and extra != 'extra-8-invokeai-cuda' and extra != 'extra-8-invokeai-rocm')" }, - { name = "torch", version = "2.7.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "extra == 'extra-8-invokeai-cpu' or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, - { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "extra == 'extra-8-invokeai-cuda' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, - { name = "torch", version = "2.7.1+rocm6.3", source = { registry = "https://download.pytorch.org/whl/rocm6.3" }, marker = "(extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra != 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra != 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, + { name = "numpy", marker = "sys_platform != 'darwin' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, + { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple" }, marker = "(sys_platform != 'darwin' and extra != 'extra-8-invokeai-cpu' and extra != 'extra-8-invokeai-cuda' and extra != 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, + { name = "torch", version = "2.7.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(sys_platform != 'darwin' and extra == 'extra-8-invokeai-cpu') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(sys_platform != 'darwin' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, + { name = "torch", version = "2.7.1+rocm6.3", source = { registry = "https://download.pytorch.org/whl/rocm6.3" }, marker = "(sys_platform != 'darwin' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/d2/b2/9dadb4f8dca3948e35c1ebfee75ca82353e41468b41ff785430595f8e6f0/bitsandbytes-0.46.1-py3-none-manylinux_2_24_aarch64.whl", hash = "sha256:21b349f776d04c6c1380405961081de29c84f49640b79d3d199b6d719818da84", size = 30713241, upload-time = "2025-07-02T19:44:21.857Z" }, @@ -1052,24 +1052,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] -[[package]] -name = "invisible-watermark" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "opencv-python", marker = "sys_platform == 'never' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, - { name = "pillow" }, - { name = "pywavelets" }, - { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra != 'extra-8-invokeai-cpu' and extra != 'extra-8-invokeai-cuda' and extra != 'extra-8-invokeai-rocm')" }, - { name = "torch", version = "2.7.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "extra == 'extra-8-invokeai-cpu' or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, - { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "extra == 'extra-8-invokeai-cuda' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, - { name = "torch", version = "2.7.1+rocm6.3", source = { registry = "https://download.pytorch.org/whl/rocm6.3" }, marker = "(extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra != 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra != 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/57/18b5a914f6d7994dd349252873169e946dc824328e9a37fd15ed836deedc/invisible_watermark-0.2.0-py3-none-any.whl", hash = "sha256:644311beed9cfe4a9a5a4a46c740f47800cef184fe2e1297f3f4542e2d992f8b", size = 1633253, upload-time = "2023-07-06T13:56:28.715Z" }, -] - [[package]] name = "invokeai" source = { editable = "." } @@ -1087,7 +1069,6 @@ dependencies = [ { name = "fastapi-events" }, { name = "gguf" }, { name = "huggingface-hub" }, - { name = "invisible-watermark" }, { name = "mediapipe" }, { name = "numpy" }, { name = "onnx" }, @@ -1101,6 +1082,7 @@ dependencies = [ { name = "pypatchmatch" }, { name = "python-multipart" }, { name = "python-socketio" }, + { name = "pywavelets" }, { name = "requests" }, { name = "safetensors" }, { name = "semver" }, @@ -1196,7 +1178,6 @@ requires-dist = [ { name = "httpx", marker = "extra == 'test'" }, { name = "huggingface-hub" }, { name = "humanize", marker = "extra == 'test'", specifier = "==4.12.1" }, - { name = "invisible-watermark", specifier = "==0.2.0" }, { name = "jurigged", marker = "extra == 'dev'" }, { name = "mediapipe", specifier = "==0.10.14" }, { name = "mkdocs-git-revision-date-localized-plugin", marker = "extra == 'docs'" }, @@ -1230,6 +1211,7 @@ requires-dist = [ { name = "python-socketio" }, { name = "pytorch-triton-rocm", marker = "sys_platform == 'linux' and extra == 'rocm'", index = "https://download.pytorch.org/whl/rocm6.3", conflict = { package = "invokeai", extra = "rocm" } }, { name = "pytorch-triton-rocm", marker = "sys_platform != 'linux' and extra == 'rocm'" }, + { name = "pywavelets" }, { name = "requests" }, { name = "requests-testadapter", marker = "extra == 'test'" }, { name = "ruff", marker = "extra == 'test'", specifier = "~=0.11.2" }, @@ -2149,7 +2131,7 @@ resolution-markers = [ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", ] dependencies = [ - { name = "nvidia-cublas-cu12", version = "12.8.3.14", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-invokeai-cuda' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, + { name = "nvidia-cublas-cu12", version = "12.8.3.14", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform == 'darwin' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c1/2e/ec5dda717eeb1de3afbbbb611ca556f9d6d057470759c6abd36d72f0063b/nvidia_cudnn_cu12-9.7.1.26-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:848a61d40ef3b32bd4e1fadb599f0cf04a4b942fbe5fb3be572ad75f9b8c53ef", size = 725862213, upload-time = "2025-02-06T22:14:57.169Z" }, @@ -2187,7 +2169,7 @@ resolution-markers = [ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", ] dependencies = [ - { name = "nvidia-nvjitlink-cu12", version = "12.8.61", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-invokeai-cuda' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, + { name = "nvidia-nvjitlink-cu12", version = "12.8.61", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform == 'darwin' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/72/95/6157cb45a49f5090a470de42353a22a0ed5b13077886dca891b4b0e350fe/nvidia_cufft_cu12-11.3.3.41-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68509dcd7e3306e69d0e2d8a6d21c8b25ed62e6df8aac192ce752f17677398b5", size = 193108626, upload-time = "2025-01-23T17:55:49.192Z" }, @@ -2287,9 +2269,9 @@ resolution-markers = [ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", ] dependencies = [ - { name = "nvidia-cublas-cu12", version = "12.8.3.14", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-invokeai-cuda' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, - { name = "nvidia-cusparse-cu12", version = "12.5.7.53", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-invokeai-cuda' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, - { name = "nvidia-nvjitlink-cu12", version = "12.8.61", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-invokeai-cuda' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, + { name = "nvidia-cublas-cu12", version = "12.8.3.14", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform == 'darwin' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, + { name = "nvidia-cusparse-cu12", version = "12.5.7.53", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform == 'darwin' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, + { name = "nvidia-nvjitlink-cu12", version = "12.8.61", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform == 'darwin' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/8c/ce/4214a892e804b20bf66d04f04a473006fc2d3dac158160ef85f1bc906639/nvidia_cusolver_cu12-11.7.2.55-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:0fd9e98246f43c15bee5561147ad235dfdf2d037f5d07c9d41af3f7f72feb7cc", size = 260094827, upload-time = "2025-01-23T17:58:17.586Z" }, @@ -2327,7 +2309,7 @@ resolution-markers = [ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", ] dependencies = [ - { name = "nvidia-nvjitlink-cu12", version = "12.8.61", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-invokeai-cuda' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, + { name = "nvidia-nvjitlink-cu12", version = "12.8.61", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform == 'darwin' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/2e/a2/313db0453087f5324a5900380ca2e57e050c8de76f407b5e11383dc762ae/nvidia_cusparse_cu12-12.5.7.53-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d869c6146ca80f4305b62e02d924b4aaced936f8173e3cef536a67eed2a91af1", size = 291963692, upload-time = "2025-01-23T17:59:40.325Z" }, @@ -2529,23 +2511,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0d/c6/146487546adc4726f0be591a65b466973feaa58cc3db711087e802e940fb/opencv_contrib_python-4.11.0.86-cp37-abi3-win_amd64.whl", hash = "sha256:654758a9ae8ca9a75fca7b64b19163636534f0eedffe1e14c3d7218988625c8d", size = 46185163, upload-time = "2025-01-16T13:52:39.745Z" }, ] -[[package]] -name = "opencv-python" -version = "4.11.0.86" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy", marker = "sys_platform != 'linux' or extra == 'extra-8-invokeai-cpu' or extra == 'extra-8-invokeai-cuda' or extra != 'extra-8-invokeai-rocm'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/17/06/68c27a523103dad5837dc5b87e71285280c4f098c60e4fe8a8db6486ab09/opencv-python-4.11.0.86.tar.gz", hash = "sha256:03d60ccae62304860d232272e4a4fda93c39d595780cb40b161b310244b736a4", size = 95171956, upload-time = "2025-01-16T13:52:24.737Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/05/4d/53b30a2a3ac1f75f65a59eb29cf2ee7207ce64867db47036ad61743d5a23/opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:432f67c223f1dc2824f5e73cdfcd9db0efc8710647d4e813012195dc9122a52a", size = 37326322, upload-time = "2025-01-16T13:52:25.887Z" }, - { url = "https://files.pythonhosted.org/packages/3b/84/0a67490741867eacdfa37bc18df96e08a9d579583b419010d7f3da8ff503/opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:9d05ef13d23fe97f575153558653e2d6e87103995d54e6a35db3f282fe1f9c66", size = 56723197, upload-time = "2025-01-16T13:55:21.222Z" }, - { url = "https://files.pythonhosted.org/packages/f3/bd/29c126788da65c1fb2b5fb621b7fed0ed5f9122aa22a0868c5e2c15c6d23/opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b92ae2c8852208817e6776ba1ea0d6b1e0a1b5431e971a2a0ddd2a8cc398202", size = 42230439, upload-time = "2025-01-16T13:51:35.822Z" }, - { url = "https://files.pythonhosted.org/packages/2c/8b/90eb44a40476fa0e71e05a0283947cfd74a5d36121a11d926ad6f3193cc4/opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b02611523803495003bd87362db3e1d2a0454a6a63025dc6658a9830570aa0d", size = 62986597, upload-time = "2025-01-16T13:52:08.836Z" }, - { url = "https://files.pythonhosted.org/packages/fb/d7/1d5941a9dde095468b288d989ff6539dd69cd429dbf1b9e839013d21b6f0/opencv_python-4.11.0.86-cp37-abi3-win32.whl", hash = "sha256:810549cb2a4aedaa84ad9a1c92fbfdfc14090e2749cedf2c1589ad8359aa169b", size = 29384337, upload-time = "2025-01-16T13:52:13.549Z" }, - { url = "https://files.pythonhosted.org/packages/a4/7d/f1c30a92854540bf789e9cd5dde7ef49bbe63f855b85a2e6b3db8135c591/opencv_python-4.11.0.86-cp37-abi3-win_amd64.whl", hash = "sha256:085ad9b77c18853ea66283e98affefe2de8cc4c1f43eda4c100cf9b2721142ec", size = 39488044, upload-time = "2025-01-16T13:52:21.928Z" }, -] - [[package]] name = "opt-einsum" version = "3.4.0" @@ -4164,7 +4129,7 @@ name = "triton" version = "3.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "setuptools" }, + { name = "setuptools", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux' and extra != 'extra-8-invokeai-cpu' and extra != 'extra-8-invokeai-rocm') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra != 'extra-8-invokeai-cpu' and extra != 'extra-8-invokeai-rocm') or (sys_platform == 'linux' and extra == 'extra-8-invokeai-cuda') or (sys_platform == 'darwin' and extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/8d/a9/549e51e9b1b2c9b854fd761a1d23df0ba2fbc60bd0c13b489ffa518cfcb7/triton-3.3.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b74db445b1c562844d3cfad6e9679c72e93fdfb1a90a24052b03bb5c49d1242e", size = 155600257, upload-time = "2025-05-29T23:39:36.085Z" }, @@ -4528,11 +4493,11 @@ name = "xformers" version = "0.0.31" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, - { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra != 'extra-8-invokeai-cpu' and extra != 'extra-8-invokeai-cuda' and extra != 'extra-8-invokeai-rocm')" }, - { name = "torch", version = "2.7.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "extra == 'extra-8-invokeai-cpu' or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, - { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "extra == 'extra-8-invokeai-cuda' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, - { name = "torch", version = "2.7.1+rocm6.3", source = { registry = "https://download.pytorch.org/whl/rocm6.3" }, marker = "(extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra != 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm') or (extra != 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm')" }, + { name = "numpy", marker = "sys_platform != 'darwin' or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, + { name = "torch", version = "2.7.1", source = { registry = "https://pypi.org/simple" }, marker = "(sys_platform != 'darwin' and extra != 'extra-8-invokeai-cpu' and extra != 'extra-8-invokeai-cuda' and extra != 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, + { name = "torch", version = "2.7.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(sys_platform != 'darwin' and extra == 'extra-8-invokeai-cpu') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, + { name = "torch", version = "2.7.1+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "(sys_platform != 'darwin' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, + { name = "torch", version = "2.7.1+rocm6.3", source = { registry = "https://download.pytorch.org/whl/rocm6.3" }, marker = "(sys_platform != 'darwin' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-cuda') or (extra == 'extra-8-invokeai-cpu' and extra == 'extra-8-invokeai-rocm') or (extra == 'extra-8-invokeai-cuda' and extra == 'extra-8-invokeai-rocm')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/35/91c172a57681e1c03de5ad1ca654dc87c282279b941052ed04e616ae5bcd/xformers-0.0.31.tar.gz", hash = "sha256:3fccb159c6327c13fc1b08f8b963c2779ca526e2e50755dee9bcc1bac67d20c6", size = 12102740, upload-time = "2025-06-25T15:12:10.241Z" } wheels = [