{"record":{"id":"57983a4a625cfaa7","repo":"sgl-project/sglang","slug":"unsupported-kimi-k3-image-channel-count-channels","errorCode":null,"errorMessage":"Unsupported Kimi-K3 image channel count: {channels}","messagePattern":"Unsupported Kimi-K3 image channel count: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/multimodal/kimi_k3_image_processing.py","lineNumber":179,"sourceCode":"    \"\"\"Run the checkpoint's exact processor only on locally owned images.\"\"\"\n    medias = []\n    for item in items:\n        image = item.feature\n        if not isinstance(image, Image.Image):\n            if not isinstance(image, torch.Tensor) or image.dtype != torch.uint8:\n                raise TypeError(\n                    \"Kimi-K3 deferred CPU preprocessing expects PIL or uint8 tensors\"\n                )\n            image = to_hwc_uint8(image).numpy()\n            channels = image.shape[-1]\n            if channels == 1:\n                image = Image.fromarray(image[..., 0], mode=\"L\")\n            elif channels == 3:\n                image = Image.fromarray(image, mode=\"RGB\")\n            elif channels == 4:\n                image = Image.fromarray(image, mode=\"RGBA\")\n            else:\n                raise ValueError(f\"Unsupported Kimi-K3 image channel count: {channels}\")\n        medias.append({\"type\": \"image\", \"image\": image})\n\n    output = image_processor.preprocess(medias, return_tensors=\"pt\")\n    expected_grids = torch.cat(\n        [item.model_specific_data[\"grid_thws\"] for item in items], dim=0\n    )\n    if not torch.equal(output[\"grid_thws\"].cpu(), expected_grids.cpu()):\n        raise ValueError(\"Kimi-K3 deferred CPU preprocessing produced wrong grids\")\n    return output[\"pixel_values\"]\n\n\ndef materialize_kimi_k3_cpu_item_features(items, image_processor) -> list[torch.Tensor]:\n    \"\"\"Return exact checkpoint-processor features split by logical image.\"\"\"\n    pixel_values = materialize_kimi_k3_cpu_features(items, image_processor)\n    patch_counts = [\n        math.prod(item.model_specific_data[\"grid_thws\"][0].tolist()) for item in items\n    ]\n    if sum(patch_counts) != pixel_values.shape[0]:","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/multimodal/kimi_k3_image_processing.py#L161-L197","documentation":"materialize_kimi_k3_cpu_features converts numpy image arrays to PIL images and only supports 1 (L), 3 (RGB), and 4 (RGBA) channels. Any other channel count (e.g. 2, or >4 as in some multispectral TIFF/EXR data) raises this ValueError.","triggerScenarios":"Feeding a numpy array whose last dimension (channels) is not 1, 3, or 4 into the CPU materialization path for Kimi-K3 images.","commonSituations":"Loading grayscale+alpha (2-channel) or 16-bit multispectral imagery via cv2/tifffile and passing it straight in; arrays with an unexpected trailing dimension from a transpose bug.","solutions":["Convert the image to RGB or RGBA before passing (e.g. cv2.cvtColor(arr, cv2.COLOR_BGR2RGB))","Squeeze accidental extra dimensions: arr = arr.squeeze() and verify arr.shape[-1] in (1,3,4)","For grayscale+alpha, drop the alpha channel or expand to RGB"],"exampleFix":"// before\narr  # shape (H, W, 2)\nmaterialize_kimi_k3_cpu_features([{'type':'image','image':arr}], ...)\n// after\narr = arr[..., :3] if arr.shape[-1] >= 3 else np.repeat(arr[..., :1], 3, axis=-1)\nmaterialize_kimi_k3_cpu_features([{'type':'image','image':arr}], ...)","handlingStrategy":"validation","validationCode":"import numpy as np\nassert isinstance(arr, np.ndarray) and arr.ndim >= 2 and arr.shape[-1] in (1, 3, 4), f\"bad channels: {None if arr.ndim<2 else arr.shape[-1]}\"","typeGuard":"def has_supported_channels(arr):\n    return getattr(arr, \"ndim\", 0) >= 2 and arr.shape[-1] in (1, 3, 4)","tryCatchPattern":null,"preventionTips":["Normalize images to RGB/RGBA immediately after loading from cv2/tifffile","Log image shapes in ingestion pipelines to catch 2-channel or multispectral data early"],"tags":["multimodal","image-processing","numpy","kimi-k3"],"backgroundTag":"unsupported-image-format","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}