huggingface/candle · error

image width {w} is not a multiple of patch width {patch_w}

Error message

image width {w} is not a multiple of patch width {patch_w}

What it means

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.

Source

Thrown at candle-transformers/src/models/beit.rs:272

            ..Default::default()
        };
        let proj = candle_nn::conv2d(in_chans, embed_dim, patch_size, config, vb.pp("proj"))?;
        Ok(Self {
            proj,
            patch_size: (patch_size, patch_size),
        })
    }
}

impl Module for PatchEmbed {
    fn forward(&self, xs: &Tensor) -> Result<Tensor> {
        let (_b, _c, h, w) = xs.dims4()?;
        let (patch_h, patch_w) = self.patch_size;
        if (h % patch_h) != 0 {
            candle::bail!("image height {h} is not a multiple of patch height {patch_h}")
        }
        if (w % patch_w) != 0 {
            candle::bail!("image width {w} is not a multiple of patch width {patch_w}")
        }
        let xs = self.proj.forward(xs)?;
        let (b, c, h, w) = xs.dims4()?;
        // flatten embeddings.
        xs.reshape((b, c, h * w))?.transpose(1, 2)
    }
}

#[derive(Debug)]
pub struct BeitVisionTransformer {
    patch_embed: PatchEmbed,
    cls_token: Tensor,
    blocks: Vec<Block>,
    norm: LayerNorm,
    head: Linear,
}

impl BeitVisionTransformer {

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Resize or pad the image so width % patch_w == 0
  2. Center-crop to the nearest valid width
  3. Confirm patch_size in the model config matches your input preprocessing
  4. Inspect tensor dims after preprocessing to catch the mismatch early

Example fix

// before
let xs = Tensor::from_shape((1, 3, 224, 225), ...)?; // 225 % 16 != 0
// after
let xs = Tensor::from_shape((1, 3, 224, 224), ...)?;
Defensive patterns

Strategy: validation

Validate before calling

let (_, patch_w) = model.patch_size;
let (_, _, _, w) = xs.dims4()?;
assert!(w % patch_w == 0, "width {} not multiple of {}", w, patch_w);

Type guard

fn width_ok(width: usize, patch_w: usize) -> bool { width % patch_w == 0 }

Try / catch

match patch_embed.forward(&xs) {
    Ok(v) => v,
    Err(e) if e.to_string().contains("not a multiple") => {
        let xs = pad_width_to_multiple(&xs, model.patch_size.1)?;
        patch_embed.forward(&xs)
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: Aspect-ratio-preserving resize producing non-multiple widths, wrong patch-size config for the checkpoint, or padding/cropping errors in preprocessing.

Related errors


AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02). Data as JSON: /api/errors/25123aadc2ded8ae. Report an issue: GitHub.