huggingface/candle · error · candle::Error
input rank for GroupNorm should be at least 3
Error message
input rank for GroupNorm should be at least 3
What it means
GroupNorm::forward requires input of rank >= 3: dimension 0 is batch, dimension 1 is channels, and the remaining dims form the spatial/feature extent. This bail fires when the tensor passed to forward has 2 or fewer dimensions, since GroupNorm cannot identify a channel axis in such input.
Source
Thrown at candle-nn/src/group_norm.rs:43
candle::bail!(
"GroupNorm: num_groups ({num_groups}) must divide num_channels ({num_channels})"
)
}
Ok(Self {
weight,
bias,
eps,
num_channels,
num_groups,
})
}
}
impl crate::Module for GroupNorm {
fn forward(&self, x: &Tensor) -> Result<Tensor> {
let x_shape = x.dims();
if x_shape.len() <= 2 {
candle::bail!("input rank for GroupNorm should be at least 3");
}
let (b_sz, n_channels) = (x_shape[0], x_shape[1]);
let hidden_size = x_shape[2..].iter().product::<usize>() * n_channels / self.num_groups;
if n_channels != self.num_channels {
candle::bail!(
"unexpected num-channels in GroupNorm ({n_channels} <> {}",
self.num_channels
)
}
let x_dtype = x.dtype();
let internal_dtype = match x_dtype {
DType::F16 | DType::BF16 => DType::F32,
d => d,
};
let x = x.reshape((b_sz, self.num_groups, hidden_size))?;
let x = x.to_dtype(internal_dtype)?;
let mean_x = (x.sum_keepdim(2)? / hidden_size as f64)?;
let x = x.broadcast_sub(&mean_x)?;View on GitHub (pinned to d5fee525bf)
Solutions
- Reshape the input to at least 3 dims, e.g. x.reshape((b, c, ()))? or restore spatial dims before forward.
- If the input is genuinely [B, C] features, use LayerNorm (candle_nn::layer_norm) instead of GroupNorm.
- Audit the module pipeline: GroupNorm should sit after conv-like layers producing [B, C, ...]; move it or replace it if placed after a flatten.
- Add a debug assert on x.rank() >= 3 in your forward path to catch this early.
Example fix
// before let x = x.flatten_all()?; // rank 1 let x = group_norm.forward(&x)?; // error // after let x = x.reshape((b, c, hw))?; let x = group_norm.forward(&x)?;
Defensive patterns
Strategy: type-guard
Validate before calling
if x.rank() < 3 {
return Err(anyhow!("GroupNorm needs rank>=3 input, got {}", x.rank()));
} Type guard
fn is_group_norm_input(x: &Tensor) -> bool { x.rank() >= 3 }
fn forward_gn(gn: &candle_nn::GroupNorm, x: &Tensor) -> candle::Result<Tensor> {
if !is_group_norm_input(x) {
candle::bail!("expected rank>=3 tensor for GroupNorm, got rank {}", x.rank());
}
gn.forward(x)
} Try / catch
let x = match group_norm.forward(&x) {
Ok(y) => y,
Err(e) if e.to_string().contains("rank") => {
let b = x.dim(0)?; let c = x.dim(1)?;
group_norm.forward(&x.reshape((b, c, ()))?)?
}
Err(e) => return Err(e.into()),
}; Prevention
- Keep GroupNorm only after conv/spatial layers producing [B, C, ...]; use LayerNorm for [B, C] features
- Avoid flatten_all before normalization layers; reshape back to 3-D first
- Assert tensor rank in a small wrapper around your norm modules
- Document expected shapes on your custom Module impls
When it happens
Trigger: Calling forward on the GroupNorm module (directly or through Module::forward) with a tensor of shape [B, C] or [C] — e.g. feeding a flattened feature vector or a 2D logits tensor into GroupNorm.
Common situations: Applying GroupNorm to MLP/transformer activations of shape [B, C] where LayerNorm was intended; forgetting to reshape flattened conv output back to [B, C, H*W]; wrong tensor routed through a Sequential that ends with GroupNorm.
Related errors
- unexpected num-channels in GroupNorm ({n_channels} <> {}
- the target tensor should have a single dimension ({dims:?})
- the target tensor should have two dimensions ({dims:?})
- cross_entropy expects an input tensor of rank 2
- backward not supported for non uniform upscaling factors
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/01fa80001b61f8f0.
Report an issue: GitHub.