How to do calibration for int8 engine correctly?

Description

Hi,

I’ve asked a question here.
So far, I’ve done the calibration for my Unet model’s int8 inference with the community’s help from github.
The process of my calibration is as below:

  1. convert keras model to .onnx with explicit batch=1 is set
  2. read the directory path of calibration data
  3. cv::imread the input data and convert cv::Mat to datatype float
  4. the calibration class do the rest

I’ve tested three different cases with the same model structure, trying to figure out the SOP of doing calibration,
but I couldn’t find a standard way to do so…
In my case, adjusting the beta value of cv::Mat::convertTo() can result to very different result.

Here are the cases I’ve tested with the best parameter to get the closest result with FP16 one:

  • case A:
    model input size: 1920 x 1920 x 1
    pre-process of calibration:
cv::Mat img = cv::imread(imgPaths[j]);
img.convertTo(img, CV_32FC(MD_size[2]), 1 / 255.0, -0.45);

result of inference: data with value 0 and 0.5

  • case B:
    model input size: 1664 x 288 x 1
    pre-process of calibration:
cv::Mat img = cv::imread(imgPaths[j]);
img.convertTo(img, CV_32FC(MD_size[2]), 1 / 255.0, 0);

result of inference: data range from 0 to 1

  • case C:
    model input size: 512 x 960 x 3
    pre-process of calibration:
cv::Mat img = cv::imread(imgPaths[j]);
img.convertTo(img, CV_32FC(MD_size[2]), 1 / 255.0, 2.5);

result of inference: data with value 0 and 0.5

If I didn’t adjust the beta value, the result of case A and case C would cause too many overkill at the OK part.
However, adjusting beta value is a trial-and-error solution for me.
(Since I didn’t use that beta value while inferencing with reading data and convert to float)
So, I want to know that:

  1. Am I doing right with the calibration part’s pre-processing?
  2. Why the result of inference’s data range is different?
    (For one case, it ranges from 0 to 1; for others, they’re value with 0 and 0.5)

Environment

TensorRT Version: 7.0.0.11
GPU Type: RTX2080 Ti
Nvidia Driver Version: 451.82
CUDA Version: 10.0
CUDNN Version: 7.6.5
Operating System + Version: Windows10
Python Version (if applicable): 3.7.0
TensorFlow Version (if applicable): 1.13.1
PyTorch Version (if applicable): -
Baremetal or Container (if container which image + tag): -

Relevant Files

TRT_code.zip

Steps To Reproduce

Focus on the part ONNX2TRT()
and this part

std::cout << "***USING INT8***\n";
config->setFlag(BuilderFlag::kINT8);

// provided by @le8888e at https://github.com/NVIDIA/TensorRT/issues/557
std::string calibration_imgs_list = Jconfig["cali_image_path"].get<std::string>(); 
std::string calibration_table_save_path = Jconfig["cali_save_path"].get<std::string>();
int8EntroyCalibrator *calibrator = nullptr;
calibrator = new int8EntroyCalibrator(1, calibration_imgs_list, calibration_table_save_path);
config->setInt8Calibrator(calibrator);

The int8EntroyCalibrator class done the calibration part.

Thanks in advance for any help or advice!