tracel-ai/burn · error

{other:?} reduction is not supported

Error message

{other:?} reduction is not supported

What it means

The RNN-T loss `forward_with_reduction` reduces the per-sequence loss only for Reduction::Auto/Mean and Reduction::Sum; any other variant hits the catch-all arm and panics. It exists because the reduced API always returns a `Tensor<1>` and unsupported reductions have no defined semantics here.

Source

Thrown at crates/burn-nn/src/loss/rnnt.rs:113

        }

        self.gather_loss(alpha, &lpb, logit_lengths, target_lengths, b)
    }

    /// Computes RNNT loss with the given reduction. Returns shape `[1]`.
    pub fn forward_with_reduction(
        &self,
        logits: Tensor<4>,
        targets: Tensor<2, Int>,
        logit_lengths: Tensor<1, Int>,
        target_lengths: Tensor<1, Int>,
        reduction: Reduction,
    ) -> Tensor<1> {
        let loss = self.forward(logits, targets, logit_lengths, target_lengths);
        match reduction {
            Reduction::Auto | Reduction::Mean => loss.mean(),
            Reduction::Sum => loss.sum(),
            other => panic!("{other:?} reduction is not supported"),
        }
    }

    /// Gathers `log_prob_blank[B, T, U+1]` and `log_prob_label[B, T, U]` from the full
    /// log-probability tensor by indexing into the vocab dimension.
    fn extract_log_probs(
        &self,
        log_probs: Tensor<4>,
        targets: Tensor<2, Int>,
    ) -> (Tensor<3>, Tensor<3>) {
        let [b, max_t, max_up1, v] = log_probs.dims();
        let max_u = max_up1 - 1;
        let vocab_dim = 3;

        // Blank probabilities: slice log_probs in vocab dim using the blank index
        let lpb = log_probs
            .clone()
            .slice_dim(vocab_dim, self.blank)

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Pass Reduction::Mean, Reduction::Auto, or Reduction::Sum.
  2. For unreduced per-sequence losses, call the underlying `forward(...)` method directly instead of forward_with_reduction.
  3. Validate/normalize any deserialized reduction config before calling.

Example fix

// before
let loss = rnnt_loss.forward_with_reduction(logits, targets, lens_in, lens_t, Reduction::None);
// after
let loss = rnnt_loss.forward_with_reduction(logits, targets, lens_in, lens_t, Reduction::Mean);
Defensive patterns

Strategy: validation

Validate before calling

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

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(|| rnnt_loss.forward_with_reduction(logits, targets, ll, tl, reduction));
match result {
    Ok(loss) => loss,
    Err(_) => rnnt_loss.forward(logits, targets, ll, tl).mean(),
}

Prevention

When it happens

Trigger: Calling `RnntLoss::forward_with_reduction(logits, targets, logit_lengths, target_lengths, reduction)` with a Reduction variant other than Auto, Mean, or Sum (e.g. Reduction::None).

Common situations: Porting code from PyTorch where reduction='none' is valid; wiring a user-supplied reduction enum from config without validating it; a new Reduction variant added upstream that this loss does not handle.

Related errors


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