From a16eee1504173aae2052b850702b6297e41e0500 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Sun, 9 Jul 2023 10:05:42 -0400 Subject: [PATCH] bugfix release --- CHANGELOG.md | 6 ++++++ TODO.md | 1 + extensions-builtin/a1111-sd-webui-lycoris | 2 +- extensions-builtin/sd-webui-controlnet | 2 +- javascript/imageViewer.js | 4 +--- modules/modelloader.py | 10 ++++++++-- modules/paths.py | 12 +++++------- modules/processing.py | 16 ++++++++-------- modules/sd_models.py | 2 +- modules/shared.py | 2 ++ modules/ui_extra_networks.py | 9 ++++----- modules/ui_models.py | 21 +++++++++++++++------ wiki | 2 +- 13 files changed, 54 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04f990a1b..d86b90f49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log for SD.Next +- fix startup issue with incorrect config +- image viewer: fixes for non-chromium browsers +- extra network: fix corrupt display on refesh when new extra network type found +- diffusers: option to move base and/or refiner model to cpu to free up vram +- diffusers: model downloader options to specify model variant/revision/mirror + ## Update for 07/08/2023 This is a massive update which has been baking in a `dev` branch for a while now diff --git a/TODO.md b/TODO.md index 8d5b1a975..bd0c322bb 100644 --- a/TODO.md +++ b/TODO.md @@ -64,3 +64,4 @@ Tech that can be integrated as part of the core workflow... - `git submodule set-url extensions-builtin/clip-interrogator-ext https://github.com/Dahvikiin/clip-interrogator-ext.git` - upate `gradio` - extra network refresh breaks if new extra network type found +- [sd-xl lora](https://civitai.com/models/104913/fcstyledxl) diff --git a/extensions-builtin/a1111-sd-webui-lycoris b/extensions-builtin/a1111-sd-webui-lycoris index 025dea967..8e97bf548 160000 --- a/extensions-builtin/a1111-sd-webui-lycoris +++ b/extensions-builtin/a1111-sd-webui-lycoris @@ -1 +1 @@ -Subproject commit 025dea96720197dd4486a5bb8e2f4d72a95a3088 +Subproject commit 8e97bf54867c25d00fc480be1ab4dae5399b35ef diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet index dd766de86..07bed6ccf 160000 --- a/extensions-builtin/sd-webui-controlnet +++ b/extensions-builtin/sd-webui-controlnet @@ -1 +1 @@ -Subproject commit dd766de8629ee6035a734217e08c26cd1b08b2ab +Subproject commit 07bed6ccf8a468a45b2833cfdadc749927cbd575 diff --git a/javascript/imageViewer.js b/javascript/imageViewer.js index 5876678de..9ff7d8cfc 100644 --- a/javascript/imageViewer.js +++ b/javascript/imageViewer.js @@ -194,7 +194,7 @@ document.addEventListener('DOMContentLoaded', () => { modalImage.tabIndex = 0; modalImage.addEventListener('keydown', modalKeyHandler, true); modalPreviewZone.appendChild(modalImage); - modalImage.onload = () => panzoom(modalImage, { zoomSpeed: 0.025, minZoom: 0.25, maxZoom: 4.0 }); + modalImage.onload = () => panzoom(modalImage, { zoomSpeed: 0.05, minZoom: 0.25, maxZoom: 4.0 }); let drag = false; modalPreviewZone.addEventListener('mousedown', () => drag = false); @@ -209,7 +209,6 @@ document.addEventListener('DOMContentLoaded', () => { modalPrev.addEventListener('click', modalPrevImage, true); modalPrev.addEventListener('keydown', modalKeyHandler, true); modal.appendChild(modalPrev); - modal.appendChild(modalPreviewZone); const modalNext = document.createElement('a'); @@ -218,7 +217,6 @@ document.addEventListener('DOMContentLoaded', () => { modalNext.tabIndex = 0; modalNext.addEventListener('click', modalNextImage, true); modalNext.addEventListener('keydown', modalKeyHandler, true); - modal.appendChild(modalNext); try { gradioApp().appendChild(modal); } catch (e) { gradioApp().body.appendChild(modal); } diff --git a/modules/modelloader.py b/modules/modelloader.py index a2d616b01..0be018e38 100644 --- a/modules/modelloader.py +++ b/modules/modelloader.py @@ -12,7 +12,7 @@ from modules.paths import script_path, models_path diffuser_repos = [] -def download_diffusers_model(hub_id: str, cache_dir: str = None, download_config: Dict[str, str] = None, token = None): +def download_diffusers_model(hub_id: str, cache_dir: str = None, download_config: Dict[str, str] = None, token = None, variant = None, revision = None, mirror = None): from diffusers import DiffusionPipeline import huggingface_hub as hf @@ -25,7 +25,13 @@ def download_diffusers_model(hub_id: str, cache_dir: str = None, download_config } if cache_dir is not None: download_config["cache_dir"] = cache_dir - shared.log.debug(f"Diffusers downloading: {hub_id} to {cache_dir}") + if variant is not None and len(variant) > 0: + download_config["variant"] = variant + if revision is not None and len(revision) > 0: + download_config["revision"] = revision + if mirror is not None and len(mirror) > 0: + download_config["mirror"] = mirror + shared.log.debug(f"Diffusers downloading: {hub_id} {download_config}") if token is not None and len(token) > 2: shared.log.debug(f"Diffusers authentication: {token}") hf.login(token) diff --git a/modules/paths.py b/modules/paths.py index 966349580..e12e4a672 100644 --- a/modules/paths.py +++ b/modules/paths.py @@ -61,14 +61,12 @@ def create_paths(opts): pass def fix_path(folder): - if opts.data[folder] is None or opts.data[folder] == '': - return opts.data[folder] - if os.path.isabs(opts.data[folder]): - return opts.data[folder] - if opts.data[folder].startswith(data_path): - return opts.data[folder] + if opts.data.get(folder, None) is None or opts.data[folder] is None or opts.data[folder] == '': + return + if os.path.isabs(opts.data[folder]) or opts.data[folder].startswith(data_path): + return opts.data[folder] = os.path.join(data_path, opts.data[folder]) - return opts.data[folder] + return create_path(fix_path('temp_dir')) create_path(extensions_dir) diff --git a/modules/processing.py b/modules/processing.py index 4854a1c31..0b664b34d 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -712,7 +712,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: shared.state.current_latent = latents shared.state.set_current_image() - # shared.sd_model.to(devices.device) + shared.sd_model.to(devices.device) output = shared.sd_model( # pylint: disable=not-callable prompt=prompts, negative_prompt=negative_prompts, @@ -725,12 +725,12 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: cross_attention_kwargs=cross_attention_kwargs, **task_specific_kwargs ) - # if shared.cmd_opts.lowvram or shared.cmd_opts.medvram: - # shared.sd_model.to('cpu') - # devices.torch_gc(force=True) if shared.sd_refiner is not None: - # shared.sd_refiner.to(devices.device) + if shared.opts.diffusers_move_base: + shared.log.debug('Moving base model to CPU') + shared.sd_model.to('cpu') + shared.sd_refiner.to(devices.device) devices.torch_gc() init_image = output.images[0] output = shared.sd_refiner( # pylint: disable=not-callable @@ -745,9 +745,9 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: cross_attention_kwargs=cross_attention_kwargs, image=init_image ) - # if shared.cmd_opts.lowvram or shared.cmd_opts.medvram: - # shared.sd_refiner.to('cpu') - # devices.torch_gc(force=True) + if shared.opts.diffusers_move_refiner: + shared.log.debug('Moving refiner model to CPU') + shared.sd_refiner.to('cpu') x_samples_ddim = output.images diff --git a/modules/sd_models.py b/modules/sd_models.py index f54132378..152c51ce4 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -718,7 +718,7 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No shared.log.info("Model compile enabled: IPEX Optimize Graph Mode") sd_model.unet.training = False sd_model.to(devices.device) - sd_model.unet = torch.xpu.optimize(sd_model.unet, dtype=devices.dtype, auto_kernel_selection=True, optimize_lstm=True, + sd_model.unet = torch.xpu.optimize(sd_model.unet, dtype=devices.dtype, auto_kernel_selection=True, optimize_lstm=True, # pylint: disable=attribute-defined-outside-init graph_mode=True if shared.opts.cuda_compile and shared.opts.cuda_compile_mode == 'ipex' else False) shared.log.info("Applied IPEX Optimize") if shared.opts.cuda_compile and torch.cuda.is_available(): diff --git a/modules/shared.py b/modules/shared.py index a1b4aead6..d01415a5f 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -361,6 +361,8 @@ options_templates.update(options_section(('cuda', "Compute Settings"), { options_templates.update(options_section(('diffusers', "Diffusers Settings"), { "diffusers_allow_safetensors": OptionInfo(False, 'Diffusers allow loading from safetensors files'), "diffusers_pipeline": OptionInfo(pipelines[0], 'Select diffuser pipeline when loading from safetensors', gr.Dropdown, lambda: {"choices": pipelines}), + "diffusers_move_base": OptionInfo(False, "Move base model to CPU when using refiner"), + "diffusers_move_refiner": OptionInfo(True, "Move refiner model to CPU when not in use"), "diffusers_extract_ema": OptionInfo(True, "Use model EMA weights when possible"), "diffusers_generator_device": OptionInfo("default", "Generator device", gr.Radio, lambda: {"choices": ["default", "cpu"]}), "diffusers_seq_cpu_offload": OptionInfo(False, "Enable sequential CPU offload"), diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index e2756917c..73bc2b1c0 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -316,11 +316,10 @@ def create_ui(container, button, tabname, skip_indexing = False): for page in ui.stored_extra_pages: page_html = page.create_html(ui.tabname, skip_indexing) - if len(page_html) > 0: - with gr.Tab(page.title, id=page.title.lower().replace(" ", "_"), elem_classes="extra-networks-tab"): - page_elem = gr.HTML(page_html, elem_id=tabname+page.name+"_extra_page", elem_classes="extra-networks-page") - page_elem.change(fn=lambda: None, _js=f'() => refreshExtraNetworks("{tabname}")', inputs=[], outputs=[]) - ui.pages.append(page_elem) + with gr.Tab(page.title, id=page.title.lower().replace(" ", "_"), elem_classes="extra-networks-tab"): + page_elem = gr.HTML(page_html, elem_id=tabname+page.name+"_extra_page", elem_classes="extra-networks-page") + page_elem.change(fn=lambda: None, _js=f'() => refreshExtraNetworks("{tabname}")', inputs=[], outputs=[]) + ui.pages.append(page_elem) def toggle_visibility(is_visible): is_visible = not is_visible diff --git a/modules/ui_models.py b/modules/ui_models.py index 592fb2e08..bd8eb2cbf 100644 --- a/modules/ui_models.py +++ b/modules/ui_models.py @@ -3,9 +3,10 @@ import json from datetime import datetime import gradio as gr from modules import sd_models, sd_vae, extras -from modules.ui_components import FormRow +from modules.ui_components import FormRow, ToolButton from modules.ui_common import create_refresh_button from modules.call_queue import wrap_gradio_gpu_call +from modules.shared import opts, log import modules.errors @@ -187,11 +188,10 @@ def create_ui(): def hf_select(evt: gr.SelectData, data): return data[evt.index[0]][0] - def hf_download_model(hub_id: str, token): - from modules.shared import log, opts + def hf_download_model(hub_id: str, token, variant, revision, mirror): from modules.modelloader import download_diffusers_model try: - download_diffusers_model(hub_id, cache_dir=opts.diffusers_dir, token=token) + download_diffusers_model(hub_id, cache_dir=opts.diffusers_dir, token=token, variant=variant, revision=revision, mirror=mirror) except Exception as e: log.error(f"Diffuser model downloaded error: model={hub_id} {e}") return f"Diffuser model downloaded error: model={hub_id} {e}" @@ -203,10 +203,18 @@ def create_ui(): with gr.Column(scale=6): with gr.Row(): hf_search_text = gr.Textbox('', label = 'Seach models', placeholder='search huggingface models') + hf_search_btn = ToolButton(value="🔍", label="Search") with gr.Row(): - hf_selected = gr.Textbox('', label = 'Select model', placeholder='select model from search results or enter model name manually') + with gr.Column(scale=2): + with gr.Row(): + hf_selected = gr.Textbox('', label = 'Select model', placeholder='select model from search results or enter model name manually') + with gr.Column(scale=1): + with gr.Row(): + hf_variant = gr.Textbox(opts.cuda_dtype.lower(), label = 'Specify model variant', placeholder='') + hf_revision = gr.Textbox('', label = 'Specify model revision', placeholder='') with gr.Row(): hf_token = gr.Textbox('', label = 'Huggingface token', placeholder='optional access token for private or gated models') + hf_mirror = gr.Textbox('', label = 'Huggingface mirror', placeholder='optional mirror site for downloads') with gr.Column(scale=1): hf_download_model_btn = gr.Button(value="Download model", variant='primary') @@ -216,8 +224,9 @@ def create_ui(): hf_results = gr.DataFrame([], label = 'Search results', show_label = True, interactive = False, wrap = True, overflow_row_behaviour = 'paginate', max_rows = 10, headers = hf_headers, datatype = hf_types, type='array') hf_search_text.submit(fn=hf_search, inputs=[hf_search_text], outputs=[hf_results]) + hf_search_btn.click(fn=hf_search, inputs=[hf_search_text], outputs=[hf_results]) hf_results.select(fn=hf_select, inputs=[hf_results], outputs=[hf_selected]) - hf_download_model_btn.click(fn=hf_download_model, inputs=[hf_selected, hf_token], outputs=[models_outcome]) + hf_download_model_btn.click(fn=hf_download_model, inputs=[hf_selected, hf_token, hf_variant, hf_revision, hf_mirror], outputs=[models_outcome]) # with gr.Tab(label="CivitAI"): # pass diff --git a/wiki b/wiki index a132c4fcf..70797fa69 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit a132c4fcffc88038614b8571acf9bd38df1a6c01 +Subproject commit 70797fa694107fc31554b1215839db0dca5998fd