sgl-project/sglang · error · ValueError

LTX-2 token latents seq_len={seq_len} is not divisible by to

Error message

LTX-2 token latents seq_len={seq_len} is not divisible by tokens_per_frame={tokens_per_frame}. Cannot time-shard for SP.

What it means

LTX-2 SP time-sharding splits packed token latents along the temporal axis, which requires seq_len to be an exact multiple of tokens_per_frame (one frame's token grid). If seq_len % tokens_per_frame != 0, the number of latent frames cannot be inferred and sharding is impossible. The message reports both values.

Source

Thrown at python/sglang/multimodal_gen/configs/pipeline_configs/ltx_2.py:367

        if (latent_height % int(self.patch_size)) != 0 or (
            latent_width % int(self.patch_size)
        ) != 0:
            raise ValueError(
                "Invalid spatial patching for packed token latents. Expected latent H/W "
                "to be divisible by patch_size, got "
                f"{latent_height=} {latent_width=} {self.patch_size=}."
            )

        post_patch_h = latent_height // int(self.patch_size)
        post_patch_w = latent_width // int(self.patch_size)
        tokens_per_frame = int(post_patch_h) * int(post_patch_w)
        if tokens_per_frame <= 0:
            raise ValueError(
                f"Invalid tokens_per_frame={tokens_per_frame} from "
                f"{latent_height=} {latent_width=} {self.patch_size=}"
            )
        if int(seq_len) % int(tokens_per_frame) != 0:
            raise ValueError(
                f"LTX-2 token latents seq_len={seq_len} is not divisible by "
                f"tokens_per_frame={tokens_per_frame}. Cannot time-shard for SP."
            )
        latent_num_frames = int(seq_len) // int(tokens_per_frame)
        return int(latent_num_frames), int(tokens_per_frame)

    def shard_latents_for_sp(self, batch, latents):
        """Shard LTX-2 packed token latents across SP ranks by latent time (frame) dimension."""
        sp_world_size = get_sp_world_size()
        if sp_world_size <= 1:
            return latents, False

        # Default behavior for 5D latents.
        if isinstance(latents, torch.Tensor) and latents.ndim == 5:
            return super().shard_latents_for_sp(batch, latents)

        # LTX-2 packed token latents [B, S, D]
        if not (isinstance(latents, torch.Tensor) and latents.ndim == 3):

View on GitHub (pinned to 0132848349)

Solutions

  1. Verify batch.height/batch.width in the request metadata exactly match the resolution used to produce the packed latents
  2. Confirm config vae_scale_factor and patch_size match the values used at latent-encoding time
  3. Check the packed tensor wasn't truncated/padded (e.g. by chunked prefill) so seq_len lost whole-frame alignment

Example fix

# before
# latents encoded at 768x1280, but batch declares 512x512 -> seq_len mismatch
batch = VideoBatch(height=512, width=512, seq_len=latent_seq_len)

# after
batch = VideoBatch(height=768, width=1280, seq_len=latent_seq_len)
assert latent_seq_len % config.tokens_per_frame(batch) == 0
Defensive patterns

Strategy: validation

Validate before calling

tpf = (batch.height // config.vae_scale_factor // config.patch_size) * (batch.width // config.vae_scale_factor // config.patch_size)
assert int(seq_len) % tpf == 0, (seq_len, tpf, batch.height, batch.width)

Prevention

When it happens

Trigger: Calling shard_latents_for_sp with a packed latent sequence whose length doesn't match whole frames — e.g. a batch mixing resolutions, seq_len from a different model's patching, or height/width in batch metadata inconsistent with the actual tensor shape.

Common situations: Feeding latents produced with a different patch_size or vae_scale_factor than the config declares; prompt-style (non-video) latents passed through the video path; batch metadata (height/width) disagreeing with the packed tensor's seq_len.

Related errors


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