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
- Change the model so both dilation values are equal and re-export
- Replace per-axis dilation with a stack of equal-dilation convs or larger kernels in the source model
- Patch candle-onnx to pass per-axis dilations to candle's conv2d
- 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
- Use equal dilation rates per axis in dilated convolutions
- Lint for asymmetric dilations in exported models
- Route models with per-axis dilation to a backend with full support
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
- more pads than expected in conv2d {pads:?} {}
- strides have to be the same on both axis {pads:?} {}
- more strides than expected in conv2d {s:?} {}
- attribute {} was of type TENSOR, but no tensor was found
- attribute {} of type TENSOR was an invalid data_type number
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/cee38a24cb8d75a3.
Report an issue: GitHub.