diff --git a/.pylintrc b/.pylintrc index fbaaf8930..f9a30d336 100644 --- a/.pylintrc +++ b/.pylintrc @@ -18,6 +18,7 @@ ignore-paths=/usr/lib/.*$, ^modules/xadapters/.*$, ^modules/hidiffusion/.*$, ^modules/pag/.*$, + ^modules/olive_script.py, ignore-patterns= ignored-modules= jobs=0 @@ -140,6 +141,7 @@ disable=bad-inline-option, consider-using-get, consider-using-in, consider-using-min-builtin, + consider-merging-isinstance, dangerous-default-value, deprecated-pragma, duplicate-code, diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f723ac1a..36dbf80ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ it is time to give credit to original [author](https://github.com/auTOMATIC1111) Simply enable checkbox in advanced menu and set desired resolution Additional settings are available in *settings -> inference settings -> hidiffusion* And can also be set and used via *xyz grid* + *Note*: HiDiffusion resolution sensitive, so if you get error, set resolution to be multiples of 128 - [Perturbed-Attention Guidance](https://github.com/KU-CVLAB/Perturbed-Attention-Guidance) PAG enhances sample quality by utilizing self-attention in formation of latent in addition to standard CFG scale Simply set *advanced -> attention guidance* and *advanced -> adaptive scaling* diff --git a/TODO.md b/TODO.md index 02755591c..35fe7ca54 100644 --- a/TODO.md +++ b/TODO.md @@ -11,11 +11,11 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma ### Models & Pipelines - stable diffusion 3.0 -- powerpaint: ### Features - async lowvram: +- fp8: - init latents: variations, img2img - diffusers public callbacks - include reference styles diff --git a/modules/extra_networks.py b/modules/extra_networks.py index 291771907..63fd2b1fe 100644 --- a/modules/extra_networks.py +++ b/modules/extra_networks.py @@ -67,7 +67,7 @@ def is_stepwise(en_obj): for en in en_obj: all_args.extend(en.positional[1:]) all_args.extend(en.named.values()) - return any([len(str(x).split("@")) > 1 for x in all_args]) # noqa C419 + return any([len(str(x).split("@")) > 1 for x in all_args]) # noqa C419 # pylint: disable=use-a-generator def activate(p, extra_network_data, step=0): diff --git a/modules/images.py b/modules/images.py index aa19eb58d..dc979c25a 100644 --- a/modules/images.py +++ b/modules/images.py @@ -701,7 +701,7 @@ def save_video_atomic(images, filename, video_type: str = 'none', duration: floa def save_video(p, images, filename = None, video_type: str = 'none', duration: float = 2.0, loop: bool = False, interpolate: int = 0, scale: float = 1.0, pad: int = 1, change: float = 0.3, sync: bool = False): if images is None or len(images) < 2 or video_type is None or video_type.lower() == 'none': - return + return None image = images[0] if p is not None: namegen = FilenameGenerator(p, seed=p.all_seeds[0], prompt=p.all_prompts[0], image=image) diff --git a/modules/interrogate.py b/modules/interrogate.py index 505dd5f7e..fdd23fd36 100644 --- a/modules/interrogate.py +++ b/modules/interrogate.py @@ -83,7 +83,7 @@ class InterrogateModels: from repositories.blip.models import blip import modules.modelloader as modelloader model_path = os.path.join(paths.models_path, "BLIP") - download_name='model_base_caption_capfilt_large.pth', + download_name='model_base_caption_capfilt_large.pth' shared.log.debug(f'Model interrogate load: type=BLiP model={download_name} path={model_path}') files = modelloader.load_models( model_path=model_path, diff --git a/modules/ipadapter.py b/modules/ipadapter.py index 4f6f5c36a..dccfde622 100644 --- a/modules/ipadapter.py +++ b/modules/ipadapter.py @@ -48,7 +48,7 @@ def get_images(input_images): for image in input_images: if image is None: continue - elif isinstance(image, list): + if isinstance(image, list): output_images.append(get_images(image)) # recursive elif isinstance(image, Image.Image): output_images.append(image) @@ -185,7 +185,7 @@ def apply(pipe, p: processing.StableDiffusionProcessing, adapter_names=[], adapt clip_loaded = f'{clip_repo}/{clip_subfolder}' except Exception as e: shared.log.error(f'IP adapter: failed to load image encoder: {e}') - return + return False sd_models.move_model(pipe.image_encoder, devices.device) # main code diff --git a/modules/masking.py b/modules/masking.py index b2200ad57..729c8fc63 100644 --- a/modules/masking.py +++ b/modules/masking.py @@ -500,8 +500,7 @@ def run_mask_live(input_image: gr.Image): res = run_mask(input_image) busy = False return res - else: - return None + return None def create_segment_ui(): diff --git a/modules/modelloader.py b/modules/modelloader.py index 29c716d80..f541281a1 100644 --- a/modules/modelloader.py +++ b/modules/modelloader.py @@ -237,7 +237,7 @@ def load_diffusers_models(clear=True): try: for folder in os.listdir(place): try: - if any([x in folder for x in excluded_models]): # noqa:C419 + if any([x in folder for x in excluded_models]): # noqa:C419 # pylint: disable=use-a-generator continue if "--" not in folder: continue diff --git a/modules/pag/__init__.py b/modules/pag/__init__.py index 37d820289..2b2b84502 100644 --- a/modules/pag/__init__.py +++ b/modules/pag/__init__.py @@ -32,6 +32,8 @@ def apply(p: processing.StableDiffusionProcessing): # pylint: disable=arguments- pag_applied_layers_index = pag_applied_layers.split() if len(pag_applied_layers) > 0 else [] pag_applied_layers_index = [p.strip() for p in pag_applied_layers_index] p.task_args['pag_applied_layers_index'] = pag_applied_layers_index if len(pag_applied_layers_index) > 0 else ['m0'] # Available layers: d[0-5], m[0], u[0-8] + p.extra_generation_params["PAG scale"] = p.pag_scale + p.extra_generation_params["PAG adaptive"] = p.pag_adaptive shared.log.debug(f'{c}: args={p.task_args}') diff --git a/modules/patches.py b/modules/patches.py index 4539180a3..10e5cdfa4 100644 --- a/modules/patches.py +++ b/modules/patches.py @@ -40,7 +40,7 @@ def undo(key, obj, field): patch_key = (obj, field) if patch_key not in originals[key]: log.error(f"Patch no patch to undo: field={field}") - return + return None original_func = originals[key].pop(patch_key) if original_func is None: delattr(obj, field) diff --git a/modules/processing_diffusers.py b/modules/processing_diffusers.py index fc8439084..b5f8ffce8 100644 --- a/modules/processing_diffusers.py +++ b/modules/processing_diffusers.py @@ -7,7 +7,6 @@ import typing import numpy as np import torch import torchvision.transforms.functional as TF -import diffusers from modules import shared, devices, processing, sd_samplers, sd_models, images, errors, prompt_parser_diffusers, sd_hijack_hypertile, processing_correction, processing_vae, sd_models_compile, extra_networks, hidiffusion from modules.processing_helpers import resize_init_images, resize_hires, fix_prompts, calculate_base_steps, calculate_hires_steps, calculate_refiner_steps from modules.onnx_impl import preprocess_pipeline as preprocess_onnx_pipeline, check_parameters_changed as olive_check_parameters_changed @@ -366,6 +365,7 @@ def process_diffusers(p: processing.StableDiffusionProcessing): def update_pipeline(sd_model, p: processing.StableDiffusionProcessing): """ + import diffusers if p.sag_scale > 0 and is_txt2img(): update_sampler(shared.sd_model) supported = ['DDIMScheduler', 'PNDMScheduler', 'DDPMScheduler', 'DEISMultistepScheduler', 'UniPCMultistepScheduler', 'DPMSolverMultistepScheduler', 'DPMSolverSinlgestepScheduler'] diff --git a/modules/prompt_parser_diffusers.py b/modules/prompt_parser_diffusers.py index 3fd60d394..33d8e8027 100644 --- a/modules/prompt_parser_diffusers.py +++ b/modules/prompt_parser_diffusers.py @@ -98,9 +98,9 @@ def get_prompt_schedule(prompt, steps): def encode_prompts(pipe, p, prompts: list, negative_prompts: list, steps: int, clip_skip: typing.Optional[int] = None): - if 'StableDiffusion' not in pipe.__class__.__name__ and 'DemoFusion': + if 'StableDiffusion' not in pipe.__class__.__name__ and 'DemoFusion' not in pipe.__class__.__name__: shared.log.warning(f"Prompt parser not supported: {pipe.__class__.__name__}") - return None, None, None, None + return else: t0 = time.time() positive_schedule, scheduled = get_prompt_schedule(prompts[0], steps) diff --git a/modules/sd_models_compile.py b/modules/sd_models_compile.py index add79b6be..2ae9512f3 100644 --- a/modules/sd_models_compile.py +++ b/modules/sd_models_compile.py @@ -78,9 +78,9 @@ def ipex_optimize(sd_model): sd_model.prior_text_encoder = ipex_optimize_model(sd_model.prior_text_encoder) t1 = time.time() shared.log.info(f"IPEX Optimize: time={t1-t0:.2f}") - return sd_model except Exception as e: shared.log.warning(f"IPEX Optimize: error: {e}") + return sd_model def nncf_compress_weights(sd_model): @@ -132,9 +132,9 @@ def nncf_compress_weights(sd_model): sd_model.prior_text_encoder = nncf_compress_model(sd_model.prior_text_encoder) t1 = time.time() shared.log.info(f"Compress Weights: time={t1-t0:.2f}") - return sd_model except Exception as e: shared.log.warning(f"Compress Weights: error: {e}") + return sd_model def optimize_openvino(sd_model): @@ -258,7 +258,7 @@ def compile_torch(sd_model): shared.compiled_model_state = CompiledModelState() return sd_model elif shared.opts.cuda_compile_backend == "migraphx": - import torch_migraphx + import torch_migraphx # pylint: disable=unused-import log_level = logging.WARNING if shared.opts.cuda_compile_verbose else logging.CRITICAL # pylint: disable=protected-access if hasattr(torch, '_logging'): torch._logging.set_logs(dynamo=log_level, aot=log_level, inductor=log_level) # pylint: disable=protected-access diff --git a/modules/ui_control.py b/modules/ui_control.py index b3281888a..f63e19baf 100644 --- a/modules/ui_control.py +++ b/modules/ui_control.py @@ -59,7 +59,7 @@ def generate_click(job_id: str, active_tab: str, *args): except Exception as e: shared.log.error(f"Control exception: {e}") errors.display(e, 'Control') - return None, None, None, None, f'Control: Exception: {e}' + yield [None, None, None, None, f'Control: Exception: {e}'] progress.finish_task(job_id) shared.state.end() @@ -114,7 +114,7 @@ def create_ui(_blocks: gr.Blocks=None): mask_controls = masking.create_segment_ui() cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, pag_scale, pag_adaptive, cfg_end = ui_sections.create_advanced_inputs('control') - hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio, = ui_sections.create_correction_inputs('control') + hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio = ui_sections.create_correction_inputs('control') with gr.Accordion(open=False, label="Video", elem_id="control_video", elem_classes=["small-accordion"]): with gr.Row(): @@ -579,6 +579,9 @@ def create_ui(_blocks: gr.Blocks=None): (refiner_steps, "Refiner steps"), (refiner_prompt, "Prompt2"), (refiner_negative, "Negative2"), + # pag + (pag_scale, "PAG scale"), + (pag_adaptive, "PAG adaptive"), # hidden (seed_resize_from_w, "Seed resize from-1"), (seed_resize_from_h, "Seed resize from-2"), diff --git a/modules/ui_img2img.py b/modules/ui_img2img.py index 065860f9d..334897f12 100644 --- a/modules/ui_img2img.py +++ b/modules/ui_img2img.py @@ -134,7 +134,7 @@ def create_ui(): cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, pag_scale, pag_adaptive, cfg_end = ui_sections.create_advanced_inputs('img2img') full_quality, restore_faces, tiling, hidiffusion = ui_sections.create_options('img2img') - hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio, = ui_sections.create_correction_inputs('img2img') + hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio = ui_sections.create_correction_inputs('img2img') # with gr.Group(elem_id="inpaint_controls", visible=False) as inpaint_controls: with gr.Accordion(open=False, label="Mask", elem_classes=["small-accordion"], elem_id="img2img_mask_group") as inpaint_controls: diff --git a/modules/ui_sections.py b/modules/ui_sections.py index d62cff23b..8d53d41cb 100644 --- a/modules/ui_sections.py +++ b/modules/ui_sections.py @@ -196,7 +196,7 @@ def create_correction_inputs(tab): with gr.Row(elem_id=f"{tab}_hdr_color_row"): hdr_color_picker = gr.ColorPicker(label="Color", show_label=True, container=False, value=None, elem_id=f"{tab}_hdr_color_picker") hdr_tint_ratio = gr.Slider(label='Color grading', minimum=-1.0, maximum=1.0, step=0.05, value=0.0, elem_id=f"{tab}_hdr_tint_ratio") - return hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio, + return hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio def create_sampler_and_steps_selection(choices, tabname): diff --git a/modules/ui_txt2img.py b/modules/ui_txt2img.py index 224fefe47..ab6545b8c 100644 --- a/modules/ui_txt2img.py +++ b/modules/ui_txt2img.py @@ -47,7 +47,7 @@ def create_ui(): ui_sections.create_sampler_options('txt2img') seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w = ui_sections.create_seed_inputs('txt2img') _cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, pag_scale, pag_adaptive, _cfg_end = ui_sections.create_advanced_inputs('txt2img', base=False) - hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio, = ui_sections.create_correction_inputs('txt2img') + hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio = ui_sections.create_correction_inputs('txt2img') enable_hr, hr_sampler_index, denoising_strength, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative = ui_sections.create_hires_inputs('txt2img') override_settings = ui_common.create_override_inputs('txt2img') @@ -131,6 +131,9 @@ def create_ui(): (refiner_steps, "Refiner steps"), (refiner_prompt, "Prompt2"), (refiner_negative, "Negative2"), + # pag + (pag_scale, "PAG scale"), + (pag_adaptive, "PAG adaptive"), # hidden (seed_resize_from_w, "Seed resize from-1"), (seed_resize_from_h, "Seed resize from-2"),