python:3.5
TensorRT-5.1.2.2
ubuntu 16.04
cuda 10.0
cudnn 7.5
gpu:2080ti
I tried to use int8 mode, and implemented a custom calibrator
# -*- coding: utf-8 -*-
"""
Created on Tue May 21 16:57:28 2019
@author: gs
"""
import tensorrt as trt
import os
import pycuda.driver as cuda
import pycuda.autoinit
import cv2
import numpy as np
class customEntropyCalibrator(trt.IInt8EntropyCalibrator2):
def __init__(self,batch_data_dir,cache_file,batch_size,input_size):
trt.IInt8EntropyCalibrator2.__init__(self)
assert os.path.exists(batch_data_dir)
if not isinstance(input_size,(tuple,list)):
self.input_size = [input_size,input_size]
else:
self.input_size = input_size
self.calib_image_paths = [os.path.join(batch_data_dir,f) for f in os.listdir(batch_data_dir)]
self.cache_file = cache_file
self.batch_size = batch_size
self.shape = [self.batch_size,3] + self.input_size
self.device_input = cuda.mem_alloc(trt.volume(self.shape) * trt.float32.itemsize)
self.indices = np.arange(len(self.calib_image_paths))
np.random.shuffle(self.indices)
def load_batches():
for i in range(0,len(self.calib_image_paths) - self.batch_size+1, self.batch_size):
indexs = self.indices[i:i+self.batch_size]
yield self.read_batch_file(self.calib_image_paths[indexs])
self.batches = load_batches()
def read_batch_file(self,filenames):
images = list()
for filename in filenames:
assert os.path.exists(filename)
image = cv2.imread(filename)
assert image.data
images.append(image)
return cv2.dnn.blobFromImages(images,scalefactor = 1./255,size=self.input_size,swapRB=True,crop=False)
def get_batch_size(self):
return self.batch_size
def get_batch(self,names):
try:
data = next(self.batches)
cuda.memcpy_htod(self.device_input,data)
return [int(self.device_input)]
except StopIteration:
return None
def read_calibration_cache(self):
if os.path.exists(self.cache_file):
with open(self.cache_file,'rb') as f:
return f.read()
def write_calibration_cache(self,cache):
with open(self.cache_file,'wb') as f:
f.write(cache)
my build engine function :
def build_engine(onnx_file_path,max_batch_size,engine_file_path,mode,calib):
assert mode in ["fp32","fp16","int8"]
assert os.path.exists(onnx_file_path)
with trt.Builder(TRT_LOGGER) as builder,builder.create_network() as network,trt.OnnxParser(network,TRT_LOGGER) as parser:
builder.max_workspace_size = 1 <<30
builder.max_batch_size = max_batch_size
if mode == "fp16":
builder.fp16_mode = True
elif mode == "int8":
builder.int8_mode = True
assert calib is not None
assert max_batch_size == calib.get_batch_size()
builder.int8_calibrator = calib
with open(onnx_file_path,'rb') as model:
parser.parse(model.read())
engine = builder.build_cuda_engine(network)
assert engine is not None
with open(engine_file_path,'wb') as f:
f.write(engine.serialize())
print("trt {} engine saved {}".format(mode,engine_file_path))
when i use these to create a engine in int8 mode,meet a error
DEPRECATED: This variant of get_batch is deprecated. Please use the single argument variant described in the documentation instead.
Traceback (most recent call last):
File "build_engine.py", line 24, in <module>
build_engine(onnx_file_path,max_batch_size,trt_engine_path,mode,calib)
File "/home/trt_yolo_int8/utils.py", line 40, in build_engine
engine = builder.build_cuda_engine(network)
TypeError: get_batch() takes 2 positional arguments but 3 were given
is there anyone can tell me how to fix that? thanks.