tracel-ai/burn · error
{scheme:?} does not take a per-tensor scale
Error message
{scheme:?} does not take a per-tensor scale What it means
The mirror case of the previous error: when building quantization parameters, the given scheme does not accept a per-tensor scale (blockwise/two-level schemes carry their own scales inside the encoded bytes), but one was supplied. The API refuses the inconsistent combination with a panic because the extra scale cannot be represented for that scheme.
Source
Thrown at crates/burn-std/src/tensor/quantization.rs:259
};
let scale_bytes = encode_scales(scales, scheme.scale_dtype());
bytes.extend_from_byte_slice_aligned(scale_bytes.as_slice(), QPARAM_ALIGN);
// Last, so a reader can peel it off the end before the block scales it normalizes.
match (global_scale_dtype(&scheme), global) {
(Some(dtype), Some(global)) => {
// Encoding the per-tensor scale narrower would round it, and the block scales were
// normalized against the unrounded one.
assert_eq!(
dtype,
ScaleDtype::F32,
"a two-level scheme stores its per-tensor scale as f32, got {scheme:?}"
);
let global_bytes = encode_scales(&[global], dtype);
bytes.extend_from_byte_slice_aligned(global_bytes.as_slice(), QPARAM_ALIGN);
}
(Some(_), None) => panic!("{scheme:?} requires a per-tensor scale"),
(None, Some(_)) => panic!("{scheme:?} does not take a per-tensor scale"),
(None, None) => {}
}
Self {
bytes,
scheme,
shape,
}
}
/// The number of quantized elements.
pub fn num_elements(&self) -> usize {
self.shape.num_elements()
}
/// Returns the int8 quantized values with the quantization parameters.
pub fn into_vec_i8(self) -> (Vec<i8>, DecodedScales) {
let scheme = self.scheme;View on GitHub (pinned to d16f7ba2ed)
Solutions
- Pass `None` for the per-tensor scale when the scheme is blockwise/two-level.
- Choose the per-tensor scheme variant if you genuinely have (and need) a single global f32 scale.
- Strip the global scale before serialization, or use burn's high-level quantize API to encode scales in the correct layout.
Example fix
// before let params = QuantizationParameters::from_bytes(bytes, blockwise_scheme, Some(scale)); // panics // after let params = QuantizationParameters::from_bytes(bytes, blockwise_scheme, None);
Defensive patterns
Strategy: validation
Validate before calling
fn validate_qparams(scheme: QuantizationScheme, scale: Option<f32>) -> Result<(), String> {
if scheme.is_blockwise() && scale.is_some() {
return Err(format!("{scheme:?} does not take a per-tensor scale"));
}
Ok(())
} Try / catch
// panic-based constructor; validate arguments first let result = std::panic::catch_unwind(|| QuantizationParameters::from_bytes(bytes, scheme, scale));
Prevention
- Pass None for the scale with blockwise/two-level schemes
- Don't reuse per-tensor param code for blockwise schemes without review
- Document which scheme each serialized artifact was quantized with
When it happens
Trigger: Passing `Some(scale)` as the per-tensor scale to `QParams`/qparams `new` while `scheme` is a blockwise/two-level scheme (e.g. QBlockwise variants) that stores scales per-block in the byte payload.
Common situations: Reusing param-construction code written for per-tensor schemes with a blockwise scheme; exporting a model quantized blockwise and also attaching a leftover global scale; misreading scheme enums when switching between symmetric per-tensor and blockwise quantization.
Related errors
- {scheme:?} requires a per-tensor scale
- Should be float, got quantized
- Should be int, got quantized
- Should be bool, got quantized
- Expected quantized handle, got {}
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/ad8c49b0e4597335.
Report an issue: GitHub.