Skip to content

Commit 35a7404

Browse files
#3487 Fix inpainting strength for various samplers (#3532)
* Throw error if strength adjusted num_inference_steps < 1 * Added new fast test to check ValueError raised when num_inference_steps < 1 when strength adjusts the num_inference_steps then the inpainting pipeline should fail * fix #3487 initial latents are now only scaled by init_noise_sigma when pure noise updated this commit w.r.t the latest merge here: #3533 * fix --------- Co-authored-by: Patrick von Platen <[email protected]>
1 parent 0612f48 commit 35a7404

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

src/diffusers/pipelines/controlnet/pipeline_controlnet_inpaint.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -863,12 +863,13 @@ def prepare_latents(
863863

864864
if latents is None:
865865
noise = randn_tensor(shape, generator=generator, device=device, dtype=dtype)
866+
# if strength is 1. then initialise the latents to noise, else initial to image + noise
866867
latents = noise if is_strength_max else self.scheduler.add_noise(image_latents, noise, timestep)
868+
# if pure noise then scale the initial latents by the Scheduler's init sigma
869+
latents = latents * self.scheduler.init_noise_sigma if is_strength_max else latents
867870
else:
868871
latents = latents.to(device)
869-
870-
# scale the initial noise by the standard deviation required by the scheduler
871-
latents = latents * self.scheduler.init_noise_sigma
872+
latents = latents * self.scheduler.init_noise_sigma
872873

873874
outputs = (latents,)
874875

src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_inpaint.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -648,12 +648,13 @@ def prepare_latents(
648648

649649
if latents is None:
650650
noise = randn_tensor(shape, generator=generator, device=device, dtype=dtype)
651+
# if strength is 1. then initialise the latents to noise, else initial to image + noise
651652
latents = noise if is_strength_max else self.scheduler.add_noise(image_latents, noise, timestep)
653+
# if pure noise then scale the initial latents by the Scheduler's init sigma
654+
latents = latents * self.scheduler.init_noise_sigma if is_strength_max else latents
652655
else:
653656
latents = latents.to(device)
654-
655-
# scale the initial noise by the standard deviation required by the scheduler
656-
latents = latents * self.scheduler.init_noise_sigma
657+
latents = latents * self.scheduler.init_noise_sigma
657658

658659
outputs = (latents,)
659660

@@ -912,6 +913,12 @@ def __call__(
912913
timesteps, num_inference_steps = self.get_timesteps(
913914
num_inference_steps=num_inference_steps, strength=strength, device=device
914915
)
916+
# check that number of inference steps is not < 1 - as this doesn't make sense
917+
if num_inference_steps < 1:
918+
raise ValueError(
919+
f"After adjusting the num_inference_steps by strength parameter: {strength}, the number of pipeline"
920+
f"steps is {num_inference_steps} which is < 1 and not appropriate for this pipeline."
921+
)
915922
# at which timestep to set the initial noise (n.b. 50% if strength is 0.5)
916923
latent_timestep = timesteps[:1].repeat(batch_size * num_images_per_prompt)
917924
# create a boolean to check if the strength is set to 1. if so then initialise the latents with pure noise

tests/pipelines/stable_diffusion/test_stable_diffusion_inpaint.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,20 @@ def test_stable_diffusion_inpaint_lora(self):
231231
def test_inference_batch_single_identical(self):
232232
super().test_inference_batch_single_identical(expected_max_diff=3e-3)
233233

234+
def test_stable_diffusion_inpaint_strength_zero_test(self):
235+
device = "cpu" # ensure determinism for the device-dependent torch.Generator
236+
components = self.get_dummy_components()
237+
sd_pipe = StableDiffusionInpaintPipeline(**components)
238+
sd_pipe = sd_pipe.to(device)
239+
sd_pipe.set_progress_bar_config(disable=None)
240+
241+
inputs = self.get_dummy_inputs(device)
242+
243+
# check that the pipeline raises value error when num_inference_steps is < 1
244+
inputs["strength"] = 0.01
245+
with self.assertRaises(ValueError):
246+
sd_pipe(**inputs).images
247+
234248

235249
class StableDiffusionSimpleInpaintPipelineFastTests(StableDiffusionInpaintPipelineFastTests):
236250
pipeline_class = StableDiffusionInpaintPipeline

0 commit comments

Comments
 (0)