sgl-project/sglang · error · ValueError
Packed pixel_values token count does not match spatial_shape
Error message
Packed pixel_values token count does not match spatial_shapes: {pixel_values_flat.shape[0]} vs {total_tokens}. What it means
Siglip2VisionModel.forward with packed (flattened, variable-resolution) pixel_values checks that the first dimension of pixel_values equals the sum of H*W over spatial_shapes. A mismatch means the image tensor and the per-image shape metadata disagree, so patches cannot be correctly unflattened.
Source
Thrown at python/sglang/srt/models/siglip2.py:95
Returns:
(1, total_tokens, embed_dim) packed embeddings.
"""
assert spatial_shapes.device.type == "cpu", (
"Expected `spatial_shapes` on CPU to avoid device-to-host sync in "
"variable-length packing."
)
if pixel_values_packed.dim() == 3:
assert pixel_values_packed.shape[0] == 1
pixel_values_flat = pixel_values_packed[0]
else:
pixel_values_flat = pixel_values_packed
lengths = (spatial_shapes[:, 0] * spatial_shapes[:, 1]).to(dtype=torch.int64)
lengths_list = lengths.tolist()
total_tokens = int(sum(lengths_list))
if total_tokens != pixel_values_flat.shape[0]:
raise ValueError(
"Packed pixel_values token count does not match spatial_shapes: "
f"{pixel_values_flat.shape[0]} vs {total_tokens}."
)
target_dtype = self.patch_embedding.weight.dtype
patch_embeds = self.patch_embedding(pixel_values_flat.to(dtype=target_dtype))
positional_embeddings = self.position_embedding.weight.reshape(
self.position_embedding_size, self.position_embedding_size, -1
)
packed_pos_embeds = self.resize_positional_embeddings_packed(
positional_embeddings,
spatial_shapes,
lengths_list=lengths_list,
)
embeddings = patch_embeds + packed_pos_embeds
return embeddings.unsqueeze(0)View on GitHub (pinned to 0132848349)
Solutions
- Regenerate pixel_values and spatial_shapes with the same processor/preprocessing pass so they stay consistent
- Debug-print sum(spatial_shapes[:,0]*spatial_shapes[:,1]) vs pixel_values.shape[0] to find which item diverges
- If packing multiple images, ensure spatial_shapes has one row per image and lengths sum to the packed token count
Example fix
# before pixel_values = preprocess(img) # shapes from another config # after out = processor(images=img, return_spatial_shapes=True) pixel_values, spatial_shapes = out.pixels, out.shapes # same pass
Defensive patterns
Strategy: validation
Validate before calling
lens = (spatial_shapes[:,0]*spatial_shapes[:,1]).sum().item() assert pixel_values.shape[0] == lens, (pixel_values.shape[0], lens)
Prevention
- Always produce pixel_values and spatial_shapes in one processor call
- Add a unit test for your preprocessing with two different image sizes
When it happens
Trigger: Feeding packed pixel_values whose rows != sum(spatial_shapes[:,0]*spatial_shapes[:,1]) — e.g. preprocessing produced shapes for a different image set, wrong patch size, or channel/format mismatch after flattening.
Common situations: Custom multimodal preprocessing pipelines for siglip2-based VLMs, resizing images differently than the processor that generated spatial_shapes, or concatenating pixel_values from multiple items without merging spatial_shapes accordingly.
Related errors
- Qwen-VL position_ids do not match the attention input
- Encoder produced {mm_embedding.shape[0]} tokens, but preproc
- Kimi-K3 deferred feature length does not match image grids
- Kimi-K3 image processor is missing deferred-preprocessing co
- Kimi GPU preprocessing expects raw uint8 pixels, got {image.
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/c83fd25fc5291aee.
Report an issue: GitHub.