sgl-project/sglang · error · ValueError

f"Input shape {tuple(x.shape)} must be divisible by patch_si

Error message

f"Input shape {tuple(x.shape)} must be divisible by patch_size {self.patch_size}"

What it means

After confirming the input is 5-D, forward() checks that the temporal, height and width dimensions are exactly divisible by the configured patch_size (pt, ph, pw). If frames % pt, height % ph, or width % pw is nonzero, it raises this ValueError because the patchify view() would be invalid.

Source

Thrown at python/sglang/multimodal_gen/runtime/layers/visual_embedding.py:149

            patch_size = tuple(patch_size)
        else:
            raise ValueError(f"Unsupported patch_size type: {type(patch_size)}")

        self.patch_size = patch_size
        pt, ph, pw = self.patch_size
        self.in_features = in_chans * pt * ph * pw
        self.proj = nn.Linear(self.in_features, embed_dim, bias=bias, dtype=dtype)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        if x.dim() != 5:
            raise ValueError(
                f"Expected camera embedding shape [B, C, F, H, W], got {tuple(x.shape)}"
            )

        bsz, channels, frames, height, width = x.shape
        pt, ph, pw = self.patch_size
        if (frames % pt) != 0 or (height % ph) != 0 or (width % pw) != 0:
            raise ValueError(
                f"Input shape {tuple(x.shape)} must be divisible by patch_size {self.patch_size}"
            )

        x = x.view(
            bsz,
            channels,
            frames // pt,
            pt,
            height // ph,
            ph,
            width // pw,
            pw,
        )
        x = x.permute(0, 2, 4, 6, 1, 3, 5, 7).reshape(bsz, -1, self.in_features)
        return self.proj(x)


class Timesteps(_Timesteps):

View on GitHub (pinned to 0132848349)

Solutions

  1. Crop or pad the input so F,H,W are multiples of pt,ph,pw (e.g. center-crop to 1024, trim frames to an even count)
  2. Align preprocessing resolution with the model's patch_size from config
  3. For odd frame counts with pt=2, drop the extra frame: x = x[:, :, : x.shape[2] // pt * pt]

Example fix

# before
emb = layer(video)  # video: [B,3,15,1023,1023], patch (2,16,16)
# after
video = video[:, :, :14, :1024, :1024]
emb = layer(video)
Defensive patterns

Strategy: validation

Validate before calling

pt, ph, pw = layer.patch_size
f, h, w = x.shape[2], x.shape[3], x.shape[4]
x = x[:, :, : f // pt * pt, : h // ph * ph, : w // pw * pw]  # crop to multiples

Prevention

When it happens

Trigger: Calling forward with e.g. patch_size=(2,16,16) on a clip of 15 frames, or a 1023x1023 image with patch 16. Any non-multiple spatial/temporal extent triggers it.

Common situations: Variable-FPS video sampling producing odd frame counts with a temporal patch of 2; resolution not a multiple of the patch size (e.g. 1000px with patch 16); mixing a model config's patch_size with a different preprocessing resolution.

Related errors


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