huggingface/pytorch-image-models · error · ValueError
Expected input ndim in (3, 4, 5); got {x.ndim}.
Error message
Expected input ndim in (3, 4, 5); got {x.ndim}. What it means
Gemma4Vit (NaFlex ViT supporting variable-resolution patchified input) accepts only 3D, 4D, or 5D tensors in patch embedding forward: (B,N,Ph*Pw*C) pre-patchified, image-like, or (B,C,Ph,Pw,N) layouts. Any other rank raises ValueError with the observed ndim.
Source
Thrown at timm/models/gemma4_vit.py:320
ph, pw = self.patch_size
if x.ndim == 4:
# Raw (B, C, H, W): patchify to C-Ph-Pw (Gemma4 native layout).
B, _, H, W = x.shape
if patch_coord is None:
patch_coord, patch_valid = self._default_patch_coord(B, H // ph, W // pw, x.device)
x, _ = batch_patchify(x, (ph, pw), pad=False, channels_last=False) # (B, N, C*Ph*Pw)
elif x.ndim == 5:
# (B, N, Ph, Pw, C) pre-patchified unflattened (NaFlex loader convention).
# Permute channels in from last to second to produce C-Ph-Pw flat.
x = x.permute(0, 1, 4, 2, 3).reshape(x.shape[0], x.shape[1], -1)
elif x.ndim == 3:
# (B, N, Ph*Pw*C) pre-patchified flat in NaFlex P-P-C layout; reinterpret as
# (B, N, Ph, Pw, C) then permute to C-Ph-Pw flat so input_proj matches layout.
B, N, PPC = x.shape
C = PPC // (ph * pw)
x = x.view(B, N, ph, pw, C).permute(0, 1, 4, 2, 3).reshape(B, N, PPC)
else:
raise ValueError(
f"Expected input ndim in (3, 4, 5); got {x.ndim}."
)
if patch_coord is None:
raise ValueError("patch_coord is required for pre-patchified input.")
if patch_valid is None:
sentinel = (patch_coord == -1).all(dim=-1)
if sentinel.any():
patch_valid = ~sentinel
else:
patch_valid = torch.ones(
patch_coord.shape[:2], dtype=torch.bool, device=patch_coord.device,
)
# Scale [0, 1] pixels to [-1, 1] (matches original Gemma4's `2 * (pixel_values - 0.5)`)
x = 2 * (x - 0.5)
x = self.input_proj(x.to(self.input_proj.weight.dtype))View on GitHub (pinned to 9a5261e31b)
Solutions
- Check x.ndim and x.shape before calling the model; add/collapse the batch dimension so ndim is 3-5
- For raw images pass (B, C, H, W) (4D); for pre-patchified input pass (B, N, Ph*Pw*C) with patch_coord
- Log shapes at the boundary of your data pipeline to find where the rank changes
Example fix
# before feats = model(x) # x.shape == (C, H, W), ndim=3 image-like mixed up with patch input # after x = x.unsqueeze(0) # (1, N, Ph*Pw*C) pre-patchified, ndim=3 with patch_coord passed feats = model(x, patch_coord=coords)
Defensive patterns
Strategy: type-guard
Validate before calling
assert x.ndim in (3, 4, 5), f'expected ndim 3-5, got {x.ndim}'
if x.ndim == 3:
assert patch_coord is not None, '3D pre-patchified input requires patch_coord'
out = model(x, patch_coord=patch_coord) Type guard
def is_valid_gemma4_input(x: torch.Tensor) -> bool:
return isinstance(x, torch.Tensor) and x.ndim in (3, 4, 5) Try / catch
try:
out = model(x)
except ValueError as e:
if 'Expected input ndim' in str(e):
raise ValueError(f'pipeline produced ndim={x.ndim}; check squeeze/unsqueeze ops') from e
raise Prevention
- Assert tensor rank at model boundaries in debug builds
- Keep (image, patch_coord, patch_valid) bundled in a dataclass to avoid rank confusion
- Unit-test preprocessing with representative shapes
When it happens
Trigger: Calling model.forward_features / forward on Gemma4ViT with a 2D or 6D tensor, e.g. flattened (N, C) embeddings or a double-batched 6D array.
Common situations: Pipeline bugs where tensors are squeezed/unsqueezed incorrectly (loss of batch dim making input 3D image-like when pre-patchified 3D expected, or extra dims from video (B,T,C,H,W)); feeding raw embeddings instead of images or patch grids.
Related errors
- output_fmt='NCHW' requires a raw image (B, C, H, W) input.
- patch_coord is required for pre-patchified input.
- Cannot pool {N} tokens with k={k}: N must be divisible by k^
- Image size ({H}, {W}) must be divisible by (patch_size * poo
- Gemma4VitEncoder does not support classification use cases.
AI-assisted analysis of huggingface/pytorch-image-models@9a5261e31b (2026-08-27).
Data as JSON: /api/errors/c8bab2a7cbba6f73.
Report an issue: GitHub.