{"record":{"id":"71e430800877635d","repo":"huggingface/transformers","slug":"conv3dtolinear-expects-a-5d-or-2d-tensor-got-ten","errorCode":null,"errorMessage":"Conv3dToLinear expects a 5D or 2D tensor, got {tensor.ndim}D","messagePattern":"Conv3dToLinear expects a 5D or 2D tensor, got (.+?)D","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/core_model_loading.py","lineNumber":379,"sourceCode":"        if len(target_patterns) > 1:\n            if len(source_patterns) == 1:\n                return source_patterns[0]\n            else:\n                raise ValueError(\"Undefined Operation encountered!\")\n        return target_patterns[0]\n\n    @torch.no_grad\n    def convert(\n        self, input_dict: dict[str, torch.Tensor], source_patterns: list[str], target_patterns: list[str], **kwargs\n    ) -> dict[str, torch.Tensor]:\n        target_pattern = self._get_target_pattern(input_dict, source_patterns, target_patterns)\n        tensors = next(iter(input_dict.values()))\n        tensor = tensors[0] if isinstance(tensors, list) else tensors\n\n        if tensor.ndim == 5:\n            tensor = tensor.reshape(tensor.shape[0], -1).contiguous()\n        elif tensor.ndim != 2:\n            raise ValueError(f\"Conv3dToLinear expects a 5D or 2D tensor, got {tensor.ndim}D\")\n\n        return {target_pattern: tensor}\n\n    @property\n    def reverse_op(self) -> ConversionOps:\n        return LinearToConv3d(in_channels=self.in_channels, kernel_size=self.kernel_size)\n\n\nclass LinearToConv3d(ConversionOps):\n    \"\"\"Flattened Linear weights → Conv3d layout.\"\"\"\n\n    def __init__(self, in_channels: int, kernel_size: tuple[int, int, int]):\n        self.in_channels = in_channels\n        self.kernel_size = kernel_size\n\n    @torch.no_grad\n    def convert(\n        self, input_dict: dict[str, torch.Tensor], source_patterns: list[str], target_patterns: list[str], **kwargs","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/core_model_loading.py#L361-L397","documentation":"Raised by Conv3dToLinear.convert (core_model_loading.py:379). This op converts a Conv3d weight (5D: [out_ch, in_ch, kH, kW, kD]) into a flattened Linear weight (2D) by merging the last four axes. If the collected tensor is neither 5D nor already 2D (e.g. it is 4D because the checkpoint stores a Conv2d weight, or 1D because a bias was matched), the reshape is ambiguous and the op refuses to proceed.","triggerScenarios":"A WeightConverter with operations=[Conv3dToLinear()] whose source pattern matches a tensor with ndim not in {5, 2}: typically a Conv2d weight (4D), a bias (1D), or a BatchNorm/LayerNorm parameter matched by an overly broad regex such as '.*weight' instead of '.*conv.*weight'.","commonSituations":"Porting a 3D-vision or video model (e.g. video encoders in VLMs) where the original repo used Conv3d but the checkpoint has an extra/fewer axis than expected; or the source regex accidentally matches unrelated weights. Also happens after upstream changes a Conv3d to Conv2d.","solutions":["Inspect the ndim/shape of the tensor collected for the failing pattern and tighten source_patterns so only the intended Conv3d weight matches.","If the checkpoint really stores a 4D Conv2d weight, use Conv2dToLinear (or the appropriate op) instead of Conv3dToLinear.","If the tensor is already a 2D Linear weight, the op passes it through — verify you are not double-converting or wrapping the tensor in an extra list dimension.","Check for a mismatch between the checkpoint revision and the conversion recipe version (old recipes vs new checkpoints)."],"exampleFix":"# before: broad pattern matches a 4D conv2d weight\nWeightConverter(source_patterns=[r\"vision.*weight\"], target_patterns=[r\"vision.fc.weight\"], operations=[Conv3dToLinear()])\n\n# after: pattern anchored to the actual conv3d block\nWeightConverter(source_patterns=[r\"vision.blocks.*conv3d.weight\"], target_patterns=[r\"vision.fc.weight\"], operations=[Conv3dToLinear()])","handlingStrategy":"validation","validationCode":"matched = [k for k in state_dict if re.search(pattern, k)]\nfor k in matched:\n    nd = state_dict[k].ndim\n    assert nd in (5, 2), f'{k} has ndim={nd}; Conv3dToLinear needs 5D or 2D — check the op or tighten the pattern'","typeGuard":"def is_conv3d_or_linear_weight(t: \"torch.Tensor\") -> bool:\n    return t.ndim in (5, 2)","tryCatchPattern":null,"preventionTips":["Anchor source patterns to concrete module names (e.g. 'conv3d.weight') instead of broad suffixes like '.*weight'.","Log the ndim/shape of every tensor matched by a converter pattern before running the full conversion.","Prefer the purpose-built op per architecture (Conv2dToLinear for 4D, Conv3dToLinear for 5D)."],"tags":["weight-conversion","conv3d","model-loading","shape-mismatch"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}