sgl-project/sglang · error · ValueError

chunk plan {plan} does not cover the incoming {incoming.shap

Error message

chunk plan {plan} does not cover the incoming {incoming.shape[2]} frames

What it means

The realtime path reads a chunk plan (list of per-chunk frame counts) from batch.extra['sana_wm_chunk_plan'], defaulting to a single chunk covering all frames. The plan's entries must sum exactly to the incoming latents' temporal size; otherwise the autoregressive chunking is inconsistent with the data.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/streaming.py:269

        pcfg = server_args.pipeline_config
        device = get_local_torch_device()
        target_dtype = PRECISION_TO_TYPE.get(
            getattr(pcfg, "dit_precision", "bf16"), torch.bfloat16
        )
        if batch.session is None:
            raise ValueError("SANA-WM realtime denoising requires a realtime session")
        state = get_realtime_causal_dit_state(batch.session)
        if batch.block_idx == 0 and state.latents is not None:
            state.dispose()  # session restart on chunk 0 (mirrors the base stage)

        sc = self._resolve_stream_conditioning(
            batch, server_args, device=device, target_dtype=target_dtype
        )
        sampler_cfg = sc.sampler_cfg
        incoming = batch.latents.to(device=device, dtype=target_dtype).clone()
        plan = list(batch.extra.get("sana_wm_chunk_plan") or [incoming.shape[2]])
        if sum(plan) != incoming.shape[2]:
            raise ValueError(
                f"chunk plan {plan} does not cover the incoming {incoming.shape[2]} frames"
            )
        if state.scheduler is None:
            state.scheduler = FlowMatchEulerDiscreteScheduler(shift=1.0)
        kv_cache = state.kv_cache
        if kv_cache is None:
            # SANA-WM stores its heterogeneous per-block 10-slot stream cache in
            # the generic causal DiT kv_cache slot.
            kv_cache = []
            state.kv_cache = kv_cache

        # Device-only move, NO dtype cast: Module.to(dtype=...) would cast the
        # DiT's complex RoPE buffers to real, discarding the imaginary part
        # (parity root cause #1). No use_declared_component round-trip either —
        # the DiT stays device-resident for the session's lifetime.
        transformer = self.transformer.to(device=device).eval()
        num_blocks = len(transformer.blocks)
        _dump_dir = parity_probe.probe_dir(parity_probe.ENV_RT_DUMP)

View on GitHub (pinned to 0132848349)

Solutions

  1. Recompute sana_wm_chunk_plan from the actual latents at prep time: sum(plan) == latents.shape[2]
  2. Align num_frame_per_block config across all streaming stages in the same run
  3. Omit the plan key to use the default single-chunk fallback when appropriate

Example fix

# before
batch.extra["sana_wm_chunk_plan"] = [n_chunk] * k  # stale counts
# after
plan, rem = [], latents.shape[2]
while rem:
    take = min(n_chunk, rem); plan.append(take); rem -= take
batch.extra["sana_wm_chunk_plan"] = plan
Defensive patterns

Strategy: validation

Validate before calling

plan = list(batch.extra.get("sana_wm_chunk_plan") or [batch.latents.shape[2]])
assert sum(plan) == batch.latents.shape[2], (plan, batch.latents.shape)

Type guard

null

Try / catch

try:
    resp = stage.forward(batch, server_args)
except ValueError as e:
    if "chunk plan" in str(e):
        batch.extra.pop("sana_wm_chunk_plan", None)  # fall back to single-chunk default
        resp = stage.forward(batch, server_args)
    else:
        raise

Prevention

When it happens

Trigger: A latent-preparation stage that emits N frames but writes a stale or miscounted chunk plan (e.g. plan built for a different chunk length after a config change, or plan not updated after trimming/padding frames).

Common situations: Changing num_frame_per_block between the prep stage and the denoiser; reusing batch.extra across retries where latents were regenerated with a different length; off-by-one in plan construction.

Related errors


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