{"record":{"id":"4cde9ceeec8358c7","repo":"sgl-project/sglang","slug":"f-expected-camera-embedding-shape-b-c-f-h-w","errorCode":null,"errorMessage":"f\"Expected camera embedding shape [B, C, F, H, W], got {tuple(x.shape)}\"","messagePattern":"f\"Expected camera embedding shape \\[B, C, F, H, W\\], got (.+?)\"","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/layers/visual_embedding.py","lineNumber":142,"sourceCode":"        super().__init__()\n        del prefix\n        if isinstance(patch_size, list | tuple):\n            if len(patch_size) != 3:\n                raise ValueError(\n                    f\"patch_size must have length 3, got {len(patch_size)}\"\n                )\n            patch_size = tuple(patch_size)\n        else:\n            raise ValueError(f\"Unsupported patch_size type: {type(patch_size)}\")\n\n        self.patch_size = patch_size\n        pt, ph, pw = self.patch_size\n        self.in_features = in_chans * pt * ph * pw\n        self.proj = nn.Linear(self.in_features, embed_dim, bias=bias, dtype=dtype)\n\n    def forward(self, x: torch.Tensor) -> torch.Tensor:\n        if x.dim() != 5:\n            raise ValueError(\n                f\"Expected camera embedding shape [B, C, F, H, W], got {tuple(x.shape)}\"\n            )\n\n        bsz, channels, frames, height, width = x.shape\n        pt, ph, pw = self.patch_size\n        if (frames % pt) != 0 or (height % ph) != 0 or (width % pw) != 0:\n            raise ValueError(\n                f\"Input shape {tuple(x.shape)} must be divisible by patch_size {self.patch_size}\"\n            )\n\n        x = x.view(\n            bsz,\n            channels,\n            frames // pt,\n            pt,\n            height // ph,\n            ph,\n            width // pw,","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/layers/visual_embedding.py#L124-L160","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reshape input to 5-D: images become x.unsqueeze(2) so [B,C,H,W] -> [B,C,1,H,W]","Fix preprocessing to always emit video clips in BCFHW order, even for a single frame","Add an assertion in the data pipeline: assert x.dim() == 5 before calling the model"],"exampleFix":"# before\nemb = layer(image)  # image: [B, 3, H, W]\n# after\nemb = layer(image.unsqueeze(2))  # [B, 3, 1, H, W]","handlingStrategy":"type-guard","validationCode":"def to_bcfhw(x: torch.Tensor) -> torch.Tensor:\n    if x.dim() == 4:\n        x = x.unsqueeze(2)\n    if x.dim() != 5:\n        raise ValueError(f\"expected 5-D input, got {tuple(x.shape)}\")\n    return x\n\nx = to_bcfhw(preprocessed)","typeGuard":"def is_bcfhw(x: torch.Tensor) -> bool:\n    return isinstance(x, torch.Tensor) and x.dim() == 5","tryCatchPattern":null,"preventionTips":["Standardize the data pipeline to always emit [B,C,F,H,W] even for single images (unsqueeze frame dim)","Assert tensor rank in dataloader collate before batching"],"tags":["multimodal","tensor-shape","validation"],"backgroundTag":"tensor-dimension-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}