Compare commits

...

48 Commits

Author SHA1 Message Date
5fe3acd44b Use 1.4 by default, instead of 1.5 2024-09-09 18:34:32 +05:30
716f30fecb Merge pull request #1810 from easydiffusion/beta
Beta
2024-06-14 09:49:27 +05:30
364902f8a1 Ignore text in the version string when comparing them 2024-06-14 09:48:49 +05:30
a261a2d47d Fix #1779 - add to PATH only if it isn't present, to avoid exploding the PATH variable each time the function is called 2024-06-14 09:43:30 +05:30
dea962dc89 Merge pull request #1808 from easydiffusion/beta
temp hotfix for rocm torch
2024-06-13 14:06:14 +05:30
d062c2149a temp hotfix for rocm torch 2024-06-13 14:05:11 +05:30
7d49dc105e Merge pull request #1806 from easydiffusion/beta
Don't crash if psutils fails to get cpu or memory usage
2024-06-11 18:28:07 +05:30
fcdc3f2dd0 Don't crash if psutils fails to get cpu or memory usage 2024-06-11 18:27:21 +05:30
d17b167a81 Merge pull request #1803 from easydiffusion/beta
Support legacy installations with torch 1.11, as well as an option for people to upgrade to the latest sdkit+diffusers
2024-06-07 10:33:56 +05:30
1fa83eda0e Merge pull request #1800 from siakc/uvicorn-run-programmatically
Enhancement - using uvicorn.run() instead of os.system()
2024-06-06 17:51:06 +05:30
969751a195 Use uvicorn.run since it's clearer to read 2024-06-06 17:50:41 +05:30
1ae8675487 typo 2024-06-06 16:20:04 +05:30
05f0bfebba Upgrade torch if using the newer sdkit versions 2024-06-06 16:18:11 +05:30
91ad53cd94 Enhancement - using uvicorn.run() instead of os.system() 2024-06-06 10:28:01 +03:30
de680dfd09 Print diffusers' version 2024-06-05 18:53:45 +05:30
4edeb14e94 Allow a user to opt-in to the latest sdkit+diffusers version, while keeping existing 2.0.15.x users restricted to diffusers 0.21.4. This avoids a lengthy upgrade for existing users, while allowing users to opt-in to the latest version. More to come. 2024-06-05 18:46:22 +05:30
e64cf9c9eb Merge pull request #1796 from easydiffusion/beta
Another typo
2024-06-01 09:02:08 +05:30
66d0c4726e Another typo 2024-06-01 09:01:35 +05:30
c923b44f56 Merge pull request #1795 from easydiffusion/beta
typo
2024-05-31 19:30:50 +05:30
b9c343195b typo 2024-05-31 19:30:29 +05:30
4427e8d3dd Merge pull request #1794 from easydiffusion/beta
Generalize the hotfix for missing sdkit dependencies. This is still a…
2024-05-31 19:28:32 +05:30
87c8fe2758 Generalize the hotfix for missing sdkit dependencies. This is still a temporary hotfix, but will ensure that missing packages are installed, not assume that having picklescan means everything's good 2024-05-31 19:27:30 +05:30
70acde7809 Merge pull request #1792 from easydiffusion/beta
Hotfix - sdkit's dependencies aren't getting pulled for some reason
2024-05-31 10:57:43 +05:30
c4b938f132 Hotfix - sdkit's dependencies aren't getting pulled for some reason 2024-05-31 10:56:43 +05:30
d6fdb8d5a9 Merge pull request #1788 from easydiffusion/beta
Hotfix for older accelerate version in the Windows installer
2024-05-30 17:51:32 +05:30
54ac1f7169 Hotfix for older accelerate version in the Windows installer 2024-05-30 17:50:36 +05:30
deebfc6850 Merge pull request #1787 from easydiffusion/beta
Controlnet Strength and SDXL Controlnet support for img2img and inpainting
2024-05-30 13:22:12 +05:30
21644adbe1 sdkit 2.0.15.6 - typo that prevented 0 controlnet strength 2024-05-29 10:01:04 +05:30
fe3c648a24 sdkit 2.0.15.5 - minor null check 2024-05-28 19:46:59 +05:30
05f3523364 Set the controlnet alpha correctly from older exports; Fix a bug with null lora model in exports 2024-05-28 19:16:48 +05:30
4d9b023378 changelog 2024-05-28 18:48:23 +05:30
44789bf16b sdkit 2.0.15.4 - Controlnet strength slider 2024-05-28 18:45:08 +05:30
ad649a8050 sdkit 2.0.15.3 - disable watermarking on SDXL ControlNets to avoid visual artifacts 2024-05-28 09:00:57 +05:30
723304204e diffusers 0.21.4 2024-05-27 15:26:09 +05:30
ddf54d589e v3.0.8 - use sdkit 2.0.15.1, to enable SDXL Controlnets for img2img and inpainting, using diffusers 0.21.4 2024-05-27 15:18:14 +05:30
a5c9c44e53 Merge pull request #1784 from easydiffusion/beta
Another hotfix for setuptools version on Windows and Linux/mac
2024-05-27 10:58:06 +05:30
4d28c78fcc Another hotfix for setuptools version on Windows and Linux/mac 2024-05-27 10:57:20 +05:30
7dc01370ea Merge pull request #1783 from easydiffusion/beta
Pin setuptools to 0.59
2024-05-27 10:45:49 +05:30
21ff109632 Pin setuptools to 0.59 2024-05-27 10:45:19 +05:30
9b0a654d32 Merge pull request #1782 from easydiffusion/beta
Hotfix to pin setuptools to 0.69 - for #1781
2024-05-27 10:38:41 +05:30
fb749dbe24 Potential hotfix for #1781 - pin setuptools to a specific version, until clip is upgraded 2024-05-27 10:37:09 +05:30
17ef1e04f7 Roll back sdkit 2.0.18 (again) 2024-03-19 20:06:49 +05:30
a5b9eefcf9 v3.0.8 - update diffusers to v0.26.3 2024-03-19 19:17:10 +05:30
e5519cda37 sdkit 2.0.18 (diffusers 0.26.3) 2024-03-19 19:12:00 +05:30
d1bd9e2a16 Prev version 2024-03-13 19:53:14 +05:30
5924d01789 Temporarily revert to sdkit 2.0.15 2024-03-13 19:05:55 +05:30
47432fe54e diffusers 0.26.3 2024-03-13 19:01:09 +05:30
8660a79ccd v3.0.8 - update diffusers to v0.26.3 2024-03-13 18:44:17 +05:30
9 changed files with 219 additions and 38 deletions

View File

@ -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.

View File

@ -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
@ -110,11 +121,114 @@ 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)}!")
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)}")
if 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
@ -177,8 +291,10 @@ 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")
@ -193,15 +309,17 @@ 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:
@ -215,43 +333,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
@ -260,7 +378,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")
@ -268,9 +386,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']}")
@ -297,7 +415,18 @@ 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,
)
### Start
@ -1102,5 +1231,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,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":

View File

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

View File

@ -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",

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.7</span> <span id="updateBranchLabel"></span></small>
<small><span id="version">v3.0.9</span> <span id="updateBranchLabel"></span></small>
</h1>
</div>
<div id="server-status">
@ -235,6 +235,8 @@
<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>

View File

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

View File

@ -309,10 +309,21 @@ 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\\")) {
@ -529,6 +540,11 @@ 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 = {}
@ -587,6 +603,7 @@ 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,6 +51,10 @@ 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) =>
@ -99,6 +103,8 @@ 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")
@ -1395,6 +1401,7 @@ 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
}
@ -2015,6 +2022,27 @@ 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