{"record":{"id":"7eae1eb25fede8f9","repo":"huggingface/transformers","slug":"unable-to-infer-channel-dimension-format","errorCode":null,"errorMessage":"Unable to infer channel dimension format","messagePattern":"Unable to infer channel dimension format","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/image_utils.py","lineNumber":324,"sourceCode":"    if image.ndim == 3:\n        first_dim, last_dim = 0, 2\n    elif image.ndim == 4:\n        first_dim, last_dim = 1, 3\n    elif image.ndim == 5:\n        first_dim, last_dim = 2, 4\n    else:\n        raise ValueError(f\"Unsupported number of image dimensions: {image.ndim}\")\n\n    if image.shape[first_dim] in num_channels and image.shape[last_dim] in num_channels:\n        logger.warning(\n            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.\"\n        )\n        return ChannelDimension.FIRST\n    elif image.shape[first_dim] in num_channels:\n        return ChannelDimension.FIRST\n    elif image.shape[last_dim] in num_channels:\n        return ChannelDimension.LAST\n    raise ValueError(\"Unable to infer channel dimension format\")\n\n\ndef get_channel_dimension_axis(image: np.ndarray, input_data_format: ChannelDimension | str | None = None) -> int:\n    \"\"\"\n    Returns the channel dimension axis of the image.\n\n    Args:\n        image (`np.ndarray`):\n            The image to get the channel dimension axis of.\n        input_data_format (`ChannelDimension` or `str`, *optional*):\n            The channel dimension format of the image. If `None`, will infer the channel dimension from the image.\n\n    Returns:\n        The channel dimension axis of the image.\n    \"\"\"\n    if input_data_format is None:\n        input_data_format = infer_channel_dimension_format(image)\n    if input_data_format == ChannelDimension.FIRST:","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/image_utils.py#L306-L342","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass the channel count explicitly: `infer_channel_dimension_format(img, num_channels=4)` (or whatever your channel count is).","Better: pass `input_data_format=ChannelDimension.FIRST` (or 'channels_last') to the processor's `preprocess` so inference is skipped entirely.","Convert RGBA to RGB before preprocessing: `image.convert('RGB')` for PIL, or slice the alpha channel away.","For multispectral data, preprocess manually or write a custom processor rather than relying on 1/3-channel inference."],"exampleFix":"// before\nrgba = load_image(\"logo.png\")               # may stay RGBA in some paths\narr = np.array(rgba)[:, :, :3]              # forget -> later (H, W, 4) raises\nfmt = infer_channel_dimension_format(arr)  # ValueError\n\n// after\nfrom transformers.image_utils import ChannelDimension\nfmt = infer_channel_dimension_format(arr, num_channels=4)\n# or bypass inference at the processor level:\ninputs = processor(images=arr, input_data_format=ChannelDimension.LAST, ...)","handlingStrategy":"validation","validationCode":"from transformers.image_utils import ChannelDimension\n\ndef infer_or_die(img, num_channels=(1, 3)):\n    if img.ndim in (3, 4, 5):\n        first = img.shape[img.ndim - 3] if False else (0, 1, 2)[img.ndim - 3]\n        last = img.ndim - 1\n        if img.shape[first] not in num_channels and img.shape[last] not in num_channels:\n            raise ValueError(f\"cannot locate channel axis in {img.shape}; pass input_data_format\")\n    return img\n\n# simplest defense: never rely on inference\ninputs = processor(images=img, input_data_format=ChannelDimension.FIRST, ...)","typeGuard":"def channel_axis_is_inferable(img, num_channels=(1, 3)) -> bool:\n    if img.ndim not in (3, 4, 5):\n        return False\n    f, l = (0, 2) if img.ndim == 3 else ((1, 3) if img.ndim == 4 else (2, 4))\n    return img.shape[f] in num_channels or img.shape[l] in num_channels","tryCatchPattern":null,"preventionTips":["Pass input_data_format explicitly wherever the layout is known.","Convert RGBA to RGB (image.convert('RGB')) before preprocessing.","For non-1/3-channel data, pass num_channels to inference or preprocess manually."],"tags":["image-processing","channel-dimension","shape-inference"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}