invoke-ai/InvokeAI · error · ValueError
Latent spatial dims must be even, got {h}x{w}
Error message
Latent spatial dims must be even, got {h}x{w} What it means
patchify_latents performs a 2x2 patchify ([B,32,H,W] -> [B,128,H/2,W/2]) by reshaping spatial dims, which is only valid when both H and W are even. Odd dimensions would lose pixels or break the view/permute, so the function raises ValueError with the offending dims.
Source
Thrown at invokeai/backend/ernie_image/sampling_utils.py:24
from typing import List
import torch
# Latent channels of the ERNIE-Image VAE (AutoencoderKLFlux2). The transformer's
# `in_channels` is this value times 4 (after a 2x2 patchify).
LATENT_CHANNELS: int = 32
# Total downscale factor between the image and the latent grid. Matches
# `2 ** len(vae.config.block_out_channels)` for AutoencoderKLFlux2.
VAE_SCALE_FACTOR: int = 16
def patchify_latents(latents: torch.Tensor) -> torch.Tensor:
"""2x2 patchify: [B, 32, H, W] -> [B, 128, H/2, W/2]."""
b, c, h, w = latents.shape
if h % 2 or w % 2:
raise ValueError(f"Latent spatial dims must be even, got {h}x{w}")
latents = latents.view(b, c, h // 2, 2, w // 2, 2)
latents = latents.permute(0, 1, 3, 5, 2, 4)
return latents.reshape(b, c * 4, h // 2, w // 2)
def unpatchify_latents(latents: torch.Tensor) -> torch.Tensor:
"""Reverse 2x2 patchify: [B, 128, H/2, W/2] -> [B, 32, H, W]."""
b, c, h, w = latents.shape
latents = latents.reshape(b, c // 4, 2, 2, h, w)
latents = latents.permute(0, 1, 4, 2, 5, 3)
return latents.reshape(b, c // 4, h * 2, w * 2)
def pad_text(
text_hiddens: List[torch.Tensor],
device: torch.device,
dtype: torch.dtype,
text_in_dim: int,View on GitHub (pinned to 0b6a024f2f)
Solutions
- Resize/pad the input image so latents are even (image dimensions multiple of 2*VAE_scale, e.g. multiples of 16 px).
- Center-crop the latents down to even H and W before patchifying.
- Round width/height choices in the UI/graph to the model's supported multiples.
Example fix
// before latents = vae.encode(image_501x333) # -> 63x42? no: 62x41 odd patchify_latents(latents) # raises // after image = image.resize((512, 512)) # multiples of 16 latents = vae.encode(image) patchify_latents(latents)
Defensive patterns
Strategy: validation
Validate before calling
b, c, h, w = latents.shape
assert h % 2 == 0 and w % 2 == 0, f"pad/crop latents before patchify: {h}x{w}" Type guard
def is_patchifiable(latents: torch.Tensor) -> bool:
return latents.dim() == 4 and latents.shape[-2] % 2 == 0 and latents.shape[-1] % 2 == 0 Try / catch
try:
patched = patchify_latents(latents)
except ValueError as e:
if "must be even" in str(e):
b, c, h, w = latents.shape
latents = latents[:, :, : h - h % 2, : w - w % 2]
patched = patchify_latents(latents)
else:
raise Prevention
- Constrain image sizes to multiples of 16 (VAE downscale x patch size).
- Pad or center-crop inputs before VAE encoding.
- Validate latent H/W parity in the graph before the diffusion node.
When it happens
Trigger: Calling patchify_latents on a latent tensor whose height or width is odd — e.g. latent size 33x41 produced by encoding an image whose dimensions don't round to a multiple of the VAE downscale factor.
Common situations: User-supplied images with odd pixel dimensions after VAE encoding (dim/8 rounding); custom resize logic producing non-multiple-of-16 latents; img2img pipelines not padding inputs.
Related errors
- Unexpected cond image shape: {tuple(rgb_bchw_01.shape)} (exp
- Unexpected mask shape: {tuple(mask_b1hw_01.shape)} (expected
- Krea-2 conditioning mask shape {tuple(mask.shape)} does not
- Expected noise with shape {expected_shape}, got {tuple(noise
- Latent channel mismatch: these latents have {latents.shape[1
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/b36f9605f5d4d670.
Report an issue: GitHub.