improve error handling

This commit is contained in:
Vladimir Mandic
2023-03-26 21:50:15 -04:00
parent f25dd739f2
commit 6fe6eff9b4
9 changed files with 59 additions and 81 deletions
+10 -4
View File
@@ -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
+2 -2
View File
@@ -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({
+1 -32
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2
View File
@@ -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)
+2 -2
View File
@@ -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; }
+3 -1
View File
@@ -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()