X Tutup
Skip to content

fix: deduplicate timesteps in DPMSolverMultistepScheduler to prevent IndexError#13239

Open
Chase-Xuu wants to merge 1 commit intohuggingface:mainfrom
Chase-Xuu:fix/dpmsolver-duplicate-timesteps
Open

fix: deduplicate timesteps in DPMSolverMultistepScheduler to prevent IndexError#13239
Chase-Xuu wants to merge 1 commit intohuggingface:mainfrom
Chase-Xuu:fix/dpmsolver-duplicate-timesteps

Conversation

@Chase-Xuu
Copy link

What does this PR do?

Fixes #12771DPMSolverMultistepScheduler crashes with IndexError: index N is out of bounds when using beta_schedule='squaredcos_cap_v2' with use_karras_sigmas=True (or use_lu_lambdas=True).

Root cause

With the cosine (squaredcos_cap_v2) noise schedule, the sigma-to-timestep mapping (_sigma_to_t) produces many nearly identical float values near the end of the schedule (e.g., 998.90, 998.80, 998.70...) that collapse to the same integer timestep (998) after casting to int64. The current code intentionally skips rounding for cosine schedules, but this only defers the problem — values like 998.9 and 998.8 still become 998 when converted to int64.

These duplicate timesteps cause index_for_timestep to return incorrect indices, making step_index drift past the sigmas array bounds, crashing at self.sigmas[self.step_index + 1].

Fix

  1. Round timesteps unconditionally — remove the squaredcos_cap_v2 exception for karras/lu sigma paths, since rounding is now handled centrally
  2. Deduplicate timesteps after rounding — keep only the first occurrence of each unique value, preserving order
  3. Filter sigmas to match the deduplicated timesteps
  4. Update num_inference_steps to reflect the actual number of unique steps

This mirrors the existing deduplication logic already present in DPMSolverMultistepInverseScheduler (lines 358-359).

Test results

Config Before After
squaredcos_cap_v2 + use_karras_sigmas (20 steps) ❌ IndexError at step 19 ✅ 12 unique steps, all complete
squaredcos_cap_v2 + use_lu_lambdas (20 steps) ❌ IndexError ✅ 17 unique steps, all complete
linear + use_karras_sigmas (20 steps) ✅ 20 steps (no duplicates, no change)
Default config (20 steps) ✅ 20 steps (no change)

Note: The reduced step count (e.g. 20 → 12) is expected. With cosine schedules, many karras sigmas map to nearly the same timestep, so those steps were effectively redundant. The sigmas array is filtered to match, so the solver still uses the correct sigma values for each unique timestep.

Who can review?

@yiyixuxu (who engaged with the original issue)

…IndexError

When using `beta_schedule='squaredcos_cap_v2'` with `use_karras_sigmas=True`,
the sigma-to-timestep mapping produces many nearly identical float values that
collapse to the same integer timestep after rounding (e.g., 998.90, 998.80 both
become 998). These duplicate timesteps cause the step_index counter to drift past
the sigmas array, resulting in an IndexError at `self.sigmas[self.step_index + 1]`.

Fix:
- Round timesteps unconditionally (remove the squaredcos_cap_v2 exception)
- Deduplicate timesteps after rounding, keeping only the first occurrence
- Filter corresponding sigmas to match the deduplicated timesteps
- Update num_inference_steps to reflect the actual number of unique steps

This mirrors the existing deduplication logic in DPMSolverMultistepInverseScheduler.

Fixes huggingface#12771
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DPMSolverMultistepScheduler out-of-bounds error when using beta_schedule="squaredcos_cap_v2" + use_karras_sigmas=True

1 participant

X Tutup