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")),
]