{"record":{"id":"37e977a5b907192b","repo":"huggingface/transformers","slug":"cannot-reshape-tensor-with-shape-tensor-shape-in","errorCode":null,"errorMessage":"Cannot reshape tensor with shape {tensor.shape} into {target_shape}","messagePattern":"Cannot reshape tensor with shape (.+?) into (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/core_model_loading.py","lineNumber":405,"sourceCode":"\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\n    ) -> dict[str, torch.Tensor]:\n        target_pattern = Conv3dToLinear._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        target_shape = (tensor.shape[0], self.in_channels, *self.kernel_size)\n        if tensor.numel() != math.prod(target_shape):\n            raise ValueError(f\"Cannot reshape tensor with shape {tensor.shape} into {target_shape}\")\n\n        return {target_pattern: tensor.reshape(target_shape).contiguous()}\n\n    @property\n    def reverse_op(self) -> ConversionOps:\n        return Conv3dToLinear(in_channels=self.in_channels, kernel_size=self.kernel_size)\n\n\nclass PermuteForRope(ConversionOps):\n    \"\"\"\n    Applies the permutation required to convert complex RoPE weights to the split sin/cos format.\n    \"\"\"\n\n    def __init__(\n        self, subconfig_key: str | None = None, permute_layer_names: list[str] | None = None, inverse: bool = False\n    ):\n        self.subconfig_key = subconfig_key\n        self.inverse = inverse","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/core_model_loading.py#L387-L423","documentation":"Raised by LinearToConv3d.convert (core_model_loading.py:405). The op reshapes a flattened [out_features, in_features*kH*kW*kD] Linear weight back into the Conv3d layout [out_ch, in_ch, kH, kW, kD] using the configured in_channels and kernel_size. It first checks total element counts: tensor.numel() must equal out_ch * in_channels * prod(kernel_size). A mismatch means the (in_channels, kernel_size) configuration does not describe this checkpoint tensor, so the reshape is impossible.","triggerScenarios":"Constructing LinearToConv3d(in_channels=..., kernel_size=(kH,kW,kD)) where in_channels * kH * kW * kD != tensor.shape[1] of the collected Linear weight — e.g. declaring kernel_size=(3,3,3) and in_channels=768 for a tensor of shape [out, 20736] (which implies a different product).","commonSituations":"Reverse-converting (saving) a model whose original implementation used a Conv3d with a patch size or channel count different from what the conversion recipe hard-codes; common when porting video encoders where patch embedding is expressed as a Linear (patchify) layer and the recipe author guessed the wrong kernel geometry.","solutions":["Compute tensor.shape[1] from the checkpoint and derive the correct factorization: in_channels * prod(kernel_size) must equal it (e.g. 20736 = 3*3*3*768 for kernel 3^3 and 768 channels).","Update the LinearToConv3d arguments in the conversion recipe to the correct in_channels/kernel_size.","If saving (reverse direction), make sure the forward op Conv3dToLinear was configured with the same geometry so the round trip is consistent."],"exampleFix":"# before: wrong kernel geometry\nLinearToConv3d(in_channels=768, kernel_size=(2, 2, 2))\n\n# after: 768 * 3*3*3 = 20736 matches tensor.shape[1]\nLinearToConv3d(in_channels=768, kernel_size=(3, 3, 3))","handlingStrategy":"validation","validationCode":"import math\nexpected_cols = in_channels * math.prod(kernel_size)\nassert tensor.shape[1] == expected_cols, (\n    f'Linear weight has {tensor.shape[1]} cols but in_channels*prod(kernel_size)={expected_cols}; '\n    'fix in_channels/kernel_size in LinearToConv3d'\n)","typeGuard":"def fits_conv3d_layout(tensor: \"torch.Tensor\", in_channels: int, kernel_size: tuple[int, ...]) -> bool:\n    import math\n    return tensor.ndim == 2 and tensor.shape[1] == in_channels * math.prod(kernel_size)","tryCatchPattern":null,"preventionTips":["Derive in_channels/kernel_size from the model config instead of hard-coding them.","Keep forward (Conv3dToLinear) and reverse (LinearToConv3d) geometry identical in recipes so round trips stay consistent.","Add a round-trip unit test: convert forward then reverse and assert shapes match the original."],"tags":["weight-conversion","conv3d","reshape","shape-mismatch"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}