sgl-project/sglang · error · ValueError
SANA-WM refiner decoding expects decoded video shaped (B, C,
Error message
SANA-WM refiner decoding expects decoded video shaped (B, C, T, H, W), got {tuple(frames.shape)}. What it means
The refiner's decode() calls the base VAE decode and verifies the result is a 5D video tensor (B, C, T, H, W). If the VAE returns a 4D image tensor or another rank, decoding cannot proceed with the sink-frame logic, so it raises with the observed shape.
Source
Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/refiner.py:783
(getattr(batch, "extra", None) or {}).get("sana_wm_refiner_applied", True)
)
try:
return super().forward(batch, server_args)
finally:
self._drop_refiner_sink = True
@torch.no_grad()
def decode(
self,
latents: torch.Tensor,
server_args: ServerArgs,
*,
vae_dtype: torch.dtype,
) -> torch.Tensor:
frames = super().decode(latents, server_args, vae_dtype=vae_dtype)
log_sana_wm_tensor_stats("refiner.decode.frames_with_sink", frames)
if frames.ndim != 5:
raise ValueError(
"SANA-WM refiner decoding expects decoded video shaped "
f"(B, C, T, H, W), got {tuple(frames.shape)}."
)
if frames.shape[2] <= 1:
raise ValueError(
"SANA-WM refiner decoding expected a sink frame plus refined "
f"frames, got temporal length {frames.shape[2]}."
)
if not getattr(self, "_drop_refiner_sink", True):
log_sana_wm_tensor_stats("refiner.decode.frames_output", frames)
return frames
# Match NVlabs `inference_sana_wm.py`: decode with the clean sink anchor,
# then drop the first frame from the returned video.
frames = frames[:, :, 1:].contiguous()
log_sana_wm_tensor_stats("refiner.decode.frames_output", frames)
return frames
View on GitHub (pinned to 0132848349)
Solutions
- Load the supported causal video VAE for the SANA-WM pipeline
- If wrapping the VAE, preserve the 5D video output shape
- Verify vae_dtype/component path configuration matches the video model
Example fix
# before frames = vae.decode(latents) # returns (B, C, H, W) # after frames = vae.decode(latents.squeeze(0)).unsqueeze(0) # keep (B, C, T, H, W) # or: load the causal video VAE so decode returns 5D natively
Defensive patterns
Strategy: validation
Validate before calling
frames = super_decode(latents)
if frames.ndim != 5:
frames = frames.unsqueeze(2) if frames.ndim == 4 else frames Type guard
def is_5d_video(t) -> bool:
return isinstance(t, torch.Tensor) and t.ndim == 5 Try / catch
try:
return stage.decode(latents, server_args, vae_dtype=dt)
except ValueError as e:
if "(B, C, T, H, W)" in str(e):
raise TypeError(f"VAE {type(stage.vae).__name__} returns non-video output; load the causal video VAE")
raise Prevention
- Load the causal video VAE for video pipelines
- Wrap VAEs so rank is preserved end to end
- Component-swap tests should assert decode output ndim
When it happens
Trigger: Loading an image VAE (or a VAE wrapper returning 4D) instead of the causal video VAE; a decode path that squeezes the temporal dimension for single-chunk outputs.
Common situations: Pointing --component_paths.vae at image VAE weights; a custom VAE wrapper normalizing outputs to 4D; config drift after changing pipeline components.
Related errors
- SANA-WM refiner requires a string prompt or one prompt per b
- Stage-1 latent has {z.shape[2]} frames but sink_size={sink_s
- SANA-WM refiner requires batch.latents from stage 1.
- SANA-WM refiner expects 5D latents shaped (B, C, T, H, W), g
- SANA-WM refiner decoding expected a sink frame plus refined
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/ba0ea5c5dabb6783.
Report an issue: GitHub.