sgl-project/sglang · error · ValueError

raw_latent_shape must be divisible by patch_size for SAP att

Error message

raw_latent_shape must be divisible by patch_size for SAP attention

What it means

After parsing (T, H, W), the builder checks divisibility by patch_size (pt, ph, pw). If any spatial/temporal dim isn't evenly divisible by its patch component, it raises this ValueError, since patch-grid construction (num_frame = t // pt, frame_size = (h//ph)*(w//pw)) would otherwise be wrong.

Source

Thrown at python/sglang/multimodal_gen/runtime/layers/attention/backends/sparse_video_gen_2_attn.py:156

        zero_step_kmeans_init: bool,
        first_layers_fp: float,
        first_times_fp: float,
        context_length: int = 0,
        prompt_length: int | None = None,
        **kwargs: dict[str, Any],
    ) -> SparseVideoGen2AttentionMetadata:
        raw_shape = tuple(raw_latent_shape)
        if len(raw_shape) == 5:
            t, h, w = raw_shape[2:5]
        elif len(raw_shape) == 3:
            t, h, w = raw_shape
        else:
            raise ValueError(
                "raw_latent_shape must be (T, H, W) or (B, C, T, H, W) for SAP attention"
            )
        pt, ph, pw = patch_size
        if t % pt != 0 or h % ph != 0 or w % pw != 0:
            raise ValueError(
                "raw_latent_shape must be divisible by patch_size for SAP attention"
            )

        num_frame = t // pt
        frame_size = (h // ph) * (w // pw)

        return SparseVideoGen2AttentionMetadata(
            current_timestep=current_timestep,
            num_q_centroids=num_q_centroids,
            num_k_centroids=num_k_centroids,
            top_p_kmeans=top_p_kmeans,
            min_kc_ratio=min_kc_ratio,
            kmeans_iter_init=kmeans_iter_init,
            kmeans_iter_step=kmeans_iter_step,
            zero_step_kmeans_init=zero_step_kmeans_init,
            first_layers_fp=first_layers_fp,
            first_times_fp=first_times_fp,
            context_length=context_length,

View on GitHub (pinned to 0132848349)

Solutions

  1. Choose resolution/frame counts divisible by patch_size per-axis (T % pt == 0, H % ph == 0, W % pw == 0).
  2. Compute latent dims as raw_dims / vae_downsample, then round each to a multiple of the patch size before building metadata.
  3. Check the model card for supported resolution lists (e.g. multiples of 32/64 px) and use only those.

Example fix

# before
raw_latent_shape = (T, H, W)  # H=130, patch_size=(1,2,2) -> 130 % 2 != 0

# after
H = (H // ph) * ph  # round down to patch multiple
raw_latent_shape = (T, H, W)
Defensive patterns

Strategy: validation

Validate before calling

def check_patch_divisible(thw, patch):
    t, h, w = thw; pt, ph, pw = patch
    assert t % pt == 0 and h % ph == 0 and w % pw == 0, (
        f"{(t,h,w)} not divisible by patch {patch}")

check_patch_divisible((T, H, W), patch_size)
meta = builder.build(kwargs={"raw_latent_shape": (T, H, W), "patch_size": patch_size, ...})

Type guard

def is_patch_divisible(thw, patch) -> bool:
    return all(d % p == 0 for d, p in zip(thw, patch))

Prevention

When it happens

Trigger: Passing e.g. raw_latent_shape=(25, 130, 256) with patch_size=(1, 2, 2) — 130 % 2 != 0 — so h // ph loses pixels and the check fires.

Common situations: Mixing VAE downsample factors and DiT patch sizes that don't align (e.g. 8x VAE with patchify 2 on an odd resolution); user-requested resolutions not on the model's supported grid; a temporal compression factor that doesn't divide the frame count.

Related errors


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