sgl-project/sglang · error · ValueError

SANA-WM realtime denoising requires a realtime session

Error message

SANA-WM realtime denoising requires a realtime session

What it means

The realtime per-chunk path stores autoregressive state (latents, scheduler, KV cache) in a per-session RealtimeCausalDiTState. If batch.session is None there is no session to key the state on, so realtime denoising cannot proceed.

Solutions

  1. Create the realtime session before sending chunks and attach it to each tick's Req
  2. Fix request routing so only session-backed Reqs take the realtime path
  3. If the session was disposed, re-establish it and resend from chunk 0

Example fix

# before
batch.session = None
streaming_stage.forward(batch, server_args)
# after
batch.session = get_or_create_session(session_id)
streaming_stage.forward(batch, server_args)
Defensive patterns

Strategy: validation

Validate before calling

if batch.session is None:
    batch.session = get_or_create_session(session_id)

Type guard

null

Try / catch

try:
    resp = stage.forward(batch, server_args)
except ValueError as e:
    if "realtime session" in str(e):
        raise SessionLost(session_id) from e
    raise

Prevention

When it happens

Trigger: Sending a realtime chunk through the streaming stage with batch.session unset — e.g. an offline-style Req routed into the realtime path, or a session that was closed/never created before the first tick.

Common situations: Misrouted requests (offline vs realtime dispatch based on session presence); a gateway/proxy stripping the session field; racing session teardown with in-flight chunks.

Related errors


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

Appendix: source

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

        SanaWMSelfForcingSampler.evict_stale_kv_cache(
            kv_cache, chunk_idx, valid, num_cached_blocks, num_blocks
        )

    # Realtime per-chunk path (sessions): per-session state in RealtimeCausalDiTState.
    @torch.no_grad()
    def _forward_realtime_chunk(self, batch: Req, server_args: ServerArgs) -> Req:
        if batch.latents is None or batch.latents.ndim != 5:
            raise ValueError(
                "SANA-WM realtime denoising expects this tick's pre-noised chunk "
                "latents (B, C, n, H, W) from the latent-preparation stage."
            )
        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:

View on GitHub (pinned to 0132848349)