From 290bfc8b41577722fd58e053b98a729fb5d162d2 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Thu, 15 Feb 2024 08:03:24 -0500 Subject: [PATCH] fix hijack and update script layout --- javascript/sdnext.css | 3 ++- modules/gr_hijack.py | 6 +++++- modules/patches.py | 9 ++++++--- modules/scripts.py | 6 +++--- modules/theme.py | 7 ++----- modules/ui.py | 4 ++-- modules/ui_extra_networks_checkpoints.py | 3 --- modules/ui_javascript.py | 2 +- scripts/demofusion.py | 12 +++++++----- scripts/mixture_tiling.py | 2 +- scripts/prompt_matrix.py | 18 +++++++++--------- scripts/prompts_from_file.py | 2 ++ scripts/regional_prompting.py | 2 +- scripts/text2video.py | 2 ++ scripts/xyz_grid.py | 2 ++ 15 files changed, 45 insertions(+), 35 deletions(-) diff --git a/javascript/sdnext.css b/javascript/sdnext.css index dd8ff6d35..5eddb7007 100644 --- a/javascript/sdnext.css +++ b/javascript/sdnext.css @@ -54,7 +54,8 @@ input[type='color'] { width: 64px; height: 32px; } .small-accordion .label-wrap .icon { margin-right: 1em; margin-left: 0.3em; color: var(--button-primary-border-color); } .small-accordion .label-wrap { padding: 16px 0px 8px 0px; margin: 0; border-top: 2px solid var(--button-secondary-border-color); } .small-accordion { width: fit-content !important; min-width: fit-content !important; padding-left: 0 !important; } -.extension-script { max-width: 48vw; } +.group-exetensions { max-width: 48vw; } +.group-scripts { max-width: 48vw; margin-top: 1em; padding-top: 0.5em; border-top: 2px solid var(--button-secondary-border-color) !important; } button.custom-button{ border-radius: var(--button-large-radius); padding: var(--button-large-padding); font-weight: var(--button-large-text-weight); border: var(--button-border-width) solid var(--button-secondary-border-color); background: var(--button-secondary-background-fill); color: var(--button-secondary-text-color); font-size: var(--text-lg); display: inline-flex; justify-content: center; align-items: center; transition: var(--button-transition); box-shadow: var(--button-shadow); text-align: center; } diff --git a/modules/gr_hijack.py b/modules/gr_hijack.py index 731481d98..b6de12e0c 100644 --- a/modules/gr_hijack.py +++ b/modules/gr_hijack.py @@ -4,6 +4,7 @@ import gradio.processing_utils from modules import scripts, patches, gr_tempdir +hijacked = False original_IOComponent_init = None original_Block_get_config = None original_BlockContext_init = None @@ -84,10 +85,13 @@ def Blocks_get_config_file(self, *args, **kwargs): def init(): - global original_IOComponent_init, original_Block_get_config, original_BlockContext_init, original_Blocks_get_config_file # pylint: disable=global-statement + global hijacked, original_IOComponent_init, original_Block_get_config, original_BlockContext_init, original_Blocks_get_config_file # pylint: disable=global-statement + if hijacked: + return gr.components.Image.preprocess = gr_image_preprocess gr.components.IOComponent.pil_to_temp_file = gr_tempdir.pil_to_temp_file original_IOComponent_init = patches.patch(__name__, obj=gr.components.IOComponent, field="__init__", replacement=IOComponent_init) original_Block_get_config = patches.patch(__name__, obj=gr.blocks.Block, field="get_config", replacement=Block_get_config) original_BlockContext_init = patches.patch(__name__, obj=gr.blocks.BlockContext, field="__init__", replacement=BlockContext_init) original_Blocks_get_config_file = patches.patch(__name__, obj=gr.blocks.Blocks, field="get_config_file", replacement=Blocks_get_config_file) + hijacked = True diff --git a/modules/patches.py b/modules/patches.py index 5305b6fab..4539180a3 100644 --- a/modules/patches.py +++ b/modules/patches.py @@ -1,5 +1,6 @@ from collections import defaultdict from typing import Optional +from modules.errors import log def patch(key, obj, field, replacement, add_if_not_exists:bool = False): @@ -16,9 +17,10 @@ def patch(key, obj, field, replacement, add_if_not_exists:bool = False): """ patch_key = (obj, field) if patch_key in originals[key]: - raise RuntimeError(f"patch for {field} is already applied") + log.error(f"Patch already applied: field={field}") if not hasattr(obj, field) and not add_if_not_exists: - raise AttributeError(f"type {type(obj)} '{type.__name__}' has no attribute '{field}'") + log.error(f"Patch no attribute: type={type(obj)} name='{type.__name__}' fiel'{field}'") + return None original_func = getattr(obj, field, None) originals[key][patch_key] = original_func setattr(obj, field, replacement) @@ -37,7 +39,8 @@ def undo(key, obj, field): """ patch_key = (obj, field) if patch_key not in originals[key]: - raise RuntimeError(f"there is no patch for {field} to undo") + log.error(f"Patch no patch to undo: field={field}") + return original_func = originals[key].pop(patch_key) if original_func is None: delattr(obj, field) diff --git a/modules/scripts.py b/modules/scripts.py index 9d82c8efe..4fc66de43 100644 --- a/modules/scripts.py +++ b/modules/scripts.py @@ -416,7 +416,7 @@ class ScriptRunner: if not script.standalone: continue t0 = time.time() - with gr.Group(elem_id=f'{parent}_script_{script.title().lower().replace(" ", "_")}', elem_classes=['extension-script']) as group: + with gr.Group(elem_id=f'{parent}_script_{script.title().lower().replace(" ", "_")}', elem_classes=['group-extension']) as group: create_script_ui(script, inputs, inputs_alwayson) script.group = group time_setup[script.title()] = time_setup.get(script.title(), 0) + (time.time()-t0) @@ -427,13 +427,13 @@ class ScriptRunner: if script.standalone: continue t0 = time.time() - with gr.Group(elem_id=f'{parent}_script_{script.title().lower().replace(" ", "_")}', elem_classes=['extension-script']) as group: + with gr.Group(elem_id=f'{parent}_script_{script.title().lower().replace(" ", "_")}', elem_classes=['group-extension']) as group: create_script_ui(script, inputs, inputs_alwayson) script.group = group time_setup[script.title()] = time_setup.get(script.title(), 0) + (time.time()-t0) for script in self.selectable_scripts: - with gr.Group(visible=False) as group: + with gr.Group(elem_id=f'{parent}_script_{script.title().lower().replace(" ", "_")}', elem_classes=['group-scripts'], visible=False) as group: t0 = time.time() create_script_ui(script, inputs, inputs_alwayson) time_setup[script.title()] = time_setup.get(script.title(), 0) + (time.time()-t0) diff --git a/modules/theme.py b/modules/theme.py index 50e9b9dc3..18d24f711 100644 --- a/modules/theme.py +++ b/modules/theme.py @@ -6,7 +6,6 @@ import modules.extensions gradio_theme = gr.themes.Base() -# modules.shared.opts.onchange("gradio_theme", reload_gradio_theme) def list_builtin_themes(): @@ -64,15 +63,13 @@ def reload_gradio_theme(theme_name=None): 'font':['Helvetica', 'ui-sans-serif', 'system-ui', 'sans-serif'], 'font_mono':['IBM Plex Mono', 'ui-monospace', 'Consolas', 'monospace'] } - is_builtin = theme_name.lower() in list_builtin_themes() - is_external = theme_name.lower() in ['lobe', 'modern'] base = 'base.css' - if is_builtin: + if theme_name.lower() in list_builtin_themes(): base = 'sdnext.css' gradio_theme = gr.themes.Base(**default_font_params) modules.shared.log.info(f'UI theme: name="{theme_name}" style={modules.shared.opts.theme_style} base={base}') return True - elif is_external: + elif theme_name.lower() in ['lobe', 'modern']: gradio_theme = gr.themes.Base(**default_font_params) modules.shared.log.info(f'UI theme: name="{theme_name}" style={modules.shared.opts.theme_style} base={base}') elif theme_name.startswith("gradio/"): diff --git a/modules/ui.py b/modules/ui.py index 343b59d6b..77f1cb41b 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -20,6 +20,8 @@ log = shared.log opts = shared.opts cmd_opts = shared.cmd_opts ui_system_tabs = None +paste_function = None +wrap_queued_call = call_queue.wrap_queued_call switch_values_symbol = ui_symbols.switch detect_image_size_symbol = ui_symbols.detect paste_symbol = ui_symbols.paste @@ -29,8 +31,6 @@ folder_symbol = ui_symbols.folder extra_networks_symbol = ui_symbols.networks apply_style_symbol = ui_symbols.apply save_style_symbol = ui_symbols.save -paste_function = None -wrap_queued_call = call_queue.wrap_queued_call gr_hijack.init() diff --git a/modules/ui_extra_networks_checkpoints.py b/modules/ui_extra_networks_checkpoints.py index eccb23e20..ab11f0f1d 100644 --- a/modules/ui_extra_networks_checkpoints.py +++ b/modules/ui_extra_networks_checkpoints.py @@ -64,9 +64,6 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage): return record def list_items(self): - import sys - shared.log.debug(f'List items: function={sys._getframe(1).f_code.co_name}') # pylint: disable=protected-access - # items = [self.create_item(cp) for cp in list(sd_models.checkpoints_list)] + list(self.list_reference()) items = [] with concurrent.futures.ThreadPoolExecutor(max_workers=shared.max_workers) as executor: future_items = {executor.submit(self.create_item, cp): cp for cp in list(sd_models.checkpoints_list.copy())} diff --git a/modules/ui_javascript.py b/modules/ui_javascript.py index 1e62318e4..0f8f12bea 100644 --- a/modules/ui_javascript.py +++ b/modules/ui_javascript.py @@ -56,7 +56,7 @@ def html_css(is_builtin: bool): if not os.path.isfile(cssfile): continue head += stylesheet(cssfile) - if shared.opts.gradio_theme in theme.list_builtin_themes(): + if shared.opts.gradio_theme in theme.list_builtin_themes() and os.path.exists(os.path.join(script_path, "javascript", f"{shared.opts.gradio_theme}.css")): head += stylesheet(os.path.join(script_path, "javascript", f"{shared.opts.gradio_theme}.css")) if os.path.exists(os.path.join(data_path, "user.css")): head += stylesheet(os.path.join(data_path, "user.css")) diff --git a/scripts/demofusion.py b/scripts/demofusion.py index 922918fd7..dd4f0b9d2 100644 --- a/scripts/demofusion.py +++ b/scripts/demofusion.py @@ -816,8 +816,8 @@ class DemoFusionSDXLPipeline(DiffusionPipeline, FromSingleFileMixin, LoraLoaderM if denoising_end is not None and isinstance(denoising_end, float) and denoising_end > 0 and denoising_end < 1: discrete_timestep_cutoff = int( round( - self.scheduler.config.num_train_timesteps - - (denoising_end * self.scheduler.config.num_train_timesteps) + self.scheduler.config.num_train_timesteps # pylint: disable=no-member + - (denoising_end * self.scheduler.config.num_train_timesteps) # pylint: disable=no-member ) ) num_inference_steps = len(list(filter(lambda ts: ts >= discrete_timestep_cutoff, timesteps))) @@ -938,7 +938,7 @@ class DemoFusionSDXLPipeline(DiffusionPipeline, FromSingleFileMixin, LoraLoaderM for i, t in enumerate(timesteps): count = torch.zeros_like(latents) value = torch.zeros_like(latents) - cosine_factor = 0.5 * (1 + torch.cos(torch.pi * (self.scheduler.config.num_train_timesteps - t) / self.scheduler.config.num_train_timesteps)).cpu() + cosine_factor = 0.5 * (1 + torch.cos(torch.pi * (self.scheduler.config.num_train_timesteps - t) / self.scheduler.config.num_train_timesteps)).cpu() # pylint: disable=no-member c1 = cosine_factor ** cosine_scale_1 latents = latents * (1 - c1) + noise_latents[i] * c1 @@ -1004,7 +1004,7 @@ class DemoFusionSDXLPipeline(DiffusionPipeline, FromSingleFileMixin, LoraLoaderM noise_pred = rescale_noise_cfg(noise_pred, noise_pred_text, guidance_rescale=guidance_rescale) # compute the previous noisy sample x_t -> x_t-1 - self.scheduler._init_step_index(t) + self.scheduler._init_step_index(t) # pylint: disable=no-member latents_denoised_batch = self.scheduler.step( noise_pred, t, latents_for_view, **extra_step_kwargs, return_dict=False)[0] @@ -1089,7 +1089,7 @@ class DemoFusionSDXLPipeline(DiffusionPipeline, FromSingleFileMixin, LoraLoaderM noise_pred = rescale_noise_cfg(noise_pred, noise_pred_text, guidance_rescale=guidance_rescale) # compute the previous noisy sample x_t -> x_t-1 - self.scheduler._init_step_index(t) + self.scheduler._init_step_index(t) # pylint: disable=no-member latents_denoised_batch = self.scheduler.step( noise_pred, t, latents_for_view, **extra_step_kwargs, return_dict=False)[0] @@ -1229,6 +1229,8 @@ class Script(scripts.Script): # return signature is array of gradio components def ui(self, _is_img2img): + with gr.Row(): + gr.HTML('  DemoFusion
') with gr.Row(): cosine_scale_1 = gr.Slider(minimum=0, maximum=5, step=0.1, value=3, label="Cosine scale 1") cosine_scale_2 = gr.Slider(minimum=0, maximum=5, step=0.1, value=1, label="Cosine scale 2") diff --git a/scripts/mixture_tiling.py b/scripts/mixture_tiling.py index 57b0723bf..4425725bf 100644 --- a/scripts/mixture_tiling.py +++ b/scripts/mixture_tiling.py @@ -33,7 +33,7 @@ class Script(scripts.Script): def ui(self, _is_img2img): with gr.Row(): - gr.HTML('  Mixture tiling') + gr.HTML('  Mixture tiling
') with gr.Row(): gr.HTML('  Separated prompts using new lines
  Number of prompts must matcxh X*Y
