From aaa0d462865a8bb7c9d1475f6257598ae1fe148f Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Wed, 7 Jun 2023 13:26:19 -0400 Subject: [PATCH] update installer and add sd_model_dict --- extensions-builtin/sd-webui-agent-scheduler | 2 +- extensions-builtin/sd-webui-controlnet | 2 +- html/locale_en.json | 5 +- installer.py | 77 +++++++------------ launch.py | 54 +++++++------ modules/extensions.py | 2 +- modules/processing.py | 4 +- modules/sd_models.py | 32 +++++--- modules/shared.py | 5 +- .../textual_inversion/textual_inversion.py | 2 +- modules/ui.py | 4 +- modules/ui_extensions.py | 2 +- scripts/xyz_grid.py | 11 ++- webui.py | 9 ++- wiki | 2 +- 15 files changed, 110 insertions(+), 103 deletions(-) diff --git a/extensions-builtin/sd-webui-agent-scheduler b/extensions-builtin/sd-webui-agent-scheduler index 340102006..5c6cbdc5a 160000 --- a/extensions-builtin/sd-webui-agent-scheduler +++ b/extensions-builtin/sd-webui-agent-scheduler @@ -1 +1 @@ -Subproject commit 3401020066a20444594ec2902d95217b0cd95e94 +Subproject commit 5c6cbdc5ae78d5162b6753c9f5aad4a850ac3f83 diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet index 1b2aa4a96..99408b9f4 160000 --- a/extensions-builtin/sd-webui-controlnet +++ b/extensions-builtin/sd-webui-controlnet @@ -1 +1 @@ -Subproject commit 1b2aa4a96e9241b96abfbce249284ed17fc98b11 +Subproject commit 99408b9f4e514efdf33b19f3215ab661b989e209 diff --git a/html/locale_en.json b/html/locale_en.json index ed034d9eb..97572b593 100755 --- a/html/locale_en.json +++ b/html/locale_en.json @@ -256,9 +256,11 @@ {"id":"","label":"random","localized":"","hint":""} ], "settings": [ + {"id":"","label":"Stable Diffusion checkpoint","localized":"","hint":"Select model checkpoint to use"}, + {"id":"","label":"Stable Diffusion checkpoint dict","localized":"","hint":"Select model from which to extract dictionary only"}, {"id":"","label":"Number of cached model checkpoints","localized":"","hint":""}, {"id":"","label":"Number of cached VAE checkpoints","localized":"","hint":""}, - {"id":"","label":"Select VAE","localized":"","hint":""}, + {"id":"","label":"Select VAE","localized":"","hint":"Select variable auto-encoder to work with model when rendering images"}, {"id":"","label":"Enable splitting of hires batch processing","localized":"","hint":""}, {"id":"","label":"When loading models attempt stream loading optimized for slow or network storage","localized":"","hint":""}, {"id":"","label":"When loading models attempt to reuse previous model dictionary","localized":"","hint":""}, @@ -513,7 +515,6 @@ {"id":"","label":"Resize to ","localized":"","hint":""}, {"id":"","label":"Resize by ","localized":"","hint":""}, {"id":"","label":"Use via API ","localized":"","hint":""}, - {"id":"","label":"Stable Diffusion checkpoint","localized":"","hint":""}, {"id":"","label":"Styles","localized":"","hint":""}, {"id":"","label":"Put variable parts at start of prompt","localized":"","hint":""}, {"id":"","label":"Use different seed for each picture","localized":"","hint":""}, diff --git a/installer.py b/installer.py index f31c25106..2c2bb5da4 100644 --- a/installer.py +++ b/installer.py @@ -12,10 +12,6 @@ import cProfile import argparse import pkg_resources -try: - from modules.cmd_args import parser -except: - parser = argparse.ArgumentParser(description="SD.Next", conflict_handler='resolve', formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=55, indent_increment=2, width=200)) class Dot(dict): # dot notation access to dictionary attributes __getattr__ = dict.get @@ -69,8 +65,6 @@ def setup_logging(clean=False): "traceback.border.syntax_error": "black", "inspect.value.border": "black", })) - # logging.getLogger("urllib3").setLevel(logging.ERROR) - # logging.getLogger("httpx").setLevel(logging.ERROR) level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig(level=logging.ERROR, format='%(asctime)s | %(name)s | %(levelname)s | %(module)s | %(message)s', filename=log_file, filemode='a', encoding='utf-8', force=True) log.setLevel(logging.DEBUG) # log to file is always at level debug for facility `sd` @@ -81,6 +75,9 @@ def setup_logging(clean=False): while log.hasHandlers() and len(log.handlers) > 0: log.removeHandler(log.handlers[0]) log.addHandler(rh) + logging.getLogger("urllib3").setLevel(logging.ERROR) + logging.getLogger("httpx").setLevel(logging.ERROR) + logging.getLogger("ControlNet").handlers = log.handlers def print_profile(profile: cProfile.Profile, msg: str): @@ -351,7 +348,7 @@ def install_packages(): if args.profile: pr = cProfile.Profile() pr.enable() - log.info('Installing packages') + log.info('Verifying packages') # gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379") # openclip_package = os.environ.get('OPENCLIP_PACKAGE', "git+https://github.com/mlfoundations/open_clip.git@bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b") # install(gfpgan_package, 'gfpgan') @@ -593,6 +590,8 @@ def check_version(offline=False, reset=True): # pylint: disable=unused-argument log.info(f'Version: {ver}') if args.version: return + if args.skip_git: + return commit = git('rev-parse HEAD') global git_commit # pylint: disable=global-statement git_commit = commit[:7] @@ -673,7 +672,7 @@ def check_timestamp(): return ok -def add_args(): +def add_args(parser): group = parser.add_argument_group('Setup options') group.add_argument('--debug', default = False, action='store_true', help = "Run installer with debug logging, default: %(default)s") group.add_argument('--reset', default = False, action='store_true', help = "Reset main repository to latest version, default: %(default)s") @@ -696,44 +695,36 @@ def add_args(): group.add_argument('--base', default = False, action='store_true', help = argparse.SUPPRESS) -def parse_args(): +def parse_args(parser): # command line args global args # pylint: disable=global-statement args = parser.parse_args() + return args -def extensions_preload(force = False): +def extensions_preload(parser): if args.profile: pr = cProfile.Profile() pr.enable() - setup_time = 0 - if not force: - if os.path.isfile(log_file): - with open(log_file, 'r', encoding='utf8') as f: - lines = f.readlines() - for line in lines: - if 'Setup complete without errors' in line: - setup_time = int(line.split(' ')[-1]) - if setup_time > 0 or force: - # log.info('Running extension preloading') - if args.safe: - 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 - extension_folders = [extensions_builtin_dir] if args.safe else [extensions_builtin_dir, extensions_dir] - if args.base: - extension_folders = [] - for ext_dir in extension_folders: - t0 = time.time() - preload_extensions(ext_dir, parser) - t1 = time.time() - log.info(f'Extension preload: {round(t1 - t0, 1)}s {ext_dir}') - except: - log.error('Error running extension preloading') + if args.safe: + 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 + extension_folders = [extensions_builtin_dir] if args.safe else [extensions_builtin_dir, extensions_dir] + if args.base: + extension_folders = [] + for ext_dir in extension_folders: + t0 = time.time() + preload_extensions(ext_dir, parser) + t1 = time.time() + log.info(f'Extension preload: {round(t1 - t0, 1)}s {ext_dir}') + except: + log.error('Error running extension preloading') if args.profile: print_profile(pr, 'Preload') + def git_reset(): log.warning('Running GIT reset') global quick_allowed # pylint: disable=global-statement @@ -752,22 +743,13 @@ def read_options(): opts = json.load(file) -# entry method when used as module def run_setup(): - # setup_logging(args.upgrade) - log.info('Starting SD.Next') - check_python() if args.reset: git_reset() if args.skip_git: log.info('Skipping GIT operations') - check_version() - set_environment() if args.reinstall: log.info('Forcing reinstall of all packages') - check_torch() - install_requirements() - install_packages() if check_timestamp(): log.info('No changes detected: Quick launch active') return @@ -782,10 +764,3 @@ def run_setup(): else: log.warning(f'Setup complete with errors: {errors}') log.warning(f'See log file for more details: {log_file}') - - -if __name__ == "__main__": - add_args() - ensure_base_requirements() - parse_args() - run_setup() diff --git a/launch.py b/launch.py index bc00d111c..56ee77a0e 100644 --- a/launch.py +++ b/launch.py @@ -4,23 +4,15 @@ import time import shlex import logging import subprocess +import installer + commandline_args = os.environ.get('COMMANDLINE_ARGS', "") sys.argv += shlex.split(commandline_args) - -import installer -installer.ensure_base_requirements() -installer.add_args() -installer.parse_args() -installer.setup_logging(False) -installer.read_options() -installer.extensions_preload(force=False) - -import modules.cmd_args -args, _ = modules.cmd_args.parser.parse_known_args() -import modules.paths_internal -script_path = modules.paths_internal.script_path -extensions_dir = modules.paths_internal.extensions_dir +args = None +parser = None +script_path = None +extensions_dir = None git = os.environ.get('GIT', "git") index_url = os.environ.get('INDEX_URL', "") stored_commit_hash = None @@ -29,6 +21,17 @@ python = sys.executable # used by some extensions to run python skip_install = False # parsed by some extensions +def init_modules(): + global parser, args, script_path, extensions_dir # pylint: disable=global-statement + import modules.cmd_args + 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 + + def commit_hash(): # compatbility function global stored_commit_hash # pylint: disable=global-statement if stored_commit_hash is not None: @@ -134,17 +137,22 @@ def start_server(immediate=True, server=None): if __name__ == "__main__": - if args.version: - installer.add_args() - installer.log.info('SD.Next version information') - installer.check_python() - installer.check_version() - installer.check_torch() - exit(0) + installer.ensure_base_requirements() + init_modules() # setup argparser and default folders + installer.args = args + installer.setup_logging(False) + installer.log.info('Starting SD.Next') + installer.check_python() + installer.check_version() + installer.set_environment() + installer.check_torch() + installer.install_requirements() + installer.install_packages() + installer.extensions_preload(parser) # adds additional args from extensions + args = installer.parse_args(parser) + installer.read_options() installer.run_setup() - installer.extensions_preload(force=True) installer.log.info(f"Server arguments: {sys.argv[1:]}") - installer.log.debug('Starting WebUI') logging.disable(logging.NOTSET if args.debug else logging.DEBUG) instance = start_server(immediate=True, server=None) diff --git a/modules/extensions.py b/modules/extensions.py index f5a5f39bf..65474592b 100644 --- a/modules/extensions.py +++ b/modules/extensions.py @@ -139,7 +139,7 @@ def list_extensions(): shared.log.info(f'Skipping conflicting extension: {path}') continue extension_names.append(extension_dirname) - extension_paths.append((extension_dirname, path, dirname == dirname)) + extension_paths.append((extension_dirname, path, dirname == extensions_builtin_dir)) for dirname, path, is_builtin in extension_paths: extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin) extensions.append(extension) diff --git a/modules/processing.py b/modules/processing.py index 2fa263887..4edef3350 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -933,7 +933,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing): image_conditioning = self.img2img_image_conditioning(decoded_samples, samples) shared.state.nextjob() img2img_sampler_name = self.sampler_name - force_latent_upscaler = shared.opts.data.get('xyz_fallback_sampler') + force_latent_upscaler = shared.opts.data.get('force_latent_sampler') if force_latent_upscaler != 'None' and force_latent_upscaler != 'PLMS': img2img_sampler_name = force_latent_upscaler if img2img_sampler_name == 'PLMS': @@ -981,7 +981,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing): self.image_conditioning = None def init(self, all_prompts, all_seeds, all_subseeds): - force_latent_upscaler = shared.opts.data.get('xyz_fallback_sampler') + force_latent_upscaler = shared.opts.data.get('force_latent_sampler') if self.sampler_name in ['PLMS']: self.sampler_name = force_latent_upscaler if force_latent_upscaler != 'None' else shared.opts.fallback_sampler # PLMS does not support img2img, use fallback instead self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model) diff --git a/modules/sd_models.py b/modules/sd_models.py index feebec737..54359b76d 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -190,8 +190,8 @@ def model_hash(filename): return 'NOHASH' -def select_checkpoint(): - model_checkpoint = shared.opts.sd_model_checkpoint +def select_checkpoint(model=True): + model_checkpoint = shared.opts.sd_model_checkpoint if model else shared.opts.sd_model_dict checkpoint_info = checkpoint_aliases.get(model_checkpoint, None) if checkpoint_info is not None: shared.log.debug(f'Select checkpoint: {checkpoint_info.title if checkpoint_info is not None else None}') @@ -300,7 +300,8 @@ def load_model_weights(model: torch.nn.Module, checkpoint_info: CheckpointInfo, shared.log.debug(f'Model weights loading: {memory_stats()}') sd_model_hash = checkpoint_info.calculate_shorthash() timer.record("hash") - shared.opts.data["sd_model_checkpoint"] = checkpoint_info.title + if model_data.sd_dict == 'None': + shared.opts.data["sd_model_checkpoint"] = checkpoint_info.title if state_dict is None: state_dict = get_checkpoint_state_dict(checkpoint_info, timer) model.load_state_dict(state_dict, strict=False) @@ -398,6 +399,7 @@ sd2_clip_weight = 'cond_stage_model.model.transformer.resblocks.0.attn.in_proj_w class SdModelData: def __init__(self): self.sd_model = None + self.sd_dict = 'None' self.initial = True self.lock = threading.Lock() @@ -406,7 +408,7 @@ class SdModelData: with self.lock: try: if shared.backend == shared.Backend.ORIGINAL: - load_model() + reload_model_weights() elif shared.backend == shared.Backend.DIFFUSERS: load_diffuser() else: @@ -552,15 +554,21 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None) shared.log.info(f'Model load finished: {memory_stats()}') -def reload_model_weights(sd_model=None, info=None): +def reload_model_weights(sd_model=None, info=None, reuse_dict=False): + load_dict = shared.opts.sd_model_dict != model_data.sd_dict global skip_next_load # pylint: disable=global-statement if skip_next_load: shared.log.debug('Reload model weights skip') skip_next_load = False return - shared.log.debug(f'Reload model weights: {sd_model is not None} {info}') from modules import lowvram, sd_hijack - checkpoint_info = info or select_checkpoint() + checkpoint_info = info or select_checkpoint(model=not load_dict) # are we selecting model or dictionary + next_checkpoint_info = info or select_checkpoint(model=load_dict) if load_dict else None + if load_dict: + shared.log.debug(f'Model dict: existing={sd_model is not None} target={checkpoint_info.filename} info={info}') + else: + model_data.sd_dict = 'None' + shared.log.debug(f'Reload model weights: existing={sd_model is not None} target={checkpoint_info.filename} info={info}') if not sd_model: sd_model = model_data.sd_model if sd_model is None: # previous model load failed @@ -573,7 +581,7 @@ def reload_model_weights(sd_model=None, info=None): lowvram.send_everything_to_cpu() else: sd_model.to(devices.cpu) - if shared.opts.model_reuse_dict and sd_model is not None: + if reuse_dict or (shared.opts.model_reuse_dict and sd_model is not None): shared.log.info('Reusing previous model dictionary') sd_hijack.model_hijack.undo_hijack(sd_model) else: @@ -590,6 +598,10 @@ def reload_model_weights(sd_model=None, info=None): load_model(checkpoint_info, already_loaded_state_dict=state_dict, timer=timer) else: load_diffuser(checkpoint_info, already_loaded_state_dict=state_dict, timer=timer) + if load_dict and next_checkpoint_info is not None: + model_data.sd_dict = shared.opts.sd_model_dict + shared.opts.data["sd_model_checkpoint"] = next_checkpoint_info.title + reload_model_weights(reuse_dict=True) # ok we loaded dict now lets redo and load model on top of it return model_data.sd_model try: load_model_weights(sd_model, checkpoint_info, state_dict, timer) @@ -615,8 +627,8 @@ def unload_model_weights(sd_model=None, _info=None): sd_hijack.model_hijack.undo_hijack(model_data.sd_model) model_data.sd_model = None sd_model = None - devices.torch_gc(force=True) - shared.log.debug(f'Model weights unloaded: {memory_stats()}') + devices.torch_gc(force=True) + shared.log.debug(f'Model weights unloaded: {memory_stats()}') return sd_model diff --git a/modules/shared.py b/modules/shared.py index ceab41342..58c7f6ab4 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -291,6 +291,7 @@ options_templates.update(options_section(('sd', "Stable Diffusion"), { "sd_checkpoint_cache": OptionInfo(0, "Number of cached model checkpoints", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}), "sd_vae_checkpoint_cache": OptionInfo(0, "Number of cached VAE checkpoints", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}), "sd_vae": OptionInfo("Automatic", "Select VAE", gr.Dropdown, lambda: {"choices": shared_items.sd_vae_items()}, refresh=shared_items.refresh_vae_list), + "sd_model_dict": OptionInfo('None', "Stable Diffusion checkpoint dict", gr.Dropdown, lambda: {"choices": ['None'] + list_checkpoint_tiles()}, refresh=refresh_checkpoints), "sd_vae_sliced_encode": OptionInfo(False, "Enable splitting of hires batch processing"), "stream_load": OptionInfo(False, "When loading models attempt stream loading optimized for slow or network storage"), "model_reuse_dict": OptionInfo(False, "When loading models attempt to reuse previous model dictionary"), @@ -440,7 +441,7 @@ options_templates.update(options_section(('ui', "Live previews"), { options_templates.update(options_section(('sampler-params', "Sampler Settings"), { "show_samplers": OptionInfo(["Euler a", "UniPC", "DDIM", "DPM++ 2M SDE", "DPM++ 2M SDE Karras", "DPM2 Karras", "DPM++ 2M Karras"], "Show samplers in user interface", gr.CheckboxGroup, lambda: {"choices": [x.name for x in list_samplers() if x.name != "PLMS"]}), "fallback_sampler": OptionInfo("Euler a", "Secondary sampler", gr.Dropdown, lambda: {"choices": ["None"] + [x.name for x in list_samplers()]}), - "xyz_fallback_sampler": OptionInfo("None", "Force latent upscaler sampler", gr.Dropdown, lambda: {"choices": ["None"] + [x.name for x in list_samplers()]}), + "force_latent_sampler": OptionInfo("None", "Force latent upscaler sampler", gr.Dropdown, lambda: {"choices": ["None"] + [x.name for x in list_samplers()]}), "eta_ancestral": OptionInfo(1.0, "Noise multiplier for ancestral samplers (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), "eta_ddim": OptionInfo(0.0, "Noise multiplier for DDIM (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), "ddim_discretize": OptionInfo('uniform', "DDIM discretize img2img", gr.Radio, {"choices": ['uniform', 'quad']}), @@ -504,7 +505,7 @@ options_templates.update(options_section(('upscaling', "Upscaling"), { })) options_templates.update(options_section(('lora', "Lora"), { - "lyco_patch_lora": OptionInfo(False, "Use LyCoris handler for all Lora types", gr.Checkbox, { "visible": True }), # TODO: lyco-patch-lora + "lyco_patch_lora": OptionInfo(False, "Use LyCoris handler for all Lora types", gr.Checkbox, { "visible": True }), "lora_disable": OptionInfo(False, "Disable built-in Lora handler", gr.Checkbox, { "visible": True }, onchange=lora_disable), "lora_functional": OptionInfo(False, "Use Kohya method for handling multiple Loras", gr.Checkbox, { "visible": True }), })) diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py index 3025bd864..e09adc184 100644 --- a/modules/textual_inversion/textual_inversion.py +++ b/modules/textual_inversion/textual_inversion.py @@ -243,7 +243,7 @@ class EmbeddingDatabase: self.previously_displayed_embeddings = displayed_embeddings shared.log.info(f"Embeddings loaded: {len(self.word_embeddings)} {[k for k in self.word_embeddings.keys()]}") if len(self.skipped_embeddings) > 0: - shared.log.info(f"Textual inversion embeddings skipped({len(self.skipped_embeddings)}): {', '.join(self.skipped_embeddings.keys())}") + shared.log.info(f"Embeddings skipped: {len(self.skipped_embeddings)} {[k for k in self.skipped_embeddings.keys()]}") def find_embedding_at_position(self, tokens, offset): token = tokens[offset] diff --git a/modules/ui.py b/modules/ui.py index 572f0aaad..03423064e 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -1638,7 +1638,7 @@ def html_head(): head += f'\n' added.append(script.path) added = [a.replace(script_path, '').replace('\\', '/') for a in added] - modules.shared.log.debug(f'Adding JS scripts: {added}') + # modules.shared.log.debug(f'Adding JS scripts: {added}') return head @@ -1671,7 +1671,7 @@ def html_css(): if os.path.exists(os.path.join(data_path, "user.css")): head += stylesheet(os.path.join(data_path, "user.css")) added = [a.replace(script_path, '').replace('\\', '/') for a in added] - modules.shared.log.debug(f'Adding CSS stylesheets: {added}') + # modules.shared.log.debug(f'Adding CSS stylesheets: {added}') return head diff --git a/modules/ui_extensions.py b/modules/ui_extensions.py index 58342e410..6e6124119 100644 --- a/modules/ui_extensions.py +++ b/modules/ui_extensions.py @@ -261,7 +261,7 @@ def search_extensions(search_text, sort_column): def refresh_extensions_list_from_data(search_text, sort_column): - shared.log.debug(f'Extensions manager: refresh list search="{search_text}" sort="{sort_column}"') + # shared.log.debug(f'Extensions manager: refresh list search="{search_text}" sort="{sort_column}"') code = """ diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py index 0175d07a0..c3025d0d6 100644 --- a/scripts/xyz_grid.py +++ b/scripts/xyz_grid.py @@ -121,7 +121,7 @@ def apply_fallback(p, x, xs): if sampler_name is None: shared.log.warning(f"XYZ grid: unknown sampler: {x}") else: - shared.opts.data["xyz_fallback_sampler"] = sampler_name + shared.opts.data["force_latent_sampler"] = sampler_name def apply_uni_pc_order(p, x, xs): @@ -209,6 +209,7 @@ axis_options = [ AxisOption("Nothing", str, do_nothing, fmt=format_nothing), AxisOption("Checkpoint name", str, apply_checkpoint, fmt=format_value, confirm=confirm_checkpoints, cost=1.0, choices=lambda: list(sd_models.checkpoints_list)), AxisOption("VAE", str, apply_vae, cost=0.7, choices=lambda: ['None'] + list(sd_vae.vae_dict)), + AxisOption("Dict name", str, apply_checkpoint, fmt=format_value, confirm=confirm_checkpoints, cost=1.0, choices=lambda: ['None'] + list(sd_models.checkpoints_list)), AxisOption("Prompt S/R", str, apply_prompt, fmt=format_value), AxisOption("Styles", str, apply_styles, choices=lambda: list(shared.prompt_styles.styles)), AxisOptionTxt2Img("Sampler", str, apply_sampler, fmt=format_value, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.samplers]), @@ -351,8 +352,9 @@ class SharedSettingsStackHelper(object): self.token_merging_ratio = shared.opts.token_merging_ratio self.token_merging_random = shared.opts.token_merging_random self.sd_model_checkpoint = shared.opts.sd_model_checkpoint + self.sd_model_dict = shared.opts.sd_model_dict self.sd_vae_checkpoint = shared.opts.sd_vae - self.xyz_fallback_sampler = shared.opts.xyz_fallback_sampler + self.force_latent_sampler = shared.opts.force_latent_sampler def __exit__(self, exc_type, exc_value, tb): #Restore overriden settings after plot generation. @@ -361,8 +363,9 @@ class SharedSettingsStackHelper(object): shared.opts.data["token_merging_ratio_hr"] = self.token_merging_ratio_hr shared.opts.data["token_merging_ratio"] = self.token_merging_ratio shared.opts.data["token_merging_random"] = self.token_merging_random - shared.opts.data["xyz_fallback_sampler"] = self.xyz_fallback_sampler - if self.sd_model_checkpoint != shared.opts.sd_model_checkpoint: + shared.opts.data["force_latent_sampler"] = self.force_latent_sampler + if (self.sd_model_checkpoint != shared.opts.sd_model_checkpoint) or (self.sd_model_dict != shared.opts.sd_model_dict): + shared.opts.data["sd_model_dict"] = self.sd_model_dict shared.opts.data["sd_model_checkpoint"] = self.sd_model_checkpoint sd_models.reload_model_weights() if self.sd_vae_checkpoint != shared.opts.sd_vae: diff --git a/webui.py b/webui.py index 6b2151a17..84f4aefc9 100644 --- a/webui.py +++ b/webui.py @@ -85,7 +85,7 @@ def check_rollback_vae(): def initialize(): - log.debug('Entering Initialize') + log.debug('Entering initialize') check_rollback_vae() modules.sd_vae.refresh_vae_list() @@ -104,6 +104,7 @@ def initialize(): gfpgan.setup_model(opts.gfpgan_models_path) startup_timer.record("gfpgan") + log.debug('Loading scripts') modules.scripts.load_scripts() startup_timer.record("scripts") @@ -157,6 +158,7 @@ def load_model(): else: 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()), call=False) + shared.opts.onchange("sd_model_dict", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()), call=False) shared.state.end() startup_timer.record("checkpoint") @@ -282,6 +284,11 @@ def webui(): start_ui() load_model() log.info(f"Startup time: {startup_timer.summary()}") + + # override all loggers to use the same handlers as the main logger + for logger in [logging.getLogger(name) for name in logging.root.manager.loggerDict]: # pylint: disable=no-member + logger.handlers = log.handlers + if cmd_opts.autolaunch and local_url is not None: cmd_opts.autolaunch = False shared.log.info('Launching browser') diff --git a/wiki b/wiki index d420606fc..d54b7fd3b 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit d420606fc4f9735aa0a4d31f6e5ef18429508ab9 +Subproject commit d54b7fd3be2783cec8f17e73b453d1d59820a3a8