diff --git a/CHANGES.md b/CHANGES.md index 389ea7b7..b6a56186 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,8 @@ - **Major rewrite of the code** - We've switched to using diffusers under-the-hood, which allows us to release new features faster, and focus on making the UI and installer even easier to use. ### Detailed changelog +* 3.0.9 - 28 May 2024 - Slider for controlling the strength of controlnets. +* 3.0.8 - 27 May 2024 - SDXL ControlNets for Img2Img and Inpainting. * 3.0.7 - 11 Dec 2023 - Setting to enable/disable VAE tiling (in the Image Settings panel). Sometimes VAE tiling reduces the quality of the image, so this setting will help control that. * 3.0.6 - 18 Sep 2023 - Add thumbnails to embeddings from the UI, using the new `Upload Thumbnail` button in the Embeddings popup. Thanks @JeLuf. * 3.0.6 - 15 Sep 2023 - Fix broken embeddings dialog when LoRA information couldn't be fetched. diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 480d4e62..9a067e68 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -15,13 +15,16 @@ import traceback import shutil from pathlib import Path from pprint import pprint +import re os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0", "2.0.1"), "torchvision": ("0.12.0", "0.14.1", "0.15.1", "0.15.2"), - "sdkit": "2.0.15", + "setuptools": "69.5.1", + # "sdkit": "2.0.15.6", # checked later + # "diffusers": "0.21.4", # checked later "stable-diffusion-sdkit": "2.1.5", "rich": "12.6.0", "uvicorn": "0.19.0", @@ -32,7 +35,7 @@ modules_to_check = { "python-multipart": "0.0.6", # "xformers": "0.0.16", } -modules_to_log = ["torch", "torchvision", "sdkit", "stable-diffusion-sdkit"] +modules_to_log = ["torch", "torchvision", "sdkit", "stable-diffusion-sdkit", "diffusers"] def version(module_name: str) -> str: @@ -91,6 +94,14 @@ def update_modules(): allowed_versions, latest_version = get_allowed_versions(module_name, allowed_versions) + if module_name == "setuptools": + if os_name == "Windows": + allowed_versions = ("59.8.0",) + latest_version = "59.8.0" + else: + allowed_versions = ("69.0.0",) + latest_version = "69.0.0" + requires_install = False if module_name in ("torch", "torchvision"): if version(module_name) is None: # allow any torch version @@ -114,8 +125,110 @@ def update_modules(): f"WARNING! Tried to install {module_name}=={latest_version}, but the version is still {version(module_name)}!" ) - if module_name in modules_to_log: - print(f"{module_name}: {version(module_name)}") + # different sdkit versions, with the corresponding diffusers + # if sdkit is 2.0.15.x (or lower), then diffusers should be restricted to 0.21.4 (see below for the reason) + # otherwise use the current sdkit version (with the corresponding diffusers version) + + expected_sdkit_version_str = "2.0.20.4" + expected_diffusers_version_str = "0.28.2" + + legacy_sdkit_version_str = "2.0.15.7" + legacy_diffusers_version_str = "0.21.4" + + sdkit_version_str = version("sdkit") + if sdkit_version_str is None: # first install + _install("sdkit", expected_sdkit_version_str) + _install("diffusers", expected_diffusers_version_str) + else: + sdkit_version = version_str_to_tuple(sdkit_version_str) + legacy_sdkit_version = version_str_to_tuple(legacy_sdkit_version_str) + + if sdkit_version[:3] <= legacy_sdkit_version[:3]: # and torch_version < (0, 13): + # stick to diffusers 0.21.4, since it preserves torch 0.11+ compatibility. + # upgrading beyond this will result in a 2+ GB download of torch on older installations + # and a time-consuming chain of small package updates due to huggingface_hub upgrade. + # for now, the user will need to explicitly upgrade to a newer sdkit, to break this ceiling. + + install_pkg_if_necessary("sdkit", legacy_sdkit_version_str) + install_pkg_if_necessary("diffusers", legacy_diffusers_version_str) + else: + torch_version = version_str_to_tuple(version("torch")) + if torch_version < (1, 13): + # install the gpu-compatible torch (if necessary), instead of the default CPU-only one + # from the diffusers dependency chain + install("torch", modules_to_check["torch"][-1]) + install("torchvision", modules_to_check["torchvision"][-1]) + + install_pkg_if_necessary("sdkit", expected_sdkit_version_str) + install_pkg_if_necessary("diffusers", expected_diffusers_version_str) + + # hotfix accelerate + accelerate_version = version("accelerate") + if accelerate_version is None: + install("accelerate", "0.23.0") + else: + accelerate_version = accelerate_version.split(".") + accelerate_version = tuple(map(int, accelerate_version)) + if accelerate_version < (0, 23): + install("accelerate", "0.23.0") + + # hotfix - 29 May 2024. sdkit has stopped pulling its dependencies for some reason + # temporarily dumping sdkit's requirements here: + if os_name != "Windows": + sdkit_deps = [ + "gfpgan", + "piexif", + "realesrgan", + "requests", + "picklescan", + "safetensors==0.3.3", + "k-diffusion==0.0.12", + "compel==2.0.1", + "controlnet-aux==0.0.6", + "invisible-watermark==0.2.0", # required for SD XL + ] + + for mod in sdkit_deps: + mod_name = mod + mod_force_version_str = None + if "==" in mod: + mod_name, mod_force_version_str = mod.split("==") + + curr_mod_version_str = version(mod_name) + if curr_mod_version_str is None: + _install(mod_name, mod_force_version_str) + elif mod_force_version_str is not None: + curr_mod_version = version_str_to_tuple(curr_mod_version_str) + mod_force_version = version_str_to_tuple(mod_force_version_str) + + if curr_mod_version != mod_force_version: + _install(mod_name, mod_force_version_str) + + for module_name in modules_to_log: + print(f"{module_name}: {version(module_name)}") + + +def _install(module_name, module_version=None): + if module_version is None: + install_cmd = f"python -m pip install {module_name}" + else: + install_cmd = f"python -m pip install --upgrade {module_name}=={module_version}" + + print(">", install_cmd) + os.system(install_cmd) + + +def install_pkg_if_necessary(pkg_name, required_version): + pkg_version = version(pkg_name) + if pkg_version != required_version: + _install(pkg_name, required_version) + + +def version_str_to_tuple(ver_str): + ver_str = ver_str.split("+")[0] + ver_str = re.sub("[^0-9.]", "", ver_str) + ver = ver_str.split(".") + return tuple(map(int, ver)) ### utilities @@ -302,8 +415,16 @@ def launch_uvicorn(): setup_amd_environment() print("\nLaunching uvicorn\n") - os.system( - f'python -m uvicorn main:server_api --app-dir "{os.environ["SD_UI_PATH"]}" --port {listen_port} --host {bind_ip} --log-level error' + + import uvicorn + + uvicorn.run( + "main:server_api", + port=listen_port, + log_level="error", + app_dir=os.environ["SD_UI_PATH"], + host=bind_ip, + access_log=False, ) diff --git a/ui/easydiffusion/device_manager.py b/ui/easydiffusion/device_manager.py index dc705927..9b0f3f5e 100644 --- a/ui/easydiffusion/device_manager.py +++ b/ui/easydiffusion/device_manager.py @@ -243,7 +243,8 @@ def get_processor_name(): if platform.system() == "Windows": return platform.processor() elif platform.system() == "Darwin": - os.environ["PATH"] = os.environ["PATH"] + os.pathsep + "/usr/sbin" + if "/usr/sbin" not in os.environ["PATH"].split(os.pathsep): + os.environ["PATH"] = os.environ["PATH"] + os.pathsep + "/usr/sbin" command = "sysctl -n machdep.cpu.brand_string" return subprocess.check_output(command, shell=True).decode().strip() elif platform.system() == "Linux": diff --git a/ui/easydiffusion/utils/save_utils.py b/ui/easydiffusion/utils/save_utils.py index 4bf66261..95298d47 100644 --- a/ui/easydiffusion/utils/save_utils.py +++ b/ui/easydiffusion/utils/save_utils.py @@ -31,6 +31,7 @@ TASK_TEXT_MAPPING = { "clip_skip": "Clip Skip", "use_controlnet_model": "ControlNet model", "control_filter_to_apply": "ControlNet Filter", + "control_alpha": "ControlNet Strength", "use_vae_model": "VAE model", "sampler_name": "Sampler", "width": "Width", diff --git a/ui/index.html b/ui/index.html index 216a8ee5..e81b6a5c 100644 --- a/ui/index.html +++ b/ui/index.html @@ -36,7 +36,7 @@