I try to run quantizitzed model ,but some error happend

as title
the crash message is as below:
Traceback (most recent call last):
File “/home/guanx/pycharmProject/erfnet/venv/erfnet_pytorch-lidarseg/eval/eval_lidar_seg.py”, line 435, in
evaluate(parser.parse_args())
File “/home/guanx/pycharmProject/erfnet/venv/erfnet_pytorch-lidarseg/eval/eval_lidar_seg.py”, line 292, in evaluate
outputs = model(inputs)
File “/home/guanx/anaconda3/envs/python37/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 532, in call
result = self.forward(*input, **kwargs)
RuntimeError: Could not run ‘aten::max_pool2d_with_indices’ with arguments from the ‘QuantizedCPUTensorId’ backend. ‘aten::max_pool2d_with_indices’ is only available for these backends: [CPUTensorId, VariableTensorId].
The above operation failed in interpreter.
Traceback (most recent call last):
File “”, line 63
dilation: List[int],
ceil_mode: bool):
output, indices = torch.max_pool2d_with_indices(self, kernel_size, stride, padding, dilation, ceil_mode)

def backward(grad_output):
grad_self = torch.max_pool2d_with_indices_backward(grad_output, self, kernel_size, stride, padding, dilation, ceil_mode, indices)

The above operation failed in interpreter.

Hey, can you show how the model and forward looks like?

Also is it already converted quantized model after calling

torch.quantization.convert()

Hi, it looks like you are trying to use backward with quantized operators, which is not supported. Quantization works only for forward methods right now.

hi
Quantiziton is used to inference in my code . This error happened ,When I sent data to net

did you run

net.eval()

before quantization?

I don’t think there is a quantized kernel for this op

ERFNET full network definition for Pytorch

Sept 2017

Eduardo Romera

#######################

import torch
import torch.nn as nn
import torch.nn.init as init
import torch.nn.functional as F
import numpy as np

from torch.quantization import QuantStub, DeQuantStub
import os

class DownsamplerBlock (nn.Module):
def init(self, ninput, noutput, caller_name=’’):
super().init()

    self.conv = nn.Conv2d(ninput, noutput - ninput, (3, 3), stride=2, padding=1, bias=True)

    self.pool = nn.MaxPool2d(2, stride=2)
    self.caller_name = caller_name

def forward(self, input):

    output = self.conv(input)
    conv_output = F.relu(output)
    output = self.pool(input)
    pool_output = F.relu(output)
    output = torch.cat([conv_output, pool_output], 1)

    return output

class non_bottleneck_1d (nn.Module):
def init(self, chann, dropprob, dilated, caller_name=’’):
super().init()

    self.conv3x1_1 = nn.Conv2d(chann, chann, (3, 1), stride=1, padding=(1, 0), bias=True)


    self.conv1x3_1 = nn.Conv2d(chann, chann, (1, 3), stride=1, padding=(0, 1), bias=True)

    self.conv3x1_2 = nn.Conv2d(chann, chann, (3, 1), stride=1, padding=(1 * dilated, 0), bias=True,
                               dilation=(dilated, 1))

    self.conv1x3_2 = nn.Conv2d(chann, chann, (1, 3), stride=1, padding=(0, 1 * dilated), bias=True,
                               dilation=(1, dilated))

    self.caller_name = caller_name


def hook(self, conv, input, out):
    print("in hook")

def forward(self, input):

    output = self.conv3x1_1(input)

    output = F.relu(output)

    output = self.conv1x3_1(output)

    output = F.relu(output)


    output = self.conv3x1_2(output)
    output = F.relu(output)

    output = self.conv1x3_2(output)

    output = output + input


    return F.relu(output)    # +input = identity (residual connection)

class Encoder(nn.Module):
def init(self, num_classes):
super().init()
self.initial_block = DownsamplerBlock(4, 16)

    self.layers = nn.ModuleList()

    self.layers.append(DownsamplerBlock(16, 64))

    for x in range(0, 5):  # 5 times
        self.layers.append(non_bottleneck_1d(64, 0.03, 1))

    self.layers.append(DownsamplerBlock(64, 128))

    for x in range(0, 2):  # 2 times
        self.layers.append(non_bottleneck_1d(128, 0.3, 2))
        self.layers.append(non_bottleneck_1d(128, 0.3, 4))
        self.layers.append(non_bottleneck_1d(128, 0.3, 8))

    # only for encoder mode:
    self.output_conv = nn.Conv2d(128, num_classes, 1, stride=1, padding=0, bias=True)

def forward(self, input, predict=torch.tensor(0)):
    output = self.initial_block(input)

    for layer in self.layers:
        output = layer(output)

    if predict:
        output = self.output_conv(output)

    return output

