sgl-project/sglang · error · TypeError
Kimi-K3 image feature must be a torch.Tensor, got {type(item
Error message
Kimi-K3 image feature must be a torch.Tensor, got {type(item.feature)} What it means
In materialize_item_features(), items without a deferred config must already hold a torch.Tensor in item.feature; any other type raises TypeError. This guards the local path where features are assumed precomputed before materialization.
Source
Thrown at python/sglang/srt/models/kimi_k3.py:3424
"Kimi-K3 cannot mix local preprocessed and deferred images"
)
return materialize_multimodal_features(
[item.feature for item in selected_items],
device=device,
dtype=target_dtype,
)
deferred = [
item.model_specific_data.get(DEFERRED_PREPROCESSING_KEY)
for item in selected_items
]
if any(config is not None for config in deferred):
materialized = [None] * len(selected_items)
deferred_by_backend = {}
for index, (item, config) in enumerate(zip(selected_items, deferred)):
if config is None:
if not isinstance(item.feature, torch.Tensor):
raise TypeError(
"Kimi-K3 image feature must be a torch.Tensor, "
f"got {type(item.feature)}"
)
materialized[index] = item.feature
else:
deferred_by_backend.setdefault(config.backend, []).append(index)
for backend, indices in deferred_by_backend.items():
group_items = [selected_items[index] for index in indices]
group_configs = [deferred[index] for index in indices]
# Map backend-group positions through the rank-local shard to global grid rows.
global_indices = [image_indices[index] for index in indices]
first_config = group_configs[0]
if backend == "gpu":
from sglang.srt.multimodal.processors.kimi_k25 import (
_gpu_preprocess_images,
)
View on GitHub (pinned to 0132848349)
Solutions
- Ensure local items have their .feature set to a torch.Tensor before calling get_image_feature()
- Convert non-tensor features with torch.as_tensor(..., dtype=target_dtype) beforehand
- If features are not computed, mark items as deferred with a proper backend config
Example fix
// before item.feature = np_array # then model.get_image_feature([item]) // after item.feature = torch.from_numpy(np_array) model.get_image_feature([item])
Defensive patterns
Strategy: type-guard
Validate before calling
for i in items:
if deferred_config(i) is None and not isinstance(i.feature, torch.Tensor):
i.feature = torch.as_tensor(i.feature) Type guard
import torch
def features_are_tensors(items) -> bool:
return all(isinstance(i.feature, torch.Tensor) for i in items if i.feature is not None) Try / catch
try:
model.get_image_feature(items)
except TypeError as e:
if "torch.Tensor" in str(e):
coerce_features_to_tensors(items)
return model.get_image_feature(items)
raise Prevention
- Always store torch.Tensor in item.feature after preprocessing
- Assert feature types in unit tests for your multimodal pipeline
When it happens
Trigger: A MultimodalDataItem with config None (not deferred) whose .feature is not a torch.Tensor — e.g. a numpy array, PIL image, raw pixel list, or None because preprocessing never ran.
Common situations: Skipping the local preprocessing step for some items; a pipeline change that stores raw pixels instead of tensor features; None feature from a failed earlier stage.
Related errors
- Unsupported image type: {type(image)}
- Input 'data' must be a torch.Tensor, but got {type(data)}
- Expected a PIL image, got {type(image)}
- Kimi-K3 encoder mode supports image input only
- Kimi-K3 expects one vision grid per MultimodalDataItem; spli
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/e5968949d86fda79.
Report an issue: GitHub.