huggingface/candle · error

dilations have to be the same on both axis {pads:?} {}

Error message

dilations have to be the same on both axis {pads:?} {}

What it means

For a Conv node with rank-2 weights, when the `dilations` attribute has two values candle-onnx requires both to be identical since it forwards a single dilation scalar to candle's conv2d. Mismatched per-axis dilations (p1 != p2) cause this bail; the message text interpolates `pads` by mistake but the problem is dilations.

Source

Thrown at candle-onnx/src/eval.rs:957

                            Some([p1, p2]) => {
                                if p1 != p2 {
                                    bail!(
                                        "strides have to be the same on both axis {pads:?} {}",
                                        node.name
                                    )
                                }
                                *p1 as usize
                            }
                            Some(s) => {
                                bail!("more strides than expected in conv2d {s:?} {}", node.name)
                            }
                        };
                        let dilations = match dilations {
                            None => 1,
                            Some([p]) => *p as usize,
                            Some([p1, p2]) => {
                                if p1 != p2 {
                                    bail!(
                                        "dilations have to be the same on both axis {pads:?} {}",
                                        node.name
                                    )
                                }
                                *p1 as usize
                            }
                            Some(s) => {
                                bail!("more dilations than expected in conv2d {s:?} {}", node.name)
                            }
                        };
                        xs.conv2d(ws, pads, strides, dilations, groups as usize)?
                    }
                    rank => bail!(
                        "unsupported rank for weight matrix {rank} in conv {}",
                        node.name
                    ),
                };
                let ys = if node.input.len() > 2 {

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Change the model so both dilation values are equal and re-export
  2. Replace per-axis dilation with a stack of equal-dilation convs or larger kernels in the source model
  3. Patch candle-onnx to pass per-axis dilations to candle's conv2d
  4. Edit the ONNX attribute directly to dilations=[d,d] when the model semantics allow it

Example fix

// before (TF): Conv2D(..., dilations=[2, 4])
// after: Conv2D(..., dilations=[2, 2])  # re-export to ONNX
Defensive patterns

Strategy: validation

Validate before calling

for node in &model.graph.node {
    if node.op_type == "Conv" {
        if let Some(d) = node.attribute.iter().find(|a| a.name == "dilations") {
            if d.ints.len() == 2 && d.ints[0] != d.ints[1] {
                panic!("node {}: asymmetric dilations {:?} unsupported", node.name, d.ints);
            }
        }
    }
}

Type guard

fn has_uniform_dilations(attr: &Attribute) -> bool {
    attr.name != "dilations" || attr.ints.iter().all(|&d| d == attr.ints[0])
}

Try / catch

match candle_onnx::simple_eval(&model, &inputs) {
    Err(e) if e.to_string().contains("dilations have to be the same") => {
        eprintln!("model needs symmetric conv dilations: {e}");
    }
    other => other?,
}

Prevention

When it happens

Trigger: simple_eval processes a Conv node with dilations like [2,4] — an atrous/dilated convolution with different rates per axis.

Common situations: TensorFlow tf.nn.atrous_conv2d variants with per-axis rates exported to ONNX; segmentation models (DeepLab-style) with asymmetric dilation; converted TFLite graphs.

Related errors


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