') with gr.Row(): diff --git a/scripts/prompt_matrix.py b/scripts/prompt_matrix.py index 00d6edc7a..39c0fe993 100644 --- a/scripts/prompt_matrix.py +++ b/scripts/prompt_matrix.py @@ -42,16 +42,16 @@ class Script(scripts.Script): return "Prompt Matrix" def ui(self, is_img2img): - gr.HTML('
') with gr.Row(): - with gr.Column(): - put_at_start = gr.Checkbox(label='Set at prompt start', value=False, elem_id=self.elem_id("put_at_start")) - different_seeds = gr.Checkbox(label='Random seeds', value=False, elem_id=self.elem_id("different_seeds")) - with gr.Column(): - prompt_type = gr.Radio(["positive", "negative"], label="Prompt type", elem_id=self.elem_id("prompt_type"), value="positive") - variations_delimiter = gr.Radio(["comma", "space"], label="Joining char", elem_id=self.elem_id("variations_delimiter"), value="comma") - with gr.Column(): - margin_size = gr.Slider(label="Grid margins", minimum=0, maximum=500, value=0, step=2, elem_id=self.elem_id("margin_size")) + gr.HTML('  Prompt matrix
') + with gr.Row(): + put_at_start = gr.Checkbox(label='Set at prompt start', value=False, elem_id=self.elem_id("put_at_start")) + different_seeds = gr.Checkbox(label='Random seeds', value=False, elem_id=self.elem_id("different_seeds")) + with gr.Row(): + prompt_type = gr.Radio(["positive", "negative"], label="Prompt type", elem_id=self.elem_id("prompt_type"), value="positive") + variations_delimiter = gr.Radio(["comma", "space"], label="Joining char", elem_id=self.elem_id("variations_delimiter"), value="comma") + with gr.Row(): + margin_size = gr.Slider(label="Grid margins", minimum=0, maximum=500, value=0, step=2, elem_id=self.elem_id("margin_size")) return [put_at_start, different_seeds, prompt_type, variations_delimiter, margin_size] diff --git a/scripts/prompts_from_file.py b/scripts/prompts_from_file.py index 80b85cd26..3e9745f6b 100644 --- a/scripts/prompts_from_file.py +++ b/scripts/prompts_from_file.py @@ -95,6 +95,8 @@ class Script(scripts.Script): return "Prompts from File" def ui(self, is_img2img): + with gr.Row(): + gr.HTML('  Prompt from file
') with gr.Row(): checkbox_iterate = gr.Checkbox(label="Iterate seed per line", value=False, elem_id=self.elem_id("checkbox_iterate")) checkbox_iterate_batch = gr.Checkbox(label="Use same seed", value=False, elem_id=self.elem_id("checkbox_iterate_batch")) diff --git a/scripts/regional_prompting.py b/scripts/regional_prompting.py index 2605436e7..e18d85600 100644 --- a/scripts/regional_prompting.py +++ b/scripts/regional_prompting.py @@ -31,7 +31,7 @@ class Script(scripts.Script): def ui(self, _is_img2img): with gr.Row(): - gr.HTML('  Regional prompting') + gr.HTML('  Regional prompting
') with gr.Row(): mode = gr.Radio(label='Mode', choices=['None', 'Prompt', 'Prompt EX', 'Columns', 'Rows'], value='None') with gr.Row(): diff --git a/scripts/text2video.py b/scripts/text2video.py index 87036edc0..ada78e849 100644 --- a/scripts/text2video.py +++ b/scripts/text2video.py @@ -46,6 +46,8 @@ class Script(scripts.Script): model = next(m for m in MODELS if m['name'] == model_name) return gr.update(value=f'   frames: {model["params"][0]} size: {model["params"][1]}x{model["params"][2]} link') + with gr.Row(): + gr.HTML('  Text to video
') with gr.Row(): model_name = gr.Dropdown(label='Model', value='None', choices=[m['name'] for m in MODELS]) with gr.Row(): diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py index b296bb732..ab93a6d96 100644 --- a/scripts/xyz_grid.py +++ b/scripts/xyz_grid.py @@ -424,6 +424,8 @@ class Script(scripts.Script): def ui(self, is_img2img): self.current_axis_options = [x for x in axis_options if type(x) == AxisOption or x.is_img2img == is_img2img] + with gr.Row(): + gr.HTML('  X/Y/Z Grid
') with gr.Row(): with gr.Column(): with gr.Row(variant='compact'):