mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2024-12-26 00:49:17 +01:00
commit
046e2acae1
@ -19,6 +19,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.23 - 8 Mar 2023 - Experimental support for mac.
|
||||||
* 2.5.22 - 28 Feb 2023 - Minor styling changes to UI buttons, and the models dropdown.
|
* 2.5.22 - 28 Feb 2023 - Minor styling changes to UI buttons, and the models dropdown.
|
||||||
* 2.5.22 - 28 Feb 2023 - Lots of UI-related bug fixes. Thanks @patriceac.
|
* 2.5.22 - 28 Feb 2023 - Lots of UI-related bug fixes. Thanks @patriceac.
|
||||||
* 2.5.21 - 22 Feb 2023 - An option to control the size of the image thumbnails. You can use the `Display options` in the top-right corner to change this. Thanks @JeLuf.
|
* 2.5.21 - 22 Feb 2023 - An option to control the size of the image thumbnails. You can use the `Display options` in the top-right corner to change this. Thanks @JeLuf.
|
||||||
|
@ -95,7 +95,7 @@ if "%ERRORLEVEL%" EQU "0" (
|
|||||||
set PYTHONNOUSERSITE=1
|
set PYTHONNOUSERSITE=1
|
||||||
set PYTHONPATH=%INSTALL_ENV_DIR%\lib\site-packages
|
set PYTHONPATH=%INSTALL_ENV_DIR%\lib\site-packages
|
||||||
|
|
||||||
call python -m pip install --upgrade sdkit==1.0.43 -q || (
|
call python -m pip install --upgrade sdkit==1.0.44 -q || (
|
||||||
echo "Error updating sdkit"
|
echo "Error updating sdkit"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -106,7 +106,7 @@ if "%ERRORLEVEL%" EQU "0" (
|
|||||||
set PYTHONNOUSERSITE=1
|
set PYTHONNOUSERSITE=1
|
||||||
set PYTHONPATH=%INSTALL_ENV_DIR%\lib\site-packages
|
set PYTHONPATH=%INSTALL_ENV_DIR%\lib\site-packages
|
||||||
|
|
||||||
call python -m pip install sdkit==1.0.43 || (
|
call python -m pip install sdkit==1.0.44 || (
|
||||||
echo "Error installing sdkit. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!"
|
echo "Error installing sdkit. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!"
|
||||||
pause
|
pause
|
||||||
exit /b
|
exit /b
|
||||||
|
@ -81,7 +81,7 @@ if python ../scripts/check_modules.py sdkit sdkit.models ldm transformers numpy
|
|||||||
export PYTHONNOUSERSITE=1
|
export PYTHONNOUSERSITE=1
|
||||||
export PYTHONPATH="$INSTALL_ENV_DIR/lib/python3.8/site-packages"
|
export PYTHONPATH="$INSTALL_ENV_DIR/lib/python3.8/site-packages"
|
||||||
|
|
||||||
python -m pip install --upgrade sdkit==1.0.43 -q
|
python -m pip install --upgrade sdkit==1.0.44 -q
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "Installing sdkit: https://pypi.org/project/sdkit/"
|
echo "Installing sdkit: https://pypi.org/project/sdkit/"
|
||||||
@ -89,7 +89,7 @@ else
|
|||||||
export PYTHONNOUSERSITE=1
|
export PYTHONNOUSERSITE=1
|
||||||
export PYTHONPATH="$INSTALL_ENV_DIR/lib/python3.8/site-packages"
|
export PYTHONPATH="$INSTALL_ENV_DIR/lib/python3.8/site-packages"
|
||||||
|
|
||||||
if python -m pip install sdkit==1.0.43 ; then
|
if python -m pip install sdkit==1.0.44 ; then
|
||||||
echo "Installed."
|
echo "Installed."
|
||||||
else
|
else
|
||||||
fail "sdkit install failed"
|
fail "sdkit install failed"
|
||||||
@ -285,6 +285,7 @@ printf "\n\nEasy Diffusion installation complete, starting the server!\n\n"
|
|||||||
|
|
||||||
SD_PATH=`pwd`
|
SD_PATH=`pwd`
|
||||||
|
|
||||||
|
export PYTORCH_ENABLE_MPS_FALLBACK=1
|
||||||
export PYTHONPATH="$INSTALL_ENV_DIR/lib/python3.8/site-packages"
|
export PYTHONPATH="$INSTALL_ENV_DIR/lib/python3.8/site-packages"
|
||||||
echo "PYTHONPATH=$PYTHONPATH"
|
echo "PYTHONPATH=$PYTHONPATH"
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import json
|
|||||||
import traceback
|
import traceback
|
||||||
import logging
|
import logging
|
||||||
import shlex
|
import shlex
|
||||||
|
import urllib
|
||||||
from rich.logging import RichHandler
|
from rich.logging import RichHandler
|
||||||
|
|
||||||
from sdkit.utils import log as sdkit_log # hack, so we can overwrite the log config
|
from sdkit.utils import log as sdkit_log # hack, so we can overwrite the log config
|
||||||
@ -54,6 +55,10 @@ APP_CONFIG_DEFAULTS = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMAGE_EXTENSIONS = [".png", ".apng", ".jpg", ".jpeg", ".jfif", ".pjpeg", ".pjp", ".jxl", ".gif", ".webp", ".avif", ".svg"]
|
||||||
|
CUSTOM_MODIFIERS_DIR = os.path.abspath(os.path.join(SD_DIR, "..", "modifiers"))
|
||||||
|
CUSTOM_MODIFIERS_PORTRAIT_EXTENSIONS=[".portrait", "_portrait", " portrait", "-portrait"]
|
||||||
|
CUSTOM_MODIFIERS_LANDSCAPE_EXTENSIONS=[".landscape", "_landscape", " landscape", "-landscape"]
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
os.makedirs(USER_UI_PLUGINS_DIR, exist_ok=True)
|
os.makedirs(USER_UI_PLUGINS_DIR, exist_ok=True)
|
||||||
@ -234,3 +239,90 @@ def open_browser():
|
|||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
||||||
webbrowser.open(f"http://localhost:{port}")
|
webbrowser.open(f"http://localhost:{port}")
|
||||||
|
|
||||||
|
def get_image_modifiers():
|
||||||
|
modifiers_json_path = os.path.join(SD_UI_DIR, "modifiers.json")
|
||||||
|
|
||||||
|
modifier_categories = {}
|
||||||
|
original_category_order=[]
|
||||||
|
with open(modifiers_json_path, "r", encoding="utf-8") as f:
|
||||||
|
modifiers_file = json.load(f)
|
||||||
|
|
||||||
|
# The trailing slash is needed to support symlinks
|
||||||
|
if not os.path.isdir(f"{CUSTOM_MODIFIERS_DIR}/"):
|
||||||
|
return modifiers_file
|
||||||
|
|
||||||
|
# convert modifiers from a list of objects to a dict of dicts
|
||||||
|
for category_item in modifiers_file:
|
||||||
|
category_name = category_item['category']
|
||||||
|
original_category_order.append(category_name)
|
||||||
|
category = {}
|
||||||
|
for modifier_item in category_item['modifiers']:
|
||||||
|
modifier = {}
|
||||||
|
for preview_item in modifier_item['previews']:
|
||||||
|
modifier[preview_item['name']] = preview_item['path']
|
||||||
|
category[modifier_item['modifier']] = modifier
|
||||||
|
modifier_categories[category_name] = category
|
||||||
|
|
||||||
|
def scan_directory(directory_path: str, category_name="Modifiers"):
|
||||||
|
for entry in os.scandir(directory_path):
|
||||||
|
if entry.is_file():
|
||||||
|
file_extension = list(filter(lambda e: entry.name.endswith(e), IMAGE_EXTENSIONS))
|
||||||
|
if len(file_extension) == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
modifier_name = entry.name[: -len(file_extension[0])]
|
||||||
|
modifier_path = f"custom/{entry.path[len(CUSTOM_MODIFIERS_DIR) + 1:]}"
|
||||||
|
# URL encode path segments
|
||||||
|
modifier_path = "/".join(map(lambda segment: urllib.parse.quote(segment), modifier_path.split("/")))
|
||||||
|
is_portrait = True
|
||||||
|
is_landscape = True
|
||||||
|
|
||||||
|
portrait_extension = list(filter(lambda e: modifier_name.lower().endswith(e), CUSTOM_MODIFIERS_PORTRAIT_EXTENSIONS))
|
||||||
|
landscape_extension = list(filter(lambda e: modifier_name.lower().endswith(e), CUSTOM_MODIFIERS_LANDSCAPE_EXTENSIONS))
|
||||||
|
|
||||||
|
if len(portrait_extension) > 0:
|
||||||
|
is_landscape = False
|
||||||
|
modifier_name = modifier_name[: -len(portrait_extension[0])]
|
||||||
|
elif len(landscape_extension) > 0:
|
||||||
|
is_portrait = False
|
||||||
|
modifier_name = modifier_name[: -len(landscape_extension[0])]
|
||||||
|
|
||||||
|
if (category_name not in modifier_categories):
|
||||||
|
modifier_categories[category_name] = {}
|
||||||
|
|
||||||
|
category = modifier_categories[category_name]
|
||||||
|
|
||||||
|
if (modifier_name not in category):
|
||||||
|
category[modifier_name] = {}
|
||||||
|
|
||||||
|
if (is_portrait or "portrait" not in category[modifier_name]):
|
||||||
|
category[modifier_name]["portrait"] = modifier_path
|
||||||
|
|
||||||
|
if (is_landscape or "landscape" not in category[modifier_name]):
|
||||||
|
category[modifier_name]["landscape"] = modifier_path
|
||||||
|
elif entry.is_dir():
|
||||||
|
scan_directory(
|
||||||
|
entry.path,
|
||||||
|
entry.name if directory_path==CUSTOM_MODIFIERS_DIR else f"{category_name}/{entry.name}",
|
||||||
|
)
|
||||||
|
|
||||||
|
scan_directory(CUSTOM_MODIFIERS_DIR)
|
||||||
|
|
||||||
|
custom_categories = sorted(
|
||||||
|
[cn for cn in modifier_categories.keys() if cn not in original_category_order],
|
||||||
|
key=str.casefold,
|
||||||
|
)
|
||||||
|
|
||||||
|
# convert the modifiers back into a list of objects
|
||||||
|
modifier_categories_list = []
|
||||||
|
for category_name in [*original_category_order, *custom_categories]:
|
||||||
|
category = { 'category': category_name, 'modifiers': [] }
|
||||||
|
for modifier_name in sorted(modifier_categories[category_name].keys(), key=str.casefold):
|
||||||
|
modifier = { 'modifier': modifier_name, 'previews': [] }
|
||||||
|
for preview_name, preview_path in modifier_categories[category_name][modifier_name].items():
|
||||||
|
modifier['previews'].append({ 'name': preview_name, 'path': preview_path })
|
||||||
|
category['modifiers'].append(modifier)
|
||||||
|
modifier_categories_list.append(category)
|
||||||
|
|
||||||
|
return modifier_categories_list
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import torch
|
import torch
|
||||||
import traceback
|
import traceback
|
||||||
import re
|
import re
|
||||||
@ -66,6 +67,9 @@ def get_device_delta(render_devices, active_devices):
|
|||||||
def auto_pick_devices(currently_active_devices):
|
def auto_pick_devices(currently_active_devices):
|
||||||
global mem_free_threshold
|
global mem_free_threshold
|
||||||
|
|
||||||
|
if platform.system() == "Darwin" and torch.backends.mps.is_available() and torch.backends.mps.is_built():
|
||||||
|
return ["mps"]
|
||||||
|
|
||||||
if not torch.cuda.is_available():
|
if not torch.cuda.is_available():
|
||||||
return ["cpu"]
|
return ["cpu"]
|
||||||
|
|
||||||
@ -115,11 +119,11 @@ def device_init(context, device):
|
|||||||
|
|
||||||
validate_device_id(device, log_prefix="device_init")
|
validate_device_id(device, log_prefix="device_init")
|
||||||
|
|
||||||
if device == "cpu":
|
if "cuda" not in device:
|
||||||
context.device = "cpu"
|
context.device = device
|
||||||
context.device_name = get_processor_name()
|
context.device_name = get_processor_name()
|
||||||
context.half_precision = False
|
context.half_precision = False
|
||||||
log.debug(f"Render device CPU available as {context.device_name}")
|
log.debug(f"Render device available as {context.device_name}")
|
||||||
return
|
return
|
||||||
|
|
||||||
context.device_name = torch.cuda.get_device_name(device)
|
context.device_name = torch.cuda.get_device_name(device)
|
||||||
@ -134,8 +138,6 @@ def device_init(context, device):
|
|||||||
log.info(f'Setting {device} as active, with precision: {"half" if context.half_precision else "full"}')
|
log.info(f'Setting {device} as active, with precision: {"half" if context.half_precision else "full"}')
|
||||||
torch.cuda.device(device)
|
torch.cuda.device(device)
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def needs_to_force_full_precision(context):
|
def needs_to_force_full_precision(context):
|
||||||
if "FORCE_FULL_PRECISION" in os.environ:
|
if "FORCE_FULL_PRECISION" in os.environ:
|
||||||
@ -174,7 +176,7 @@ def validate_device_id(device, log_prefix=""):
|
|||||||
def is_valid():
|
def is_valid():
|
||||||
if not isinstance(device, str):
|
if not isinstance(device, str):
|
||||||
return False
|
return False
|
||||||
if device == "cpu":
|
if device == "cpu" or device == "mps":
|
||||||
return True
|
return True
|
||||||
if not device.startswith("cuda:") or not device[5:].isnumeric():
|
if not device.startswith("cuda:") or not device[5:].isnumeric():
|
||||||
return False
|
return False
|
||||||
@ -182,7 +184,7 @@ def validate_device_id(device, log_prefix=""):
|
|||||||
|
|
||||||
if not is_valid():
|
if not is_valid():
|
||||||
raise EnvironmentError(
|
raise EnvironmentError(
|
||||||
f"{log_prefix}: device id should be 'cpu', or 'cuda:N' (where N is an integer index for the GPU). Got: {device}"
|
f"{log_prefix}: device id should be 'cpu', 'mps', or 'cuda:N' (where N is an integer index for the GPU). Got: {device}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -217,14 +219,14 @@ def is_device_compatible(device):
|
|||||||
|
|
||||||
def get_processor_name():
|
def get_processor_name():
|
||||||
try:
|
try:
|
||||||
import platform, subprocess
|
import subprocess
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
return platform.processor()
|
return platform.processor()
|
||||||
elif platform.system() == "Darwin":
|
elif platform.system() == "Darwin":
|
||||||
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"
|
command = "sysctl -n machdep.cpu.brand_string"
|
||||||
return subprocess.check_output(command).strip()
|
return subprocess.check_output(command, shell=True).decode().strip()
|
||||||
elif platform.system() == "Linux":
|
elif platform.system() == "Linux":
|
||||||
command = "cat /proc/cpuinfo"
|
command = "cat /proc/cpuinfo"
|
||||||
all_info = subprocess.check_output(command, shell=True).decode().strip()
|
all_info = subprocess.check_output(command, shell=True).decode().strip()
|
||||||
|
@ -25,6 +25,13 @@ NOCACHE_HEADERS = {"Cache-Control": "no-cache, no-store, must-revalidate", "Prag
|
|||||||
|
|
||||||
|
|
||||||
class NoCacheStaticFiles(StaticFiles):
|
class NoCacheStaticFiles(StaticFiles):
|
||||||
|
def __init__(self, directory: str):
|
||||||
|
# follow_symlink is only available on fastapi >= 0.92.0
|
||||||
|
if (os.path.islink(directory)):
|
||||||
|
super().__init__(directory = os.path.realpath(directory))
|
||||||
|
else:
|
||||||
|
super().__init__(directory = directory)
|
||||||
|
|
||||||
def is_not_modified(self, response_headers, request_headers) -> bool:
|
def is_not_modified(self, response_headers, request_headers) -> bool:
|
||||||
if "content-type" in response_headers and (
|
if "content-type" in response_headers and (
|
||||||
"javascript" in response_headers["content-type"] or "css" in response_headers["content-type"]
|
"javascript" in response_headers["content-type"] or "css" in response_headers["content-type"]
|
||||||
@ -45,6 +52,13 @@ class SetAppConfigRequest(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
|
if os.path.isdir(app.CUSTOM_MODIFIERS_DIR):
|
||||||
|
server_api.mount(
|
||||||
|
"/media/modifier-thumbnails/custom",
|
||||||
|
NoCacheStaticFiles(directory=app.CUSTOM_MODIFIERS_DIR),
|
||||||
|
name="custom-thumbnails",
|
||||||
|
)
|
||||||
|
|
||||||
server_api.mount("/media", NoCacheStaticFiles(directory=os.path.join(app.SD_UI_DIR, "media")), name="media")
|
server_api.mount("/media", NoCacheStaticFiles(directory=os.path.join(app.SD_UI_DIR, "media")), name="media")
|
||||||
|
|
||||||
for plugins_dir, dir_prefix in app.UI_PLUGINS_SOURCES:
|
for plugins_dir, dir_prefix in app.UI_PLUGINS_SOURCES:
|
||||||
@ -156,7 +170,7 @@ def read_web_data_internal(key: str = None):
|
|||||||
elif key == "models":
|
elif key == "models":
|
||||||
return JSONResponse(model_manager.getModels(), headers=NOCACHE_HEADERS)
|
return JSONResponse(model_manager.getModels(), headers=NOCACHE_HEADERS)
|
||||||
elif key == "modifiers":
|
elif key == "modifiers":
|
||||||
return FileResponse(os.path.join(app.SD_UI_DIR, "modifiers.json"), headers=NOCACHE_HEADERS)
|
return JSONResponse(app.get_image_modifiers(), headers=NOCACHE_HEADERS)
|
||||||
elif key == "ui_plugins":
|
elif key == "ui_plugins":
|
||||||
return JSONResponse(app.getUIPlugins(), headers=NOCACHE_HEADERS)
|
return JSONResponse(app.getUIPlugins(), headers=NOCACHE_HEADERS)
|
||||||
else:
|
else:
|
||||||
|
@ -385,7 +385,7 @@ def get_devices():
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_device_info(device):
|
def get_device_info(device):
|
||||||
if device == "cpu":
|
if "cuda" not in device:
|
||||||
return {"name": device_manager.get_processor_name()}
|
return {"name": device_manager.get_processor_name()}
|
||||||
|
|
||||||
mem_free, mem_total = torch.cuda.mem_get_info(device)
|
mem_free, mem_total = torch.cuda.mem_get_info(device)
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<div id="logo">
|
<div id="logo">
|
||||||
<h1>
|
<h1>
|
||||||
Easy Diffusion
|
Easy Diffusion
|
||||||
<small>v2.5.22 <span id="updateBranchLabel"></span></small>
|
<small>v2.5.23 <span id="updateBranchLabel"></span></small>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="server-status">
|
<div id="server-status">
|
||||||
|
Loading…
Reference in New Issue
Block a user