diff --git a/html/locale_en.json b/html/locale_en.json index 31344ff93..e5cbfd43a 100644 --- a/html/locale_en.json +++ b/html/locale_en.json @@ -114,11 +114,18 @@ {"id":"","label":"Tiling","localized":"","hint":"Produce an image that can be tiled"}, {"id":"","label":"Hires fix","localized":"","hint":"Use a similar process as image to image to upscale and add detail to the final image."}, {"id":"","label":"Denoising strength","localized":"","hint":"Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies"}, + {"id":"","label":"Denoise start","localized":"","hint":"Override denoise strength by stating how early base model should finish and when refiner should start. Only applicable to refiner usage. If set to 0 or 1, denoising strength will be used"}, {"id":"","label":"Hires steps","localized":"","hint":"Number of sampling steps for upscaled picture. If 0, uses same as for original"}, {"id":"","label":"Upscaler","localized":"","hint":"Which pre-tarined model to use for the upscaling process."}, {"id":"","label":"Upscale by","localized":"","hint":"Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero"}, {"id":"","label":"Resize width to","localized":"","hint":"Resizes image to this width. If 0, width is inferred from either of two nearby sliders"}, {"id":"","label":"Resize height to","localized":"","hint":"Resizes image to this height. If 0, height is inferred from either of two nearby sliders"}, + {"id":"","label":"Secondary sampler","localized":"","hint":"Use specific sampler as fallback sampler if primary is not supported for specific operation"}, + {"id":"","label":"Secondary steps","localized":"","hint":"Number of steps to use for second pass"}, + {"id":"","label":"Secondary CFG Scale","localized":"","hint":"CFG scale used for refiner pass"}, + {"id":"","label":"Guidance rescale","localized":"","hint":"Rescale CFG generated noise to avoid overexposed images"}, + {"id":"","label":"Secondary prompt","localized":"","hint":"Prompt used for both second encoder in base model (if it exists) and for refiner pass (if enabled)"}, + {"id":"","label":"Secondary negative prompt","localized":"","hint":"Negative prompt used for both second encoder in base model (if it exists) and for refiner pass (if enabled)"}, {"id":"","label":"Width","localized":"","hint":"Image width"}, {"id":"","label":"Height","localized":"","hint":"Image height"}, {"id":"","label":"Batch count","localized":"","hint":"How many batches of images to create (has no impact on generation performance or VRAM usage)"}, @@ -491,7 +498,6 @@ {"id":"","label":"DPM++ 2M SDE Karras","localized":"","hint":""}, {"id":"","label":"DDIM","localized":"","hint":"Denoising Diffusion Implicit Models - best at inpainting"}, {"id":"","label":"UniPC","localized":"","hint":"Unified Predictor-Corrector Framework for Fast Sampling of Diffusion Models"}, - {"id":"","label":"Secondary sampler","localized":"","hint":"Use specific sampler as fallback sampler if primary is not supported for specific operation"}, {"id":"","label":"Force latent upscaler sampler","localized":"","hint":"Force specific sampler for second pass operations"}, {"id":"","label":"Noise multiplier for ancestral samplers (eta)","localized":"","hint":""}, {"id":"","label":"Noise multiplier for DDIM (eta)","localized":"","hint":""}, diff --git a/modules/img2img.py b/modules/img2img.py index 661a0b023..7ec50aaab 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -74,7 +74,7 @@ def process_batch(p, input_files, input_dir, output_dir, inpaint_mask_dir, args) shared.log.debug(f'Processed: {len(image_files)} 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, latent_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, diffusers_guidance_rescale: float, refiner_denoise_start: float, refiner_denoise_end: float, clip_skip: int, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, 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_files: list, 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, latent_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, diffusers_guidance_rescale: float, refiner_start: float, clip_skip: int, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, 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_files: list, 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') @@ -167,8 +167,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s denoising_strength=denoising_strength, image_cfg_scale=image_cfg_scale, diffusers_guidance_rescale=diffusers_guidance_rescale, - refiner_denoise_start=refiner_denoise_start, - refiner_denoise_end=refiner_denoise_end, + refiner_start=refiner_start, inpaint_full_res=inpaint_full_res, inpaint_full_res_padding=inpaint_full_res_padding, inpainting_mask_invert=inpainting_mask_invert, diff --git a/modules/processing.py b/modules/processing.py index a50988884..aafb5a3f8 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -149,7 +149,7 @@ class StableDiffusionProcessing: self.iteration = 0 self.is_hr_pass = False self.enable_hr = None - self.refiner_denoise_start = 0 + self.refiner_start = 0 self.ops = [] shared.opts.data['clip_skip'] = clip_skip @@ -471,8 +471,7 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts, all_seeds, all_su "Latent sampler": p.latent_sampler if p.enable_hr else None, "Image CFG scale": p.image_cfg_scale if p.enable_hr else None, "Denoising strength": p.denoising_strength if p.enable_hr else None, - "Denoise start": p.refiner_denoise_start if p.enable_hr else None, - "Denoise end": p.refiner_denoise_end if p.enable_hr else None, + "Refiner start": p.refiner_start if p.enable_hr else None, # restore_faces "Face restoration": shared.opts.face_restoration_model if p.restore_faces else None, # sdnext @@ -807,7 +806,7 @@ def old_hires_fix_first_pass_dimensions(width, height): class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing): sampler = None - def __init__(self, enable_hr: bool = False, denoising_strength: float = 0.75, firstphase_width: int = 0, firstphase_height: int = 0, hr_scale: float = 2.0, hr_upscaler: str = None, hr_second_pass_steps: int = 0, hr_resize_x: int = 0, hr_resize_y: int = 0, refiner_denoise_start: float = 0, refiner_denoise_end: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs): + def __init__(self, enable_hr: bool = False, denoising_strength: float = 0.75, firstphase_width: int = 0, firstphase_height: int = 0, hr_scale: float = 2.0, hr_upscaler: str = None, hr_second_pass_steps: int = 0, hr_resize_x: int = 0, hr_resize_y: int = 0, refiner_start: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs): super().__init__(**kwargs) self.enable_hr = enable_hr @@ -827,8 +826,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing): self.truncate_x = 0 self.truncate_y = 0 self.applied_old_hires_behavior_to = None - self.refiner_denoise_start = refiner_denoise_start - self.refiner_denoise_end = refiner_denoise_end + self.refiner_start = refiner_start self.refiner_prompt = refiner_prompt self.refiner_negative = refiner_negative @@ -975,7 +973,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing): class StableDiffusionProcessingImg2Img(StableDiffusionProcessing): sampler = None - def __init__(self, init_images: list = None, resize_mode: int = 0, denoising_strength: float = 0.3, image_cfg_scale: float = None, mask: Any = None, mask_blur: int = 4, inpainting_fill: int = 0, inpaint_full_res: bool = True, inpaint_full_res_padding: int = 0, inpainting_mask_invert: int = 0, initial_noise_multiplier: float = None, refiner_denoise_start: float = 0, refiner_denoise_end: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs): + def __init__(self, init_images: list = None, resize_mode: int = 0, denoising_strength: float = 0.3, image_cfg_scale: float = None, mask: Any = None, mask_blur: int = 4, inpainting_fill: int = 0, inpaint_full_res: bool = True, inpaint_full_res_padding: int = 0, inpainting_mask_invert: int = 0, initial_noise_multiplier: float = None, refiner_start: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs): super().__init__(**kwargs) self.init_images = init_images self.resize_mode: int = resize_mode @@ -994,8 +992,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing): self.mask = None self.nmask = None self.image_conditioning = None - self.refiner_denoise_start = refiner_denoise_start - self.refiner_denoise_end = refiner_denoise_end + self.refiner_start = refiner_start self.refiner_prompt = refiner_prompt self.refiner_negative = refiner_negative self.enable_hr = None diff --git a/modules/processing_diffusers.py b/modules/processing_diffusers.py index 8eb44c1ce..39f206f1a 100644 --- a/modules/processing_diffusers.py +++ b/modules/processing_diffusers.py @@ -139,7 +139,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro negative_prompt_2=[p.refiner_negative] if len(p.refiner_negative) > 0 else negative_prompts, eta=shared.opts.eta_ddim, guidance_rescale=p.diffusers_guidance_rescale, - denoising_end=p.refiner_denoise_start if refiner_enabled else None, + denoising_end=p.refiner_start if p.refiner_start > 0 and p.refiner_start < 1 else None, # aesthetic_score=shared.opts.diffusers_aesthetics_score, output_type='latent' if hasattr(shared.sd_model, 'vae') else 'np', **task_specific_kwargs @@ -189,8 +189,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro guidance_scale=p.image_cfg_scale if p.image_cfg_scale is not None else p.cfg_scale, guidance_rescale=p.diffusers_guidance_rescale, # aesthetic_score=shared.opts.diffusers_aesthetics_score, - denoising_start=p.refiner_denoise_start, - denoising_end=p.refiner_denoise_end, + denoising_start=p.refiner_start if p.refiner_start > 0 and p.refiner_start < 1 else None, image=output.images[i], output_type='latent' if hasattr(shared.sd_refiner, 'vae') else 'np', ) diff --git a/modules/txt2img.py b/modules/txt2img.py index 3ad784430..64cb978ac 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -5,9 +5,9 @@ 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, latent_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, diffusers_guidance_rescale: float, clip_skip: int, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, 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, refiner_denoise_start: int, refiner_denoise_end: float, refiner_prompt: str, refiner_negative: str, 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, latent_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, diffusers_guidance_rescale: float, clip_skip: int, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, 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, refiner_start: int, refiner_prompt: str, refiner_negative: str, override_settings_texts, *args): # pylint: disable=unused-argument - 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}|latent_index={latent_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}||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}|image_cfg_scale={image_cfg_scale}|diffusers_guidance_rescale={diffusers_guidance_rescale}|refiner_denoise_start={refiner_denoise_start}|refiner_denoise_end={refiner_denoise_end}|refiner_prompt={refiner_prompt}|refiner_negative={refiner_negative}|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}|latent_index={latent_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}||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}|image_cfg_scale={image_cfg_scale}|diffusers_guidance_rescale={diffusers_guidance_rescale}|refiner_start={refiner_start}||refiner_prompt={refiner_prompt}|refiner_negative={refiner_negative}|override_settings_texts={override_settings_texts}args={args}') if shared.sd_model is None: shared.log.warning('Model not loaded') @@ -52,8 +52,7 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step hr_second_pass_steps=hr_second_pass_steps, hr_resize_x=hr_resize_x, hr_resize_y=hr_resize_y, - refiner_denoise_start=refiner_denoise_start, - refiner_denoise_end=refiner_denoise_end, + refiner_start=refiner_start, refiner_prompt=refiner_prompt, refiner_negative=refiner_negative, override_settings=override_settings, diff --git a/modules/ui.py b/modules/ui.py index b773b3afb..43c250351 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -384,6 +384,7 @@ def create_ui(startup_timer = None): hr_second_pass_steps, latent_index = create_sampler_and_steps_selection(modules.sd_samplers.samplers, "txt2img", False) with FormRow(elem_id="txt2img_hires_fix_row1", variant="compact"): denoising_strength = gr.Slider(minimum=0.05, maximum=1.0, step=0.01, label='Denoising strength', value=0.3, elem_id="txt2img_denoising_strength") + refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise start', value=1.0, elem_id="txt2img_refiner_start") with FormRow(elem_id="txt2img_hires_finalres", variant="compact"): hr_final_resolution = FormHTML(value="", elem_id="txtimg_hr_finalres", label="Upscaled resolution", interactive=False) with FormRow(elem_id="txt2img_hires_fix_row2", variant="compact"): @@ -398,12 +399,10 @@ def create_ui(startup_timer = None): with FormRow(elem_id="txt2img_refiner_row1", variant="compact"): image_cfg_scale = gr.Slider(minimum=1.1, maximum=30.0, step=0.1, label='Secondary CFG Scale', value=6.0, elem_id="txt2img_image_cfg_scale") diffusers_guidance_rescale = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Guidance rescale', value=0.7, elem_id="txt2img_image_cfg_rescale") - refiner_denoise_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise start', value=0.8, elem_id="txt2img_refiner_denoise_start") - refiner_denoise_end = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise end', value=1.0, elem_id="txt2img_refiner_denoise_end") with FormRow(elem_id="txt2img_refiner_row2", variant="compact"): - refiner_prompt = gr.Textbox(value='', label='Prompt') + refiner_prompt = gr.Textbox(value='', label='Secondary Prompt') with FormRow(elem_id="txt2img_refiner_row3", variant="compact"): - refiner_negative = gr.Textbox(value='', label='Negative prompt') + refiner_negative = gr.Textbox(value='', label='Secondary negative prompt') with FormRow(elem_id="txt2img_override_settings_row") as row: override_settings = create_override_settings_dropdown('txt2img', row) @@ -443,7 +442,7 @@ def create_ui(startup_timer = None): height, width, show_second_pass, denoising_strength, hr_scale, hr_upscaler, hr_second_pass_steps, hr_resize_x, hr_resize_y, - refiner_denoise_start, refiner_denoise_end, refiner_prompt, refiner_negative, + refiner_start, refiner_prompt, refiner_negative, override_settings, ] + custom_inputs, outputs=[ @@ -482,8 +481,7 @@ def create_ui(startup_timer = None): (clip_skip, "Clip skip"), (latent_index, "Latent sampler"), (denoising_strength, "Denoising strength"), - (refiner_denoise_start, "Denoise start"), - (refiner_denoise_end, "Denoise end"), + (refiner_start, "Refiner start"), (restore_faces, "Face restoration"), (batch_size, "Batch size"), (batch_count, "Batch count"), @@ -657,8 +655,7 @@ def create_ui(startup_timer = None): with FormGroup(visible=show_denoise.value, elem_id=f"{tab}_denoise_group") as denoise_group: with FormRow(): denoising_strength = gr.Slider(minimum=0.05, maximum=1.0, step=0.01, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength") - refiner_denoise_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise start', value=0.0, elem_id="txt2img_refiner_denoise_start") - refiner_denoise_end = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise end', value=1.0, elem_id="txt2img_refiner_denoise_end") + refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise start', value=0.0, elem_id="txt2img_refiner_start") with FormGroup(visible=show_advanced.value, elem_id=f"{tab}_advanced_group") as advanced_group: with FormRow(): @@ -739,7 +736,7 @@ def create_ui(startup_timer = None): batch_count, batch_size, cfg_scale, image_cfg_scale, diffusers_guidance_rescale, - refiner_denoise_start, refiner_denoise_end, + refiner_start, clip_skip, denoising_strength, seed, subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, @@ -836,8 +833,7 @@ def create_ui(startup_timer = None): (clip_skip, "Clip skip"), (latent_index, "Latent sampler"), (denoising_strength, "Denoising strength"), - (refiner_denoise_start, "Denoise start"), - (refiner_denoise_end, "Denoise end"), + (refiner_start, "Refiner start"), (restore_faces, "Face restoration"), (batch_size, "Batch size"), (batch_count, "Batch count"), diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py index 88b7ec8a5..9448f5ed0 100644 --- a/scripts/xyz_grid.py +++ b/scripts/xyz_grid.py @@ -239,10 +239,7 @@ axis_options = [ AxisOption("SecondPass Steps", int, apply_field("hr_second_pass_steps")), AxisOption("SecondPass CFG Scale", float, apply_field("image_cfg_scale")), AxisOption("SecondPass Guidance Rescale", float, apply_field("diffusers_guidance_rescale")), - AxisOption("SecondPass Denoise Start", float, apply_field("refiner_denoise_start")), - AxisOption("SecondPass Denoise End", float, apply_field("refiner_denoise_end")), - - + AxisOption("SecondPass Refiner Start", float, apply_field("refiner_start")), ]