sgl-project/sglang · error · ValueError

streaming needs >= {num_frame_per_block} latent frames, got

Error message

streaming needs >= {num_frame_per_block} latent frames, got {total_frames}.

What it means

_forward_offline chunks the total latent frames into autoregressive blocks of num_frame_per_block. It requires at least one full block (total_frames >= num_frame_per_block); otherwise num_chunks < 1 and it raises with the required minimum echoed.

Source

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

        sink_token = sampler_cfg.sink_token
        explicit_sigmas = sc.explicit_sigmas
        cfg_scale = sc.cfg_scale
        do_cfg = sc.do_cfg
        embeds_in, mask_in, cam_in, plk_in = sc.embeds, sc.mask, sc.camera, sc.plucker

        # parity harness: full-length conditioning fed to forward_long (windowed
        # internally per chunk via [start_f:end_f]).
        _fdump("cond_embeds", embeds_in)
        _fdump("cond_mask", mask_in)
        _fdump("cond_camera", cam_in)
        _fdump("cond_plucker", plk_in)

        scheduler = FlowMatchEulerDiscreteScheduler(shift=1.0)

        chunk_indices = self._autoregressive_segments(total_frames, num_frame_per_block)
        num_chunks = len(chunk_indices) - 1
        if num_chunks < 1:
            raise ValueError(
                f"streaming needs >= {num_frame_per_block} latent frames, got {total_frames}."
            )

        start_time = time.perf_counter()
        with self.use_declared_component(
            component_name="transformer", module=self.transformer
        ) as transformer:
            assert transformer is not None
            self.transformer = transformer
            num_blocks = len(transformer.blocks)
            if _dump_dir:  # parity harness: weights fingerprint
                parity_probe.dump_obj(
                    _dump_dir,
                    "dit_fingerprint",
                    parity_probe.weights_fingerprint(transformer),
                )
            kv_cache = [
                [[None] * _NUM_STREAM_CACHE_SLOTS for _ in range(num_blocks)]

View on GitHub (pinned to 0132848349)

Solutions

  1. Increase the requested duration/frames so total latent frames >= num_frame_per_block
  2. Lower num_frame_per_block to fit the clip
  3. Check temporal-compression and fps settings compute the intended frame count

Example fix

# before
server_args.pipeline_config.sampler.num_frame_per_block = 8
req.duration = 0.2  # yields ~3 latent frames
# after
req.duration = 1.0  # yields >= 8 latent frames
Defensive patterns

Strategy: validation

Validate before calling

assert total_frames >= num_frame_per_block, f"need >= {num_frame_per_block} latent frames, got {total_frames}"

Type guard

def long_enough(total_frames: int, block: int) -> bool:
    return total_frames >= block

Try / catch

null

Prevention

When it happens

Trigger: Requesting a video so short its latent frame count is below num_frame_per_block (e.g. duration*fps/temporal-compression yields 0 or partial frames), or num_frame_per_block configured larger than the generated length.

Common situations: Very short clips (sub-second durations); raising num_frame_per_block for throughput without regenerating latent length; fps/duration math producing fewer frames than expected.

Related errors


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