sgl-project/sglang · error · TypeError
Expected CHW image tensor with 1 or 3 channels, got shape
Error message
Expected CHW image tensor with 1 or 3 channels, got shape {shape} What it means
After confirming the tensor is 3D CHW, the Step3-VL transform requires the channel dimension to be exactly 1 (grayscale, auto-replicated to 3) or 3 (RGB). Any other first dimension (e.g. 2, 4 for RGBA, or an HWC tensor misread as CHW) fails this check. This catches layout mistakes where width or an alpha channel ends up in the channel slot.
Solutions
- Convert RGBA to RGB before tensorizing: image.convert('RGB')
- permute HWC to CHW so channels are dim 0
- For grayscale masks, keep 1 channel — it is auto-expanded to 3
Example fix
# before
img = torch.from_numpy(rgba_array) # (H, W, 4)
img = img.permute(2, 0, 1)
# after
img = Image.fromarray(rgba_array).convert('RGB')
img = torch.from_numpy(np.array(img)).permute(2, 0, 1) Defensive patterns
Strategy: validation
Validate before calling
if isinstance(t, torch.Tensor) and t.ndim == 3:
assert t.shape[0] in (1, 3), f'bad channels: {tuple(t.shape)}' Type guard
def has_valid_channels(t: torch.Tensor) -> bool:
return t.ndim == 3 and t.shape[0] in (1, 3) Prevention
- Convert RGBA/multi-channel images to RGB at load time (PIL .convert('RGB'))
- Always permute HWC numpy arrays to CHW immediately after from_numpy
When it happens
Trigger: Passing a CHW tensor with shape[0] not in {1,3}: a 4-channel RGBA tensor (4,H,W), or an HWC tensor of a 4-pixel-wide image permuted incorrectly so a non-channel dim lands first.
Common situations: PNG images with alpha loaded as (4,H,W); masks saved as 2-channel float arrays; tensors converted from HWC without permute so channels land in the wrong axis.
Related errors
- Expected CHW image tensor, got shape
- Unsupported image type
- Step3-VL image item has num_patches > 0 but no…
- Step3-VL image item is missing num_patches.
- The number of placeholders does not match the number of…
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/8942a2d99d9112ce.
Report an issue: GitHub.
Appendix: source
Thrown at python/sglang/srt/multimodal/processors/step3_vl.py:43
Step3Image = Union[Image.Image, torch.Tensor]
ImageWithPatches = tuple[Step3Image, list[Step3Image], list[int] | None]
class GPUToTensor(torch.nn.Module):
def forward(
self, raw_image: Union[np.ndarray, Image.Image, torch.Tensor]
) -> torch.Tensor:
if isinstance(raw_image, torch.Tensor):
image_tensor = raw_image
if image_tensor.ndim != 3:
raise TypeError(
f"Expected CHW image tensor, got shape {tuple(image_tensor.shape)}"
)
if image_tensor.shape[0] == 1:
image_tensor = image_tensor.repeat(3, 1, 1)
elif image_tensor.shape[0] != 3:
raise TypeError(
f"Expected CHW image tensor with 1 or 3 channels, got shape {tuple(image_tensor.shape)}"
)
if image_tensor.dtype == torch.uint8:
image_tensor = image_tensor.to(torch.float32).div(255)
elif not image_tensor.is_floating_point():
image_tensor = image_tensor.to(torch.float32)
return image_tensor.contiguous()
if isinstance(raw_image, Image.Image):
image_tensor = transforms.ToTensor()(raw_image)
if torch.cuda.is_available():
image_tensor = image_tensor.to(torch.device("cuda"))
return image_tensor
if raw_image.ndim == 2:
raw_image = raw_image[:, :, None].repeat(3, -1)
if torch.cuda.is_available():
device = torch.device("cuda")
else:
device = torch.device("cpu")View on GitHub (pinned to 0132848349)