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))
continueView on GitHub (pinned to 0132848349)
Solutions
- Supply one original [w,h] (or h,w per API) size entry per image, matching image_token_counts
- Populate image_sizes from the actual uploaded files (PIL Image.size) at request build time
- 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
- Capture original file dimensions at upload time and keep them attached to each image
- Regenerate sizes whenever the image list changes
- Treat counts and sizes as a paired per-image record
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
- Grid dim ({_mm_grid_attrs[modality]}) not found in {mm_input
- Invalid grid metadata for kimi image tokens: {vals} (expecte
- The number of image placeholders exceeds img_grid_thw entrie
- The number of image placeholders does not match img_grid_thw
- Kimi image placeholders must map one-to-one to image data: e
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/8f230a68ae50e1ad.
Report an issue: GitHub.