| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| """ |
| This script demonstrates how to use the Calibrator API provided by Polygraphy |
| to calibrate a TensorRT engine to run in INT8 precision. |
| """ |
| import numpy as np |
| from polygraphy.backend.trt import Calibrator, CreateConfig, EngineFromNetwork, NetworkFromOnnxPath, TrtRunner, save_engine, load_plugins, Profile |
| from polygraphy.logger import G_LOGGER |
| from termcolor import cprint |
| load_plugins(plugins=['libmmdeploy_tensorrt_ops.so']) |
| import cv2 |
| import argparse |
|
|
| G_LOGGER.severity = G_LOGGER.EXTRA_VERBOSE |
| PREVIEW_CALIBRATOR_OUTPUT = True |
| |
| def calib_data_from_video(batch_size=1): |
|
|
| |
| def preprocess(img: np.ndarray): |
| """Do preprocessing for RTMPose model inference. |
| |
| Args: |
| img (np.ndarray): Input image in shape. |
| |
| Returns: |
| tuple: |
| - resized_img (np.ndarray): Preprocessed image. |
| - center (np.ndarray): Center of image. |
| - scale (np.ndarray): Scale of image. |
| """ |
| if len(img.shape) == 3: |
| padded_img = np.ones( |
| (MODEL_INPUT_SIZE[0], MODEL_INPUT_SIZE[1], 3), |
| dtype=np.uint8) * 114 |
| else: |
| padded_img = np.ones(MODEL_INPUT_SIZE, dtype=np.uint8) * 114 |
|
|
| ratio = min(MODEL_INPUT_SIZE[0] / img.shape[0], |
| MODEL_INPUT_SIZE[1] / img.shape[1]) |
| resized_img = cv2.resize( |
| img, |
| (int(img.shape[1] * ratio), int(img.shape[0] * ratio)), |
| interpolation=cv2.INTER_LINEAR, |
| ).astype(np.uint8) |
| padded_shape = (int(img.shape[0] * ratio), int(img.shape[1] * ratio)) |
| padded_img[:padded_shape[0], :padded_shape[1]] = resized_img |
|
|
| return padded_img, ratio |
|
|
| cap = cv2.VideoCapture(filename=VIDEO_PATH) |
| imgs = [] |
| while cap.isOpened(): |
| |
| success, frame = cap.read() |
| if success: |
| img, ratio = preprocess(frame) |
| img = img.transpose(2, 0, 1) |
| img = np.ascontiguousarray(img, dtype=np.float32) |
| img = img[None, :, :, :] |
| |
| imgs.append(img) |
| if len(imgs) == batch_size: |
| batch_img = np.vstack(imgs) |
| yield {"input": batch_img} |
| imgs = [] |
| |
| else: |
| break |
| |
| cap.release() |
|
|
| def main(onnx_path, engine_path, batch_size): |
|
|
| |
| |
| |
| |
| |
| if batch_size < 1: |
|
|
| profiles = [ |
| |
| Profile().add("input", |
| min=(1, 3, MODEL_INPUT_SIZE[0], MODEL_INPUT_SIZE[1]), |
| opt=(4, 3, MODEL_INPUT_SIZE[0], MODEL_INPUT_SIZE[1]), |
| max=(9, 3, MODEL_INPUT_SIZE[0], MODEL_INPUT_SIZE[1])), |
| ] |
| |
| else: |
| profiles = [ |
| |
| Profile().add("input", |
| min=(batch_size, 3, MODEL_INPUT_SIZE[0], MODEL_INPUT_SIZE[1]), |
| opt=(batch_size, 3, MODEL_INPUT_SIZE[0], MODEL_INPUT_SIZE[1]), |
| max=(batch_size, 3, MODEL_INPUT_SIZE[0], MODEL_INPUT_SIZE[1])), |
| ] |
|
|
| opt_batch_size = profiles[0]['input'].opt[0] |
| calibrator = Calibrator(data_loader=calib_data_from_video(opt_batch_size)) |
|
|
| |
| build_engine = EngineFromNetwork( |
| NetworkFromOnnxPath(f"{onnx_path}"), config=CreateConfig( |
| use_dla=False, |
| tf32=True, |
| fp16=True, |
| int8=True, |
| precision_constraints="prefer", |
| sparse_weights=True, |
| calibrator=calibrator, |
| profiles=profiles, |
| max_workspace_size = 2 * 1024 * 1024 * 1024, |
| allow_gpu_fallback=True, |
| ) |
| ) |
|
|
| |
| |
| save_engine(build_engine, f'{engine_path}') |
|
|
| if __name__ == "__main__": |
| |
| parser = argparse.ArgumentParser(description="Process a video file.") |
| parser.add_argument("video_path", type=str, help="The path to the video file used to calibrate int8 engine") |
| parser.add_argument("onnx_path", type=str, help="The path to the input ONNX model file") |
| parser.add_argument("engine_path", type=str, help="The path to the exported TensorRT Engine model file") |
| parser.add_argument("--batch_size", type=int, default=-1, help="Input batch size (not specified if dynamic)") |
| args = parser.parse_args() |
| VIDEO_PATH = args.video_path |
| MODEL_INPUT_SIZE=(416,416) if 'rtmo-t' in args.onnx_path else (640,640) |
| |
| if PREVIEW_CALIBRATOR_OUTPUT: |
| cprint('You are previwing video used to calibrate TensorRT int8 engine model ...', 'yellow') |
| for output_dict in calib_data_from_video(): |
| if output_dict: |
| image = output_dict['input'] |
| image_to_show = image.squeeze(0).transpose(1, 2, 0) / 255.0 |
| cv2.imshow(VIDEO_PATH,image_to_show) |
| if cv2.waitKey(1) & 0xFF == ord('q'): |
| break |
| cv2.destroyAllWindows() |
| |
| main(args.onnx_path, args.engine_path, args.batch_size) |
|
|