sgl-project/sglang · error · ValueError
f"Unsupported patch_size type: {type(patch_size)}"
Error message
f"Unsupported patch_size type: {type(patch_size)}" What it means
The visual embedding layer's __init__ accepts patch_size only as an int (converted to a 3-tuple) or a 3-element sequence. Any other type — a string, a single float, a dict, or a tuple/list of length != 3 — reaches the else branch and raises this ValueError.
Source
Thrown at python/sglang/multimodal_gen/runtime/layers/visual_embedding.py:133
def __init__(
self,
patch_size=(1, 2, 2),
in_chans=384,
embed_dim=2048,
bias=True,
dtype=None,
prefix: str = "",
):
super().__init__()
del prefix
if isinstance(patch_size, list | tuple):
if len(patch_size) != 3:
raise ValueError(
f"patch_size must have length 3, got {len(patch_size)}"
)
patch_size = tuple(patch_size)
else:
raise ValueError(f"Unsupported patch_size type: {type(patch_size)}")
self.patch_size = patch_size
pt, ph, pw = self.patch_size
self.in_features = in_chans * pt * ph * pw
self.proj = nn.Linear(self.in_features, embed_dim, bias=bias, dtype=dtype)
def forward(self, x: torch.Tensor) -> torch.Tensor:
if x.dim() != 5:
raise ValueError(
f"Expected camera embedding shape [B, C, F, H, W], got {tuple(x.shape)}"
)
bsz, channels, frames, height, width = x.shape
pt, ph, pw = self.patch_size
if (frames % pt) != 0 or (height % ph) != 0 or (width % pw) != 0:
raise ValueError(
f"Input shape {tuple(x.shape)} must be divisible by patch_size {self.patch_size}"
)View on GitHub (pinned to 0132848349)
Solutions
- Pass patch_size as an int (e.g. 16, meaning (16,16,16)) or a length-3 sequence of ints like (2,16,16) (temporal, height, width)
- If the value comes from a config file, parse it before construction: json.loads(value) if isinstance(value, str)
- Add a sanity check on the config: assert isinstance(patch_size, (int, list, tuple)) and len(patch_size) in (1, 3)
Example fix
# before layer = VisualEmbedding(patch_size="2x16x16", ...) # after layer = VisualEmbedding(patch_size=(2, 16, 16), ...)
Defensive patterns
Strategy: validation
Validate before calling
def coerce_patch_size(v):
if isinstance(v, int):
return (v, v, v)
if isinstance(v, (list, tuple)) and len(v) == 3:
return tuple(int(x) for x in v)
raise TypeError(f"bad patch_size: {v!r}")
patch_size = coerce_patch_size(model_config['patch_size']) Type guard
def is_valid_patch_size(v) -> bool:
return isinstance(v, int) or (
isinstance(v, (list, tuple)) and len(v) == 3 and all(isinstance(x, int) for x in v)
) Prevention
- Normalize patch_size to a 3-tuple of ints right after reading the config file
- Validate config schemas before model construction
When it happens
Trigger: Constructing the camera/projector embedding layer with patch_size passed as e.g. "2x16x16" (a string), 16.0 (a float), a dict from a JSON config, or a 2-element tuple like (16, 16). Only int or length-3 list/tuple of ints is accepted.
Common situations: Loading a model config from JSON/YAML where patch_size got serialized as a string or nested list; hand-written model definitions copying HF config strings like patch_size=(1,16) with a typo; config round-tripping converting tuples to strings.
Related errors
- f"Unknown feature map: {feature_map}"
- batching config rule requires max_batch_size
- Z-Image text embeddings must have shape [seq, dim] or [batch
- Invalid threshold_type for topk: {threshold_type}. Choose 'q
- Invalid threshold_type: {threshold_type}. Choose 'query_head
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/fb2e84417edd4b59.
Report an issue: GitHub.