class UpsamplerBlock(nn.Module):
def init(self, ninput, noutput, caller_name=’’):
super().init()
self.conv = nn.ConvTranspose2d(ninput, noutput, 3, stride=2, padding=1, output_padding=1, bias=True)
self.caller_name = caller_name

def forward(self, input):
    output = self.conv(input)

    return F.relu(output)

class Decoder(nn.Module):
def init(self, num_classes):
super().init()

    self.layers = nn.ModuleList()

    self.layers.append(UpsamplerBlock(128, 64))
    self.layers.append(non_bottleneck_1d(64, 0, 1))
    self.layers.append(non_bottleneck_1d(64, 0, 1))

    self.layers.append(UpsamplerBlock(64, 16))
    self.layers.append(non_bottleneck_1d(16, 0, 1))
    self.layers.append(non_bottleneck_1d(16, 0, 1))

    self.output_conv = nn.ConvTranspose2d(16, num_classes, 2, stride=2, padding=0, output_padding=0, bias=True)

def forward(self, input):
    output = input

    for layer in self.layers:
        output = layer(output)

    output = self.output_conv(output)

    return output

ERFNet

class ERFNet(nn.Module):
def init(self, num_classes, encoder=None): # use encoder to pass pretrained encoder
super().init()
if encoder == None:
self.encoder = Encoder(num_classes)
else:
self.encoder = encoder
self.decoder = Decoder(num_classes)
self.quant = QuantStub()
self.dequant = DeQuantStub()

def forward(self, input, only_encode=torch.tensor(0)):
    input = self.quant(input)
    if only_encode:
        x = self.encoder.forward(input, predict=torch.tensor(1))
        x = self.dequant(x)
        return (x)
    else:
        output = self.encoder(input)    # predict=False by default
        x = self.decoder.forward(output)
        x = self.dequant(x)
        return (x)

if name == ‘main’:
print(os.getcwd())
print(cur_quant_dir)

there is a maxpool in may code . It seems that pytorch could not handle maxpool quantiztion.how could I do

It’s hard to read the unformatted code. Do you think it wold be possible for you to format the code? Also, how are you quantizing? Are you going through the prepare/convert flow?

I do not know how to format the code. I capture the code as picture

I capture the code as picture as below

pytorch does support quantization for maxpool, you don’t need to change anything and it should just work when you pass a quantized Tensor to maxpool because the output quantization parametere for quantized maxpool can be inferred from input Tensors.

hi jerry
thanks for you replay
I do not add any QuantStub, DeQuantStub in my new code. but it does not work still. and the error information is here https://github.com/pytorch/pytorch/issues/34583。I also use Intel‘s distiller to quantize my mode, the quantiztion information is as below:
but when I change the qconfig from “torch.quantization.default_qconfig” to “torch.quantization.get_default_qconfig(‘fbgemm’)”. It seems that the code hang on somewhere.
I also use Intel’s distiller to quntize my mode. I found some information as below:
encoder.layers.1.conv1x3_2.output_zero_point: 0.0
encoder.layers.2.conv3x1_1.output_scale: .inf
encoder.layers.2.conv3x1_1.output_zero_point: 0.0
encoder.layers.2.conv1x3_1.output_scale: .inf
encoder.layers.2.conv1x3_1.output_zero_point: 0.0
encoder.layers.2.conv3x1_2.output_scale: .inf
encoder.layers.2.conv3x1_2.output_zero_point: 0.0
encoder.layers.2.conv1x3_2.output_scale: 808.11376953125
encoder.layers.2.conv1x3_2.output_zero_point: 0.0
encoder.layers.3.conv3x1_1.output_scale: .inf
encoder.layers.3.conv3x1_1.output_zero_point: 0.0
encoder.layers.3.conv1x3_1.output_scale: .inf
encoder.layers.3.conv1x3_1.output_zero_point: 0.0
encoder.layers.3.conv3x1_2.output_scale: .inf
encoder.layers.3.conv3x1_2.output_zero_point: 0.0
encoder.layers.3.conv1x3_2.output_scale: 819.0990600585938
encoder.layers.3.conv1x3_2.output_zero_point: 0.0
encoder.layers.4.conv3x1_1.output_scale: .inf
encoder.layers.4.conv3x1_1.output_zero_point: 0.0
encoder.layers.4.conv1x3_1.output_scale: .inf
encoder.layers.4.conv1x3_1.output_zero_point: 0.0
encoder.layers.4.conv3x1_2.output_scale: .inf
encoder.layers.4.conv3x1_2.output_zero_point: 0.0
it seems that some weight is very small

you’ll need to place QuantStub DeQuantStub manually in the code to use eager mode quantization, please follow the tutorials here: (beta) Static Quantization with Eager Mode in PyTorch — PyTorch Tutorials 2.1.1+cu121 documentation