tracel-ai/burn · error
input rank for GroupNorm should be at least 3, but got {}
Error message
input rank for GroupNorm should be at least 3, but got {} What it means
GroupNorm in burn-nn panics when the input tensor's rank (number of dimensions) is less than 3. GroupNorm normalizes over the channel dimension within each batch sample, so it requires at least [batch, channels, spatial...] shaped input. Rather than returning a Result, group_norm panics immediately because a rank < 3 input is always a programming error.
Source
Thrown at crates/burn-nn/src/modules/norm/group.rs:160
/// - `Y` is the output tensor
/// - `γ` is the learnable weight
/// - `β` is the learnable bias
///
pub(crate) fn group_norm<const D: usize>(
input: Tensor<D>,
gamma: Option<Tensor<1>>,
beta: Option<Tensor<1>>,
num_groups: usize,
epsilon: f64,
affine: bool,
) -> Tensor<D> {
if (beta.is_none() || gamma.is_none()) && affine {
panic!("Affine is set to true, but gamma or beta is None");
}
let shape = input.shape();
if shape.num_elements() <= 2 {
panic!(
"input rank for GroupNorm should be at least 3, but got {}",
shape.num_elements()
);
}
let batch_size = shape[0];
let num_channels = shape[1];
let hidden_size = shape[2..].iter().product::<usize>() * num_channels / num_groups;
let input = input.reshape([batch_size, num_groups, hidden_size]);
// Widen before the reduction when the input dtype cannot hold a sum of
// squares (see [`accumulation_dtype`]); `square()` below is what overflows.
// Narrowed again straight after, so the affine still runs at the model's
// own dtype and only the statistics pay for the wider arithmetic.
let original: FloatDType = input.dtype().into();
let widened = accumulation_dtype(input.dtype());
let input = match widened {View on GitHub (pinned to d16f7ba2ed)
Solutions
- Reshape the input to at least 3 dimensions ([batch, channels, ...]) before calling forward on GroupNorm.
- Check input.dims().len() >= 3 (and > 2 elements) before invoking group_norm.
- Audit the layer order so normalization happens before any flatten/reshape to 2D.
Example fix
// before let logits = model(x); // shape [batch, classes] let out = group_norm.forward(logits); // panics: rank 2 // after let features = features.reshape([batch, channels, spatial]); let normed = group_norm.forward(features);
Defensive patterns
Strategy: validation
Validate before calling
fn ensure_groupnorm_rank<B: burn::tensor::backend::Backend>(x: &burn::tensor::Tensor<B, 2>) -> burn::tensor::Tensor<B, 3> {
// rank < 3 would panic inside group_norm; reshape to [1, C, N] minimum
x.reshape([1, x.dims()[0], x.dims()[1]])
} Type guard
fn is_valid_groupnorm_input(shape: &[usize]) -> bool {
shape.len() >= 3
} Try / catch
// panic-based API: validate before calling instead of catching
if !is_valid_groupnorm_input(&input.dims()) {
input = input.reshape([...]); // fix rank before forward
}
let out = group_norm.forward(input); Prevention
- Assert input.dims().len() >= 3 at model boundaries (debug_assert in dev builds).
- Never flatten tensors before normalization layers; flatten only after the last norm/pool.
- Add a unit test feeding a rank-2 tensor to catch regressions early.
- Wrap GroupNorm usage in helper functions that reshape to [N, C, ...] automatically.
When it happens
Trigger: Calling group_norm (via GroupNorm::forward or forward_with_slicing) with a tensor of rank 2 or lower, e.g. a flattened tensor of shape [N, C] or a single [C] vector.
Common situations: Feeding a flattened tensor straight from a Linear layer into GroupNorm; forgetting to reshape after a squeeze/view; passing a 1D bias-like tensor; misconfigured model that removes the spatial dims before normalization.
Related errors
- Affine is set to true, but gamma or beta is None
- Unsupported tensor rank for optimizer state: {other}
- capture tensor operations must run inside CaptureDevice::cap
- Capture tensors do not support autodiff
- Autodiff should not wrap an autodiff tensor.
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/a1930cfd4f95cc90.
Report an issue: GitHub.