forked from extern/easydiffusion
Merge remote-tracking branch 'origin/beta' into restart-needed
This commit is contained in:
commit
3461bb669d
@ -22,6 +22,7 @@
|
|||||||
Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed.
|
Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed.
|
||||||
|
|
||||||
### Detailed changelog
|
### Detailed changelog
|
||||||
|
* 2.5.44 - 15 Jul 2023 - (beta-only) Support for multiple LoRA files.
|
||||||
* 2.5.43 - 9 Jul 2023 - (beta-only) Support for loading Textual Inversion embeddings. You can find the option in the Image Settings panel. Thanks @JeLuf.
|
* 2.5.43 - 9 Jul 2023 - (beta-only) Support for loading Textual Inversion embeddings. You can find the option in the Image Settings panel. Thanks @JeLuf.
|
||||||
* 2.5.43 - 9 Jul 2023 - Improve the startup time of the UI.
|
* 2.5.43 - 9 Jul 2023 - Improve the startup time of the UI.
|
||||||
* 2.5.42 - 4 Jul 2023 - Keyboard shortcuts for the Image Editor. Thanks @JeLuf.
|
* 2.5.42 - 4 Jul 2023 - Keyboard shortcuts for the Image Editor. Thanks @JeLuf.
|
||||||
|
@ -41,6 +41,10 @@ call python --version
|
|||||||
|
|
||||||
echo PYTHONPATH=%PYTHONPATH%
|
echo PYTHONPATH=%PYTHONPATH%
|
||||||
|
|
||||||
|
if exist "%cd%\profile" (
|
||||||
|
set HF_HOME=%cd%\profile\.cache\huggingface
|
||||||
|
)
|
||||||
|
|
||||||
@rem done
|
@rem done
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ os_name = platform.system()
|
|||||||
modules_to_check = {
|
modules_to_check = {
|
||||||
"torch": ("1.11.0", "1.13.1", "2.0.0"),
|
"torch": ("1.11.0", "1.13.1", "2.0.0"),
|
||||||
"torchvision": ("0.12.0", "0.14.1", "0.15.1"),
|
"torchvision": ("0.12.0", "0.14.1", "0.15.1"),
|
||||||
"sdkit": "1.0.116",
|
"sdkit": "1.0.125",
|
||||||
"stable-diffusion-sdkit": "2.1.4",
|
"stable-diffusion-sdkit": "2.1.4",
|
||||||
"rich": "12.6.0",
|
"rich": "12.6.0",
|
||||||
"uvicorn": "0.19.0",
|
"uvicorn": "0.19.0",
|
||||||
|
@ -104,18 +104,21 @@ call python --version
|
|||||||
|
|
||||||
@FOR /F "tokens=* USEBACKQ" %%F IN (`python scripts\get_config.py --default=False net listen_to_network`) DO (
|
@FOR /F "tokens=* USEBACKQ" %%F IN (`python scripts\get_config.py --default=False net listen_to_network`) DO (
|
||||||
if "%%F" EQU "True" (
|
if "%%F" EQU "True" (
|
||||||
@SET ED_BIND_IP=0.0.0.0
|
@FOR /F "tokens=* USEBACKQ" %%G IN (`python scripts\get_config.py --default=0.0.0.0 net bind_ip`) DO (
|
||||||
|
@SET ED_BIND_IP=%%G
|
||||||
|
)
|
||||||
) else (
|
) else (
|
||||||
@SET ED_BIND_IP=127.0.0.1
|
@SET ED_BIND_IP=127.0.0.1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@cd stable-diffusion
|
@cd stable-diffusion
|
||||||
|
|
||||||
@rem set any overrides
|
@rem set any overrides
|
||||||
set HF_HUB_DISABLE_SYMLINKS_WARNING=true
|
set HF_HUB_DISABLE_SYMLINKS_WARNING=true
|
||||||
|
|
||||||
@uvicorn main:server_api --app-dir "%SD_UI_PATH%" --port %ED_BIND_PORT% --host %ED_BIND_IP% --log-level error
|
@python -m uvicorn main:server_api --app-dir "%SD_UI_PATH%" --port %ED_BIND_PORT% --host %ED_BIND_IP% --log-level error
|
||||||
|
|
||||||
|
|
||||||
@pause
|
@pause
|
||||||
|
@ -72,7 +72,7 @@ export SD_UI_PATH=`pwd`/ui
|
|||||||
export ED_BIND_PORT="$( python scripts/get_config.py --default=9000 net listen_port )"
|
export ED_BIND_PORT="$( python scripts/get_config.py --default=9000 net listen_port )"
|
||||||
case "$( python scripts/get_config.py --default=False net listen_to_network )" in
|
case "$( python scripts/get_config.py --default=False net listen_to_network )" in
|
||||||
"True")
|
"True")
|
||||||
export ED_BIND_IP=0.0.0.0
|
export ED_BIND_IP=$( python scripts/get_config.py --default=0.0.0.0 net bind_ip)
|
||||||
;;
|
;;
|
||||||
"False")
|
"False")
|
||||||
export ED_BIND_IP=127.0.0.1
|
export ED_BIND_IP=127.0.0.1
|
||||||
|
@ -2,6 +2,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
from glob import glob
|
from glob import glob
|
||||||
import traceback
|
import traceback
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from easydiffusion import app
|
from easydiffusion import app
|
||||||
from easydiffusion.types import TaskData
|
from easydiffusion.types import TaskData
|
||||||
@ -93,7 +94,14 @@ def unload_all(context: Context):
|
|||||||
del context.model_load_errors[model_type]
|
del context.model_load_errors[model_type]
|
||||||
|
|
||||||
|
|
||||||
def resolve_model_to_use(model_name: str = None, model_type: str = None, fail_if_not_found: bool = True):
|
def resolve_model_to_use(model_name: Union[str, list] = None, model_type: str = None, fail_if_not_found: bool = True):
|
||||||
|
model_names = model_name if isinstance(model_name, list) else [model_name]
|
||||||
|
model_paths = [resolve_model_to_use_single(m, model_type, fail_if_not_found) for m in model_names]
|
||||||
|
|
||||||
|
return model_paths[0] if len(model_paths) == 1 else model_paths
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_model_to_use_single(model_name: str = None, model_type: str = None, fail_if_not_found: bool = True):
|
||||||
model_extensions = MODEL_EXTENSIONS.get(model_type, [])
|
model_extensions = MODEL_EXTENSIONS.get(model_type, [])
|
||||||
default_models = DEFAULT_MODELS.get(model_type, [])
|
default_models = DEFAULT_MODELS.get(model_type, [])
|
||||||
config = app.getConfig()
|
config = app.getConfig()
|
||||||
|
@ -473,15 +473,15 @@ def start_render_thread(device):
|
|||||||
render_threads.append(rthread)
|
render_threads.append(rthread)
|
||||||
finally:
|
finally:
|
||||||
manager_lock.release()
|
manager_lock.release()
|
||||||
# timeout = DEVICE_START_TIMEOUT
|
timeout = DEVICE_START_TIMEOUT
|
||||||
# while not rthread.is_alive() or not rthread in weak_thread_data or not "device" in weak_thread_data[rthread]:
|
while not rthread.is_alive() or not rthread in weak_thread_data or not "device" in weak_thread_data[rthread]:
|
||||||
# if rthread in weak_thread_data and "error" in weak_thread_data[rthread]:
|
if rthread in weak_thread_data and "error" in weak_thread_data[rthread]:
|
||||||
# log.error(f"{rthread}, {device}, error: {weak_thread_data[rthread]['error']}")
|
log.error(f"{rthread}, {device}, error: {weak_thread_data[rthread]['error']}")
|
||||||
# return False
|
return False
|
||||||
# if timeout <= 0:
|
if timeout <= 0:
|
||||||
# return False
|
return False
|
||||||
# timeout -= 1
|
timeout -= 1
|
||||||
# time.sleep(1)
|
time.sleep(1)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -535,12 +535,12 @@ def update_render_threads(render_devices, active_devices):
|
|||||||
if not start_render_thread(device):
|
if not start_render_thread(device):
|
||||||
log.warn(f"{device} failed to start.")
|
log.warn(f"{device} failed to start.")
|
||||||
|
|
||||||
# if is_alive() <= 0: # No running devices, probably invalid user config.
|
if is_alive() <= 0: # No running devices, probably invalid user config.
|
||||||
# raise EnvironmentError(
|
raise EnvironmentError(
|
||||||
# 'ERROR: No active render devices! Please verify the "render_devices" value in config.json'
|
'ERROR: No active render devices! Please verify the "render_devices" value in config.json'
|
||||||
# )
|
)
|
||||||
|
|
||||||
# log.debug(f"active devices: {get_devices()['active']}")
|
log.debug(f"active devices: {get_devices()['active']}")
|
||||||
|
|
||||||
|
|
||||||
def shutdown_event(): # Signal render thread to close on shutdown
|
def shutdown_event(): # Signal render thread to close on shutdown
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import Any
|
from typing import Any, List, Union
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ class GenerateImageRequest(BaseModel):
|
|||||||
|
|
||||||
sampler_name: str = None # "ddim", "plms", "heun", "euler", "euler_a", "dpm2", "dpm2_a", "lms"
|
sampler_name: str = None # "ddim", "plms", "heun", "euler", "euler_a", "dpm2", "dpm2_a", "lms"
|
||||||
hypernetwork_strength: float = 0
|
hypernetwork_strength: float = 0
|
||||||
lora_alpha: float = 0
|
lora_alpha: Union[float, List[float]] = 0
|
||||||
tiling: str = "none" # "none", "x", "y", "xy"
|
tiling: str = "none" # "none", "x", "y", "xy"
|
||||||
|
|
||||||
|
|
||||||
@ -32,15 +32,14 @@ class TaskData(BaseModel):
|
|||||||
save_to_disk_path: str = None
|
save_to_disk_path: str = None
|
||||||
vram_usage_level: str = "balanced" # or "low" or "medium"
|
vram_usage_level: str = "balanced" # or "low" or "medium"
|
||||||
|
|
||||||
use_face_correction: str = None # or "GFPGANv1.3"
|
use_face_correction: Union[str, List[str]] = None # or "GFPGANv1.3"
|
||||||
use_upscale: str = None # or "RealESRGAN_x4plus" or "RealESRGAN_x4plus_anime_6B" or "latent_upscaler"
|
use_upscale: Union[str, List[str]] = None
|
||||||
upscale_amount: int = 4 # or 2
|
upscale_amount: int = 4 # or 2
|
||||||
latent_upscaler_steps: int = 10
|
latent_upscaler_steps: int = 10
|
||||||
use_stable_diffusion_model: str = "sd-v1-4"
|
use_stable_diffusion_model: Union[str, List[str]] = "sd-v1-4"
|
||||||
# use_stable_diffusion_config: str = "v1-inference"
|
use_vae_model: Union[str, List[str]] = None
|
||||||
use_vae_model: str = None
|
use_hypernetwork_model: Union[str, List[str]] = None
|
||||||
use_hypernetwork_model: str = None
|
use_lora_model: Union[str, List[str]] = None
|
||||||
use_lora_model: str = None
|
|
||||||
|
|
||||||
show_only_filtered_image: bool = False
|
show_only_filtered_image: bool = False
|
||||||
block_nsfw: bool = False
|
block_nsfw: bool = False
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
import regex
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
@ -30,11 +32,12 @@ TASK_TEXT_MAPPING = {
|
|||||||
"lora_alpha": "LoRA Strength",
|
"lora_alpha": "LoRA Strength",
|
||||||
"use_hypernetwork_model": "Hypernetwork model",
|
"use_hypernetwork_model": "Hypernetwork model",
|
||||||
"hypernetwork_strength": "Hypernetwork Strength",
|
"hypernetwork_strength": "Hypernetwork Strength",
|
||||||
|
"use_embedding_models": "Embedding models",
|
||||||
"tiling": "Seamless Tiling",
|
"tiling": "Seamless Tiling",
|
||||||
"use_face_correction": "Use Face Correction",
|
"use_face_correction": "Use Face Correction",
|
||||||
"use_upscale": "Use Upscaling",
|
"use_upscale": "Use Upscaling",
|
||||||
"upscale_amount": "Upscale By",
|
"upscale_amount": "Upscale By",
|
||||||
"latent_upscaler_steps": "Latent Upscaler Steps"
|
"latent_upscaler_steps": "Latent Upscaler Steps",
|
||||||
}
|
}
|
||||||
|
|
||||||
time_placeholders = {
|
time_placeholders = {
|
||||||
@ -202,6 +205,9 @@ def get_printable_request(req: GenerateImageRequest, task_data: TaskData):
|
|||||||
req_metadata = req.dict()
|
req_metadata = req.dict()
|
||||||
task_data_metadata = task_data.dict()
|
task_data_metadata = task_data.dict()
|
||||||
|
|
||||||
|
app_config = app.getConfig()
|
||||||
|
using_diffusers = app_config.get("test_diffusers", False)
|
||||||
|
|
||||||
# Save the metadata in the order defined in TASK_TEXT_MAPPING
|
# Save the metadata in the order defined in TASK_TEXT_MAPPING
|
||||||
metadata = {}
|
metadata = {}
|
||||||
for key in TASK_TEXT_MAPPING.keys():
|
for key in TASK_TEXT_MAPPING.keys():
|
||||||
@ -209,6 +215,24 @@ def get_printable_request(req: GenerateImageRequest, task_data: TaskData):
|
|||||||
metadata[key] = req_metadata[key]
|
metadata[key] = req_metadata[key]
|
||||||
elif key in task_data_metadata:
|
elif key in task_data_metadata:
|
||||||
metadata[key] = task_data_metadata[key]
|
metadata[key] = task_data_metadata[key]
|
||||||
|
elif key is "use_embedding_models" and using_diffusers:
|
||||||
|
embeddings_extensions = {".pt", ".bin", ".safetensors"}
|
||||||
|
def scan_directory(directory_path: str):
|
||||||
|
used_embeddings = []
|
||||||
|
for entry in os.scandir(directory_path):
|
||||||
|
if entry.is_file():
|
||||||
|
entry_extension = os.path.splitext(entry.name)[1]
|
||||||
|
if entry_extension not in embeddings_extensions:
|
||||||
|
continue
|
||||||
|
|
||||||
|
embedding_name_regex = regex.compile(r"(^|[\s,])" + regex.escape(os.path.splitext(entry.name)[0]) + r"([+-]*$|[\s,]|[+-]+[\s,])")
|
||||||
|
if embedding_name_regex.search(req.prompt) or embedding_name_regex.search(req.negative_prompt):
|
||||||
|
used_embeddings.append(entry.path)
|
||||||
|
elif entry.is_dir():
|
||||||
|
used_embeddings.extend(scan_directory(entry.path))
|
||||||
|
return used_embeddings
|
||||||
|
used_embeddings = scan_directory(os.path.join(app.MODELS_DIR, "embeddings"))
|
||||||
|
metadata["use_embedding_models"] = ", ".join(used_embeddings) if len(used_embeddings) > 0 else None
|
||||||
|
|
||||||
# Clean up the metadata
|
# Clean up the metadata
|
||||||
if req.init_image is None and "prompt_strength" in metadata:
|
if req.init_image is None and "prompt_strength" in metadata:
|
||||||
@ -222,8 +246,7 @@ def get_printable_request(req: GenerateImageRequest, task_data: TaskData):
|
|||||||
if task_data.use_upscale != "latent_upscaler" and "latent_upscaler_steps" in metadata:
|
if task_data.use_upscale != "latent_upscaler" and "latent_upscaler_steps" in metadata:
|
||||||
del metadata["latent_upscaler_steps"]
|
del metadata["latent_upscaler_steps"]
|
||||||
|
|
||||||
app_config = app.getConfig()
|
if not using_diffusers:
|
||||||
if not app_config.get("test_diffusers", False):
|
|
||||||
for key in (x for x in ["use_lora_model", "lora_alpha", "clip_skip", "tiling", "latent_upscaler_steps"] if x in metadata):
|
for key in (x for x in ["use_lora_model", "lora_alpha", "clip_skip", "tiling", "latent_upscaler_steps"] if x in metadata):
|
||||||
del metadata[key]
|
del metadata[key]
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<h1>
|
<h1>
|
||||||
<img id="logo_img" src="/media/images/icon-512x512.png" >
|
<img id="logo_img" src="/media/images/icon-512x512.png" >
|
||||||
Easy Diffusion
|
Easy Diffusion
|
||||||
<small><span id="version">v2.5.43</span> <span id="updateBranchLabel"></span></small>
|
<small><span id="version">v2.5.44</span> <span id="updateBranchLabel"></span></small>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="server-status">
|
<div id="server-status">
|
||||||
@ -162,9 +162,10 @@
|
|||||||
<option value="dpm2_a">DPM2 Ancestral</option>
|
<option value="dpm2_a">DPM2 Ancestral</option>
|
||||||
<option value="lms">LMS</option>
|
<option value="lms">LMS</option>
|
||||||
<option value="dpm_solver_stability">DPM Solver (Stability AI)</option>
|
<option value="dpm_solver_stability">DPM Solver (Stability AI)</option>
|
||||||
<option value="dpmpp_2s_a" class="k_diffusion-only">DPM++ 2s Ancestral (Karras)</option>
|
<option value="dpmpp_2s_a">DPM++ 2s Ancestral (Karras)</option>
|
||||||
<option value="dpmpp_2m">DPM++ 2m (Karras)</option>
|
<option value="dpmpp_2m">DPM++ 2m (Karras)</option>
|
||||||
<option value="dpmpp_sde" class="k_diffusion-only">DPM++ SDE (Karras)</option>
|
<option value="dpmpp_2m_sde" class="diffusers-only">DPM++ 2m SDE (Karras)</option>
|
||||||
|
<option value="dpmpp_sde">DPM++ SDE (Karras)</option>
|
||||||
<option value="dpm_fast" class="k_diffusion-only">DPM Fast (Karras)</option>
|
<option value="dpm_fast" class="k_diffusion-only">DPM Fast (Karras)</option>
|
||||||
<option value="dpm_adaptive" class="k_diffusion-only">DPM Adaptive (Karras)</option>
|
<option value="dpm_adaptive" class="k_diffusion-only">DPM Adaptive (Karras)</option>
|
||||||
<option value="ddpm" class="diffusers-only">DDPM</option>
|
<option value="ddpm" class="diffusers-only">DDPM</option>
|
||||||
@ -224,21 +225,14 @@
|
|||||||
<label for="height"><small>(height)</small></label>
|
<label for="height"><small>(height)</small></label>
|
||||||
<div id="small_image_warning" class="displayNone">Small image sizes can cause bad image quality</div>
|
<div id="small_image_warning" class="displayNone">Small image sizes can cause bad image quality</div>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr class="pl-5"><td><label for="num_inference_steps">Inference Steps:</label></td><td> <input id="num_inference_steps" name="num_inference_steps" size="4" value="25" onkeypress="preventNonNumericalInput(event)"></td></tr>
|
<tr class="pl-5"><td><label for="num_inference_steps">Inference Steps:</label></td><td> <input id="num_inference_steps" name="num_inference_steps" type="number" min="1" step="1" style="width: 42pt" value="25" onkeypress="preventNonNumericalInput(event)"></td></tr>
|
||||||
<tr class="pl-5"><td><label for="guidance_scale_slider">Guidance Scale:</label></td><td> <input id="guidance_scale_slider" name="guidance_scale_slider" class="editor-slider" value="75" type="range" min="11" max="500"> <input id="guidance_scale" name="guidance_scale" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"></td></tr>
|
<tr class="pl-5"><td><label for="guidance_scale_slider">Guidance Scale:</label></td><td> <input id="guidance_scale_slider" name="guidance_scale_slider" class="editor-slider" value="75" type="range" min="11" max="500"> <input id="guidance_scale" name="guidance_scale" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"></td></tr>
|
||||||
<tr id="prompt_strength_container" class="pl-5"><td><label for="prompt_strength_slider">Prompt Strength:</label></td><td> <input id="prompt_strength_slider" name="prompt_strength_slider" class="editor-slider" value="80" type="range" min="0" max="99"> <input id="prompt_strength" name="prompt_strength" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"><br/></td></tr>
|
<tr id="prompt_strength_container" class="pl-5"><td><label for="prompt_strength_slider">Prompt Strength:</label></td><td> <input id="prompt_strength_slider" name="prompt_strength_slider" class="editor-slider" value="80" type="range" min="0" max="99"> <input id="prompt_strength" name="prompt_strength" size="4" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)"><br/></td></tr>
|
||||||
<tr id="lora_model_container" class="pl-5">
|
<tr id="lora_model_container" class="pl-5">
|
||||||
<td><label for="lora_model">LoRA:</label></td>
|
<td>
|
||||||
<td class="diffusers-restart-needed">
|
<label for="lora_model">LoRA:</label>
|
||||||
<input id="lora_model" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr id="lora_alpha_container" class="pl-5">
|
|
||||||
<td><label for="lora_alpha_slider">LoRA Strength:</label></td>
|
|
||||||
<td class="diffusers-restart-needed">
|
|
||||||
<small>-2</small> <input id="lora_alpha_slider" name="lora_alpha_slider" class="editor-slider" value="50" type="range" min="-200" max="200"> <small>2</small>
|
|
||||||
<input id="lora_alpha" name="lora_alpha" size="4" pattern="^-?[0-9]*\.?[0-9]*$" onkeypress="preventNonNumericalInput(event)"><br/>
|
|
||||||
</td>
|
</td>
|
||||||
|
<td class="model_entries diffusers-restart-needed"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="pl-5"><td><label for="hypernetwork_model">Hypernetwork:</label></td><td>
|
<tr class="pl-5"><td><label for="hypernetwork_model">Hypernetwork:</label></td><td>
|
||||||
<input id="hypernetwork_model" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
|
<input id="hypernetwork_model" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
from easydiffusion import model_manager, app, server
|
from easydiffusion import model_manager, app, server
|
||||||
from easydiffusion.server import server_api # required for uvicorn
|
from easydiffusion.server import server_api # required for uvicorn
|
||||||
|
|
||||||
|
server.init()
|
||||||
|
|
||||||
# Init the app
|
# Init the app
|
||||||
model_manager.init()
|
model_manager.init()
|
||||||
app.init()
|
app.init()
|
||||||
server.init()
|
app.init_render_threads()
|
||||||
|
|
||||||
# start the browser ui
|
# start the browser ui
|
||||||
app.open_browser()
|
app.open_browser()
|
||||||
|
|
||||||
app.init_render_threads()
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
html {
|
html {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overscroll-behavior-y: none;
|
||||||
|
color-scheme: dark !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@ -1677,6 +1679,10 @@ body.wait-pause {
|
|||||||
background: var(--background-color3);
|
background: var(--background-color3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.model_entry .model_name {
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
.diffusers-disabled-on-startup .diffusers-restart-needed {
|
.diffusers-disabled-on-startup .diffusers-restart-needed {
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,9 @@ const SETTINGS_IDS_LIST = [
|
|||||||
"clip_skip",
|
"clip_skip",
|
||||||
"vae_model",
|
"vae_model",
|
||||||
"hypernetwork_model",
|
"hypernetwork_model",
|
||||||
"lora_model",
|
"lora_model_0",
|
||||||
|
"lora_model_1",
|
||||||
|
"lora_model_2",
|
||||||
"sampler_name",
|
"sampler_name",
|
||||||
"width",
|
"width",
|
||||||
"height",
|
"height",
|
||||||
@ -24,7 +26,9 @@ const SETTINGS_IDS_LIST = [
|
|||||||
"guidance_scale",
|
"guidance_scale",
|
||||||
"prompt_strength",
|
"prompt_strength",
|
||||||
"hypernetwork_strength",
|
"hypernetwork_strength",
|
||||||
"lora_alpha",
|
"lora_alpha_0",
|
||||||
|
"lora_alpha_1",
|
||||||
|
"lora_alpha_2",
|
||||||
"tiling",
|
"tiling",
|
||||||
"output_format",
|
"output_format",
|
||||||
"output_quality",
|
"output_quality",
|
||||||
@ -176,13 +180,14 @@ function loadSettings() {
|
|||||||
// So this is likely the first time Easy Diffusion is running.
|
// So this is likely the first time Easy Diffusion is running.
|
||||||
// Initialize vram_usage_level based on the available VRAM
|
// Initialize vram_usage_level based on the available VRAM
|
||||||
function initGPUProfile(event) {
|
function initGPUProfile(event) {
|
||||||
if ( "detail" in event
|
if (
|
||||||
&& "active" in event.detail
|
"detail" in event &&
|
||||||
&& "cuda:0" in event.detail.active
|
"active" in event.detail &&
|
||||||
&& event.detail.active["cuda:0"].mem_total <4.5 )
|
"cuda:0" in event.detail.active &&
|
||||||
{
|
event.detail.active["cuda:0"].mem_total < 4.5
|
||||||
vramUsageLevelField.value = "low"
|
) {
|
||||||
vramUsageLevelField.dispatchEvent(new Event("change"))
|
vramUsageLevelField.value = "low"
|
||||||
|
vramUsageLevelField.dispatchEvent(new Event("change"))
|
||||||
}
|
}
|
||||||
document.removeEventListener("system_info_update", initGPUProfile)
|
document.removeEventListener("system_info_update", initGPUProfile)
|
||||||
}
|
}
|
||||||
|
@ -292,29 +292,58 @@ const TASK_MAPPING = {
|
|||||||
use_lora_model: {
|
use_lora_model: {
|
||||||
name: "LoRA model",
|
name: "LoRA model",
|
||||||
setUI: (use_lora_model) => {
|
setUI: (use_lora_model) => {
|
||||||
const oldVal = loraModelField.value
|
use_lora_model.forEach((model_name, i) => {
|
||||||
use_lora_model =
|
let field = loraModels[i][0]
|
||||||
use_lora_model === undefined || use_lora_model === null || use_lora_model === "None"
|
const oldVal = field.value
|
||||||
? ""
|
|
||||||
: use_lora_model
|
|
||||||
|
|
||||||
if (use_lora_model !== "") {
|
if (model_name !== "") {
|
||||||
use_lora_model = getModelPath(use_lora_model, [".ckpt", ".safetensors"])
|
model_name = getModelPath(model_name, [".ckpt", ".safetensors"])
|
||||||
use_lora_model = use_lora_model !== "" ? use_lora_model : oldVal
|
model_name = model_name !== "" ? model_name : oldVal
|
||||||
|
}
|
||||||
|
field.value = model_name
|
||||||
|
})
|
||||||
|
|
||||||
|
// clear the remaining entries
|
||||||
|
for (let i = use_lora_model.length; i < loraModels.length; i++) {
|
||||||
|
loraModels[i][0].value = ""
|
||||||
}
|
}
|
||||||
loraModelField.value = use_lora_model
|
|
||||||
},
|
},
|
||||||
readUI: () => loraModelField.value,
|
readUI: () => {
|
||||||
parse: (val) => val,
|
let values = loraModels.map((e) => e[0].value)
|
||||||
|
values = values.filter((e) => e.trim() !== "")
|
||||||
|
values = values.length > 0 ? values : "None"
|
||||||
|
return values
|
||||||
|
},
|
||||||
|
parse: (val) => {
|
||||||
|
val = !val || val === "None" ? "" : val
|
||||||
|
val = Array.isArray(val) ? val : [val]
|
||||||
|
return val
|
||||||
|
},
|
||||||
},
|
},
|
||||||
lora_alpha: {
|
lora_alpha: {
|
||||||
name: "LoRA Strength",
|
name: "LoRA Strength",
|
||||||
setUI: (lora_alpha) => {
|
setUI: (lora_alpha) => {
|
||||||
loraAlphaField.value = lora_alpha
|
lora_alpha.forEach((model_strength, i) => {
|
||||||
updateLoraAlphaSlider()
|
let field = loraModels[i][1]
|
||||||
|
field.value = model_strength
|
||||||
|
})
|
||||||
|
|
||||||
|
// clear the remaining entries
|
||||||
|
for (let i = lora_alpha.length; i < loraModels.length; i++) {
|
||||||
|
loraModels[i][1].value = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
readUI: () => {
|
||||||
|
let models = loraModels.filter((e) => e[0].value.trim() !== "")
|
||||||
|
let values = models.map((e) => e[1].value)
|
||||||
|
values = values.length > 0 ? values : 0
|
||||||
|
return values
|
||||||
|
},
|
||||||
|
parse: (val) => {
|
||||||
|
val = Array.isArray(val) ? val : [val]
|
||||||
|
val = val.map((e) => parseFloat(e))
|
||||||
|
return val
|
||||||
},
|
},
|
||||||
readUI: () => parseFloat(loraAlphaField.value),
|
|
||||||
parse: (val) => parseFloat(val),
|
|
||||||
},
|
},
|
||||||
use_hypernetwork_model: {
|
use_hypernetwork_model: {
|
||||||
name: "Hypernetwork model",
|
name: "Hypernetwork model",
|
||||||
@ -426,8 +455,11 @@ function restoreTaskToUI(task, fieldsToSkip) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!("use_lora_model" in task.reqBody)) {
|
if (!("use_lora_model" in task.reqBody)) {
|
||||||
loraModelField.value = ""
|
loraModels.forEach((e) => {
|
||||||
loraModelField.dispatchEvent(new Event("change"))
|
e[0].value = ""
|
||||||
|
e[1].value = 0
|
||||||
|
e[0].dispatchEvent(new Event("change"))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore the original prompt if provided (e.g. use settings), fallback to prompt as needed (e.g. copy/paste or d&d)
|
// restore the original prompt if provided (e.g. use settings), fallback to prompt as needed (e.g. copy/paste or d&d)
|
||||||
|
@ -103,9 +103,6 @@ let vaeModelField = new ModelDropdown(document.querySelector("#vae_model"), "vae
|
|||||||
let hypernetworkModelField = new ModelDropdown(document.querySelector("#hypernetwork_model"), "hypernetwork", "None")
|
let hypernetworkModelField = new ModelDropdown(document.querySelector("#hypernetwork_model"), "hypernetwork", "None")
|
||||||
let hypernetworkStrengthSlider = document.querySelector("#hypernetwork_strength_slider")
|
let hypernetworkStrengthSlider = document.querySelector("#hypernetwork_strength_slider")
|
||||||
let hypernetworkStrengthField = document.querySelector("#hypernetwork_strength")
|
let hypernetworkStrengthField = document.querySelector("#hypernetwork_strength")
|
||||||
let loraModelField = new ModelDropdown(document.querySelector("#lora_model"), "lora", "None")
|
|
||||||
let loraAlphaSlider = document.querySelector("#lora_alpha_slider")
|
|
||||||
let loraAlphaField = document.querySelector("#lora_alpha")
|
|
||||||
let outputFormatField = document.querySelector("#output_format")
|
let outputFormatField = document.querySelector("#output_format")
|
||||||
let outputLosslessField = document.querySelector("#output_lossless")
|
let outputLosslessField = document.querySelector("#output_lossless")
|
||||||
let outputLosslessContainer = document.querySelector("#output_lossless_container")
|
let outputLosslessContainer = document.querySelector("#output_lossless_container")
|
||||||
@ -159,6 +156,8 @@ let undoButton = document.querySelector("#undo")
|
|||||||
let undoBuffer = []
|
let undoBuffer = []
|
||||||
const UNDO_LIMIT = 20
|
const UNDO_LIMIT = 20
|
||||||
|
|
||||||
|
let loraModels = []
|
||||||
|
|
||||||
imagePreview.addEventListener("drop", function(ev) {
|
imagePreview.addEventListener("drop", function(ev) {
|
||||||
const data = ev.dataTransfer?.getData("text/plain")
|
const data = ev.dataTransfer?.getData("text/plain")
|
||||||
if (!data) {
|
if (!data) {
|
||||||
@ -1292,13 +1291,31 @@ function getCurrentUserRequest() {
|
|||||||
newTask.reqBody.use_hypernetwork_model = hypernetworkModelField.value
|
newTask.reqBody.use_hypernetwork_model = hypernetworkModelField.value
|
||||||
newTask.reqBody.hypernetwork_strength = parseFloat(hypernetworkStrengthField.value)
|
newTask.reqBody.hypernetwork_strength = parseFloat(hypernetworkStrengthField.value)
|
||||||
}
|
}
|
||||||
if (testDiffusers.checked && loraModelField.value) {
|
if (testDiffusers.checked) {
|
||||||
newTask.reqBody.use_lora_model = loraModelField.value
|
let [modelNames, modelStrengths] = getModelInfo(loraModels)
|
||||||
newTask.reqBody.lora_alpha = parseFloat(loraAlphaField.value)
|
|
||||||
|
if (modelNames.length > 0) {
|
||||||
|
modelNames = modelNames.length == 1 ? modelNames[0] : modelNames
|
||||||
|
modelStrengths = modelStrengths.length == 1 ? modelStrengths[0] : modelStrengths
|
||||||
|
|
||||||
|
newTask.reqBody.use_lora_model = modelNames
|
||||||
|
newTask.reqBody.lora_alpha = modelStrengths
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return newTask
|
return newTask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getModelInfo(models) {
|
||||||
|
let modelInfo = models.map((e) => [e[0].value, e[1].value])
|
||||||
|
modelInfo = modelInfo.filter((e) => e[0].trim() !== "")
|
||||||
|
modelInfo = modelInfo.map((e) => [e[0], parseFloat(e[1])])
|
||||||
|
|
||||||
|
let modelNames = modelInfo.map((e) => e[0])
|
||||||
|
let modelStrengths = modelInfo.map((e) => e[1])
|
||||||
|
|
||||||
|
return [modelNames, modelStrengths]
|
||||||
|
}
|
||||||
|
|
||||||
function getPrompts(prompts) {
|
function getPrompts(prompts) {
|
||||||
if (typeof prompts === "undefined") {
|
if (typeof prompts === "undefined") {
|
||||||
prompts = promptField.value
|
prompts = promptField.value
|
||||||
@ -1346,7 +1363,8 @@ function getPromptsNumber(prompts) {
|
|||||||
|
|
||||||
let promptsToMake = []
|
let promptsToMake = []
|
||||||
let numberOfPrompts = 0
|
let numberOfPrompts = 0
|
||||||
if (prompts.trim() !== "") { // this needs to stay sort of the same, as the prompts have to be passed through to the other functions
|
if (prompts.trim() !== "") {
|
||||||
|
// this needs to stay sort of the same, as the prompts have to be passed through to the other functions
|
||||||
prompts = prompts.split("\n")
|
prompts = prompts.split("\n")
|
||||||
prompts = prompts.map((prompt) => prompt.trim())
|
prompts = prompts.map((prompt) => prompt.trim())
|
||||||
prompts = prompts.filter((prompt) => prompt !== "")
|
prompts = prompts.filter((prompt) => prompt !== "")
|
||||||
@ -1354,7 +1372,11 @@ function getPromptsNumber(prompts) {
|
|||||||
// estimate number of prompts
|
// estimate number of prompts
|
||||||
let estimatedNumberOfPrompts = 0
|
let estimatedNumberOfPrompts = 0
|
||||||
prompts.forEach((prompt) => {
|
prompts.forEach((prompt) => {
|
||||||
estimatedNumberOfPrompts += (prompt.match(/{[^}]*}/g) || []).map((e) => (e.match(/,/g) || []).length + 1).reduce( (p,a) => p*a, 1) * (2**(prompt.match(/\|/g) || []).length)
|
estimatedNumberOfPrompts +=
|
||||||
|
(prompt.match(/{[^}]*}/g) || [])
|
||||||
|
.map((e) => (e.match(/,/g) || []).length + 1)
|
||||||
|
.reduce((p, a) => p * a, 1) *
|
||||||
|
2 ** (prompt.match(/\|/g) || []).length
|
||||||
})
|
})
|
||||||
|
|
||||||
if (estimatedNumberOfPrompts >= 10000) {
|
if (estimatedNumberOfPrompts >= 10000) {
|
||||||
@ -1394,7 +1416,8 @@ function applySetOperator(prompts) {
|
|||||||
return promptsToMake
|
return promptsToMake
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyPermuteOperator(prompts) { // prompts is array of input, trimmed, filtered and split by \n
|
function applyPermuteOperator(prompts) {
|
||||||
|
// prompts is array of input, trimmed, filtered and split by \n
|
||||||
let promptsToMake = []
|
let promptsToMake = []
|
||||||
prompts.forEach((prompt) => {
|
prompts.forEach((prompt) => {
|
||||||
let promptMatrix = prompt.split("|")
|
let promptMatrix = prompt.split("|")
|
||||||
@ -1414,13 +1437,14 @@ function applyPermuteOperator(prompts) { // prompts is array of input, trimmed,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns how many prompts would have to be made with the given prompts
|
// returns how many prompts would have to be made with the given prompts
|
||||||
function applyPermuteOperatorNumber(prompts) { // prompts is array of input, trimmed, filtered and split by \n
|
function applyPermuteOperatorNumber(prompts) {
|
||||||
|
// prompts is array of input, trimmed, filtered and split by \n
|
||||||
let numberOfPrompts = 0
|
let numberOfPrompts = 0
|
||||||
prompts.forEach((prompt) => {
|
prompts.forEach((prompt) => {
|
||||||
let promptCounter = 1
|
let promptCounter = 1
|
||||||
let promptMatrix = prompt.split("|")
|
let promptMatrix = prompt.split("|")
|
||||||
promptMatrix.shift()
|
promptMatrix.shift()
|
||||||
|
|
||||||
promptMatrix = promptMatrix.map((p) => p.trim())
|
promptMatrix = promptMatrix.map((p) => p.trim())
|
||||||
promptMatrix = promptMatrix.filter((p) => p !== "")
|
promptMatrix = promptMatrix.filter((p) => p !== "")
|
||||||
|
|
||||||
@ -1510,8 +1534,12 @@ clearAllPreviewsBtn.addEventListener("click", (e) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
/* Download images popup */
|
/* Download images popup */
|
||||||
showDownloadDialogBtn.addEventListener("click", (e) => { saveAllImagesDialog.showModal() })
|
showDownloadDialogBtn.addEventListener("click", (e) => {
|
||||||
saveAllImagesCloseBtn.addEventListener("click", (e) => { saveAllImagesDialog.close() })
|
saveAllImagesDialog.showModal()
|
||||||
|
})
|
||||||
|
saveAllImagesCloseBtn.addEventListener("click", (e) => {
|
||||||
|
saveAllImagesDialog.close()
|
||||||
|
})
|
||||||
modalDialogCloseOnBackdropClick(saveAllImagesDialog)
|
modalDialogCloseOnBackdropClick(saveAllImagesDialog)
|
||||||
makeDialogDraggable(saveAllImagesDialog)
|
makeDialogDraggable(saveAllImagesDialog)
|
||||||
|
|
||||||
@ -1629,15 +1657,11 @@ function renameMakeImageButton() {
|
|||||||
imageLabel = totalImages + " Images"
|
imageLabel = totalImages + " Images"
|
||||||
}
|
}
|
||||||
if (SD.activeTasks.size == 0) {
|
if (SD.activeTasks.size == 0) {
|
||||||
if (totalImages >= 10000)
|
if (totalImages >= 10000) makeImageBtn.innerText = "Make 10000+ images"
|
||||||
makeImageBtn.innerText = "Make 10000+ images"
|
else makeImageBtn.innerText = "Make " + imageLabel
|
||||||
else
|
|
||||||
makeImageBtn.innerText = "Make " + imageLabel
|
|
||||||
} else {
|
} else {
|
||||||
if (totalImages >= 10000)
|
if (totalImages >= 10000) makeImageBtn.innerText = "Enqueue 10000+ images"
|
||||||
makeImageBtn.innerText = "Enqueue 10000+ images"
|
else makeImageBtn.innerText = "Enqueue Next " + imageLabel
|
||||||
else
|
|
||||||
makeImageBtn.innerText = "Enqueue Next " + imageLabel
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
numOutputsTotalField.addEventListener("change", renameMakeImageButton)
|
numOutputsTotalField.addEventListener("change", renameMakeImageButton)
|
||||||
@ -1829,36 +1853,6 @@ function updateHypernetworkStrengthContainer() {
|
|||||||
hypernetworkModelField.addEventListener("change", updateHypernetworkStrengthContainer)
|
hypernetworkModelField.addEventListener("change", updateHypernetworkStrengthContainer)
|
||||||
updateHypernetworkStrengthContainer()
|
updateHypernetworkStrengthContainer()
|
||||||
|
|
||||||
/********************* LoRA alpha **********************/
|
|
||||||
function updateLoraAlpha() {
|
|
||||||
loraAlphaField.value = loraAlphaSlider.value / 100
|
|
||||||
loraAlphaField.dispatchEvent(new Event("change"))
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateLoraAlphaSlider() {
|
|
||||||
if (loraAlphaField.value < -2) {
|
|
||||||
loraAlphaField.value = -2
|
|
||||||
} else if (loraAlphaField.value > 2) {
|
|
||||||
loraAlphaField.value = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
loraAlphaSlider.value = loraAlphaField.value * 100
|
|
||||||
loraAlphaSlider.dispatchEvent(new Event("change"))
|
|
||||||
}
|
|
||||||
|
|
||||||
loraAlphaSlider.addEventListener("input", updateLoraAlpha)
|
|
||||||
loraAlphaField.addEventListener("input", updateLoraAlphaSlider)
|
|
||||||
updateLoraAlpha()
|
|
||||||
|
|
||||||
function updateLoraAlphaContainer() {
|
|
||||||
const loraModelContainer = document.querySelector("#lora_model_container")
|
|
||||||
if (loraModelContainer && window.getComputedStyle(loraModelContainer).display !== "none") {
|
|
||||||
document.querySelector("#lora_alpha_container").style.display = loraModelField.value === "" ? "none" : ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loraModelField.addEventListener("change", updateLoraAlphaContainer)
|
|
||||||
updateLoraAlphaContainer()
|
|
||||||
|
|
||||||
/********************* JPEG/WEBP Quality **********************/
|
/********************* JPEG/WEBP Quality **********************/
|
||||||
function updateOutputQuality() {
|
function updateOutputQuality() {
|
||||||
outputQualityField.value = 0 | outputQualitySlider.value
|
outputQualityField.value = 0 | outputQualitySlider.value
|
||||||
@ -2076,9 +2070,8 @@ function resumeClient() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function splashScreen(force = false) {
|
function splashScreen(force = false) {
|
||||||
const splashVersion = splashScreenPopup.dataset['version']
|
const splashVersion = splashScreenPopup.dataset["version"]
|
||||||
const lastSplash = localStorage.getItem("lastSplashScreenVersion") || 0
|
const lastSplash = localStorage.getItem("lastSplashScreenVersion") || 0
|
||||||
if (testDiffusers.checked) {
|
if (testDiffusers.checked) {
|
||||||
if (force || lastSplash < splashVersion) {
|
if (force || lastSplash < splashVersion) {
|
||||||
@ -2088,8 +2081,9 @@ function splashScreen(force = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById("logo_img").addEventListener("click", (e) => {
|
||||||
document.getElementById("logo_img").addEventListener("click", (e) => { splashScreen(true) })
|
splashScreen(true)
|
||||||
|
})
|
||||||
|
|
||||||
promptField.addEventListener("input", debounce(renameMakeImageButton, 1000))
|
promptField.addEventListener("input", debounce(renameMakeImageButton, 1000))
|
||||||
|
|
||||||
@ -2142,21 +2136,21 @@ document.getElementById("toggle-cloudflare-tunnel").addEventListener("click", as
|
|||||||
|
|
||||||
/* Embeddings */
|
/* Embeddings */
|
||||||
|
|
||||||
function updateEmbeddingsList(filter="") {
|
function updateEmbeddingsList(filter = "") {
|
||||||
function html(model, prefix="", filter="") {
|
function html(model, prefix = "", filter = "") {
|
||||||
filter = filter.toLowerCase()
|
filter = filter.toLowerCase()
|
||||||
let toplevel=""
|
let toplevel = ""
|
||||||
let folders=""
|
let folders = ""
|
||||||
|
|
||||||
model?.forEach( m => {
|
model?.forEach((m) => {
|
||||||
if (typeof(m) == "string") {
|
if (typeof m == "string") {
|
||||||
if (m.toLowerCase().search(filter)!=-1) {
|
if (m.toLowerCase().search(filter) != -1) {
|
||||||
toplevel += `<button data-embedding="${m}">${m}</button> `
|
toplevel += `<button data-embedding="${m}">${m}</button> `
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let subdir = html(m[1], prefix+m[0]+"/", filter)
|
let subdir = html(m[1], prefix + m[0] + "/", filter)
|
||||||
if (subdir != "") {
|
if (subdir != "") {
|
||||||
folders += `<h4>${prefix}${m[0]}</h4>` + subdir
|
folders += `<h4>${prefix}${m[0]}</h4>` + subdir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -2174,7 +2168,7 @@ function updateEmbeddingsList(filter="") {
|
|||||||
insertAtCursor(promptField, text)
|
insertAtCursor(promptField, text)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let pad=""
|
let pad = ""
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
if (!negativePromptField.value.endsWith(" ")) {
|
if (!negativePromptField.value.endsWith(" ")) {
|
||||||
pad = " "
|
pad = " "
|
||||||
@ -2189,14 +2183,26 @@ function updateEmbeddingsList(filter="") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
embeddingsList.innerHTML = html(modelsOptions.embeddings, "", filter)
|
// Remove after fixing https://github.com/huggingface/diffusers/issues/3922
|
||||||
embeddingsList.querySelectorAll("button").forEach( (b) => { b.addEventListener("click", onButtonClick)})
|
let warning = ""
|
||||||
|
if (vramUsageLevelField.value == "low") {
|
||||||
|
warning = `
|
||||||
|
<div style="border-color: var(--accent-color); border-width: 4px; border-radius: 1em; border-style: solid; background: black; text-align: center; padding: 1em; margin: 1em; ">
|
||||||
|
<i class="fa fa-fire" style="color:#f7630c;"></i> Warning: Your GPU memory profile is set to "Low". Embeddings currently only work in "Balanced" mode!
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
|
// END of remove block
|
||||||
|
|
||||||
|
embeddingsList.innerHTML = warning + html(modelsOptions.embeddings, "", filter)
|
||||||
|
embeddingsList.querySelectorAll("button").forEach((b) => {
|
||||||
|
b.addEventListener("click", onButtonClick)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
embeddingsButton.addEventListener("click", () => {
|
embeddingsButton.addEventListener("click", () => {
|
||||||
updateEmbeddingsList()
|
updateEmbeddingsList()
|
||||||
embeddingsSearchBox.value=""
|
embeddingsSearchBox.value = ""
|
||||||
embeddingsDialog.showModal()
|
embeddingsDialog.showModal()
|
||||||
})
|
})
|
||||||
embeddingsDialogCloseBtn.addEventListener("click", (e) => {
|
embeddingsDialogCloseBtn.addEventListener("click", (e) => {
|
||||||
embeddingsDialog.close()
|
embeddingsDialog.close()
|
||||||
@ -2208,7 +2214,6 @@ embeddingsSearchBox.addEventListener("input", (e) => {
|
|||||||
modalDialogCloseOnBackdropClick(embeddingsDialog)
|
modalDialogCloseOnBackdropClick(embeddingsDialog)
|
||||||
makeDialogDraggable(embeddingsDialog)
|
makeDialogDraggable(embeddingsDialog)
|
||||||
|
|
||||||
|
|
||||||
if (testDiffusers.checked) {
|
if (testDiffusers.checked) {
|
||||||
document.getElementById("embeddings-container").classList.remove("displayNone")
|
document.getElementById("embeddings-container").classList.remove("displayNone")
|
||||||
}
|
}
|
||||||
@ -2235,3 +2240,43 @@ prettifyInputs(document)
|
|||||||
// set the textbox as focused on start
|
// set the textbox as focused on start
|
||||||
promptField.focus()
|
promptField.focus()
|
||||||
promptField.selectionStart = promptField.value.length
|
promptField.selectionStart = promptField.value.length
|
||||||
|
|
||||||
|
// multi-models
|
||||||
|
function addModelEntry(i, modelContainer, modelsList, modelType, defaultValue, strengthStep) {
|
||||||
|
let nameId = modelType + "_model_" + i
|
||||||
|
let strengthId = modelType + "_alpha_" + i
|
||||||
|
|
||||||
|
const modelEntry = document.createElement("div")
|
||||||
|
modelEntry.className = "model_entry"
|
||||||
|
modelEntry.innerHTML = `
|
||||||
|
<input id="${nameId}" class="model_name" type="text" spellcheck="false" autocomplete="off" class="model-filter" data-path="" />
|
||||||
|
<input id="${strengthId}" class="model_strength" type="number" step="${strengthStep}" style="width: 50pt" value="${defaultValue}" pattern="^-?[0-9]*\.?[0-9]*$" onkeypress="preventNonNumericalInput(event)"><br/>
|
||||||
|
`
|
||||||
|
|
||||||
|
let modelName = new ModelDropdown(modelEntry.querySelector(".model_name"), modelType, "None")
|
||||||
|
let modelStrength = modelEntry.querySelector(".model_strength")
|
||||||
|
|
||||||
|
modelContainer.appendChild(modelEntry)
|
||||||
|
modelsList.push([modelName, modelStrength])
|
||||||
|
}
|
||||||
|
|
||||||
|
function createLoRAEntries() {
|
||||||
|
let container = document.querySelector("#lora_model_container .model_entries")
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
addModelEntry(i, container, loraModels, "lora", 0.5, 0.02)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createLoRAEntries()
|
||||||
|
|
||||||
|
// chrome-like spinners only on hover
|
||||||
|
function showSpinnerOnlyOnHover(e) {
|
||||||
|
e.addEventListener("mouseenter", () => {
|
||||||
|
e.setAttribute("type", "number")
|
||||||
|
})
|
||||||
|
e.addEventListener("mouseleave", () => {
|
||||||
|
e.removeAttribute("type")
|
||||||
|
})
|
||||||
|
e.removeAttribute("type")
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll("input[type=number]").forEach(showSpinnerOnlyOnHover)
|
||||||
|
@ -436,7 +436,6 @@ async function getAppConfig() {
|
|||||||
|
|
||||||
if (!testDiffusersEnabled) {
|
if (!testDiffusersEnabled) {
|
||||||
document.querySelector("#lora_model_container").style.display = "none"
|
document.querySelector("#lora_model_container").style.display = "none"
|
||||||
document.querySelector("#lora_alpha_container").style.display = "none"
|
|
||||||
document.querySelector("#tiling_container").style.display = "none"
|
document.querySelector("#tiling_container").style.display = "none"
|
||||||
|
|
||||||
document.querySelectorAll("#sampler_name option.diffusers-only").forEach((option) => {
|
document.querySelectorAll("#sampler_name option.diffusers-only").forEach((option) => {
|
||||||
@ -444,7 +443,6 @@ async function getAppConfig() {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
document.querySelector("#lora_model_container").style.display = ""
|
document.querySelector("#lora_model_container").style.display = ""
|
||||||
document.querySelector("#lora_alpha_container").style.display = loraModelField.value ? "" : "none"
|
|
||||||
document.querySelector("#tiling_container").style.display = ""
|
document.querySelector("#tiling_container").style.display = ""
|
||||||
|
|
||||||
document.querySelectorAll("#sampler_name option.k_diffusion-only").forEach((option) => {
|
document.querySelectorAll("#sampler_name option.k_diffusion-only").forEach((option) => {
|
||||||
|
@ -1074,6 +1074,12 @@ async function deleteKeys(keyToDelete) {
|
|||||||
|
|
||||||
function modalDialogCloseOnBackdropClick(dialog) {
|
function modalDialogCloseOnBackdropClick(dialog) {
|
||||||
dialog.addEventListener('mousedown', function (event) {
|
dialog.addEventListener('mousedown', function (event) {
|
||||||
|
// Firefox creates an event with clientX|Y = 0|0 when choosing an <option>.
|
||||||
|
// Test whether the element interacted with is a child of the dialog, but not the
|
||||||
|
// dialog itself (the backdrop would be a part of the dialog)
|
||||||
|
if (dialog.contains(event.target) && dialog != event.target) {
|
||||||
|
return
|
||||||
|
}
|
||||||
var rect = dialog.getBoundingClientRect()
|
var rect = dialog.getBoundingClientRect()
|
||||||
var isInDialog=(rect.top <= event.clientY && event.clientY <= rect.top + rect.height
|
var isInDialog=(rect.top <= event.clientY && event.clientY <= rect.top + rect.height
|
||||||
&& rect.left <= event.clientX && event.clientX <= rect.left + rect.width)
|
&& rect.left <= event.clientX && event.clientX <= rect.left + rect.width)
|
||||||
|
Loading…
Reference in New Issue
Block a user