mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
add models-dir to settings and simplify path improts
This commit is contained in:
+9
-2
@@ -4,8 +4,11 @@
|
||||
|
||||
*Note*: Pending release of `diffusers==0.22.0`
|
||||
|
||||
Support for several new models and additional optimizations.
|
||||
Plus tons of fixes...
|
||||
Another pretty big release, this time with focus on
|
||||
new models, new backends and optimizations and tons of fixes
|
||||
|
||||
Also, [Wiki](https://github.com/vladmandic/automatic/wiki) has been updated with new content, so check it out!
|
||||
Some highlights: [OpenVINO](https://github.com/vladmandic/automatic/wiki/OpenVINO), [IntelArc](https://github.com/vladmandic/automatic/wiki/Intel-ARC), [DirectML](https://github.com/vladmandic/automatic/wiki/DirectML), [ONNX/Olive>](https://github.com/vladmandic/automatic/wiki/ONNX-Runtime)
|
||||
|
||||
- **Diffusers**
|
||||
- new model type: [Segmind SSD-1B](https://huggingface.co/segmind/SSD-1B)
|
||||
@@ -24,6 +27,8 @@ Plus tons of fixes...
|
||||
- new custom pipeline: `Disty0/zero123plus-pipeline`
|
||||
generate 4 output images with different camera positions: front, side, top, back!
|
||||
for more details, see <https://github.com/vladmandic/automatic/discussions/2421>
|
||||
- new backend: **ONNX/Olive** (experimental)
|
||||
for details, see WiKi
|
||||
- extend support for [Free-U](https://github.com/ChenyangSi/FreeU)
|
||||
improve generations quality at no cost (other than finding params that work for you)
|
||||
- **General**
|
||||
@@ -35,6 +40,8 @@ Plus tons of fixes...
|
||||
- **Extra networks** sort by name, size, date, etc.
|
||||
- new option: *settings -> images -> keep incomplete*
|
||||
can be used to skip vae decode on aborted/skipped/interrupted image generations
|
||||
- new option: *settings -> system paths -> models*
|
||||
can be used to set custom base path for *all* models (previously only as cli option)
|
||||
- remove external clone of items in `/repositories`
|
||||
- switch core font in default theme to **noto-sans**
|
||||
previously default font was simply *system-ui*, but it lead to too much variations between browsers and platforms
|
||||
|
||||
@@ -56,21 +56,23 @@ Additional models will be added as they become available and there is public int
|
||||
- [Stable Diffusion](https://github.com/Stability-AI/stablediffusion/) 1.x and 2.x *(all variants)*
|
||||
- [Stable Diffusion XL](https://github.com/Stability-AI/generative-models)
|
||||
- [Kandinsky](https://github.com/ai-forever/Kandinsky-2) 2.1 and 2.2
|
||||
- [DeepFloyd IF](https://github.com/deep-floyd/IF)
|
||||
- [UniDiffusion](https://github.com/thu-ml/unidiffuser)
|
||||
- [SD-Distilled](https://huggingface.co/blog/sd_distillation) *(all variants)*
|
||||
- [Wuerstchen](https://huggingface.co/blog/wuertschen)
|
||||
- [Segmind SSD-1B](https://huggingface.co/segmind/SSD-1B)
|
||||
- [UniDiffusion](https://github.com/thu-ml/unidiffuser)
|
||||
- [DeepFloyd IF](https://github.com/deep-floyd/IF)
|
||||
|
||||
## Platform support
|
||||
|
||||
- *nVidia* GPUs using **CUDA** libraries on both *Windows and Linux*
|
||||
- *AMD* GPUs using **ROCm** libraries on *Linux*.
|
||||
Support will be extended to *Windows* once AMD releases ROCm for Windows
|
||||
- *Intel Arc* GPUs using **OneAPI** with *IPEX XPU* libraries on both *Windows and Linux*
|
||||
- Any GPU compatible with *DirectX* on *Windows* using **DirectML** libraries.
|
||||
This includes support for AMD GPUs that are not supported by native ROCm libraries
|
||||
- Any GPU or device compatible with **OpenVINO** libraries on both *Windows and Linux*
|
||||
- *Apple M1/M2* on *OSX* using built-in support in Torch with **MPS** optimizations
|
||||
- *nVidia* GPUs using **CUDA** libraries on both *Windows and Linux*
|
||||
- *AMD* GPUs using **ROCm** libraries on *Linux*
|
||||
Support will be extended to *Windows* once AMD releases ROCm for Windows
|
||||
- *Intel Arc* GPUs using **OneAPI** with *IPEX XPU* libraries on both *Windows and Linux*
|
||||
- Any GPU compatible with *DirectX* on *Windows* using **DirectML** libraries
|
||||
This includes support for AMD GPUs that are not supported by native ROCm libraries
|
||||
- Any GPU or device compatible with **OpenVINO** libraries on both *Windows and Linux*
|
||||
- *Apple M1/M2* on *OSX* using built-in support in Torch with **MPS** optimizations
|
||||
- *ONNX/Olive* (experimental)
|
||||
|
||||
## Install & Run
|
||||
|
||||
|
||||
+3
-3
@@ -661,7 +661,7 @@ def install_extensions():
|
||||
pkg_resources._initialize_master_working_set() # pylint: disable=protected-access
|
||||
pkgs = [f'{p.project_name}=={p._version}' for p in pkg_resources.working_set] # pylint: disable=protected-access,not-an-iterable
|
||||
log.debug(f'Installed packages: {len(pkgs)}')
|
||||
from modules.paths_internal import extensions_builtin_dir, extensions_dir
|
||||
from modules.paths import extensions_builtin_dir, extensions_dir
|
||||
extensions_duplicates = []
|
||||
extensions_enabled = []
|
||||
extension_folders = [extensions_builtin_dir] if args.safe else [extensions_builtin_dir, extensions_dir]
|
||||
@@ -795,7 +795,7 @@ def set_environment():
|
||||
|
||||
def check_extensions():
|
||||
newest_all = os.path.getmtime('requirements.txt')
|
||||
from modules.paths_internal import extensions_builtin_dir, extensions_dir
|
||||
from modules.paths import extensions_builtin_dir, extensions_dir
|
||||
extension_folders = [extensions_builtin_dir] if args.safe else [extensions_builtin_dir, extensions_dir]
|
||||
disabled_extensions_all = opts.get('disable_all_extensions', 'none')
|
||||
if disabled_extensions_all != 'none':
|
||||
@@ -983,7 +983,7 @@ def extensions_preload(parser):
|
||||
log.info('Running in safe mode without user extensions')
|
||||
try:
|
||||
from modules.script_loading import preload_extensions
|
||||
from modules.paths_internal import extensions_builtin_dir, extensions_dir
|
||||
from modules.paths import extensions_builtin_dir, extensions_dir
|
||||
extension_folders = [extensions_builtin_dir] if args.safe else [extensions_builtin_dir, extensions_dir]
|
||||
preload_time = {}
|
||||
for ext_dir in extension_folders:
|
||||
|
||||
@@ -28,9 +28,9 @@ def init_modules():
|
||||
parser = modules.cmd_args.parser
|
||||
installer.add_args(parser)
|
||||
args, _ = parser.parse_known_args()
|
||||
import modules.paths_internal
|
||||
script_path = modules.paths_internal.script_path
|
||||
extensions_dir = modules.paths_internal.extensions_dir
|
||||
import modules.paths
|
||||
script_path = modules.paths.script_path
|
||||
extensions_dir = modules.paths.extensions_dir
|
||||
|
||||
|
||||
def get_custom_args():
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
import argparse
|
||||
from modules.paths_internal import data_path
|
||||
from modules.paths import data_path
|
||||
|
||||
parser = argparse.ArgumentParser(description="SD.Next", conflict_handler='resolve', epilog='For other options see UI Settings page', prog='', add_help=True, formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=55, indent_increment=2, width=200))
|
||||
parser._optionals = parser.add_argument_group('Other options') # pylint: disable=protected-access
|
||||
|
||||
@@ -2,7 +2,7 @@ import os
|
||||
from datetime import datetime
|
||||
import git
|
||||
from modules import shared, errors
|
||||
from modules.paths_internal import extensions_dir, extensions_builtin_dir
|
||||
from modules.paths import extensions_dir, extensions_builtin_dir
|
||||
|
||||
|
||||
extensions = []
|
||||
|
||||
+50
-15
@@ -1,9 +1,43 @@
|
||||
# this module must not have any dependencies as it first import
|
||||
import os
|
||||
import sys
|
||||
from modules import paths_internal, errors
|
||||
import json
|
||||
import argparse
|
||||
from modules.errors import log
|
||||
|
||||
# parse args, parse again after we have the data-dir and early-read the config file
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser.add_argument("--ckpt", type=str, default=os.environ.get("SD_MODEL", None), help="Path to model checkpoint to load immediately, default: %(default)s")
|
||||
parser.add_argument("--data-dir", type=str, default=os.environ.get("SD_DATADIR", ''), help="Base path where all user data is stored, default: %(default)s")
|
||||
parser.add_argument("--models-dir", type=str, default=os.environ.get("SD_MODELSDIR", None), help="Base path where all models are stored, default: %(default)s",)
|
||||
cli = parser.parse_known_args()[0]
|
||||
parser.add_argument("--config", type=str, default=os.environ.get("SD_CONFIG", os.path.join(cli.data_dir, 'config.json')), help="Use specific server configuration file, default: %(default)s")
|
||||
cli = parser.parse_known_args()[0]
|
||||
config_path = cli.config if os.path.isabs(cli.config) else os.path.join(cli.data_dir, cli.config)
|
||||
try:
|
||||
with open(config_path, 'r', encoding='utf8') as f:
|
||||
config = json.load(f)
|
||||
except Exception as err:
|
||||
print('Error loading config file: ${config_path} {err}')
|
||||
config = {}
|
||||
|
||||
debug = errors.log.info if os.environ.get('SD_PATH_DEBUG', None) is not None else lambda *args, **kwargs: None
|
||||
modules_path = os.path.dirname(os.path.realpath(__file__))
|
||||
script_path = os.path.dirname(modules_path)
|
||||
data_path = cli.data_dir
|
||||
models_config = cli.models_dir or config.get('models_dir') or 'models'
|
||||
models_path = models_config if os.path.isabs(models_config) else os.path.join(data_path, models_config)
|
||||
extensions_dir = os.path.join(data_path, "extensions")
|
||||
extensions_builtin_dir = "extensions-builtin"
|
||||
sd_configs_path = os.path.join(script_path, "configs")
|
||||
sd_default_config = os.path.join(sd_configs_path, "v1-inference.yaml")
|
||||
sd_model_file = cli.ckpt or os.path.join(script_path, 'model.ckpt') # not used
|
||||
default_sd_model_file = sd_model_file # not used
|
||||
debug = log.info if os.environ.get('SD_PATH_DEBUG', None) is not None else lambda *args, **kwargs: None
|
||||
|
||||
if os.environ.get('SD_PATH_DEBUG', None) is not None:
|
||||
print(f'Paths: script-path="{script_path}" data-dir="{data_path}" models-dir="{models_path}" config="{config_path}"')
|
||||
|
||||
"""
|
||||
data_path = paths_internal.data_path
|
||||
script_path = paths_internal.script_path
|
||||
models_path = paths_internal.models_path
|
||||
@@ -13,8 +47,8 @@ sd_model_file = paths_internal.sd_model_file
|
||||
default_sd_model_file = paths_internal.default_sd_model_file
|
||||
extensions_dir = paths_internal.extensions_dir
|
||||
extensions_builtin_dir = paths_internal.extensions_builtin_dir
|
||||
"""
|
||||
|
||||
# data_path = cmd_opts_pre.data
|
||||
sys.path.insert(0, script_path)
|
||||
|
||||
sd_path = os.path.join(script_path, 'repositories')
|
||||
@@ -31,25 +65,26 @@ paths = {}
|
||||
for d, must_exist, what, _options in path_dirs:
|
||||
must_exist_path = os.path.abspath(os.path.join(script_path, d, must_exist))
|
||||
if not os.path.exists(must_exist_path):
|
||||
errors.log.error(f'Required path not found: path={must_exist_path} item={what}')
|
||||
log.error(f'Required path not found: path={must_exist_path} item={what}')
|
||||
else:
|
||||
d = os.path.abspath(d)
|
||||
sys.path.append(d)
|
||||
paths[what] = d
|
||||
|
||||
|
||||
def create_paths(opts):
|
||||
def create_path(folder):
|
||||
if folder is None or folder == '':
|
||||
return
|
||||
if os.path.exists(folder):
|
||||
return
|
||||
try:
|
||||
os.makedirs(folder, exist_ok=True)
|
||||
errors.log.info(f'Create folder={folder}')
|
||||
except Exception as e:
|
||||
errors.log.error(f'Create Failed folder={folder} {e}')
|
||||
def create_path(folder):
|
||||
if folder is None or folder == '':
|
||||
return
|
||||
if os.path.exists(folder):
|
||||
return
|
||||
try:
|
||||
os.makedirs(folder, exist_ok=True)
|
||||
log.info(f'Create folder={folder}')
|
||||
except Exception as e:
|
||||
log.error(f'Create Failed folder={folder} {e}')
|
||||
|
||||
|
||||
def create_paths(opts):
|
||||
def fix_path(folder):
|
||||
tgt = opts.data.get(folder, None) or opts.data_labels[folder].default
|
||||
if tgt is None or tgt == '':
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
"""this module defines internal paths used by program and is safe to import before dependencies are installed in launch.py"""
|
||||
# no longer used, all paths are defined in paths.py
|
||||
|
||||
from modules.paths import modules_path, script_path, sd_configs_path, sd_default_config, sd_model_file, default_sd_model_file, data_path, models_path, extensions_dir, extensions_builtin_dir # pylint: disable=unused-import
|
||||
|
||||
"""
|
||||
import argparse
|
||||
import os
|
||||
|
||||
@@ -7,15 +10,21 @@ modules_path = os.path.dirname(os.path.realpath(__file__))
|
||||
script_path = os.path.dirname(modules_path)
|
||||
sd_configs_path = os.path.join(script_path, "configs")
|
||||
sd_default_config = os.path.join(sd_configs_path, "v1-inference.yaml")
|
||||
sd_model_file = os.path.join(script_path, 'model.ckpt')
|
||||
default_sd_model_file = sd_model_file
|
||||
|
||||
# Parse the --data-dir flag first so we can use it as a base for our other argument default values
|
||||
parser_pre = argparse.ArgumentParser(add_help=False)
|
||||
parser_pre.add_argument("--data-dir", type=str, default="", help="base path where all user data is stored", )
|
||||
parser_pre.add_argument("--models-dir", type=str, default="models", help="base path where all models are stored",)
|
||||
parser_pre.add_argument("--ckpt", type=str, default=os.environ.get("SD_MODEL", None), help="Path to model checkpoint to load immediately, default: %(default)s")
|
||||
parser_pre.add_argument("--data-dir", type=str, default=os.environ.get("SD_DATADIR", ''), help="Base path where all user data is stored, default: %(default)s")
|
||||
parser_pre.add_argument("--models-dir", type=str, default=os.environ.get("SD_MODELSDIR", 'models'), help="Base path where all models are stored, default: %(default)s",)
|
||||
cmd_opts_pre = parser_pre.parse_known_args()[0]
|
||||
|
||||
# parser_pre.add_argument("--config", type=str, default=os.environ.get("SD_CONFIG", os.path.join(data_path, 'config.json')), help="Use specific server configuration file, default: %(default)s")
|
||||
|
||||
data_path = cmd_opts_pre.data_dir
|
||||
models_path = cmd_opts_pre.models_dir if os.path.isabs(cmd_opts_pre.models_dir) else os.path.join(data_path, cmd_opts_pre.models_dir)
|
||||
extensions_dir = os.path.join(data_path, "extensions")
|
||||
extensions_builtin_dir = "extensions-builtin"
|
||||
|
||||
sd_model_file = cmd_opts_pre.ckpt or os.path.join(script_path, 'model.ckpt') # not used
|
||||
default_sd_model_file = sd_model_file # not used
|
||||
"""
|
||||
|
||||
@@ -24,7 +24,7 @@ from modules import paths, shared, shared_items, shared_state, modelloader, devi
|
||||
from modules.sd_hijack_inpainting import do_inpainting_hijack
|
||||
from modules.timer import Timer
|
||||
from modules.memstats import memory_stats
|
||||
from modules.paths_internal import models_path, script_path
|
||||
from modules.paths import models_path, script_path
|
||||
|
||||
try:
|
||||
import diffusers
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ import collections
|
||||
import glob
|
||||
from copy import deepcopy
|
||||
import torch
|
||||
from modules import shared, paths, paths_internal, devices, script_callbacks, sd_models
|
||||
from modules import shared, paths, devices, script_callbacks, sd_models
|
||||
|
||||
|
||||
vae_ignore_keys = {"model_ema.decay", "model_ema.num_updates"}
|
||||
@@ -200,7 +200,7 @@ def load_vae_diffusers(model_file, vae_file=None, vae_source="unknown-source"):
|
||||
import diffusers
|
||||
if os.path.isfile(vae_file):
|
||||
_pipeline, model_type = sd_models.detect_pipeline(model_file, 'vae')
|
||||
diffusers_load_config = { "config_file": paths_internal.sd_default_config if model_type != 'Stable Diffusion XL' else os.path.join(paths_internal.sd_configs_path, 'sd_xl_base.yaml')}
|
||||
diffusers_load_config = { "config_file": paths.sd_default_config if model_type != 'Stable Diffusion XL' else os.path.join(paths.sd_configs_path, 'sd_xl_base.yaml')}
|
||||
vae = diffusers.AutoencoderKL.from_single_file(vae_file, **diffusers_load_config)
|
||||
vae = vae.to(devices.dtype_vae)
|
||||
else:
|
||||
|
||||
+8
-4
@@ -12,13 +12,13 @@ import gradio as gr
|
||||
import fasteners
|
||||
from rich.console import Console
|
||||
from modules import errors, shared_items, shared_state, cmd_args, ui_components, theme
|
||||
from modules.paths_internal import models_path, script_path, data_path, sd_configs_path, sd_default_config, sd_model_file, default_sd_model_file, extensions_dir, extensions_builtin_dir # pylint: disable=W0611
|
||||
from modules.paths import models_path, script_path, data_path, sd_configs_path, sd_default_config, sd_model_file, default_sd_model_file, extensions_dir, extensions_builtin_dir # pylint: disable=W0611
|
||||
from modules.dml import memory_providers, default_memory_provider, directml_do_hijack
|
||||
import modules.interrogate
|
||||
import modules.memmon
|
||||
import modules.styles
|
||||
import modules.devices as devices # pylint: disable=R0402
|
||||
import modules.paths_internal as paths
|
||||
import modules.paths as paths
|
||||
from installer import print_dict
|
||||
from installer import log as central_logger # pylint: disable=E0611
|
||||
|
||||
@@ -346,8 +346,8 @@ options_templates.update(options_section(('diffusers', "Diffusers Settings"), {
|
||||
}))
|
||||
|
||||
options_templates.update(options_section(('system-paths', "System Paths"), {
|
||||
"temp_dir": OptionInfo("", "Directory for temporary images; leave empty for default", folder=True),
|
||||
"clean_temp_dir_at_start": OptionInfo(True, "Cleanup non-default temporary directory when starting webui"),
|
||||
"models_paths_sep_options": OptionInfo("<h2>Models paths</h2>", "", gr.HTML),
|
||||
"models_dir": OptionInfo('models', "Base path where all models are stored", folder=True),
|
||||
"ckpt_dir": OptionInfo(os.path.join(paths.models_path, 'Stable-diffusion'), "Folder with stable diffusion models", folder=True),
|
||||
"diffusers_dir": OptionInfo(os.path.join(paths.models_path, 'Diffusers'), "Folder with Hugggingface models", folder=True),
|
||||
"vae_dir": OptionInfo(os.path.join(paths.models_path, 'VAE'), "Folder with VAE files", folder=True),
|
||||
@@ -366,6 +366,10 @@ options_templates.update(options_section(('system-paths', "System Paths"), {
|
||||
"swinir_models_path": OptionInfo(os.path.join(paths.models_path, 'SwinIR'), "Folder with SwinIR models", folder=True),
|
||||
"ldsr_models_path": OptionInfo(os.path.join(paths.models_path, 'LDSR'), "Folder with LDSR models", folder=True),
|
||||
"clip_models_path": OptionInfo(os.path.join(paths.models_path, 'CLIP'), "Folder with CLIP models", folder=True),
|
||||
|
||||
"other_paths_sep_options": OptionInfo("<h2>Other paths</h2>", "", gr.HTML),
|
||||
"temp_dir": OptionInfo("", "Directory for temporary images; leave empty for default", folder=True),
|
||||
"clean_temp_dir_at_start": OptionInfo(True, "Cleanup non-default temporary directory when starting webui"),
|
||||
}))
|
||||
|
||||
options_templates.update(options_section(('saving-images', "Image Options"), {
|
||||
|
||||
@@ -6,7 +6,7 @@ https://github.com/madebyollin/taesd
|
||||
"""
|
||||
import os
|
||||
from PIL import Image
|
||||
from modules import devices, paths_internal
|
||||
from modules import devices, paths
|
||||
from modules.taesd.taesd import TAESD
|
||||
|
||||
taesd_models = { 'sd-decoder': None, 'sd-encoder': None, 'sdxl-decoder': None, 'sdxl-encoder': None }
|
||||
@@ -25,7 +25,7 @@ def download_model(model_path):
|
||||
def model(model_class = 'sd', model_type = 'decoder'):
|
||||
vae = taesd_models[f'{model_class}-{model_type}']
|
||||
if vae is None:
|
||||
model_path = os.path.join(paths_internal.models_path, "TAESD", f"tae{model_class}_{model_type}.pth")
|
||||
model_path = os.path.join(paths.models_path, "TAESD", f"tae{model_class}_{model_type}.pth")
|
||||
download_model(model_path)
|
||||
if os.path.exists(model_path):
|
||||
from modules.shared import log
|
||||
@@ -52,7 +52,7 @@ def decode(latents):
|
||||
return Image.new('RGB', (8, 8), color = (0, 0, 0))
|
||||
vae = taesd_models[f'{model_class}-decoder']
|
||||
if vae is None:
|
||||
model_path = os.path.join(paths_internal.models_path, "TAESD", f"tae{model_class}_decoder.pth")
|
||||
model_path = os.path.join(paths.models_path, "TAESD", f"tae{model_class}_decoder.pth")
|
||||
download_model(model_path)
|
||||
if os.path.exists(model_path):
|
||||
taesd_models[f'{model_class}-decoder'] = TAESD(decoder_path=model_path, encoder_path=None)
|
||||
@@ -73,7 +73,7 @@ def encode(image):
|
||||
return Image.new('RGB', (8, 8), color = (0, 0, 0))
|
||||
vae = taesd_models[f'{model_class}-encoder']
|
||||
if vae is None:
|
||||
model_path = os.path.join(paths_internal.models_path, "TAESD", f"tae{model_class}_encoder.pth")
|
||||
model_path = os.path.join(paths.models_path, "TAESD", f"tae{model_class}_encoder.pth")
|
||||
download_model(model_path)
|
||||
if os.path.exists(model_path):
|
||||
taesd_models[f'{model_class}-encoder'] = TAESD(encoder_path=model_path, decoder_path=None)
|
||||
|
||||
Reference in New Issue
Block a user