tracel-ai/burn · error
{scheme:?} requires a per-tensor scale
Error message
{scheme:?} requires a per-tensor scale What it means
When constructing quantization parameters (`QuantizationParameters`/qparams `new`) from raw bytes and an optional per-tensor scale, the combination of scheme and scale must be consistent. A scheme that requires a per-tensor scale (e.g. per-tensor affine symmetric schemes without block scaling) was given `Some(...)`-style bytes but no global/per-tensor scale, so construction panics. The qparams would be unusable for dequantization without that scale.
Source
Thrown at crates/burn-std/src/tensor/quantization.rs:258
Some(_) => scales,
};
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) {View on GitHub (pinned to d16f7ba2ed)
Solutions
- Provide the per-tensor scale (ScaleDtype::F32) when constructing params for a scheme that requires one.
- Use the correct scheme variant that matches the data you actually have (e.g. a blockwise scheme if you have no global scale).
- Re-quantize the tensor with burn's quantization API so scales are generated and encoded automatically instead of assembling bytes by hand.
Example fix
// before let params = QuantizationParameters::from_bytes(bytes, scheme, None); // panics: requires scale // after let params = QuantizationParameters::from_bytes(bytes, scheme, Some(global_scale));
Defensive patterns
Strategy: validation
Validate before calling
fn validate_qparams(scheme: QuantizationScheme, scale: Option<f32>) -> Result<(), String> {
match (scheme, scale) {
(s, None) if s.requires_per_tensor_scale() => Err(format!("{s:?} requires a per-tensor scale")),
_ => Ok(()),
}
} Try / catch
// panic-based constructor; validate arguments first, or wrap in catch_unwind let result = std::panic::catch_unwind(|| QuantizationParameters::from_bytes(bytes, scheme, scale));
Prevention
- Match scheme variant to the data you have before constructing qparams
- Prefer burn's quantize APIs over hand-assembling scale bytes
- Write unit tests that construct qparams for each scheme you ship
When it happens
Trigger: Building quantization params for a scheme such as QAffinePerTensor / symmetric per-tensor modes while passing `None` for the per-tensor scale — e.g. `QParams::new(bytes, scheme, None)` for a scheme whose variant expects `Some(global_scale)`.
Common situations: Hand-writing quantized model export/serialization code and forgetting the scale; converting checkpoints between formats and dropping the scale tensor; copying param construction code from a blockwise (two-level) example and applying it to a per-tensor scheme.
Related errors
- {scheme:?} does not take 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/1be242c13d98044e.
Report an issue: GitHub.