sgl-project/sglang · error · ValueError

f"Expected camera embedding shape [B, C, F, H, W], got {tupl

Error message

f"Expected camera embedding shape [B, C, F, H, W], got {tuple(x.shape)}"

What it means

The forward pass of the visual embedding expects a 5-D video tensor shaped [Batch, Channels, Frames, Height, Width] (BCFHW). If x.dim() != 5 — e.g. a 4-D image tensor [B,C,H,W] or a flat batch of patches — it raises this ValueError before any computation.

Source

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

        super().__init__()
        del prefix
        if isinstance(patch_size, list | tuple):
            if len(patch_size) != 3:
                raise ValueError(
                    f"patch_size must have length 3, got {len(patch_size)}"
                )
            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,

View on GitHub (pinned to 0132848349)

Solutions

  1. Reshape input to 5-D: images become x.unsqueeze(2) so [B,C,H,W] -> [B,C,1,H,W]
  2. Fix preprocessing to always emit video clips in BCFHW order, even for a single frame
  3. Add an assertion in the data pipeline: assert x.dim() == 5 before calling the model

Example fix

# before
emb = layer(image)  # image: [B, 3, H, W]
# after
emb = layer(image.unsqueeze(2))  # [B, 3, 1, H, W]
Defensive patterns

Strategy: type-guard

Validate before calling

def to_bcfhw(x: torch.Tensor) -> torch.Tensor:
    if x.dim() == 4:
        x = x.unsqueeze(2)
    if x.dim() != 5:
        raise ValueError(f"expected 5-D input, got {tuple(x.shape)}")
    return x

x = to_bcfhw(preprocessed)

Type guard

def is_bcfhw(x: torch.Tensor) -> bool:
    return isinstance(x, torch.Tensor) and x.dim() == 5

Prevention

When it happens

Trigger: Calling forward() with a single image [B,C,H,W], an unbatched clip [C,F,H,W], or channels-last input [B,F,H,W,C]. Any tensor that is not 5-D triggers it.

Common situations: Reusing an image-only pipeline that produces 4-D tensors; preprocessing that squeezes the frame dimension for single-frame video; converting from NHWC layout and forgetting to permute/add a frame axis.

Related errors


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