tracel-ai/burn · error

{other:?} reduction is not supported

Error message

{other:?} reduction is not supported

What it means

CtcLoss::forward_with_reduction supports only Mean, Auto, and Sum reductions; any other Reduction variant panics with this message. The CTC loss otherwise follows PyTorch's behavior of dividing per-sample losses by target lengths before averaging.

Source

Thrown at crates/burn-nn/src/loss/ctc.rs:203

        &self,
        log_probs: Tensor<3>,
        targets: Tensor<2, Int>,
        input_lengths: Tensor<1, Int>,
        target_lengths: Tensor<1, Int>,
        reduction: Reduction,
    ) -> Tensor<1> {
        let ctc_loss_tensor =
            self.forward(log_probs, targets, input_lengths, target_lengths.clone());

        match reduction {
            Reduction::Auto | Reduction::Mean => {
                // Following PyTorch's behavior where the output losses are divided
                // by the target lengths and then the mean over the batch is taken
                let target_lengths_float = target_lengths.float();
                ctc_loss_tensor.div(target_lengths_float).mean()
            }
            Reduction::Sum => ctc_loss_tensor.sum(),
            other => panic!("{other:?} reduction is not supported"),
        }
    }

    /// Checks the per-element length invariants required by the alpha
    /// recursion. These require reading the length tensors from the device,
    /// so the checks are gated behind `cfg(debug_assertions)` to avoid the
    /// device-to-host sync in release builds.
    ///
    /// Validated:
    /// - `target_lengths[i] >= 0`
    /// - `target_lengths[i] <= max_target_len`
    /// - `input_lengths[i] >= target_lengths[i]`
    /// - `input_lengths[i] <= max_input_length`
    #[allow(unused_variables)]
    fn length_assertions(
        &self,
        input_lengths: Tensor<1, Int>,
        target_lengths: Tensor<1, Int>,

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Use Reduction::Mean, Reduction::Sum, or Reduction::Auto.
  2. If per-sequence (unreduced) losses are needed, check whether the module exposes a no-reduction variant and use it, otherwise compute per-sample inside a loop or patch/extend the loss.
  3. Normalize the reduction in your config layer to only the supported variants before invoking the loss.

Example fix

// before
let loss = ctc.forward_with_reduction(logits, targets, input_lengths, target_lengths, Reduction::None);
// after
let loss = ctc.forward_with_reduction(logits, targets, input_lengths, target_lengths, Reduction::Mean);
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_supported(r: &Reduction) -> Result<(), String> {
    match r {
        Reduction::Mean | Reduction::Auto | Reduction::Sum => Ok(()),
        other => Err(format!("unsupported reduction for CTC loss: {other:?}")),
    }
}

Type guard

fn is_supported_reduction(r: &Reduction) -> bool {
    matches!(r, Reduction::Mean | Reduction::Auto | Reduction::Sum)
}

Try / catch

let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(||
    ctc.forward_with_reduction(logits, targets, in_lens, tgt_lens, reduction.clone())));

Prevention

When it happens

Trigger: Calling CtcLoss::forward_with_reduction with reduction = Reduction::None (or any non-Mean/Auto/Sum variant).

Common situations: Porting PyTorch CTCLoss(reduction='none') code to burn; passing a user-configured Reduction through without validating supported variants; expecting per-sequence unreduced CTC losses via forward with None.

Related errors


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