Skip to content

FlowMatchEulerDiscreteScheduler.set_timesteps silently ignores explicit timesteps since #14011 — intended semantics change or unreleased regression? #14461

Description

@codeAnqiang-ma

Describe the bug

Since #14011 (merged 2026-07-07, not yet in any release — v0.39.0 predates it), FlowMatchEulerDiscreteScheduler.set_timesteps unconditionally recomputes timesteps from the shifted sigmas (scheduling_flow_match_euler_discrete.py#L367), so an explicitly passed custom timesteps list is silently discarded. The docstring still promises "Custom values for timesteps to be used for each diffusion step" (L305-L307), and FlowMatchLCMScheduler still honors the argument (scheduling_flow_match_lcm.py#L376-L379), so the two flow-match schedulers now disagree on the same argument.

Concrete impact inside the library: CogView4 / CogView4-Control / GLM-Image deliberately pass integer-cast timesteps plus paired sigmas (pipeline_cogview4.py#L587-L606 — a mechanism the model authors added in #10649) and feed scheduler.timesteps to the transformer as conditioning. With the official CogView4-6B scheduler config at 1024x1024, the conditioning timesteps now deviate from the passed values by up to 285.75 / 1000 (repro below). The #14011 discussion covered the SD3/Flux pattern (deriving timesteps when only sigmas are given) and did not mention these pipelines.

Question for the maintainers: is discarding explicit timesteps the intended new semantics after #14011?

  • If intended: the docstring, the now-dead is_timesteps_provided variable (L329), FlowMatchLCMScheduler, and the now-ineffective integer-cast in the CogView4/GLM-Image pipelines should be aligned — I'm happy to submit that PR.
  • If not intended: restoring the explicit-timesteps branch (while keeping fix rf time scheduler problem #14011's recomputation for the derived case) before v0.40 ships would avoid releasing a silent behavior change — I'm happy to submit that PR instead; a minimal fix plus regression test is already prepared on my fork.

Reproduction

Repro 1 — exactly what pipeline_cogview4.py passes (CogView4-6B config, 1024x1024, 10 steps):

import numpy as np
from diffusers import FlowMatchEulerDiscreteScheduler

# THUDM/CogView4-6B scheduler config; mu=3.25 is what calculate_shift() yields at 1024x1024
sched = FlowMatchEulerDiscreteScheduler(
    num_train_timesteps=1000, shift=1.0, use_dynamic_shifting=True,
    base_shift=0.25, max_shift=0.75, base_image_seq_len=256,
    max_image_seq_len=4096, time_shift_type="linear")
timesteps = np.linspace(1000, 1.0, 10).astype(np.int64).astype(np.float32)  # as pipeline_cogview4.py does
sched.set_timesteps(10, sigmas=(timesteps / 1000).tolist(), timesteps=timesteps.tolist(), mu=3.25)
print(sched.timesteps.tolist())  # expected: the passed values [1000.0, 889.0, ..., 1.0]

Output on main (614ae4b):

passed   : [1000.0, 889.0, 778.0, 667.0, 556.0, 445.0, 334.0, 223.0, 112.0, 1.0]
got      : [1000.0, 963.0, 919.29, 866.84, 802.75, 722.67, 619.75, 482.6, 290.73, 3.24]
max delta: 285.75

Before #14011 (all releases through v0.39.0), the output equals the passed values.

Repro 2 — divergence from FlowMatchLCMScheduler (same inputs, static shift=3.0)
from diffusers import FlowMatchEulerDiscreteScheduler
from diffusers.schedulers.scheduling_flow_match_lcm import FlowMatchLCMScheduler

ts = [1000.0, 750.0, 500.0, 250.0, 1.0]
sg = [t / 1000 for t in ts]
euler = FlowMatchEulerDiscreteScheduler(num_train_timesteps=1000, shift=3.0)
lcm = FlowMatchLCMScheduler(num_train_timesteps=1000, shift=3.0)
euler.set_timesteps(sigmas=sg, timesteps=ts)
lcm.set_timesteps(sigmas=sg, timesteps=ts)
print(euler.timesteps.tolist())  # [1000.0, 900.0, 750.0, 500.0, 2.99]  <- input ignored
print(lcm.timesteps.tolist())    # [1000.0, 750.0, 500.0, 250.0, 1.0]   <- input honored

(Both produce identical sigmas; only timesteps diverge.)

Logs

(see outputs inline above)

System Info

  • 🤗 Diffusers version: 0.40.0.dev0 (main @ 614ae4b)
  • Platform: macOS-26.5.2-arm64-arm-64bit-Mach-O
  • Running on Google Colab?: No
  • Python version: 3.13.3
  • PyTorch version (GPU?): 2.13.0 (False)
  • Huggingface_hub version: 1.27.0
  • Transformers version: 5.15.0
  • Accelerate version: not installed
  • PEFT version: not installed
  • Safetensors version: 0.8.0
  • xFormers version: not installed
  • Accelerator: Apple M4
  • Using GPU in script?: No
  • Using distributed or parallel set-up in script?: No

Who can help?

No response


Disclosure: this report was prepared with AI assistance following the "AI-assisted and agentic contributions" guide; I reproduced the issue locally at 614ae4b and reviewed every claim. Per the guide, I'm coordinating here first and will wait for maintainer acknowledgment before opening any PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions