tracel-ai/burn · error

Quantized float is not supported

Error message

Quantized float is not supported

What it means

burn-vision's color conversion helpers call `reject_quantized`, which panics with "Quantized float is not supported" when the input image tensor has a QFloat dtype. Quantized (QFloat) tensors are not valid inputs for rgb2gray, gray2rgb, rgb2hsv, or hsv2rgb, matching the library's stance on float vision ops.

Source

Thrown at crates/burn-vision/src/color.rs:51

    /// # Returns
    /// The same-shape image tensor in HSV color space.
    fn rgb2hsv(self) -> Tensor<4>;
    /// Converts a batch of images from the HSV color space to the RGB color space.
    ///
    /// # Arguments
    /// * `self`: A batched image tensor of shape `[batch, channel, height, width]`.
    ///   The first channel (hue) is in the `0.0..360.0` range.
    ///   The other two (saturation and value) are in the `0.0..=1.0` range.
    ///
    /// # Returns
    /// The same-shape image tensor in RGB color space.
    fn hsv2rgb(self) -> Tensor<4>;
}

/// Quantized floats aren't supported, matching the other float vision ops.
fn reject_quantized(images: &Tensor<4>) {
    if matches!(images.dtype(), DType::QFloat(_)) {
        unimplemented!("Quantized float is not supported");
    }
}

fn channel(img: &Tensor<4>, at: usize) -> Tensor<4> {
    img.clone().narrow(1, at, 1)
}

/// One channel back out of a hue, its value and its chroma.
/// `target` - target channel : `0` for red, `1` for green and `2` for blue.
fn from_hue(sixths: &Tensor<4>, target: usize, value: &Tensor<4>, chroma: &Tensor<4>) -> Tensor<4> {
    // Rotate the wheel depending on the target channel.
    let rotated = sixths
        .clone()
        .add_scalar(5.0 - (target as f32) * 2.0)
        .remainder_scalar(6.0);
    let ramp = rotated.clone().min_pair(4.0 - rotated).clamp(0.0, 1.0);

    value.clone() - chroma.clone() * ramp

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Dequantize the image tensor to a float dtype (F32/F16/BF16) before the color conversion
  2. Keep color conversions before any quantization step in the pipeline
  3. Check the input dtype with a guard and convert when it is QFloat
  4. Use float inference for preprocessing/color ops and quantize only where needed

Example fix

// before
let gray = img.clone().rgb2gray(); // img.dtype() == DType::QFloat(_) -> panic
// after
let float_img = img.dequantize();
let gray = float_img.rgb2gray();
Defensive patterns

Strategy: validation

Validate before calling

assert!(!is_quantized_image(&img), "dequantize before color conversion");

Type guard

fn is_quantized_image<B: Backend>(img: &Tensor<B, 4>) -> bool {
    matches!(img.dtype(), DType::QFloat(_))
}

Prevention

When it happens

Trigger: Passing a quantized tensor (`matches!(img.dtype(), DType::QFloat(_))`) to TensorVision::rgb2gray, gray2rgb, rgb2hsv, or hsv2rgb with any backend.

Common situations: Running color conversion on frames coming out of an int8-quantized vision model or camera pipeline without dequantizing first; chaining vision ops after quantized inference and forgetting QFloat persists across ops.

Related errors


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