sgl-project/sglang · error · ValueError

denoising_step_list must end with 0, got {schedule}

Error message

denoising_step_list must end with 0, got {schedule}

What it means

build_per_chunk_sigmas converts a denoising_step_list such as (1000, 960, 889, 727, 0) into flow-Euler sigmas. The schedule must have at least 2 entries and its last entry must be 0 (terminal timestep); sigmas are the non-terminal steps divided by 1000. Violating either invariant raises this ValueError.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/self_forcing.py:207

        for stale in range(chunk_idx):
            if stale in keep:
                continue
            kv_cache[stale] = [
                [None] * _NUM_STREAM_CACHE_SLOTS for _ in range(num_blocks)
            ]

    # ----------------------------------------------------------------- #
    # Per-chunk flow-Euler sigma schedule
    # ----------------------------------------------------------------- #
    @staticmethod
    def build_per_chunk_sigmas(denoising_step_list) -> list[float]:
        """Explicit flow-Euler sigmas for one chunk's short self-forcing schedule.

        The ``denoising_step_list`` (e.g. (1000, 960, 889, 727, 0)) must end with
        0; sigmas are the non-terminal steps divided by 1000."""
        schedule = list(denoising_step_list)
        if len(schedule) < 2 or schedule[-1] != 0:
            raise ValueError(f"denoising_step_list must end with 0, got {schedule}")
        return [float(t) / 1000.0 for t in schedule[:-1]]

View on GitHub (pinned to 0132848349)

Solutions

  1. Append a terminal 0 to the step list, e.g. (1000, 960, 889, 727, 0)
  2. Use the official SANA-WM self-forcing schedule values verbatim
  3. Ensure entries are integer timesteps in [0,1000], not normalized sigmas

Example fix

# before
build_per_chunk_sigmas([1000, 960, 889])
# after
build_per_chunk_sigmas([1000, 960, 889, 727, 0])
Defensive patterns

Strategy: validation

Validate before calling

def valid_schedule(steps):
    steps = list(steps)
    return len(steps) >= 2 and steps[-1] == 0
assert valid_schedule(denoising_step_list), denoising_step_list

Type guard

def is_terminal_zero_schedule(steps) -> bool:
    steps = list(steps)
    return len(steps) >= 2 and steps[-1] == 0 and all(isinstance(t, int) and 0 <= t <= 1000 for t in steps)

Try / catch

null

Prevention

When it happens

Trigger: Passing a schedule like (1000, 960, 889) with no terminal 0, a single-element list, or a schedule normalized to sigmas (0.0 terminal in wrong units) instead of raw timesteps.

Common situations: Copying a sigma list from a diffusers config directly instead of the timestep list; truncating a schedule when reducing step counts; hand-editing denoising_step_list in server args.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/743535dad9e74970. Report an issue: GitHub.