huggingface/transformers · error · ValueError

Unable to infer channel dimension format

Error message

Unable to infer channel dimension format

What it means

Raised by `transformers.image_utils.infer_channel_dimension_format` when the array rank is fine (3/4/5) but neither the candidate first axis nor the candidate last axis has a size matching `num_channels` (default (1, 3)). The function decides channels-first vs channels-last by looking for an axis of size 1 or 3; if neither end has such a size, the channel location is genuinely unidentifiable and it refuses to guess. If both ends match, it warns and assumes FIRST.

Source

Thrown at src/transformers/image_utils.py:324

    if image.ndim == 3:
        first_dim, last_dim = 0, 2
    elif image.ndim == 4:
        first_dim, last_dim = 1, 3
    elif image.ndim == 5:
        first_dim, last_dim = 2, 4
    else:
        raise ValueError(f"Unsupported number of image dimensions: {image.ndim}")

    if image.shape[first_dim] in num_channels and image.shape[last_dim] in num_channels:
        logger.warning(
            f"The channel dimension is ambiguous. Got image shape {image.shape}. Assuming channels are the first dimension. Use the [input_data_format](https://huggingface.co/docs/transformers/main/internal/image_processing_utils#transformers.image_transforms.rescale.input_data_format) parameter to assign the channel dimension."
        )
        return ChannelDimension.FIRST
    elif image.shape[first_dim] in num_channels:
        return ChannelDimension.FIRST
    elif image.shape[last_dim] in num_channels:
        return ChannelDimension.LAST
    raise ValueError("Unable to infer channel dimension format")


def get_channel_dimension_axis(image: np.ndarray, input_data_format: ChannelDimension | str | None = None) -> int:
    """
    Returns the channel dimension axis of the image.

    Args:
        image (`np.ndarray`):
            The image to get the channel dimension axis of.
        input_data_format (`ChannelDimension` or `str`, *optional*):
            The channel dimension format of the image. If `None`, will infer the channel dimension from the image.

    Returns:
        The channel dimension axis of the image.
    """
    if input_data_format is None:
        input_data_format = infer_channel_dimension_format(image)
    if input_data_format == ChannelDimension.FIRST:

View on GitHub (pinned to a597f97485)

Solutions

  1. Pass the channel count explicitly: `infer_channel_dimension_format(img, num_channels=4)` (or whatever your channel count is).
  2. Better: pass `input_data_format=ChannelDimension.FIRST` (or 'channels_last') to the processor's `preprocess` so inference is skipped entirely.
  3. Convert RGBA to RGB before preprocessing: `image.convert('RGB')` for PIL, or slice the alpha channel away.
  4. For multispectral data, preprocess manually or write a custom processor rather than relying on 1/3-channel inference.

Example fix

// before
rgba = load_image("logo.png")               # may stay RGBA in some paths
arr = np.array(rgba)[:, :, :3]              # forget -> later (H, W, 4) raises
fmt = infer_channel_dimension_format(arr)  # ValueError

// after
from transformers.image_utils import ChannelDimension
fmt = infer_channel_dimension_format(arr, num_channels=4)
# or bypass inference at the processor level:
inputs = processor(images=arr, input_data_format=ChannelDimension.LAST, ...)
Defensive patterns

Strategy: validation

Validate before calling

from transformers.image_utils import ChannelDimension

def infer_or_die(img, num_channels=(1, 3)):
    if img.ndim in (3, 4, 5):
        first = img.shape[img.ndim - 3] if False else (0, 1, 2)[img.ndim - 3]
        last = img.ndim - 1
        if img.shape[first] not in num_channels and img.shape[last] not in num_channels:
            raise ValueError(f"cannot locate channel axis in {img.shape}; pass input_data_format")
    return img

# simplest defense: never rely on inference
inputs = processor(images=img, input_data_format=ChannelDimension.FIRST, ...)

Type guard

def channel_axis_is_inferable(img, num_channels=(1, 3)) -> bool:
    if img.ndim not in (3, 4, 5):
        return False
    f, l = (0, 2) if img.ndim == 3 else ((1, 3) if img.ndim == 4 else (2, 4))
    return img.shape[f] in num_channels or img.shape[l] in num_channels

Prevention

When it happens

Trigger: Passing a 4-channel RGBA image (shape (4, H, W) or (H, W, 4)) with default num_channels; a (224, 224, 224)-shaped array where no axis is size 1 or 3; a 2-channel or multispectral (e.g. 12-band) image; any tensor whose batch/channel sizes happen to avoid {1, 3} at both ends.

Common situations: PNG with alpha channel not converted to RGB; satellite/multispectral imagery; images resized so spatial dims equal 3; forgetting to pass `input_data_format='channels_first'` in a custom pipeline where inference is ambiguous or impossible.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/7eae1eb25fede8f9. Report an issue: GitHub.