mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
improve error handling
This commit is contained in:
@@ -23,8 +23,8 @@ Fork adds extra functionality:
|
||||
- [System Info](https://github.com/vladmandic/sd-extension-system-info)
|
||||
- [ControlNet](https://github.com/Mikubill/sd-webui-controlnet)
|
||||
- [Image Browser](https://github.com/AlUlkesh/stable-diffusion-webui-images-browser)
|
||||
- [LORA](https://github.com/kohya-ss/sd-scripts) (both training and inference)
|
||||
- [LyCORIS](https://github.com/KohakuBlueleaf/LyCORIS) (both training and inference)
|
||||
- [LORA](https://github.com/kohya-ss/sd-scripts) *(both training and inference)*
|
||||
- [LyCORIS](https://github.com/KohakuBlueleaf/LyCORIS) *(both training and inference)*
|
||||
- [Model Converter](https://github.com/Akegarasu/sd-webui-model-converter)
|
||||
- [CLiP Interrogator](https://github.com/pharmapsychotic/clip-interrogator-ext)
|
||||
- [Dynamic Thresholding](https://github.com/mcmonkeyprojects/sd-dynamic-thresholding)
|
||||
@@ -95,7 +95,7 @@ Start with listen on public IP with authentication enabled
|
||||
## Install
|
||||
|
||||
1. Install `Python`, `Git`
|
||||
2. Install `PyTorch` and `Xformers`
|
||||
2. Install `PyTorch`
|
||||
See [Wiki](wiki/Torch%20Optimizations.md) for details or TL;DR below
|
||||
3. Clone and initialize repository
|
||||
|
||||
@@ -116,6 +116,11 @@ Start with listen on public IP with authentication enabled
|
||||
Detached repos
|
||||
Local changes
|
||||
|
||||
*Note*: If you're not using `automatic.sh` launcher, install dependencies manually:
|
||||
|
||||
> pip -r requirements.txt
|
||||
> pip -r requirements_versions.txt
|
||||
|
||||
<br>
|
||||
|
||||
## Differences
|
||||
@@ -142,11 +147,12 @@ Fork does differ in few things:
|
||||
|
||||
User Interface:
|
||||
|
||||
- Includes reskinned **UI**
|
||||
- Includes updated **UI**: reskinned and reorganized
|
||||
Black and orange dark theme with fixed width options panels and larger previews
|
||||
|
||||
Optimizations:
|
||||
|
||||
- Optimized for `Torch` 2.0
|
||||
- Runs with `SDP` memory attention enabled by default if supported by system
|
||||
- Fallback to `XFormers` if SDP is not supported
|
||||
- If either `SDP` or `XFormers` are not supported, falls back to usual cmd line arguments
|
||||
|
||||
@@ -33,8 +33,8 @@ prompts = [
|
||||
|
||||
('wlop', 'a stunning portrait of sexy teen girl in a wet t-shirt, vivid color palette, digital painting, octane render, highly detailed, particles, light effect, volumetric lighting, art by wlop'),
|
||||
('greg rutkowski', 'beautiful woman, high detailed, sharp focus, depth of field, 4k, art by greg rutkowski'),
|
||||
('carne griggiths', 'beautiful woman taylor swift, high detailed, sharp focus, depth of field, art by carne griffiths <lora:taylor-swift:1>'),
|
||||
('carne griggiths', 'man vlado, high detailed, sharp focus, depth of field, art by carne griffiths <lora:vlado-full:1>'),
|
||||
('carne griffiths', 'beautiful woman taylor swift, high detailed, sharp focus, depth of field, art by carne griffiths <lora:taylor-swift:1>'),
|
||||
('carne griffiths', 'man vlado, high detailed, sharp focus, depth of field, art by carne griffiths <lora:vlado-full:1>'),
|
||||
]
|
||||
|
||||
options = Map({
|
||||
|
||||
Submodule extensions-builtin/sd-extension-system-info updated: c7a5c647e0...a42e9e3648
@@ -209,7 +209,7 @@ def run_extensions_installers(settings_file):
|
||||
def prepare_environment():
|
||||
global skip_install
|
||||
|
||||
torch_command = os.environ.get('TORCH_COMMAND', "pip install torch torchaudio torchvision triton --force --extra-index-url https://download.pytorch.org/whl/cu118")
|
||||
torch_command = os.environ.get('TORCH_COMMAND', "pip install torch torchaudio torchvision --force --extra-index-url https://download.pytorch.org/whl/cu118")
|
||||
requirements_file = os.environ.get('REQS_FILE', "requirements_versions.txt")
|
||||
|
||||
xformers_package = os.environ.get('XFORMERS_PACKAGE', 'xformers==0.0.16')
|
||||
@@ -290,37 +290,6 @@ def prepare_environment():
|
||||
print("Exiting because of --exit argument")
|
||||
exit(0)
|
||||
|
||||
if args.tests and not args.no_tests:
|
||||
exitcode = tests(args.tests)
|
||||
exit(exitcode)
|
||||
|
||||
|
||||
def tests(test_dir):
|
||||
if "--api" not in sys.argv:
|
||||
sys.argv.append("--api")
|
||||
if "--ckpt" not in sys.argv:
|
||||
sys.argv.append("--ckpt")
|
||||
sys.argv.append(os.path.join(script_path, "test/test_files/empty.pt"))
|
||||
if "--skip-torch-cuda-test" not in sys.argv:
|
||||
sys.argv.append("--skip-torch-cuda-test")
|
||||
if "--disable-nan-check" not in sys.argv:
|
||||
sys.argv.append("--disable-nan-check")
|
||||
if "--no-tests" not in sys.argv:
|
||||
sys.argv.append("--no-tests")
|
||||
|
||||
print(f"Launching Web UI in another process for testing with arguments: {' '.join(sys.argv[1:])}")
|
||||
|
||||
os.environ['COMMANDLINE_ARGS'] = ""
|
||||
with open(os.path.join(script_path, 'test/stdout.txt'), "w", encoding="utf8") as stdout, open(os.path.join(script_path, 'test/stderr.txt'), "w", encoding="utf8") as stderr:
|
||||
proc = subprocess.Popen([sys.executable, *sys.argv], stdout=stdout, stderr=stderr)
|
||||
|
||||
import test.server_poll
|
||||
exitcode = test.server_poll.run_tests(proc, test_dir)
|
||||
|
||||
print(f"Stopping Web UI process with id {proc.pid}")
|
||||
proc.kill()
|
||||
return exitcode
|
||||
|
||||
|
||||
def start():
|
||||
print(f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}")
|
||||
|
||||
+5
-14
@@ -1,11 +1,13 @@
|
||||
import sys
|
||||
import traceback
|
||||
from rich.console import Console
|
||||
|
||||
already_displayed = {}
|
||||
|
||||
|
||||
def print_error_explanation(message):
|
||||
lines = message.strip().split("\n")
|
||||
max_len = max([len(x) for x in lines])
|
||||
|
||||
print('=' * max_len, file=sys.stderr)
|
||||
for line in lines:
|
||||
print(line, file=sys.stderr)
|
||||
@@ -14,25 +16,14 @@ def print_error_explanation(message):
|
||||
|
||||
def display(e: Exception, task):
|
||||
print(f"{task or 'error'}: {type(e).__name__}", file=sys.stderr)
|
||||
print(traceback.format_exc(), file=sys.stderr)
|
||||
|
||||
message = str(e)
|
||||
if "copying a param with shape torch.Size([640, 1024]) from checkpoint, the shape in current model is torch.Size([640, 768])" in message:
|
||||
print_error_explanation("""
|
||||
The most likely cause of this is you are trying to load Stable Diffusion 2.0 model without specifying its config file.
|
||||
See https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#stable-diffusion-20 for how to solve this.
|
||||
""")
|
||||
|
||||
|
||||
already_displayed = {}
|
||||
console = Console()
|
||||
console.print_exception(show_locals=False, max_frames=2, extra_lines=1, suppress=[], word_wrap=False, width=min([console.width, 200]))
|
||||
|
||||
|
||||
def display_once(e: Exception, task):
|
||||
if task in already_displayed:
|
||||
return
|
||||
|
||||
display(e, task)
|
||||
|
||||
already_displayed[task] = 1
|
||||
|
||||
|
||||
|
||||
+33
-25
@@ -238,28 +238,31 @@ def read_metadata_from_safetensors(filename):
|
||||
|
||||
|
||||
def read_state_dict(checkpoint_file):
|
||||
with progress.open(checkpoint_file, 'rb', description=f'Loading weights: [cyan]{checkpoint_file}', auto_refresh=True) as f:
|
||||
_, extension = os.path.splitext(checkpoint_file)
|
||||
if 'v1-5-pruned-emaonly.safetensors' or 'vae-ft-mse-840000-ema-pruned.ckpt' in checkpoint_file:
|
||||
if extension.lower() == ".safetensors":
|
||||
pl_sd = safetensors.torch.load_file(checkpoint_file, device='cpu')
|
||||
try:
|
||||
with progress.open(checkpoint_file, 'rb', description=f'Loading weights: [cyan]{checkpoint_file}', auto_refresh=True) as f:
|
||||
_, extension = os.path.splitext(checkpoint_file)
|
||||
if 'v1-5-pruned-emaonly.safetensors' or 'vae-ft-mse-840000-ema-pruned.ckpt' in checkpoint_file:
|
||||
if extension.lower() == ".safetensors":
|
||||
pl_sd = safetensors.torch.load_file(checkpoint_file, device='cpu')
|
||||
else:
|
||||
pl_sd = torch.load(checkpoint_file, map_location='cpu')
|
||||
else:
|
||||
pl_sd = torch.load(checkpoint_file, map_location='cpu')
|
||||
else:
|
||||
if extension.lower() == ".safetensors":
|
||||
buffer = f.read()
|
||||
pl_sd = safetensors.torch.load(buffer)
|
||||
else:
|
||||
buffer = io.BytesIO(f.read())
|
||||
pl_sd = torch.load(buffer, map_location='cpu')
|
||||
sd = get_state_dict_from_checkpoint(pl_sd)
|
||||
if extension.lower() == ".safetensors":
|
||||
buffer = f.read()
|
||||
pl_sd = safetensors.torch.load(buffer)
|
||||
else:
|
||||
buffer = io.BytesIO(f.read())
|
||||
pl_sd = torch.load(buffer, map_location='cpu')
|
||||
sd = get_state_dict_from_checkpoint(pl_sd)
|
||||
except Exception as e:
|
||||
from rich.console import Console
|
||||
console = Console()
|
||||
console.print_exception(show_locals=False, max_frames=2, extra_lines=1, suppress=[], word_wrap=False, width=min([console.width, 200]))
|
||||
sd = None
|
||||
return sd
|
||||
|
||||
|
||||
def get_checkpoint_state_dict(checkpoint_info: CheckpointInfo, timer):
|
||||
sd_model_hash = checkpoint_info.calculate_shorthash()
|
||||
timer.record("calculate hash")
|
||||
|
||||
if checkpoint_info in checkpoints_loaded:
|
||||
# use checkpoint cache
|
||||
print(f"Loading weights from cache")
|
||||
@@ -394,22 +397,31 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None):
|
||||
from modules import lowvram, sd_hijack
|
||||
checkpoint_info = checkpoint_info or select_checkpoint()
|
||||
|
||||
do_inpainting_hijack()
|
||||
|
||||
timer = Timer()
|
||||
|
||||
current_checkpoint_info = None
|
||||
if shared.sd_model:
|
||||
current_checkpoint_info = shared.sd_model.sd_checkpoint_info
|
||||
sd_hijack.model_hijack.undo_hijack(shared.sd_model)
|
||||
shared.sd_model = None
|
||||
gc.collect()
|
||||
devices.torch_gc()
|
||||
|
||||
do_inpainting_hijack()
|
||||
|
||||
timer = Timer()
|
||||
|
||||
if already_loaded_state_dict is not None:
|
||||
state_dict = already_loaded_state_dict
|
||||
else:
|
||||
state_dict = get_checkpoint_state_dict(checkpoint_info, timer)
|
||||
|
||||
checkpoint_config = sd_models_config.find_checkpoint_config(state_dict, checkpoint_info)
|
||||
if state_dict is None or checkpoint_config is None:
|
||||
print(f"Failed to load checkpooint: {checkpoint_info.filename}")
|
||||
if current_checkpoint_info is not None:
|
||||
print(f"Restoring previous checkpoint: {current_checkpoint_info.filename}")
|
||||
load_model(current_checkpoint_info, None)
|
||||
return
|
||||
|
||||
clip_is_included_into_sd = sd1_clip_weight in state_dict or sd2_clip_weight in state_dict
|
||||
|
||||
timer.record("find config")
|
||||
@@ -426,10 +438,6 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None):
|
||||
with sd_disable_initialization.DisableInitialization(disable_clip=clip_is_included_into_sd):
|
||||
sd_model = instantiate_from_config(sd_config.model)
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
if sd_model is None:
|
||||
print('Failed to create model quickly; will retry using slow method.', file=sys.stderr)
|
||||
sd_model = instantiate_from_config(sd_config.model)
|
||||
|
||||
sd_model.used_config = checkpoint_config
|
||||
|
||||
@@ -63,6 +63,8 @@ def is_using_v_parameterization_for_sd2(state_dict):
|
||||
|
||||
|
||||
def guess_model_config_from_state_dict(sd, filename):
|
||||
if sd is None:
|
||||
return None
|
||||
sd2_cond_proj_weight = sd.get('cond_stage_model.model.transformer.resblocks.0.attn.in_proj_weight', None)
|
||||
diffusion_model_input = sd.get('model.diffusion_model.input_blocks.0.0.weight', None)
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ div.gradio-container.dark > div.w-full.flex.flex-col.min-h-screen > div { backgr
|
||||
.dark fieldset span.text-gray-500, .dark .gr-block.gr-box span.text-gray-500, .dark label.block span { border-radius: 0;}
|
||||
.eta-bar { display: none !important }
|
||||
.extra-network-cards .card .actions .name { font-weight: 400; font-size: 1.2rem; }
|
||||
.extra-network-cards .card { width: 10em; height: 10em; box-shadow: none; }
|
||||
.extra-network-cards .card:hover { transform: scale(1.3); transition: all 0.3s ease; z-index: 99; box-shadow: none; }
|
||||
.extra-network-cards .card { width: 18em; height: 12em; box-shadow: none; }
|
||||
.extra-network-cards .card:hover { transform: scale(1.5); transition: all 0.3s ease; z-index: 99; box-shadow: none; }
|
||||
.feather .feather-image { display: none }
|
||||
.gap-2 { padding-top: 8px; }
|
||||
.gr-box > div > div > input.gr-text-input { right: 0; width: 4em; padding: 0; top: -12px; border: none; max-height: 20px; }
|
||||
|
||||
@@ -157,9 +157,11 @@ def load_model():
|
||||
modules.sd_models.load_model()
|
||||
except Exception as e:
|
||||
errors.display(e, "loading stable diffusion model")
|
||||
print("", file=sys.stderr)
|
||||
print("Stable diffusion model failed to load, exiting", file=sys.stderr)
|
||||
exit(1)
|
||||
if shared.sd_model is None:
|
||||
print("No stable diffusion model loaded, exiting", file=sys.stderr)
|
||||
exit(1)
|
||||
shared.opts.data["sd_model_checkpoint"] = shared.sd_model.sd_checkpoint_info.title
|
||||
shared.opts.onchange("sd_model_checkpoint", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()))
|
||||
shared.state.end()
|
||||
|
||||
Reference in New Issue
Block a user