huggingface/candle · error

backward not supported for non uniform upscaling factors

Error message

backward not supported for non uniform upscaling factors

What it means

Even when both height and width scale factors are integers, candle additionally requires them to be equal (uniform scaling) for the UpsampleNearest2D backward, because the gradient is accumulated with a single square kernel Tensor::ones((c,1,scale_h,scale_w)) fed to conv2d whose stride is set to scale_h. scale_h != scale_w would corrupt that computation, so candle bails.

Source

Thrown at candle-core/src/backprop.rs:403

                        let kernel = Tensor::ones((c, 1, scale), arg.dtype(), arg.device())?;
                        let conv_sum = grad.conv1d(&kernel, 0, scale, 1, c)?;
                        let sum_grad = grads.or_insert(arg)?;
                        *sum_grad = conv_sum;
                    }
                    Op::UpsampleNearest2D {
                        arg,
                        target_h,
                        target_w,
                    } => {
                        let (_n, c, h, w) = arg.dims4()?;
                        if target_h % h != 0 || target_w % w != 0 {
                            crate::bail!("backward not supported for non integer upscaling factors")
                        }
                        let scale_h = target_h / h;
                        let scale_w = target_w / w;

                        if scale_h != scale_w {
                            crate::bail!("backward not supported for non uniform upscaling factors")
                        };
                        let kernel =
                            Tensor::ones((c, 1, scale_h, scale_w), arg.dtype(), arg.device())?;
                        let conv_sum = grad.conv2d(&kernel, 0, scale_h, 1, c)?;
                        let sum_grad = grads.or_insert(arg)?;
                        *sum_grad = conv_sum;
                    }
                    Op::UpsampleBilinear2D { .. } => {
                        crate::bail!("backward not supported for upsample_bilinear2d")
                    }
                    Op::SliceScatter0(lhs, rhs, start_rhs) => {
                        let rhs_sum_grad = grads.or_insert(rhs)?;
                        let rhs_grad = grad.narrow(0, *start_rhs, rhs.dim(0)?)?;
                        *rhs_sum_grad = rhs_sum_grad.add(&rhs_grad)?;

                        let lhs_sum_grad = grads.or_insert(lhs)?;
                        let lhs_grad = grad.slice_scatter0(&rhs.zeros_like()?, *start_rhs)?;
                        *lhs_sum_grad = lhs_sum_grad.add(&lhs_grad)?

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Use uniform scale factors so target_h/h == target_w/w (e.g. 2x2, 4x4 upscaling).
  2. Split the anisotropic upscale into consecutive uniform steps if the scales share a common factor.
  3. Register a custom backward implementation for anisotropic nearest upsampling.
  4. Avoid the upsample in autograd contexts: treat it as a fixed preprocessing step outside the graph and drop its gradient.

Example fix

// before
let up = x.upsample_nearest2d(8, 12)?; // scale_h=4, scale_w=6 -> non uniform
// after
let up = x.upsample_nearest2d(8, 8)?;  // uniform 4x scaling
Defensive patterns

Strategy: validation

Validate before calling

let (_n, _c, h, w) = x.dims4()?;
if target_h % h != 0 || target_w % w != 0 || (target_h / h) != (target_w / w) {
    return Err(anyhow::anyhow!("backward requires uniform integer upscaling: got scale_h={} scale_w={}", target_h / h, target_w / w));
}

Try / catch

match result { Err(e) if e.to_string().contains("non uniform upscaling") => { // switch to uniform scale or detach
}, other => other?, }

Prevention

When it happens

Trigger: backward() over Op::UpsampleNearest2D where target_h/h != target_w/w, e.g. Tensor::upsample_nearest2d(&t, 8, 12) on input with h=2,w=3 (scale 4 vs 4 is fine, but h=2,w=2 with target 8x12 gives 4 vs 6).

Common situations: Non-square feature maps upsampled with different aspect ratios; models ported from PyTorch that use nn.Upsample(scale_factor=(2.0, 3.0)) or explicit size with anisotropic scaling.

Related errors


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