sgl-project/sglang · error · ValueError

Unsupported Kimi-K3 image channel count: {channels}

Error message

Unsupported Kimi-K3 image channel count: {channels}

What it means

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.

Source

Thrown at python/sglang/srt/multimodal/kimi_k3_image_processing.py:179

    """Run the checkpoint's exact processor only on locally owned images."""
    medias = []
    for item in items:
        image = item.feature
        if not isinstance(image, Image.Image):
            if not isinstance(image, torch.Tensor) or image.dtype != torch.uint8:
                raise TypeError(
                    "Kimi-K3 deferred CPU preprocessing expects PIL or uint8 tensors"
                )
            image = to_hwc_uint8(image).numpy()
            channels = image.shape[-1]
            if channels == 1:
                image = Image.fromarray(image[..., 0], mode="L")
            elif channels == 3:
                image = Image.fromarray(image, mode="RGB")
            elif channels == 4:
                image = Image.fromarray(image, mode="RGBA")
            else:
                raise ValueError(f"Unsupported Kimi-K3 image channel count: {channels}")
        medias.append({"type": "image", "image": image})

    output = image_processor.preprocess(medias, return_tensors="pt")
    expected_grids = torch.cat(
        [item.model_specific_data["grid_thws"] for item in items], dim=0
    )
    if not torch.equal(output["grid_thws"].cpu(), expected_grids.cpu()):
        raise ValueError("Kimi-K3 deferred CPU preprocessing produced wrong grids")
    return output["pixel_values"]


def materialize_kimi_k3_cpu_item_features(items, image_processor) -> list[torch.Tensor]:
    """Return exact checkpoint-processor features split by logical image."""
    pixel_values = materialize_kimi_k3_cpu_features(items, image_processor)
    patch_counts = [
        math.prod(item.model_specific_data["grid_thws"][0].tolist()) for item in items
    ]
    if sum(patch_counts) != pixel_values.shape[0]:

View on GitHub (pinned to 0132848349)

Solutions

  1. Convert the image to RGB or RGBA before passing (e.g. cv2.cvtColor(arr, cv2.COLOR_BGR2RGB))
  2. Squeeze accidental extra dimensions: arr = arr.squeeze() and verify arr.shape[-1] in (1,3,4)
  3. For grayscale+alpha, drop the alpha channel or expand to RGB

Example fix

// before
arr  # shape (H, W, 2)
materialize_kimi_k3_cpu_features([{'type':'image','image':arr}], ...)
// after
arr = arr[..., :3] if arr.shape[-1] >= 3 else np.repeat(arr[..., :1], 3, axis=-1)
materialize_kimi_k3_cpu_features([{'type':'image','image':arr}], ...)
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
assert 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]}"

Type guard

def has_supported_channels(arr):
    return getattr(arr, "ndim", 0) >= 2 and arr.shape[-1] in (1, 3, 4)

Prevention

When it happens

Trigger: Feeding a numpy array whose last dimension (channels) is not 1, 3, or 4 into the CPU materialization path for Kimi-K3 images.

Common situations: 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.

Related errors


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