Skip to content

Commit fe4837a

Browse files
yiyixuxuyiyixuxu
andauthored
add step_index and clear noise_sampler at begining of each loop (huggingface#5024)
Co-authored-by: yiyixuxu <yixu310@gmail,com>
1 parent 342c5c0 commit fe4837a

1 file changed

Lines changed: 41 additions & 7 deletions

File tree

src/diffusers/schedulers/scheduling_dpmsolver_sde.py

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ def __init__(
199199
self.use_karras_sigmas = use_karras_sigmas
200200
self.noise_sampler = None
201201
self.noise_sampler_seed = noise_sampler_seed
202+
self._step_index = None
202203

203204
# Copied from diffusers.schedulers.scheduling_heun_discrete.HeunDiscreteScheduler.index_for_timestep
204205
def index_for_timestep(self, timestep, schedule_timesteps=None):
@@ -219,6 +220,24 @@ def index_for_timestep(self, timestep, schedule_timesteps=None):
219220

220221
return indices[pos].item()
221222

223+
# Copied from diffusers.schedulers.scheduling_euler_discrete.EulerDiscreteScheduler._init_step_index
224+
def _init_step_index(self, timestep):
225+
if isinstance(timestep, torch.Tensor):
226+
timestep = timestep.to(self.timesteps.device)
227+
228+
index_candidates = (self.timesteps == timestep).nonzero()
229+
230+
# The sigma index that is taken for the **very** first `step`
231+
# is always the second index (or the last index if there is only 1)
232+
# This way we can ensure we don't accidentally skip a sigma in
233+
# case we start in the middle of the denoising schedule (e.g. for image-to-image)
234+
if len(index_candidates) > 1:
235+
step_index = index_candidates[1]
236+
else:
237+
step_index = index_candidates[0]
238+
239+
self._step_index = step_index.item()
240+
222241
@property
223242
def init_noise_sigma(self):
224243
# standard deviation of the initial noise distribution
@@ -227,6 +246,13 @@ def init_noise_sigma(self):
227246

228247
return (self.sigmas.max() ** 2 + 1) ** 0.5
229248

249+
@property
250+
def step_index(self):
251+
"""
252+
The index counter for current timestep. It will increae 1 after each scheduler step.
253+
"""
254+
return self._step_index
255+
230256
def scale_model_input(
231257
self,
232258
sample: torch.FloatTensor,
@@ -246,9 +272,10 @@ def scale_model_input(
246272
`torch.FloatTensor`:
247273
A scaled input sample.
248274
"""
249-
step_index = self.index_for_timestep(timestep)
275+
if self.step_index is None:
276+
self._init_step_index(timestep)
250277

251-
sigma = self.sigmas[step_index]
278+
sigma = self.sigmas[self.step_index]
252279
sigma_input = sigma if self.state_in_first_order else self.mid_point_sigma
253280
sample = sample / ((sigma_input**2 + 1) ** 0.5)
254281
return sample
@@ -321,6 +348,9 @@ def set_timesteps(
321348
self.sample = None
322349
self.mid_point_sigma = None
323350

351+
self._step_index = None
352+
self.noise_sampler = None
353+
324354
# for exp beta schedules, such as the one for `pipeline_shap_e.py`
325355
# we need an index counter
326356
self._index_counter = defaultdict(int)
@@ -411,7 +441,8 @@ def step(
411441
If return_dict is `True`, [`~schedulers.scheduling_utils.SchedulerOutput`] is returned, otherwise a
412442
tuple is returned where the first element is the sample tensor.
413443
"""
414-
step_index = self.index_for_timestep(timestep)
444+
if self.step_index is None:
445+
self._init_step_index(timestep)
415446

416447
# advance index counter by 1
417448
timestep_int = timestep.cpu().item() if torch.is_tensor(timestep) else timestep
@@ -430,12 +461,12 @@ def t_fn(_sigma: torch.FloatTensor) -> torch.FloatTensor:
430461
return _sigma.log().neg()
431462

432463
if self.state_in_first_order:
433-
sigma = self.sigmas[step_index]
434-
sigma_next = self.sigmas[step_index + 1]
464+
sigma = self.sigmas[self.step_index]
465+
sigma_next = self.sigmas[self.step_index + 1]
435466
else:
436467
# 2nd order
437-
sigma = self.sigmas[step_index - 1]
438-
sigma_next = self.sigmas[step_index]
468+
sigma = self.sigmas[self.step_index - 1]
469+
sigma_next = self.sigmas[self.step_index]
439470

440471
# Set the midpoint and step size for the current step
441472
midpoint_ratio = 0.5
@@ -488,6 +519,9 @@ def t_fn(_sigma: torch.FloatTensor) -> torch.FloatTensor:
488519
self.sample = None
489520
self.mid_point_sigma = None
490521

522+
# upon completion increase step index by one
523+
self._step_index += 1
524+
491525
if not return_dict:
492526
return (prev_sample,)
493527

0 commit comments

Comments
 (0)