huggingface/candle · error

convtr1d: shape mismatch on c_in {:?} {:?}

Error message

convtr1d: shape mismatch on c_in {:?} {:?}

What it means

When Metal conv_transpose1d uses the col2im path (USE_COL2IM_CONV1D_TR), it treats the input as (b_size, c_in, l_in) and the kernel as (c_in, c_out, k_size); if the input's c_in does not match the kernel's c_in the shapes are incompatible and the backend bails with both shapes in the message.

Source

Thrown at candle-core/src/metal_backend/mod.rs:1006

        layout: &Layout,
        k: &Self,
        k_layout: &Layout,
        params: &ParamsConvTranspose1D,
    ) -> Result<Self> {
        const USE_COL2IM_CONV1D_TR: bool = true;

        let can_use_col2im = k_layout.is_contiguous()
            && params.dilation == 1
            && params.padding == 0
            && params.output_padding == 0;
        let l_out = params.l_out();
        let dst_el = params.c_out * l_out * params.b_size;

        let buffer = if USE_COL2IM_CONV1D_TR && can_use_col2im {
            let (b_size, c_in, l_in) = layout.shape().dims3()?;
            let (c_in2, c_out, k_size) = k_layout.shape().dims3()?;
            if c_in != c_in2 {
                crate::bail!(
                    "convtr1d: shape mismatch on c_in {:?} {:?}",
                    layout.shape(),
                    k_layout.shape()
                )
            }
            let buffer = self
                .device
                .new_buffer_builder()
                .with_size_for(dst_el, self.dtype)
                .with_label("conv_transpose1d")
                .build()?;

            let name = match self.dtype {
                DType::F32 => "col2im1d_f32",
                DType::F16 => "col2im1d_f16",
                DType::BF16 => "col2im1d_bf16",
                DType::U32 => "col2im1d_u32",
                DType::U8 => "col2im1d_u8",

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Ensure the kernel weight has shape (c_in, c_out, k_size) matching the input's channels
  2. Fix the layer config so in_channels matches the previous layer's out_channels
  3. Permute the weight with transpose/permute to the expected layout
  4. Check checkpoint conversion code for axis ordering mistakes

Example fix

// before
let k = weight.transpose(0, 1)?; // (c_out, c_in, k) — wrong order
// after
let k = weight; // keep (c_in, c_out, k) as expected by convtr1d
Defensive patterns

Strategy: validation

Validate before calling

let (b, c_in, l) = x.dims3()?;
let (k_c_in, _k_c_out, _k) = kernel.dims3()?;
if c_in != k_c_in {
    anyhow::bail!("convtr1d kernel expects (c_in, c_out, k); got c_in={} vs input c={}", k_c_in, c_in);
}

Prevention

When it happens

Trigger: Calling conv_transpose1d on Metal with a kernel whose input-channel count differs from the tensor's channel count — a misconfigured ConvTranspose1d layer (wrong in_channels) or wrongly-shaped weight tensor.

Common situations: Hand-constructing transposed-conv weights with transposed dims; loading checkpoints whose convtr weight layout differs; passing (c_out, c_in, k) instead of (c_in, c_out, k).

Related errors


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