{"record":{"id":"a7e028ffff43252b","repo":"sgl-project/sglang","slug":"expected-chw-image-tensor-got-shape-shape","errorCode":null,"errorMessage":"Expected CHW image tensor, got shape {shape}","messagePattern":"Expected CHW image tensor, got shape (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/multimodal/processors/step3_vl.py","lineNumber":37,"sourceCode":"    BaseMultimodalProcessor as SGLangBaseProcessor,\n)\nfrom sglang.srt.multimodal.processors.base_processor import (\n    MultimodalSpecialTokens,\n)\n\nStep3Image = Union[Image.Image, torch.Tensor]\nImageWithPatches = tuple[Step3Image, list[Step3Image], list[int] | None]\n\n\nclass GPUToTensor(torch.nn.Module):\n\n    def forward(\n        self, raw_image: Union[np.ndarray, Image.Image, torch.Tensor]\n    ) -> torch.Tensor:\n        if isinstance(raw_image, torch.Tensor):\n            image_tensor = raw_image\n            if image_tensor.ndim != 3:\n                raise TypeError(\n                    f\"Expected CHW image tensor, got shape {tuple(image_tensor.shape)}\"\n                )\n            if image_tensor.shape[0] == 1:\n                image_tensor = image_tensor.repeat(3, 1, 1)\n            elif image_tensor.shape[0] != 3:\n                raise TypeError(\n                    f\"Expected CHW image tensor with 1 or 3 channels, got shape {tuple(image_tensor.shape)}\"\n                )\n            if image_tensor.dtype == torch.uint8:\n                image_tensor = image_tensor.to(torch.float32).div(255)\n            elif not image_tensor.is_floating_point():\n                image_tensor = image_tensor.to(torch.float32)\n            return image_tensor.contiguous()\n        if isinstance(raw_image, Image.Image):\n            image_tensor = transforms.ToTensor()(raw_image)\n            if torch.cuda.is_available():\n                image_tensor = image_tensor.to(torch.device(\"cuda\"))\n            return image_tensor","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/multimodal/processors/step3_vl.py#L19-L55","documentation":"The Step3-VL multimodal preprocessor's image transform only accepts 3-dimensional torch tensors in CHW layout (channels, height, width). Passing a batched tensor (4D), a flat vector (1D), or an HWC tensor raises this TypeError before any normalization happens. The check runs first in forward() so downstream shape math never sees malformed input.","triggerScenarios":"Calling Step3VlImageTransform.forward (or the processor pipeline that uses it) with a torch.Tensor whose ndim != 3, e.g. a (1,3,224,224) batched tensor, a (224,224,3) HWC tensor, or a (224,224) grayscale tensor.","commonSituations":"Feeding tensors produced by torchvision DataLoader (usually BCHW) or by numpy-based code that converts with torch.from_numpy(img) keeping HWC order; passing an already-preprocessed batch instead of a single image.","solutions":["Permute HWC to CHW: tensor.permute(2, 0, 1) before passing","Squeeze batch dim: tensor.squeeze(0) if it is (1, C, H, W)","Pass a PIL Image or numpy HWC array instead of a raw tensor — the transform handles those natively"],"exampleFix":"# before\nimg = torch.from_numpy(np_image)  # HWC\nt = transform(img)\n# after\nimg = torch.from_numpy(np_image).permute(2, 0, 1)  # -> CHW\nt = transform(img)","handlingStrategy":"validation","validationCode":"def to_chw(t: torch.Tensor) -> torch.Tensor:\n    if t.ndim == 4 and t.shape[0] == 1:\n        t = t.squeeze(0)\n    if t.ndim == 3 and t.shape[-1] in (1, 3) and t.shape[0] not in (1, 3):\n        t = t.permute(2, 0, 1)\n    assert t.ndim == 3, f'expected CHW, got {tuple(t.shape)}'\n    return t","typeGuard":"def is_chw_tensor(t) -> bool:\n    return isinstance(t, torch.Tensor) and t.ndim == 3","tryCatchPattern":null,"preventionTips":["Standardize on CHW float tensors at your preprocessing boundary","Use PIL Images as the interchange format between pipeline stages"],"tags":["multimodal","image-processing","tensor-shape","step3-vl"],"backgroundTag":"invalid-tensor-shape","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}