{"record":{"id":"25123aadc2ded8ae","repo":"huggingface/candle","slug":"image-width-w-is-not-a-multiple-of-patch-width","errorCode":null,"errorMessage":"image width {w} is not a multiple of patch width {patch_w}","messagePattern":"image width (.+?) is not a multiple of patch width (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-transformers/src/models/beit.rs","lineNumber":272,"sourceCode":"            ..Default::default()\n        };\n        let proj = candle_nn::conv2d(in_chans, embed_dim, patch_size, config, vb.pp(\"proj\"))?;\n        Ok(Self {\n            proj,\n            patch_size: (patch_size, patch_size),\n        })\n    }\n}\n\nimpl Module for PatchEmbed {\n    fn forward(&self, xs: &Tensor) -> Result<Tensor> {\n        let (_b, _c, h, w) = xs.dims4()?;\n        let (patch_h, patch_w) = self.patch_size;\n        if (h % patch_h) != 0 {\n            candle::bail!(\"image height {h} is not a multiple of patch height {patch_h}\")\n        }\n        if (w % patch_w) != 0 {\n            candle::bail!(\"image width {w} is not a multiple of patch width {patch_w}\")\n        }\n        let xs = self.proj.forward(xs)?;\n        let (b, c, h, w) = xs.dims4()?;\n        // flatten embeddings.\n        xs.reshape((b, c, h * w))?.transpose(1, 2)\n    }\n}\n\n#[derive(Debug)]\npub struct BeitVisionTransformer {\n    patch_embed: PatchEmbed,\n    cls_token: Tensor,\n    blocks: Vec<Block>,\n    norm: LayerNorm,\n    head: Linear,\n}\n\nimpl BeitVisionTransformer {","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-transformers/src/models/beit.rs#L254-L290","documentation":"The width counterpart of the BeiT PatchEmbed check: PatchEmbed::forward requires the image width to be an exact multiple of the patch width so the convolutional projection yields whole patches. Thrown before the projection when w % patch_w != 0.","triggerScenarios":"Forwarding an image tensor whose W dimension is not divisible by the model's patch_size.1, e.g. width 225 with patch width 16.","commonSituations":"Aspect-ratio-preserving resize producing non-multiple widths, wrong patch-size config for the checkpoint, or padding/cropping errors in preprocessing.","solutions":["Resize or pad the image so width % patch_w == 0","Center-crop to the nearest valid width","Confirm patch_size in the model config matches your input preprocessing","Inspect tensor dims after preprocessing to catch the mismatch early"],"exampleFix":"// before\nlet xs = Tensor::from_shape((1, 3, 224, 225), ...)?; // 225 % 16 != 0\n// after\nlet xs = Tensor::from_shape((1, 3, 224, 224), ...)?;","handlingStrategy":"validation","validationCode":"let (_, patch_w) = model.patch_size;\nlet (_, _, _, w) = xs.dims4()?;\nassert!(w % patch_w == 0, \"width {} not multiple of {}\", w, patch_w);","typeGuard":"fn width_ok(width: usize, patch_w: usize) -> bool { width % patch_w == 0 }","tryCatchPattern":"match patch_embed.forward(&xs) {\n    Ok(v) => v,\n    Err(e) if e.to_string().contains(\"not a multiple\") => {\n        let xs = pad_width_to_multiple(&xs, model.patch_size.1)?;\n        patch_embed.forward(&xs)\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Preserve divisibility when resizing with aspect ratio kept","Pad width to the next multiple of patch_w if cropping is unacceptable","Assert both h and w divisibility before forward","Keep a single preprocessing function so all inputs are normalized"],"tags":["rust","candle","vision","beit","shape-constraint"],"backgroundTag":"image-size-not-divisible-by-patch-size","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}