Compare commits

..

1 Commits

Author SHA1 Message Date
94f9e74d67 Update check_modules.py 2024-03-13 19:22:33 +05:30
10 changed files with 41 additions and 220 deletions

1
.github/FUNDING.yml vendored
View File

@ -1,3 +1,4 @@
# These are supported funding model platforms
ko_fi: easydiffusion
patreon: easydiffusion

View File

@ -17,8 +17,7 @@
- **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.8 - 13 Mar 2024 - Update diffusers version to v0.26.3.
* 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.

View File

@ -15,16 +15,13 @@ 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"),
"setuptools": "69.5.1",
# "sdkit": "2.0.15.6", # checked later
# "diffusers": "0.21.4", # checked later
"sdkit": "2.0.18",
"stable-diffusion-sdkit": "2.1.5",
"rich": "12.6.0",
"uvicorn": "0.19.0",
@ -35,7 +32,7 @@ modules_to_check = {
"python-multipart": "0.0.6",
# "xformers": "0.0.16",
}
modules_to_log = ["torch", "torchvision", "sdkit", "stable-diffusion-sdkit", "diffusers"]
modules_to_log = ["torch", "torchvision", "sdkit", "stable-diffusion-sdkit"]
def version(module_name: str) -> str:
@ -94,14 +91,6 @@ 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
@ -121,114 +110,11 @@ def update_modules():
fail(module_name)
else:
if version(module_name) != latest_version:
print(
f"WARNING! Tried to install {module_name}=={latest_version}, but the version is still {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)}")
print(f"WARNING! Tried to install {module_name}=={latest_version}, but the version is still {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))
if module_name in modules_to_log:
print(f"{module_name}: {version(module_name)}")
### utilities
@ -291,10 +177,8 @@ Thanks!"""
)
exit(1)
### Launcher
def get_config():
config_directory = os.path.dirname(__file__) # this will be "scripts"
config_yaml = os.path.join(config_directory, "..", "config.yaml")
@ -309,17 +193,15 @@ def get_config():
if os.path.isfile(config_yaml):
from ruamel.yaml import YAML
yaml = YAML(typ="safe")
with open(config_yaml, "r") as configfile:
yaml = YAML(typ='safe')
with open(config_yaml, 'r') as configfile:
try:
config = yaml.load(configfile)
except Exception as e:
print(e, file=sys.stderr)
elif os.path.isfile(config_json):
import json
with open(config_json, "r") as configfile:
with open(config_json, 'r') as configfile:
try:
config = json.load(configfile)
except Exception as e:
@ -333,43 +215,43 @@ def get_config():
def setup_amd_environment():
if not os.access("/dev/kfd", os.W_OK):
print(
"#########################################################################\n"
+ "# EasyDiffusion has no write access to /dev/kfd. #\n"
+ "#########################################################################\n"
+ "\n"
+ "Without this, the ROCm driver will probably not be able to initialize the GPU and EasyDiffusion will use the CPU for rendering.\n"
+ "\n"
+ "Follow the instructions on this site to configure the access:\n"
+ "https://github.com/easydiffusion/easydiffusion/wiki/AMD-on-Linux#access-permissions\n"
+ "\n"
"#########################################################################\n"
+ "# EasyDiffusion has no write access to /dev/kfd. #\n"
+ "#########################################################################\n"
+ "\n"
+ "Without this, the ROCm driver will probably not be able to initialize the GPU and EasyDiffusion will use the CPU for rendering.\n"
+ "\n"
+ "Follow the instructions on this site to configure the access:\n"
+ "https://github.com/easydiffusion/easydiffusion/wiki/AMD-on-Linux#access-permissions\n"
+ "\n"
)
gpus = list(filter(lambda x: ("amdgpu" in x), open("/proc/bus/pci/devices", "r").readlines()))
gpus = [x.split("\t")[1].upper() for x in gpus]
gpus = [AMD_PCI_IDs[x] for x in gpus if x in AMD_PCI_IDs]
i = 0
supported_gpus = []
gpus = [ x.split("\t")[1].upper() for x in gpus ]
gpus = [ AMD_PCI_IDs[x] for x in gpus if x in AMD_PCI_IDs ]
i=0
supported_gpus=[]
for gpu in gpus:
print(f"Found AMD GPU {gpu}.")
if gpu.startswith("Navi 1"):
print("--- Applying Navi 1 settings")
os.environ["HSA_OVERRIDE_GFX_VERSION"] = "10.3.0"
os.environ["FORCE_FULL_PRECISION"] = "yes"
os.environ["HIP_VISIBLE_DEVICES"] = str(i)
os.environ["HSA_OVERRIDE_GFX_VERSION"]="10.3.0"
os.environ["FORCE_FULL_PRECISION"]="yes"
os.environ["HIP_VISIBLE_DEVICES"]=str(i)
supported_gpus.append("Navi 1")
elif gpu.startswith("Navi 2"):
elif gpu.startswith("Navi 2"):
print("--- Applying Navi 2 settings")
os.environ["HSA_OVERRIDE_GFX_VERSION"] = "10.3.0"
os.environ["HIP_VISIBLE_DEVICES"] = str(i)
os.environ["HSA_OVERRIDE_GFX_VERSION"]="10.3.0"
os.environ["HIP_VISIBLE_DEVICES"]=str(i)
supported_gpus.append("Navi 2")
elif gpu.startswith("Navi 3"):
print("--- Applying Navi 3 settings")
os.environ["HSA_OVERRIDE_GFX_VERSION"] = "11.0.0"
os.environ["HIP_VISIBLE_DEVICES"] = str(i)
os.environ["HSA_OVERRIDE_GFX_VERSION"]="11.0.0"
os.environ["HIP_VISIBLE_DEVICES"]=str(i)
supported_gpus.append("Navi 3")
else:
print("--- This GPU is probably not supported by ROCm\n")
i += 1
i+=1
return supported_gpus
@ -378,7 +260,7 @@ def launch_uvicorn():
pprint(config)
with open("scripts/install_status.txt", "a") as f:
with open("scripts/install_status.txt","a") as f:
f.write("sd_weights_downloaded\n")
f.write("sd_install_complete\n")
@ -386,9 +268,9 @@ def launch_uvicorn():
os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
if os_name == "Windows":
os.environ["PYTHONPATH"] = str(Path(os.environ["INSTALL_ENV_DIR"], "lib", "site-packages"))
os.environ["PYTHONPATH"] = str(Path( os.environ["INSTALL_ENV_DIR"], "lib", "site-packages"))
else:
os.environ["PYTHONPATH"] = str(Path(os.environ["INSTALL_ENV_DIR"], "lib", "python3.8", "site-packages"))
os.environ["PYTHONPATH"] = str(Path( os.environ["INSTALL_ENV_DIR"], "lib", "python3.8", "site-packages"))
os.environ["SD_UI_PATH"] = str(Path(Path.cwd(), "ui"))
print(f"PYTHONPATH={os.environ['PYTHONPATH']}")
@ -415,18 +297,7 @@ def launch_uvicorn():
setup_amd_environment()
print("\nLaunching uvicorn\n")
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,
)
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')
### Start
@ -1231,5 +1102,5 @@ AMD_PCI_IDs = {
update_modules()
if len(sys.argv) > 1 and sys.argv[1] == "--launch-uvicorn":
if len(sys.argv) > 1 and sys.argv[1]=="--launch-uvicorn":
launch_uvicorn()

View File

@ -243,8 +243,7 @@ def get_processor_name():
if platform.system() == "Windows":
return platform.processor()
elif platform.system() == "Darwin":
if "/usr/sbin" not in os.environ["PATH"].split(os.pathsep):
os.environ["PATH"] = os.environ["PATH"] + os.pathsep + "/usr/sbin"
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":

View File

@ -37,7 +37,7 @@ MODEL_EXTENSIONS = {
}
DEFAULT_MODELS = {
"stable-diffusion": [
{"file_name": "sd-v1-4.ckpt", "model_id": "1.4"},
{"file_name": "sd-v1-5.safetensors", "model_id": "1.5-pruned-emaonly-fp16"},
],
"gfpgan": [
{"file_name": "GFPGANv1.4.pth", "model_id": "1.4"},

View File

@ -31,7 +31,6 @@ 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",

View File

@ -35,7 +35,7 @@
<h1>
<img id="logo_img" src="/media/images/icon-512x512.png" >
Easy Diffusion
<small><span id="version">v3.0.9</span> <span id="updateBranchLabel"></span></small>
<small><span id="version">v3.0.8</span> <span id="updateBranchLabel"></span></small>
</h1>
</div>
<div id="server-status">
@ -235,8 +235,6 @@
<label for="controlnet_model"><small>Model:</small></label> <input id="controlnet_model" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
<br/>
<label><small>Will download the necessary models, the first time.</small></label>
<br/>
<label for="controlnet_alpha_slider"><small>Strength:</small></label> <input id="controlnet_alpha_slider" name="controlnet_alpha_slider" class="editor-slider" value="10" type="range" min="0" max="10"> <input id="controlnet_alpha" name="controlnet_alpha" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)" inputmode="decimal">
</div>
</td>
</tr>
@ -268,7 +266,7 @@
<option value="unipc_tu_2" class="k_diffusion-only">UniPC TU 2</option>
<option value="unipc_tq" class="k_diffusion-only">UniPC TQ</option>
</select>
<a href="https://github.com/easydiffusion/easydiffusion/wiki/Samplers" target="_blank"><i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip top-left">Click to learn more about samplers</span></i></a>
<a href="https://github.com/easydiffusion/easydiffusion/wiki/How-to-Use#samplers" target="_blank"><i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip top-left">Click to learn more about samplers</span></i></a>
</td></tr>
<tr class="pl-5"><td><label>Image Size: </label></td><td id="image-size-options">
<select id="width" name="width" value="512">

View File

@ -57,7 +57,6 @@ const SETTINGS_IDS_LIST = [
"embedding-card-size-selector",
"lora_model",
"enable_vae_tiling",
"controlnet_alpha",
]
const IGNORE_BY_DEFAULT = ["prompt"]

View File

@ -309,21 +309,10 @@ const TASK_MAPPING = {
readUI: () => controlImageFilterField.value,
parse: (val) => val,
},
control_alpha: {
name: "ControlNet Strength",
setUI: (control_alpha) => {
control_alpha = control_alpha || 1.0
controlAlphaField.value = control_alpha
updateControlAlphaSlider()
},
readUI: () => parseFloat(controlAlphaField.value),
parse: (val) => val === null ? 1.0 : parseFloat(val),
},
use_lora_model: {
name: "LoRA model",
setUI: (use_lora_model) => {
let modelPaths = []
use_lora_model = use_lora_model === null ? "" : use_lora_model
use_lora_model = Array.isArray(use_lora_model) ? use_lora_model : [use_lora_model]
use_lora_model.forEach((m) => {
if (m.includes("models\\lora\\")) {
@ -540,11 +529,6 @@ function restoreTaskToUI(task, fieldsToSkip) {
// listen for inpainter loading event, which happens AFTER the main image loads (which reloads the inpai
controlImagePreview.src = task.reqBody.control_image
}
if ("use_controlnet_model" in task.reqBody && task.reqBody.use_controlnet_model && !("control_alpha" in task.reqBody)) {
controlAlphaField.value = 1.0
updateControlAlphaSlider()
}
}
function readUI() {
const reqBody = {}
@ -603,7 +587,6 @@ const TASK_TEXT_MAPPING = {
lora_alpha: "LoRA Strength",
use_controlnet_model: "ControlNet model",
control_filter_to_apply: "ControlNet Filter",
control_alpha: "ControlNet Strength",
tiling: "Seamless Tiling",
}
function parseTaskFromText(str) {

View File

@ -51,10 +51,6 @@ const taskConfigSetup = {
preserve_init_image_color_profile: "Preserve Color Profile",
strict_mask_border: "Strict Mask Border",
use_controlnet_model: "ControlNet Model",
control_alpha: {
label: "ControlNet Strength",
visible: ({ reqBody }) => !!reqBody?.use_controlnet_model,
},
},
pluginTaskConfig: {},
getCSSKey: (key) =>
@ -103,8 +99,6 @@ let controlImagePreview = document.querySelector("#control_image_preview")
let controlImageClearBtn = document.querySelector(".control_image_clear")
let controlImageContainer = document.querySelector("#control_image_wrapper")
let controlImageFilterField = document.querySelector("#control_image_filter")
let controlAlphaSlider = document.querySelector("#controlnet_alpha_slider")
let controlAlphaField = document.querySelector("#controlnet_alpha")
let applyColorCorrectionField = document.querySelector("#apply_color_correction")
let strictMaskBorderField = document.querySelector("#strict_mask_border")
let colorCorrectionSetting = document.querySelector("#apply_color_correction_setting")
@ -1401,7 +1395,6 @@ function getCurrentUserRequest() {
if (controlnetModelField.value !== "" && IMAGE_REGEX.test(controlImagePreview.src)) {
newTask.reqBody.use_controlnet_model = controlnetModelField.value
newTask.reqBody.control_image = controlImagePreview.src
newTask.reqBody.control_alpha = parseFloat(controlAlphaField.value)
if (controlImageFilterField.value !== "") {
newTask.reqBody.control_filter_to_apply = controlImageFilterField.value
}
@ -2022,27 +2015,6 @@ function updateHypernetworkStrengthContainer() {
hypernetworkModelField.addEventListener("change", updateHypernetworkStrengthContainer)
updateHypernetworkStrengthContainer()
/********************* Controlnet Alpha **************************/
function updateControlAlpha() {
controlAlphaField.value = controlAlphaSlider.value / 10
controlAlphaField.dispatchEvent(new Event("change"))
}
function updateControlAlphaSlider() {
if (controlAlphaField.value < 0) {
controlAlphaField.value = 0
} else if (controlAlphaField.value > 10) {
controlAlphaField.value = 10
}
controlAlphaSlider.value = controlAlphaField.value * 10
controlAlphaSlider.dispatchEvent(new Event("change"))
}
controlAlphaSlider.addEventListener("input", updateControlAlpha)
controlAlphaField.addEventListener("input", updateControlAlphaSlider)
updateControlAlpha()
/********************* JPEG/WEBP Quality **********************/
function updateOutputQuality() {
outputQualityField.value = 0 | outputQualitySlider.value