sgl-project/sglang · error · ValueError

Expected one Kimi-K3 image span for each image

Error message

Expected one Kimi-K3 image span for each image

What it means

Raised in _build_deferred_output when the number of image-token spans found in input_ids does not equal the number of loaded images, before deferring GPU preprocessing. Each loaded image needs exactly one placeholder span to attach its deferred artifact.

Source

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

            processed_bytes += 3 * padded_width * padded_height * torch.float32.itemsize

        return raw_bytes <= processed_bytes

    def _build_deferred_output(self, base_output):
        (
            input_ids,
            resize_configs,
            deferred_preprocessing,
        ) = self._processor.prepare_deferred(
            base_output.input_text,
            base_output.images,
            base_output.input_ids,
        )
        offsets = self.get_mm_items_offset(
            input_ids.flatten(), self.mm_tokens.image_token_id
        )
        if len(offsets) != len(base_output.images):
            raise ValueError("Expected one Kimi-K3 image span for each image")

        items = []
        for image, resize_config, offset in zip(
            base_output.images, resize_configs, offsets
        ):
            grid_thw = _grid_thw_from_resize_config(
                resize_config, self._processor.preprocess_config.patch_size
            )
            item = MultimodalDataItem(
                modality=Modality.IMAGE,
                feature=to_chw_uint8(image),
                offsets=[offset],
                model_specific_data={
                    "image_grid_thw": torch.tensor([grid_thw], dtype=torch.int64),
                    DEFERRED_PREPROCESSING_KEY: deferred_preprocessing(
                        resize_config=resize_config
                    ),
                },

View on GitHub (pinned to 0132848349)

Solutions

  1. Ensure exactly one image placeholder per image in the prompt
  2. Check that image loading (load_mm_data) does not drop or merge images
  3. Verify get_mm_items_offset isn't collapsing consecutive placeholder tokens; keep separators between images
Defensive patterns

Strategy: validation

Validate before calling

def check_spans(processor, input_ids, images):
    offs = processor.get_mm_items_offset(input_ids.flatten(), processor.mm_tokens.image_token_id)
    return len(offs) == len(images)

Prevention

When it happens

Trigger: _process_mm_data_uncached with GPU preprocessing deferred and base_output.images length != number of image_token_id offsets in input_ids; usually a placeholder-mismatch that slipped past earlier checks or offsets merged after token expansion.

Common situations: Prompt template emits adjacent image tokens that merge into one span; images filtered/deduplicated during loading so base_output.images count changed.

Related errors


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