tracel-ai/burn · error

Quantization scheme is not valid for dtype {other:?}

Error message

Quantization scheme is not valid for dtype {other:?}

What it means

`TensorData::scheme()` returns the `QuantScheme` for quantized tensors. It matches on the tensor's dtype and expects `DType::QFloat(scheme)`; any other dtype (F32, U8, etc.) triggers this panic. Calling `scheme()` on a non-quantized tensor is an API misuse, since the method is documented to panic unless the tensor is quantized.

Source

Thrown at crates/burn-backend/src/backend/primitive.rs:104

    fn device(&self) -> Self::Device;

    /// Whether the tensor's buffer can be mutated in place — i.e. this handle
    /// uniquely owns it, so an in-place op (`slice_assign`, an inplace kernel)
    /// writes the existing allocation instead of copying it first.
    ///
    /// Backends that track buffer ownership (cubecl, fusion, tch) answer
    /// precisely; a backend that can't must return a conservative `false` —
    /// the buffer may be aliased, so an in-place write can't be assumed safe.
    fn can_mut(&self) -> bool;

    /// Get the [quantization scheme](QuantScheme) for a quantized float tensor.
    ///
    /// # Panics
    /// Panics if the tensor is not quantized.
    fn scheme(&self) -> QuantScheme {
        match self.dtype() {
            DType::QFloat(scheme) => scheme,
            other => panic!("Quantization scheme is not valid for dtype {other:?}"),
        }
    }
}

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Check `tensor.dtype()` first and only call `scheme()` when it matches `DType::QFloat(_)`, or use the defensive match shown in the source.
  2. Ensure the tensor actually went through a quantization op (`quantize`/`quantize_dynamic`) before querying its scheme.
  3. If you need the scheme from a model, inspect the module's quantization state/config rather than a dequantized tensor.

Example fix

// before
let scheme = tensor.scheme(); // panics for F32 tensors

// after
let scheme = match tensor.dtype() {
    burn::tensor::DType::QFloat(s) => s,
    other => panic!("expected quantized tensor, got {other:?}"),
};
Defensive patterns

Strategy: type-guard

Validate before calling

// only query scheme on quantized tensors
if matches!(tensor.dtype(), burn::tensor::DType::QFloat(_)) {
    let scheme = tensor.scheme();
}

Type guard

fn quantized_dtype(dtype: &burn::tensor::DType) -> Option<burn::tensor::QuantScheme> {
    match dtype {
        burn::tensor::DType::QFloat(s) => Some(*s),
        _ => None,
    }
}

Try / catch

// panics are not catchable idiomatically here; use the guard instead
// but if needed:
let scheme = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| tensor.scheme()))
    .ok(); // None => tensor was not quantized

Prevention

When it happens

Trigger: Calling `.scheme()` on a tensor whose `dtype()` is anything other than `DType::QFloat(_)` — e.g. a float tensor loaded from a checkpoint that was never quantized, or after calling a dequantize/convert op that changed the dtype away from QFloat.

Common situations: Reading quantization metadata from a tensor that was dequantized earlier; mixing quantized and non-quantized layers when inspecting model parameters; loading weights with a dtype change; assuming all int8 tensors are quantized (U8 dtype vs QFloat).

Related errors


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