tracel-ai/burn · error

Requires autodiff tensor.

Error message

Requires autodiff tensor.

What it means

backward() only handles tensors whose outer kind is DispatchTensorKind::Autodiff. Any other kind (NdArray, LibTorch, Cube, Flex, Remote, Capture) reaching backward() directly panics with 'Requires autodiff tensor.' — the tensor was never wrapped for gradient tracking.

Source

Thrown at crates/burn-dispatch/src/backend.rs:351

                #[cfg(cube_backend)]
                DispatchTensorKind::Cube(tensor) => tensor.autodiff().backward(),
                #[cfg(any(feature = "flex", default_backend))]
                DispatchTensorKind::Flex(tensor) => tensor.autodiff().backward(),
                #[cfg(feature = "ndarray")]
                DispatchTensorKind::NdArray(tensor) => tensor.autodiff().backward(),
                #[cfg(feature = "tch")]
                DispatchTensorKind::LibTorch(tensor) => tensor.autodiff().backward(),
                #[cfg(feature = "remote")]
                DispatchTensorKind::Remote(tensor) => tensor.autodiff().backward(),
                #[cfg(feature = "capture")]
                DispatchTensorKind::Capture(_) => {
                    panic!("Capture tensors do not support autodiff")
                }
                DispatchTensorKind::Autodiff(_) => {
                    panic!("Autodiff should not wrap an autodiff tensor.")
                }
            },
            _ => panic!("Requires autodiff tensor."),
        }
    }

    fn grad(tensor: &DispatchTensor, grads: &Self::Gradients) -> Option<DispatchTensor> {
        let DispatchTensor { kind, .. } = tensor;
        let grad: Option<DispatchTensorKind> = match &kind {
            DispatchTensorKind::Autodiff(inner_kind) => match &**inner_kind {
                #[cfg(cube_backend)]
                DispatchTensorKind::Cube(tensor) => tensor
                    .as_autodiff()
                    .grad(grads)
                    .map(|t| DispatchTensorKind::Cube(crate::BackendTensor::Float(t))),
                #[cfg(any(feature = "flex", default_backend))]
                DispatchTensorKind::Flex(tensor) => tensor
                    .as_autodiff()
                    .grad(grads)
                    .map(|t| DispatchTensorKind::Flex(crate::BackendTensor::Float(t))),
                #[cfg(feature = "ndarray")]

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Ensure the tensor comes from an autodiff-tracked computation (training forward pass), not an eval/inference call
  2. Enable the 'autodiff' feature and use Autodiff-wrapped tensors for training
  3. Do not reuse grad()/inner() results as backward() roots; recompute the loss with the autodiff backend

Example fix

// before
let out = model.eval(x);
let grads = out.backward(); // panics: not an autodiff tensor
// after
let out = model.forward(x); // autodiff-tracked
let grads = out.backward();
Defensive patterns

Strategy: type-guard

Validate before calling

fn ensure_autodiff(t: &DispatchTensor) -> Result<(), String> {
    match &t.kind {
        DispatchTensorKind::Autodiff(_) => Ok(()),
        _ => Err("backward() requires an autodiff-wrapped tensor".into()),
    }
}

Type guard

fn is_autodiff_tensor(t: &DispatchTensor) -> bool {
    matches!(t.kind, DispatchTensorKind::Autodiff(_))
}

Try / catch

let result = std::panic::catch_unwind(AssertUnwindSafe(|| Dispatch::backward(loss)));
match result {
    Ok(grads) => grads,
    Err(_) => panic!("loss tensor was not autodiff-tracked; recompute with training forward"),
}

Prevention

When it happens

Trigger: Calling Dispatch::backward(tensor) where tensor.kind is not Autodiff — e.g. a plain inference tensor from backend.eval()/forward, or a grad() output (which returns inner-backend tensors with autodiff: Disabled) fed back into backward().

Common situations: Calling backward() on outputs of no_grad/eval inference; using a tensor returned by grad() or inner() as a new loss root; forgetting to enable the 'autodiff' feature so tensors are never autodiff-wrapped.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/5045026be1c66378. Report an issue: GitHub.