huggingface/candle · error

Trilu expects input with at least 2 dimensions: {:?}

Error message

Trilu expects input with at least 2 dimensions: {:?}

What it means

The Trilu operator (upper/lower triangular extraction) operates on matrices, so its input must have at least 2 dimensions — the last two being the matrix shape. candle-onnx validates this and bails if the input tensor rank is below 2, since there is no matrix to triangularize.

Source

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

                values.insert(node.output[0].clone(), output);
            }
            "Trilu" => {
                let input = get(&node.input[0])?;

                // Get the diagonal offset 'k' from the second input if provided
                let k = if node.input.len() > 1 && !node.input[1].is_empty() {
                    to_vec0_flexible::<i64>(get(&node.input[1])?)?
                } else {
                    0
                };

                // Get the 'upper' attribute
                let upper = get_attr_opt::<i64>(node, "upper")?.copied().unwrap_or(1);

                // For batched inputs, we need to handle each matrix separately
                let dims = input.dims();
                if dims.len() < 2 {
                    bail!("Trilu expects input with at least 2 dimensions: {:?}", dims);
                }

                // Get the last two dimensions which represent the matrix
                let n = dims[dims.len() - 2];
                let m = dims[dims.len() - 1];
                let max_dim = std::cmp::max(n, m);

                // Handle the diagonal offset k
                let mask = if k != 0 {
                    let mut data = vec![0u32; n * m];
                    for i in 0..n {
                        for j in 0..m {
                            if (upper != 0 && (j as i64) >= (i as i64) + k)
                                || (upper == 0 && (j as i64) <= (i as i64) + k)
                            {
                                data[i * m + j] = 1u32;
                            }
                        }

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Add a reshape/unsqueeze before the Trilu node so input is at least 2-D
  2. Fix the exporting code to keep the matrix dimensions
  3. Validate input ranks in the graph before running inference

Example fix

# before: Trilu input shape [N]
# after
x = x.reshape((1, N))  # or Unsqueeze with axes=[0] before Trilu
Defensive patterns

Strategy: type-guard

Validate before calling

let dims = input.dims();
if dims.len() < 2 {
    return Err(format!("Trilu input rank {} < 2", dims.len()));
}

Type guard

fn is_matrix_like(t: &Tensor) -> bool { t.rank() >= 2 }

Try / catch

match eval(...) {
    Err(e) if e.contains("Trilu expects input") => unsqueeze_and_retry(input),
    other => other,
}

Prevention

When it happens

Trigger: Feeding a 0-d or 1-d tensor to a Trilu node, e.g. a graph that reshapes/squeezes data before Trilu leaving a [N] tensor.

Common situations: Malformed or badly exported graphs (attention mask construction, causal-mask builders) where an unsqueeze was lost; hand-crafted ONNX models.

Related errors


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