Skip to content

Validate num_inference_steps > 0 in DDPMScheduler.set_timesteps (#13394)#13705

Open
jbbqqf wants to merge 1 commit into
huggingface:mainfrom
jbbqqf:fix/13394-ddpm-validate-num-inference-steps
Open

Validate num_inference_steps > 0 in DDPMScheduler.set_timesteps (#13394)#13705
jbbqqf wants to merge 1 commit into
huggingface:mainfrom
jbbqqf:fix/13394-ddpm-validate-num-inference-steps

Conversation

@jbbqqf
Copy link
Copy Markdown

@jbbqqf jbbqqf commented May 10, 2026

Fixes #13394.

Summary

DDPMScheduler.set_timesteps(num_inference_steps=0) (or negative) silently accepted the input, ran np.linspace(0, num_train_timesteps - 1, 0) to produce an empty schedule, and left the scheduler in a broken state. The bug only surfaced later when step() operated on stale state — instead of failing fast.

`scheduling_block_refinement.py` already validates num_inference_steps > 0. This PR brings DDPM in line.

Fix

Add the same guard in DDPMScheduler.set_timesteps (and propagate to its # Copied from sibling `DDPMSchedulerParallel` via python utils/check_copies.py --fix_and_overwrite):

if num_inference_steps is None or num_inference_steps <= 0:
    raise ValueError(
        f"`num_inference_steps` must be a positive integer, got {num_inference_steps}."
    )

(The pre-existing too-large check is preserved.)

Reproduce BEFORE/AFTER yourself (copy-paste)

# --- BEFORE: origin/main, no error raised ---
git fetch origin main && git checkout origin/main
python - <<'PY'
from diffusers import DDPMScheduler
sched = DDPMScheduler()
sched.set_timesteps(num_inference_steps=0)
print(\"NO ERROR. timesteps:\", sched.timesteps)  # Expected: NO ERROR / empty
PY

# --- AFTER: this branch ---
git fetch origin pull/<PR>/head:fix && git checkout fix
python - <<'PY'
from diffusers import DDPMScheduler
sched = DDPMScheduler()
try:
    sched.set_timesteps(num_inference_steps=0)
except ValueError as e:
    print(f\"OK: {e}\")  # Expected: \`num_inference_steps\` must be a positive integer, got 0.
PY

What I ran locally

pytest tests/schedulers/test_scheduler_ddpm.py -k \"custom_timesteps or rejects_non_positive\"
# 5 passed

The new `test_set_timesteps_rejects_non_positive_num_inference_steps` covers both 0 and -1, and verifies the scheduler still works for a positive value afterwards. It fails on origin/main (no exception raised) and passes on this branch.

Notes

  • 2 source files updated (DDPM + parallel sibling), 1 test file. Verified no other # Copied from consumers exist for DDPMScheduler.set_timesteps via python utils/check_copies.py.

🤖 Disclosure: Authored with assistance from Claude (Anthropic), reviewed and tested by me.

…uggingface#13394)

`DDPMScheduler.set_timesteps(num_inference_steps=0)` (or negative) silently
left the scheduler with an empty schedule and stale state, instead of failing
fast like other schedulers do. This made the bug invisible until a downstream
`step()` call produced wrong results.

Add the same `num_inference_steps must be a positive integer` check that
`scheduling_block_refinement` already has, propagated to `DDPMScheduler` and
its `# Copied from` sibling `DDPMSchedulerParallel` via `make fix-copies`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DDPMScheduler allows num_inference_steps=0 without validation (inconsistent with DDIMScheduler)

1 participant