sgl-project/sglang · error · ValueError

SANA-WM streaming denoising expects 5D latents (B, C, T, H,

Error message

SANA-WM streaming denoising expects 5D latents (B, C, T, H, W).

What it means

The offline streaming forward (_forward_offline) requires batch.latents to be a 5D (B, C, T, H, W) tensor. None or non-5D latents mean the noise/latent initialization expected by the streaming denoiser is missing or malformed.

Source

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

            do_cfg=do_cfg,
            embeds=embeds_in,
            mask=mask_in,
            camera=cam_in,
            plucker=plk_in,
        )

    @torch.no_grad()
    def forward(self, batch: Req, server_args: ServerArgs) -> Req:
        # LingBot-style dispatch: realtime sessions denoise ONE chunk per call
        # with per-session state; otherwise run the whole clip offline.
        if batch.session is not None:
            return self._forward_realtime_chunk(batch, server_args)
        return self._forward_offline(batch, server_args)

    @torch.no_grad()
    def _forward_offline(self, batch: Req, server_args: ServerArgs) -> Req:
        if batch.latents is None or batch.latents.ndim != 5:
            raise ValueError(
                "SANA-WM streaming denoising expects 5D latents (B, C, T, H, W)."
            )

        pcfg = server_args.pipeline_config
        device = get_local_torch_device()
        target_dtype = PRECISION_TO_TYPE.get(
            getattr(pcfg, "dit_precision", "bf16"), torch.bfloat16
        )

        # .clone() detaches from the loader's InferenceMode tensor so the
        # per-chunk in-place latent updates below are allowed.
        latents = batch.latents.to(device=device, dtype=target_dtype).clone()
        init_latents = latents.clone()
        B, C, total_frames, H, W = latents.shape

        def _iload(_name):
            return torch.load(f"{_SANAWM_INJECT_DIR}/{_name}.pt", map_location=device)

View on GitHub (pinned to 0132848349)

Solutions

  1. Initialize latents as (B, C, T, H, W) before calling the streaming stage (typical T from duration/fps config)
  2. Unsqueeze squeezed temporal dims
  3. Use the provided latent-init stage rather than manual construction where possible

Example fix

# before
batch.latents = init_noise(b, c, h, w)  # 4D
# after
batch.latents = init_noise(b, c, t, h, w)  # 5D, t = num latent frames
Defensive patterns

Strategy: validation

Validate before calling

assert batch.latents is not None and batch.latents.ndim == 5, "offline streaming needs 5D latents"

Type guard

def is_5d_latents(z) -> bool:
    return isinstance(z, torch.Tensor) and z.ndim == 5

Try / catch

try:
    out = stage._forward_offline(batch, server_args)
except ValueError as e:
    if "5D latents" in str(e) and batch.latents.ndim == 4:
        batch.latents = batch.latents.unsqueeze(2)
        out = stage._forward_offline(batch, server_args)
    else:
        raise

Prevention

When it happens

Trigger: Invoking the streaming stage offline without a prior stage creating initial latents; passing image-style 4D latents; a tensor path that squeezed the temporal dim.

Common situations: Running the streaming model in offline/batch mode with a hand-built Req; reusing an image pipeline's latent init; a shape-normalizing wrapper between stages.

Related errors


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