From 54fb11ba032fe9c31abbd249c58d1faf26a23662 Mon Sep 17 00:00:00 2001 From: Beinsezii Date: Sun, 12 Apr 2026 21:53:42 -0700 Subject: [PATCH] Fix denoising_start/end with higher orders --- .../pipeline_stable_diffusion_xl.py | 6 ++++-- .../pipeline_stable_diffusion_xl_img2img.py | 13 +++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py b/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py index 2f6b105702e8..9b8f55bd2d68 100644 --- a/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py +++ b/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py @@ -1175,8 +1175,10 @@ def __call__( - (self.denoising_end * self.scheduler.config.num_train_timesteps) ) ) - num_inference_steps = len(list(filter(lambda ts: ts >= discrete_timestep_cutoff, timesteps))) - timesteps = timesteps[:num_inference_steps] + num_inference_steps = ( + (torch.as_tensor(timesteps)[:: self.scheduler.order] >= discrete_timestep_cutoff).sum().item() + ) + timesteps = timesteps[: num_inference_steps * self.scheduler.order] # 9. Optionally get Guidance Scale Embedding timestep_cond = None diff --git a/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_img2img.py b/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_img2img.py index 19ccfab3de0a..b90d8464741b 100644 --- a/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_img2img.py +++ b/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl_img2img.py @@ -666,18 +666,11 @@ def get_timesteps(self, num_inference_steps, strength, device, denoising_start=N ) ) - num_inference_steps = (self.scheduler.timesteps < discrete_timestep_cutoff).sum().item() - if self.scheduler.order == 2 and num_inference_steps % 2 == 0: - # if the scheduler is a 2nd order scheduler we might have to do +1 - # because `num_inference_steps` might be even given that every timestep - # (except the highest one) is duplicated. If `num_inference_steps` is even it would - # mean that we cut the timesteps in the middle of the denoising step - # (between 1st and 2nd derivative) which leads to incorrect results. By adding 1 - # we ensure that the denoising process always ends after the 2nd derivate step of the scheduler - num_inference_steps = num_inference_steps + 1 + real_timesteps = self.scheduler.timesteps[:: self.scheduler.order] + num_inference_steps = (real_timesteps < discrete_timestep_cutoff).sum().item() # because t_n+1 >= t_n, we slice the timesteps starting from the end - t_start = len(self.scheduler.timesteps) - num_inference_steps + t_start = (len(real_timesteps) - num_inference_steps) * self.scheduler.order timesteps = self.scheduler.timesteps[t_start:] if hasattr(self.scheduler, "set_begin_index"): self.scheduler.set_begin_index(t_start)