diff --git a/CHANGELOG.md b/CHANGELOG.md index a0cc3428b..9c2cdee35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,11 @@ ## TODO -- EDM samplers for Playground require `diffusers==0.27.0` -- StableCascade requires diffusers `kashif/diffusers.git@wuerstchen-v3` +- `diffusers==0.27.0`: + - EDM samplers for Playground 2.5 + - Stable Cascade -## Update for 2024-03-05 +## Update for 2024-03-06 - [Playground v2.5](https://huggingface.co/playgroundai/playground-v2.5-1024px-aesthetic) - new model version from Playground: based on SDXL, but with some cool new concepts @@ -50,6 +51,7 @@ - **FaceID** extend support for LoRA, HyperTile and FreeU, thanks @Trojaner - **Tiling** now extends to both Unet and VAE producing smoother outputs, thanks @AI-Casanova - new setting in image options: *include mask in output* + - improved params parsing from from prompt string and styles - default theme updates and additional built-in theme *black-gray* - add **ROCm** 6.0 nightly option to installer, thanks @jicka - support models with their own YAML model config files diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet index 4b5a42f26..aa2aa812e 160000 --- a/extensions-builtin/sd-webui-controlnet +++ b/extensions-builtin/sd-webui-controlnet @@ -1 +1 @@ -Subproject commit 4b5a42f265594c00b26937b947630895d632a9f7 +Subproject commit aa2aa812e86a1f47ef360572888d66027d640f60 diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index 49aa581b3..c0f450926 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -187,24 +187,32 @@ def send_image_and_dimensions(x): return img, w, h -def parse_generation_parameters(x: str): +def parse_generation_parameters(param_str: str): res = {} - if x is None: + if param_str is None: return res - remaining = x.replace('\n', ' ').strip() + # remaining = x.replace('\n', ' ').strip() + remaining = param_str.strip() if len(remaining) == 0: return res - remaining = x[7:] if x.startswith('Prompt: ') else x - remaining = x[11:] if x.startswith('parameters: ') else x - if 'Steps: ' in remaining and 'Negative prompt: ' not in remaining: - remaining = remaining.replace('Steps: ', 'Negative prompt: Steps: ') - prompt, remaining = remaining.strip().split('Negative prompt: ', maxsplit=1) if 'Negative prompt: ' in remaining else (remaining, '') + if 'prompt:' in remaining: + remaining = remaining.replace('prompt:', 'Prompt:') + if 'negative prompt:' in remaining: + remaining = remaining.replace('negative prompt:', 'Negative prompt:') + if 'steps:' in remaining: + remaining = remaining.replace('steps:', 'Steps:') + remaining = remaining[7:] if remaining.startswith('Prompt:') else remaining + remaining = remaining[11:] if remaining.startswith('parameters:') else remaining + if 'Steps:' in remaining and 'Negative prompt:' not in remaining: + remaining = remaining.replace('Steps:', 'Negative prompt: Steps:') + prompt, remaining = remaining.strip().split('Negative prompt:', maxsplit=1) if 'Negative prompt:' in remaining else (remaining, '') res["Prompt"] = prompt.strip() - negative, remaining = remaining.strip().split('Steps: ', maxsplit=1) if 'Steps: ' in remaining else (remaining, None) + negative, remaining = remaining.strip().split('Steps:', maxsplit=1) if 'Steps:' in remaining else (remaining, None) res["Negative prompt"] = negative.strip() + if remaining is None: return res - remaining = f'Steps: {remaining}' + remaining = f'Steps: {remaining.strip()}' for k, v in re_param.findall(remaining.strip()): try: if v[0] == '"' and v[-1] == '"': diff --git a/modules/images.py b/modules/images.py index 5dc300363..32cd3ccec 100644 --- a/modules/images.py +++ b/modules/images.py @@ -254,6 +254,7 @@ def resize_image(resize_mode, im, width, height, upscaler_name=None, output_type if upscaler is not None: im = latent(im, w, h, upscaler) else: + upscaler = upscalers[0] shared.log.warning(f"Resize upscaler: invalid={upscaler_name} fallback={upscaler.name}") if im.width != w or im.height != h: # probably downsample after upscaler created larger image im = im.resize((w, h), resample=Image.Resampling.LANCZOS) diff --git a/modules/sd_models.py b/modules/sd_models.py index 1ac2354a9..3911b6056 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -916,7 +916,7 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No shared.log.debug(f'StableCascade experimental: args={diffusers_load_config} device={devices.device} dtype={devices.dtype}') diffusers_load_config.pop("vae", None) diffusers_load_config.pop("variant", None) - decoder = diffusers.StableCascadeDecoderPipeline.from_pretrained("stabilityai/stable-cascade", cache_dir=shared.opts.diffusers_dir, revision="refs/pr/17", **diffusers_load_config) + decoder = diffusers.StableCascadeDecoderPipeline.from_pretrained("stabilityai/stable-cascade", cache_dir=shared.opts.diffusers_dir, revision="refs/pr/44", **diffusers_load_config) shared.log.debug(f'StableCascade decoder: scale={decoder.latent_dim_scale}') prior = diffusers.StableCascadePriorPipeline.from_pretrained("stabilityai/stable-cascade-prior", cache_dir=shared.opts.diffusers_dir, **diffusers_load_config) shared.log.debug(f'StableCascade prior: scale={prior.resolution_multiple}') diff --git a/modules/styles.py b/modules/styles.py index 59047b565..53b47f079 100644 --- a/modules/styles.py +++ b/modules/styles.py @@ -47,10 +47,14 @@ def apply_styles_to_extra(p, style: Style): 'sampler': 'sampler_name', } from modules.generation_parameters_copypaste import parse_generation_parameters - extra = parse_generation_parameters(style.extra) + s = style.extra + s = 'Negative prompt: ' + s if 'Negative prompt:' not in s else s + s = 'Prompt: ' + s if 'Prompt:' not in s else s + extra = parse_generation_parameters(s) extra.pop('Prompt', None) extra.pop('Negative prompt', None) fields = [] + skipped = [] for k, v in extra.items(): k = k.lower() k = k.replace(' ', '_') @@ -62,7 +66,9 @@ def apply_styles_to_extra(p, style: Style): v = type(orig)(v) setattr(p, k, v) fields.append(f'{k}={v}') - log.debug(f'Applying style: name="{style.name}" extra={fields}') + else: + skipped.append(f'{k}={v}') + log.debug(f'Applying style: name="{style.name}" extra={fields} skipped={skipped}') class StyleDatabase: diff --git a/modules/ui_postprocessing.py b/modules/ui_postprocessing.py index dac010ac1..5322840a8 100644 --- a/modules/ui_postprocessing.py +++ b/modules/ui_postprocessing.py @@ -26,7 +26,7 @@ def create_ui(): with gr.Row(): extras_image = gr.Image(label="Source", source="upload", interactive=True, type="pil", elem_id="extras_image") with gr.Row(elem_id='copy_buttons_process'): - buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "inpaint", "control"]) + copy_process_buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "inpaint", "control"]) with gr.Tab('Process Batch', id="batch_process", elem_id="extras_batch_process_tab") as tab_batch: image_batch = gr.Files(label="Batch process", interactive=True, elem_id="extras_image_batch") with gr.Tab('Process Folder', id="batch_from_directory", elem_id="extras_batch_directory_tab") as tab_batch_dir: @@ -54,9 +54,7 @@ def create_ui(): btn_analyze_img = gr.Button("Analyze", elem_id="interrogate_btn_analyze", variant='primary') btn_unload = gr.Button("Unload", elem_id="interrogate_btn_unload") with gr.Row(elem_id='copy_buttons_interrogate'): - buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "extras", "control"]) - for tabname, button in buttons.items(): - parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(paste_button=button, tabname=tabname, source_text_component=prompt, source_image_component=image,)) + copy_interrogate_buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "extras", "control"]) btn_interrogate_img.click(interrogate.interrogate_image, inputs=[image, clip_model, mode], outputs=prompt) btn_analyze_img.click(interrogate.analyze_image, inputs=[image, clip_model], outputs=[medium, artist, movement, trending, flavor]) btn_unload.click(interrogate.unload_clip_model) @@ -103,8 +101,11 @@ def create_ui(): gr.HTML('File metadata') exif_info = gr.HTML(elem_id="pnginfo_html_info") gen_info = gr.Text(elem_id="pnginfo_gen_info", visible=False) - for tabname, button in buttons.items(): + for tabname, button in copy_process_buttons.items(): parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(paste_button=button, tabname=tabname, source_text_component=gen_info, source_image_component=extras_image)) + for tabname, button in copy_interrogate_buttons.items(): + parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(paste_button=button, tabname=tabname, source_text_component=prompt, source_image_component=image,)) + tab_single.select(fn=lambda: 0, inputs=[], outputs=[tab_index]) tab_batch.select(fn=lambda: 1, inputs=[], outputs=[tab_index])