sgl-project/sglang · error · ValueError

Expected one original size for each K3 image.

Error message

Expected one original size for each K3 image.

What it means

Kimi K3 expansion requires one original uploaded (width, height) per image so it can wrap each expanded feature span with the model's size-control tokens. If len(image_token_counts) != len(image_sizes), it cannot pair counts with sizes and raises ValueError.

Source

Thrown at python/sglang/srt/multimodal/processors/kimi_k3.py:90

        return list(tokenizer.encode(text))


def _expand_k3_image_prompt_token_ids(
    input_ids: Union[List[int], torch.Tensor],
    image_token_id: int,
    image_token_counts: List[int],
    image_sizes: List[tuple[int, int]],
    tokenizer,
) -> torch.Tensor:
    """Expand K3 image placeholders into the checkpoint's media contract.

    K3 requires each image feature span to be enclosed by its original uploaded
    dimensions.  The chat template deliberately emits one ``media_pad`` per
    image; after decode, insert the surrounding control tokens and expand that
    one placeholder to the NaViT feature count.
    """
    if len(image_token_counts) != len(image_sizes):
        raise ValueError("Expected one original size for each K3 image.")

    if isinstance(input_ids, torch.Tensor):
        input_ids = input_ids.detach().flatten().cpu().numpy()
    input_ids = np.asarray(input_ids, dtype=np.int64)

    placeholder_count = np.count_nonzero(input_ids == image_token_id)
    if placeholder_count != len(image_token_counts):
        raise ValueError(
            f"Expected {len(image_token_counts)} image placeholder token(s), "
            f"found {placeholder_count}."
        )

    output = []
    image_index = 0
    for token_id in input_ids:
        if token_id != image_token_id:
            output.append(int(token_id))
            continue

View on GitHub (pinned to 0132848349)

Solutions

  1. Supply one original [w,h] (or h,w per API) size entry per image, matching image_token_counts
  2. Populate image_sizes from the actual uploaded files (PIL Image.size) at request build time
  3. Add a pre-flight assert len(image_token_counts) == len(image_sizes)

Example fix

# before
expand(ids, image_token_counts=[c1, c2], image_sizes=[(1024, 768)])

# after
expand(ids, image_token_counts=[c1, c2], image_sizes=[(1024, 768), (512, 512)])
Defensive patterns

Strategy: validation

Validate before calling

assert len(image_token_counts) == len(image_sizes), (
    f"{len(image_token_counts)} counts vs {len(image_sizes)} sizes"
)

Prevention

When it happens

Trigger: Calling _expand_k3_image_prompt_token_ids (via _prepare_input_ids, compose_request, or get_mm_data) with image_token_counts and image_sizes lists of different lengths.

Common situations: Passing original sizes only for a subset of images, reusing cached sizes after adding/removing an image, or a data loader that fails to record the source dimensions for downscaled/cached images.

Related errors


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