tracel-ai/burn · error
Can't differentiate deform conv 2d backward.
Error message
Can't differentiate deform conv 2d backward.
What it means
q_to_device (moving a quantized tensor to another device) is stubbed in BackendRouter's QTensorOps and panics. Related stubs (q_reshape, etc.) show the whole router quantized-tensor surface is unimplemented.
Source
Thrown at crates/burn-autodiff/src/ops/module.rs:915
weight.primitive,
None,
None,
options,
)),
},
}
}
fn deform_conv2d_backward(
_x: AutodiffTensor<B>,
_offset: AutodiffTensor<B>,
_weight: AutodiffTensor<B>,
_mask: Option<AutodiffTensor<B>>,
_bias: Option<AutodiffTensor<B>>,
_output_grad: AutodiffTensor<B>,
_options: DeformConvOptions<2>,
) -> DeformConv2dBackward<Self> {
panic!("Can't differentiate deform conv 2d backward.");
}
fn conv_transpose2d(
x: AutodiffTensor<B>,
weight: AutodiffTensor<B>,
bias: Option<AutodiffTensor<B>>,
options: ConvTransposeOptions<2>,
) -> AutodiffTensor<B> {
#[derive(Debug)]
struct ConvTranspose2DWithBias;
#[derive(Debug)]
struct ConvTranspose2DNoBias;
impl<B: Backend> Backward<B, 3> for ConvTranspose2DWithBias {
type State = (NodeId, NodeId, NodeId, ConvTransposeOptions<2>);
fn backward(
self,View on GitHub (pinned to d16f7ba2ed)
Solutions
- Move the tensor while it is still float (float to_device), then quantize on the target device's concrete backend.
- Handle quantized tensors on the concrete backend that supports q_to_device.
- Avoid device transfers of quantized tensors under BackendRouter until quantized ops are routed.
Example fix
// before let q = q_tensor.to_device(&gpu_device); // panics on BackendRouter // after let f = ConcreteBackend::dequantize(q_tensor, FloatDType::F32); let f = ConcreteBackend::float_to_device(f, &gpu_device); let q = ConcreteBackend::quantize(f, &scheme, qparams);
Defensive patterns
Strategy: validation
Validate before calling
fn q_device_transfer_ok(dtype: &burn_tensor::DType) -> bool {
!matches!(dtype, burn_tensor::DType::QFloat(_)) // move floats across devices, not quantized
} Type guard
fn is_quantized(dtype: &burn_tensor::DType) -> bool {
matches!(dtype, burn_tensor::DType::QFloat(_))
} Try / catch
std::panic::catch_unwind(std::panic::AssertUnwindSafe(||
q_tensor.clone().to_device(&device)
)).map_err(|_| anyhow::anyhow!("q_to_device is a stub on BackendRouter; transfer before quantizing")) Prevention
- Move tensors to the target device while float, then quantize there.
- Avoid device transfers of QuantizedTensor under BackendRouter.
- Plan device placement before quantization in multi-GPU pipelines.
- Add a dtype check before every to_device call in generic code.
When it happens
Trigger: Calling q_to_device / Tensor::to_device on a quantized tensor whose backend is BackendRouter; multi-GPU or CPU/GPU placement changes for quantized tensors under the router.
Common situations: Moving quantized checkpoints to GPU for inference; device management in code generic over Backend using the router; quantized tensors crossing device boundaries.
Related errors
- ctc_loss_backward: 2 * max_target_len + 1 = {} exceeds the k
- Invalid broadcast shapes: Next grad shape {:?}, Previous gra
- Can't differentiate embedding backward.
- Can't differentiate linear_x_backward.
- Can't differentiate linear_weight_backward.
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/5c5da46720dbbf10.
Report an issue: GitHub.