From df65e8e30a584bdc88812ebcd356b1eb04a3097b Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Thu, 18 May 2023 22:16:24 -0400 Subject: [PATCH] update clip skip and attention normalization --- cli/run-benchmark.py | 1 - .../Lora/scripts/lora_script.py | 4 ---- extensions-builtin/sd-webui-controlnet | 2 +- modules/generation_parameters_copypaste.py | 1 - modules/images.py | 4 ++-- modules/img2img.py | 5 +++-- modules/processing.py | 5 +++-- modules/sd_hijack_clip.py | 20 ++++++++++--------- modules/sd_hijack_open_clip.py | 3 +-- modules/sd_vae.py | 4 ++-- modules/shared.py | 1 + modules/txt2img.py | 5 +++-- modules/ui.py | 14 ++++++------- scripts/xyz_grid.py | 5 ++--- 14 files changed, 35 insertions(+), 39 deletions(-) diff --git a/cli/run-benchmark.py b/cli/run-benchmark.py index 300820ad2..498f0cff3 100755 --- a/cli/run-benchmark.py +++ b/cli/run-benchmark.py @@ -87,7 +87,6 @@ async def main(): 'vae': opts.sd_vae, 'hypernetwork': opts.sd_hypernetwork, 'sampler': options.sampler_name, - 'clip-stop': opts.CLIP_stop_at_last_layers, 'preview': opts.show_progress_every_n_steps } }) cpu, gpu = memstats() diff --git a/extensions-builtin/Lora/scripts/lora_script.py b/extensions-builtin/Lora/scripts/lora_script.py index 7b485d97d..1f0677938 100644 --- a/extensions-builtin/Lora/scripts/lora_script.py +++ b/extensions-builtin/Lora/scripts/lora_script.py @@ -54,10 +54,6 @@ script_callbacks.on_infotext_pasted(lora.infotext_pasted) shared.options_templates.update(shared.options_section(('extra_networks', "Extra Networks"), { "sd_lora": shared.OptionInfo("None", "Add Lora to prompt", gr.Dropdown, lambda: {"choices": ["None"] + [x for x in lora.available_loras]}, refresh=lora.list_available_loras), "lora_preferred_name": shared.OptionInfo("Alias from file", "When adding to prompt, refer to lora by", gr.Radio, {"choices": ["Alias from file", "Filename"]}), -})) - - -shared.options_templates.update(shared.options_section(('compatibility', "Compatibility"), { "lora_functional": shared.OptionInfo(False, "Lora: use old method that takes longer when you have multiple Loras active and produces same results as kohya-ss/sd-webui-additional-networks extension"), })) diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet index d7a02838b..8d84f1f74 160000 --- a/extensions-builtin/sd-webui-controlnet +++ b/extensions-builtin/sd-webui-controlnet @@ -1 +1 @@ -Subproject commit d7a02838b03cdbcf1a0c84059aa2656f5245c383 +Subproject commit 8d84f1f74f89ff29f3ef0af833d7b354b9b21da8 diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index 2d6c64951..6b0d4c00b 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -303,7 +303,6 @@ settings_map = {} infotext_to_setting_name_mapping = [ - ('Clip skip', 'CLIP_stop_at_last_layers', ), ('Conditional mask weight', 'inpainting_mask_weight'), ('Model hash', 'sd_model_checkpoint'), ('ENSD', 'eta_noise_seed_delta'), diff --git a/modules/images.py b/modules/images.py index 7b3688412..cf83106ef 100644 --- a/modules/images.py +++ b/modules/images.py @@ -287,7 +287,7 @@ def sanitize_filename_part(text, replace_spaces=True): class FilenameGenerator: replacements = { 'seed': lambda self: self.seed if self.seed is not None else '', - 'steps': lambda self: self.p and self.p.steps, + 'steps': lambda self: self.p and self.p.steps, 'cfg': lambda self: self.p and self.p.cfg_scale, 'width': lambda self: self.image.width, 'height': lambda self: self.image.height, @@ -307,7 +307,7 @@ class FilenameGenerator: 'batch_number': lambda self: NOTHING_AND_SKIP_PREVIOUS_TEXT if self.p.batch_size == 1 else self.p.batch_index + 1, 'generation_number': lambda self: NOTHING_AND_SKIP_PREVIOUS_TEXT if self.p.n_iter == 1 and self.p.batch_size == 1 else self.p.iteration * self.p.batch_size + self.p.batch_index + 1, 'hasprompt': lambda self, *args: self.hasprompt(*args), # accepts formats:[hasprompt..] - 'clip_skip': lambda self: shared.opts.data["CLIP_stop_at_last_layers"], + 'clip_skip': lambda self: self.p and self.p.clip_skip, 'denoising': lambda self: self.p.denoising_strength if self.p and self.p.denoising_strength else NOTHING_AND_SKIP_PREVIOUS_TEXT, } default_time_format = '%Y%m%d%H%M%S' diff --git a/modules/img2img.py b/modules/img2img.py index c5aa93804..9433fd899 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -65,12 +65,12 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args): shared.log.debug(f'Processed: {len(images)} Memory: {memory_stats()} batch') -def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, *args): # pylint: disable=unused-argument +def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, clip_skip: int, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, *args): # pylint: disable=unused-argument if shared.sd_model is None: shared.log.warning('Model not loaded') return - shared.log.debug(f'img2img: id_task={id_task}|mode={mode}|prompt={prompt}|negative_prompt={negative_prompt}|prompt_styles={prompt_styles}|init_img={init_img}|sketch={sketch}|init_img_with_mask={init_img_with_mask}|inpaint_color_sketch={inpaint_color_sketch}|inpaint_color_sketch_orig={inpaint_color_sketch_orig}|init_img_inpaint={init_img_inpaint}|init_mask_inpaint={init_mask_inpaint}|steps={steps}|sampler_index={sampler_index}|mask_blur={mask_blur}|mask_alpha={mask_alpha}|inpainting_fill={inpainting_fill}|restore_faces={restore_faces}|tiling={tiling}|n_iter={n_iter}|batch_size={batch_size}|cfg_scale={cfg_scale}|image_cfg_scale={image_cfg_scale}|denoising_strength={denoising_strength}|seed={seed}|subseed{subseed}|subseed_strength={subseed_strength}|seed_resize_from_h={seed_resize_from_h}|seed_resize_from_w={seed_resize_from_w}|seed_enable_extras={seed_enable_extras}|selected_scale_tab={selected_scale_tab}|height={height}|width={width}|scale_by={scale_by}|resize_mode={resize_mode}|inpaint_full_res={inpaint_full_res}|inpaint_full_res_padding={inpaint_full_res_padding}|inpainting_mask_invert={inpainting_mask_invert}|img2img_batch_input_dir={img2img_batch_input_dir}|img2img_batch_output_dir={img2img_batch_output_dir}|img2img_batch_inpaint_mask_dir={img2img_batch_inpaint_mask_dir}|override_settings_texts={override_settings_texts}|args={args}') + shared.log.debug(f'img2img: id_task={id_task}|mode={mode}|prompt={prompt}|negative_prompt={negative_prompt}|prompt_styles={prompt_styles}|init_img={init_img}|sketch={sketch}|init_img_with_mask={init_img_with_mask}|inpaint_color_sketch={inpaint_color_sketch}|inpaint_color_sketch_orig={inpaint_color_sketch_orig}|init_img_inpaint={init_img_inpaint}|init_mask_inpaint={init_mask_inpaint}|steps={steps}|sampler_index={sampler_index}|mask_blur={mask_blur}|mask_alpha={mask_alpha}|inpainting_fill={inpainting_fill}|restore_faces={restore_faces}|tiling={tiling}|n_iter={n_iter}|batch_size={batch_size}|cfg_scale={cfg_scale}|image_cfg_scale={image_cfg_scale}|clip_skip={clip_skip}|denoising_strength={denoising_strength}|seed={seed}|subseed{subseed}|subseed_strength={subseed_strength}|seed_resize_from_h={seed_resize_from_h}|seed_resize_from_w={seed_resize_from_w}|seed_enable_extras={seed_enable_extras}|selected_scale_tab={selected_scale_tab}|height={height}|width={width}|scale_by={scale_by}|resize_mode={resize_mode}|inpaint_full_res={inpaint_full_res}|inpaint_full_res_padding={inpaint_full_res_padding}|inpainting_mask_invert={inpainting_mask_invert}|img2img_batch_input_dir={img2img_batch_input_dir}|img2img_batch_output_dir={img2img_batch_output_dir}|img2img_batch_inpaint_mask_dir={img2img_batch_inpaint_mask_dir}|override_settings_texts={override_settings_texts}|args={args}') if sampler_index is None: shared.log.warning('Selected sampler is not enabled') @@ -131,6 +131,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s n_iter=n_iter, steps=steps, cfg_scale=cfg_scale, + clip_skip=clip_skip, width=width, height=height, restore_faces=restore_faces, diff --git a/modules/processing.py b/modules/processing.py index fdeb5cd75..69450e341 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -87,7 +87,7 @@ class StableDiffusionProcessing: """ The first set of paramaters: sd_models -> do_not_reload_embeddings represent the minimum required to create a StableDiffusionProcessing """ - def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt: str = "", styles: List[str] = None, seed: int = -1, subseed: int = -1, subseed_strength: float = 0, seed_resize_from_h: int = -1, seed_resize_from_w: int = -1, seed_enable_extras: bool = True, sampler_name: str = None, batch_size: int = 1, n_iter: int = 1, steps: int = 50, cfg_scale: float = 7.0, width: int = 512, height: int = 512, restore_faces: bool = False, tiling: bool = False, do_not_save_samples: bool = False, do_not_save_grid: bool = False, extra_generation_params: Dict[Any, Any] = None, overlay_images: Any = None, negative_prompt: str = None, eta: float = None, do_not_reload_embeddings: bool = False, denoising_strength: float = 0, ddim_discretize: str = None, s_min_uncond: float = 0.0, s_churn: float = 0.0, s_tmax: float = None, s_tmin: float = 0.0, s_noise: float = 1.0, override_settings: Dict[str, Any] = None, override_settings_restore_afterwards: bool = True, sampler_index: int = None, script_args: list = None): # pylint: disable=unused-argument + def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt: str = "", styles: List[str] = None, seed: int = -1, subseed: int = -1, subseed_strength: float = 0, seed_resize_from_h: int = -1, seed_resize_from_w: int = -1, seed_enable_extras: bool = True, sampler_name: str = None, batch_size: int = 1, n_iter: int = 1, steps: int = 50, cfg_scale: float = 7.0, clip_skip: int = 1, width: int = 512, height: int = 512, restore_faces: bool = False, tiling: bool = False, do_not_save_samples: bool = False, do_not_save_grid: bool = False, extra_generation_params: Dict[Any, Any] = None, overlay_images: Any = None, negative_prompt: str = None, eta: float = None, do_not_reload_embeddings: bool = False, denoising_strength: float = 0, ddim_discretize: str = None, s_min_uncond: float = 0.0, s_churn: float = 0.0, s_tmax: float = None, s_tmin: float = 0.0, s_noise: float = 1.0, override_settings: Dict[str, Any] = None, override_settings_restore_afterwards: bool = True, sampler_index: int = None, script_args: list = None): # pylint: disable=unused-argument self.outpath_samples: str = outpath_samples self.outpath_grids: str = outpath_grids @@ -141,9 +141,10 @@ class StableDiffusionProcessing: self.all_negative_prompts = None self.all_seeds = None self.all_subseeds = None - self.clip_skip = opts.CLIP_stop_at_last_layers + self.clip_skip = clip_skip self.iteration = 0 self.is_hr_pass = False + opts.data['clip_skip'] = clip_skip @property def sd_model(self): diff --git a/modules/sd_hijack_clip.py b/modules/sd_hijack_clip.py index fe59f976c..4d79cd3fa 100644 --- a/modules/sd_hijack_clip.py +++ b/modules/sd_hijack_clip.py @@ -203,10 +203,13 @@ class FrozenCLIPEmbedderWithCustomWordsBase(torch.nn.Module): z = self.encode_with_transformers(tokens) # restoring original mean is likely not correct, but it seems to work well to prevent artifacts that happen otherwise batch_multipliers = torch.asarray(batch_multipliers).to(devices.device) - original_mean = z.mean() - z = z * batch_multipliers.reshape(batch_multipliers.shape + (1,)).expand(z.shape) - new_mean = z.mean() - z = z * (original_mean / new_mean) + if opts.prompt_mean_norm: + original_mean = z.mean() + z = z * batch_multipliers.reshape(batch_multipliers.shape + (1,)).expand(z.shape) + new_mean = z.mean() + z = z * (original_mean / new_mean) + else: + z = z * batch_multipliers.reshape(batch_multipliers.shape + (1,)).expand(z.shape) return z @@ -240,11 +243,10 @@ class FrozenCLIPEmbedderWithCustomWords(FrozenCLIPEmbedderWithCustomWordsBase): return tokenized def encode_with_transformers(self, tokens): - if opts.CLIP_stop_at_last_layers is None: - opts.CLIP_stop_at_last_layers = 1 - outputs = self.wrapped.transformer(input_ids=tokens, output_hidden_states=-opts.CLIP_stop_at_last_layers) - if opts.CLIP_stop_at_last_layers > 1: - z = outputs.hidden_states[-opts.CLIP_stop_at_last_layers] + clip_skip = opts.data['clip_skip'] or 1 + outputs = self.wrapped.transformer(input_ids=tokens, output_hidden_states=-clip_skip) + if clip_skip > 1: + z = outputs.hidden_states[-clip_skip] z = self.wrapped.transformer.text_model.final_layer_norm(z) else: z = outputs.last_hidden_state diff --git a/modules/sd_hijack_open_clip.py b/modules/sd_hijack_open_clip.py index f76fc1f3b..5f19f6632 100644 --- a/modules/sd_hijack_open_clip.py +++ b/modules/sd_hijack_open_clip.py @@ -3,7 +3,7 @@ import torch from modules import sd_hijack_clip, devices -tokenizer = open_clip.tokenizer._tokenizer +tokenizer = open_clip.tokenizer._tokenizer # pylint: disable=protected-access class FrozenOpenCLIPEmbedderWithCustomWords(sd_hijack_clip.FrozenCLIPEmbedderWithCustomWordsBase): @@ -21,7 +21,6 @@ class FrozenOpenCLIPEmbedderWithCustomWords(sd_hijack_clip.FrozenCLIPEmbedderWit return tokenized def encode_with_transformers(self, tokens): - # set self.wrapped.layer_idx here according to opts.CLIP_stop_at_last_layers z = self.wrapped.encode_with_transformer(tokens) return z diff --git a/modules/sd_vae.py b/modules/sd_vae.py index 0e8db42ea..0c55d88f0 100644 --- a/modules/sd_vae.py +++ b/modules/sd_vae.py @@ -128,7 +128,7 @@ def load_vae(model, vae_file=None, vae_source="from unknown source"): if vae_file: if cache_enabled and vae_file in checkpoints_loaded: # use vae checkpoint cache - shared.log.info(f"Loading VAE weights {vae_source}: cached {get_filename(vae_file)}") + shared.log.info(f"Loading VAE weights: {vae_source}: cached {get_filename(vae_file)}") store_base_vae(model) _load_vae_dict(model, checkpoints_loaded[vae_file]) else: @@ -192,5 +192,5 @@ def reload_vae_weights(sd_model=None, vae_file=unspecified): script_callbacks.model_loaded_callback(sd_model) if not shared.cmd_opts.lowvram and not shared.cmd_opts.medvram: sd_model.to(devices.device) - shared.log.info("VAE weights loaded.") + shared.log.info(f"VAE weights loaded: {vae_file}") return sd_model diff --git a/modules/shared.py b/modules/shared.py index eaa3cbfe1..12f292e75 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -255,6 +255,7 @@ options_templates.update(options_section(('sd', "Stable Diffusion"), { "sub_quad_chunk_threshold": OptionInfo(80, "Sub-quadratic cross-attention percentage of VRAM chunking threshold", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1}), "always_batch_cond_uncond": OptionInfo(False, "Disables cond/uncond batching that is enabled to save memory with --medvram or --lowvram"), "prompt_attention": OptionInfo("Full parser", "Prompt attention parser", gr.Radio, lambda: {"choices": ["Full parser", "Compel parser", "A1111 parser", "Fixed attention"] }), + "prompt_mean_norm": OptionInfo(True, "Prompt attention mean normalization"), })) options_templates.update(options_section(('system-paths', "System Paths"), { diff --git a/modules/txt2img.py b/modules/txt2img.py index f7a99df6b..e2e37afc5 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -7,12 +7,12 @@ from modules.ui import plaintext_to_html from modules.memstats import memory_stats -def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, override_settings_texts, *args): # pylint: disable=unused-argument +def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, clip_skip: int, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, override_settings_texts, *args): # pylint: disable=unused-argument if shared.sd_model is None: shared.log.warning('Model not loaded') return - shared.log.debug(f'txt2img: id_task={id_task}|prompt={prompt}|negative_prompt={negative_prompt}|prompt_styles={prompt_styles}|steps={steps}|sampler_index={sampler_index}|restore_faces={restore_faces}|tiling={tiling}|n_iter={n_iter}|batch_size={batch_size}|cfg_scale={cfg_scale}|seed={seed}|subseed={subseed}|subseed_strength={subseed_strength}|seed_resize_from_h={seed_resize_from_h}|seed_resize_from_w={seed_resize_from_w}|seed_enable_extras={seed_enable_extras}|height={height}|width={width}|enable_hr={enable_hr}|denoising_strength={denoising_strength}|hr_scale={hr_scale}|hr_upscaler={hr_upscaler}|hr_second_pass_steps={hr_second_pass_steps}|hr_resize_x={hr_resize_x}|hr_resize_y={hr_resize_y}|override_settings_texts={override_settings_texts}args={args}') + shared.log.debug(f'txt2img: id_task={id_task}|prompt={prompt}|negative_prompt={negative_prompt}|prompt_styles={prompt_styles}|steps={steps}|sampler_index={sampler_index}|restore_faces={restore_faces}|tiling={tiling}|n_iter={n_iter}|batch_size={batch_size}|cfg_scale={cfg_scale}|clip_skip={clip_skip}|seed={seed}|subseed={subseed}|subseed_strength={subseed_strength}|seed_resize_from_h={seed_resize_from_h}|seed_resize_from_w={seed_resize_from_w}|seed_enable_extras={seed_enable_extras}|height={height}|width={width}|enable_hr={enable_hr}|denoising_strength={denoising_strength}|hr_scale={hr_scale}|hr_upscaler={hr_upscaler}|hr_second_pass_steps={hr_second_pass_steps}|hr_resize_x={hr_resize_x}|hr_resize_y={hr_resize_y}|override_settings_texts={override_settings_texts}args={args}') if sampler_index is None: shared.log.warning('Selected sampler is not enabled') sampler_index = 0 @@ -36,6 +36,7 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step n_iter=n_iter, steps=steps, cfg_scale=cfg_scale, + clip_skip=clip_skip, width=width, height=height, restore_faces=restore_faces, diff --git a/modules/ui.py b/modules/ui.py index cc0de9e6e..c98b201f4 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -142,10 +142,6 @@ def interrogate_deepbooru(image): return gr.update() if prompt is None else prompt -def change_clip_skip(val): - modules.shared.opts.CLIP_stop_at_last_layers = val - - def create_seed_inputs(target_interface): with FormRow(elem_id=f"{target_interface}_seed_row", variant="compact"): seed = gr.Number(label='Seed', value=-1, elem_id=f"{target_interface}_seed") @@ -369,8 +365,7 @@ def create_ui(): elif category == "cfg": with FormRow(): cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=6.0, elem_id="txt2img_cfg_scale") - clip_skip = gr.Slider(label='CLIP Skip', value=modules.shared.opts.CLIP_stop_at_last_layers, minimum=1, maximum=4, step=1, elem_id='txt2img_clip_skip', interactive=True) - clip_skip.change(fn=change_clip_skip, show_progress=False, inputs=clip_skip) + clip_skip = gr.Slider(label='CLIP skip', value=1, minimum=1, maximum=4, step=1, elem_id='txt2img_clip_skip', interactive=True) elif category == "seed": seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('txt2img') elif category == "checkboxes": @@ -430,6 +425,7 @@ def create_ui(): batch_count, batch_size, cfg_scale, + clip_skip, seed, subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox, # seed_enable_extras @@ -484,6 +480,7 @@ def create_ui(): (sampler_index, "Sampler"), (restore_faces, "Face restoration"), (cfg_scale, "CFG scale"), + (clip_skip, "Clip skip"), (seed, "Seed"), (width, "Size-1"), (height, "Size-2"), @@ -681,8 +678,7 @@ def create_ui(): cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=6.0, elem_id="img2img_cfg_scale") image_cfg_scale = gr.Slider(minimum=0, maximum=3.0, step=0.05, label='Image CFG Scale', value=1.5, elem_id="img2img_image_cfg_scale", visible=False) denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength") - clip_skip = gr.Slider(label='CLIP Skip', value=modules.shared.opts.CLIP_stop_at_last_layers, minimum=1, maximum=4, step=1, elem_id='img2img_clip_skip', interactive=True) - clip_skip.change(fn=change_clip_skip, show_progress=False, inputs=clip_skip) + clip_skip = gr.Slider(label='CLIP skip', value=1, minimum=1, maximum=4, step=1, elem_id='img2img_clip_skip', interactive=True) elif category == "seed": seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('img2img') @@ -772,6 +768,7 @@ def create_ui(): batch_size, cfg_scale, image_cfg_scale, + clip_skip, denoising_strength, seed, subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox, @@ -861,6 +858,7 @@ def create_ui(): (restore_faces, "Face restoration"), (cfg_scale, "CFG scale"), (image_cfg_scale, "Image CFG scale"), + (clip_skip, "Clip skip"), (seed, "Seed"), (width, "Size-1"), (height, "Size-2"), diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py index 72afab4ad..30c8d31bd 100644 --- a/scripts/xyz_grid.py +++ b/scripts/xyz_grid.py @@ -82,7 +82,8 @@ def confirm_checkpoints(p, xs): def apply_clip_skip(p, x, xs): - shared.opts.data["CLIP_stop_at_last_layers"] = x + p.clip_skip = x + shared.opts.data["clip_skip"] = x def apply_upscale_latent_space(p, x, xs): @@ -344,7 +345,6 @@ def draw_xyz_grid(p, xs, ys, zs, x_labels, y_labels, z_labels, cell, draw_legend class SharedSettingsStackHelper(object): def __enter__(self): #Save overridden settings so they can be restored later. - self.CLIP_stop_at_last_layers = shared.opts.CLIP_stop_at_last_layers self.vae = shared.opts.sd_vae self.uni_pc_order = shared.opts.uni_pc_order self.token_merging_ratio_hr = shared.opts.token_merging_ratio_hr @@ -358,7 +358,6 @@ class SharedSettingsStackHelper(object): #Restore overriden settings after plot generation. shared.opts.data["sd_vae"] = self.vae shared.opts.data["uni_pc_order"] = self.uni_pc_order - shared.opts.data["CLIP_stop_at_last_layers"] = self.CLIP_stop_at_last_layers 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