From 2c0bf92dd68f47d3c6780996b452e6d9a703d154 Mon Sep 17 00:00:00 2001 From: "hongliang.yuan" Date: Tue, 2 Dec 2025 16:11:12 +0800 Subject: [PATCH] fix yolov4 --- .../cv/object_detection/yolov4/ixrt/README.md | 23 +- .../yolov4/ixrt/build_engine.py | 19 +- .../yolov4/ixrt/calibration_dataset.py | 31 --- .../yolov4/ixrt/ci/prepare.sh | 9 +- .../yolov4/ixrt/config/YOLOV4_CONFIG | 49 ----- .../cv/object_detection/yolov4/ixrt/deploy.py | 88 ++++++-- .../cv/object_detection/yolov4/ixrt/export.py | 7 +- .../yolov4/ixrt/modify_batchsize.py | 54 ----- .../cv/object_detection/yolov4/ixrt/quant.py | 77 +++++-- .../scripts/infer_yolov4_fp16_accuracy.sh | 186 ++++------------ .../scripts/infer_yolov4_fp16_performance.sh | 187 ++++------------ .../scripts/infer_yolov4_int8_accuracy.sh | 200 +++++------------ .../scripts/infer_yolov4_int8_performance.sh | 201 +++++------------- .../yolov4/ixrt/simplify_model.py | 21 -- 14 files changed, 356 insertions(+), 796 deletions(-) delete mode 100644 models/cv/object_detection/yolov4/ixrt/calibration_dataset.py delete mode 100644 models/cv/object_detection/yolov4/ixrt/config/YOLOV4_CONFIG delete mode 100644 models/cv/object_detection/yolov4/ixrt/modify_batchsize.py delete mode 100644 models/cv/object_detection/yolov4/ixrt/simplify_model.py diff --git a/models/cv/object_detection/yolov4/ixrt/README.md b/models/cv/object_detection/yolov4/ixrt/README.md index 456de06c..bf57bb15 100644 --- a/models/cv/object_detection/yolov4/ixrt/README.md +++ b/models/cv/object_detection/yolov4/ixrt/README.md @@ -71,26 +71,21 @@ pip3 install -r requirements.txt git clone https://github.com/Tianxiaomo/pytorch-YOLOv4.git yolov4 # download weight -mkdir checkpoints -wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights -P checkpoints +mkdir data +wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights -P data # export onnx model -python3 export.py --cfg yolov4/cfg/yolov4.cfg --weight yolov4.weights --output yolov4.onnx -mv yolov4.onnx checkpoints/yolov4.onnx -``` +python3 export.py --cfg yolov4/cfg/yolov4.cfg --weight data/yolov4.weights --batchsize 16 --output data/yolov4.onnx +mv yolov4_16_3_608_608_static.onnx data/yolov4.onnx -## Model Inference +# Use onnxsim optimize onnx model +onnxsim data/yolov4.onnx data/yolov4_sim.onnx -```bash -export PROJ_DIR=./ -export DATASETS_DIR=./coco/ -export CHECKPOINTS_DIR=./checkpoints -export COCO_GT=./coco/annotations/instances_val2017.json -export EVAL_DIR=./coco/images/val2017 -export RUN_DIR=./ -export CONFIG_DIR=config/YOLOV4_CONFIG +# Make sure the dataset path is "data/coco" ``` +## Model Inference + ### FP16 ```bash diff --git a/models/cv/object_detection/yolov4/ixrt/build_engine.py b/models/cv/object_detection/yolov4/ixrt/build_engine.py index d47e45e5..53e501b3 100644 --- a/models/cv/object_detection/yolov4/ixrt/build_engine.py +++ b/models/cv/object_detection/yolov4/ixrt/build_engine.py @@ -5,6 +5,7 @@ import numpy as np import torch import tensorrt +from tensorrt import Dims from load_ixrt_plugin import load_ixrt_plugin load_ixrt_plugin() @@ -15,17 +16,33 @@ def main(config): EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) network = builder.create_network(EXPLICIT_BATCH) build_config = builder.create_builder_config() + + profile = builder.create_optimization_profile() + profile.set_shape("input", + Dims([16, 3, 608, 608]), + Dims([16, 3, 608, 608]), + Dims([16, 3, 608, 608]), + ) + build_config.add_optimization_profile(profile) + parser = tensorrt.OnnxParser(network, IXRT_LOGGER) parser.parse_from_file(config.model) - precision = tensorrt.BuilderFlag.INT8 if config.precision == "int8" else tensorrt.BuilderFlag.FP16 # print("precision : ", precision) build_config.set_flag(precision) + # set dynamic + num_inputs = network.num_inputs + for i in range(num_inputs): + input_tensor = network.get_input(i) + input_tensor.shape = Dims([16, 3, 608, 608]) + plan = builder.build_serialized_network(network, build_config) engine_file_path = config.engine with open(engine_file_path, "wb") as f: f.write(plan) + print("Build dynamic shape engine done!") + def parse_args(): parser = argparse.ArgumentParser() diff --git a/models/cv/object_detection/yolov4/ixrt/calibration_dataset.py b/models/cv/object_detection/yolov4/ixrt/calibration_dataset.py deleted file mode 100644 index 578e013d..00000000 --- a/models/cv/object_detection/yolov4/ixrt/calibration_dataset.py +++ /dev/null @@ -1,31 +0,0 @@ -import os -import torch -import torchvision.datasets -from torch.utils.data import DataLoader - - - -from datasets.coco import CocoDetection - -def create_dataloaders(data_path, annFile, img_sz=640, batch_size=32, step=32, workers=2, data_process_type="yolov5"): - dataset = CocoDetection( - root=data_path, - annFile=annFile, - img_size=img_sz, - data_process_type=data_process_type - ) - calibration_dataset = dataset - num_samples = min(5000, batch_size * step) - if num_samples > 0: - calibration_dataset = torch.utils.data.Subset( - dataset, indices=range(num_samples) - ) - - calibration_dataloader = DataLoader( - calibration_dataset, - shuffle=False, - batch_size=batch_size, - drop_last=False, - num_workers=workers, - ) - return calibration_dataloader \ No newline at end of file diff --git a/models/cv/object_detection/yolov4/ixrt/ci/prepare.sh b/models/cv/object_detection/yolov4/ixrt/ci/prepare.sh index 63b53420..142bef3d 100644 --- a/models/cv/object_detection/yolov4/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/yolov4/ixrt/ci/prepare.sh @@ -30,8 +30,9 @@ pip3 install -r requirements.txt # clone yolov4 cp -r /root/data/3rd_party/yolov4 ./ -mkdir checkpoints +mkdir data # export onnx model -python3 export.py --cfg yolov4/cfg/yolov4.cfg --weight /root/data/checkpoints/yolov4.weights --output yolov4.onnx -mv yolov4.onnx checkpoints/yolov4.onnx - +python3 export.py --cfg yolov4/cfg/yolov4.cfg --weight /root/data/checkpoints/yolov4.weights --batchsize 16 --output data/yolov4.onnx +mv yolov4_16_3_608_608_static.onnx data/yolov4.onnx +onnxsim data/yolov4.onnx data/yolov4_sim.onnx +ln -s /root/data/datasets/coco data/coco diff --git a/models/cv/object_detection/yolov4/ixrt/config/YOLOV4_CONFIG b/models/cv/object_detection/yolov4/ixrt/config/YOLOV4_CONFIG deleted file mode 100644 index c0499494..00000000 --- a/models/cv/object_detection/yolov4/ixrt/config/YOLOV4_CONFIG +++ /dev/null @@ -1,49 +0,0 @@ -# BSZ : 构建engine以及推理时的batchsize -# IMGSIZE : 模型输入hw大小 -# RUN_MODE : [FPS, MAP] -# PRECISION : [float16, int8] -# MODEL_NAME : 生成onnx/engine的basename -# ORIGINE_MODEL : 原始onnx文件 -# COCO_GT : COCOEVAL标签文件 -# DATASET_DIR : 量化/推理数据集路径 -# CHECKPOINTS_DIR : 存放生成的onnx/engine路径 -# LAYER_FUSION : decoder部分走融合算子实现 0不融合 1融合 -# DECODER_FASTER : 有两种融合实现,faster版本速度快且可以直接对接gpu nms;另一种实现的输出和onnx保持一致. 1:faster -IMGSIZE=416 -MODEL_NAME=yolov4 -ORIGINE_MODEL=yolov4.onnx -DATA_PROCESS_TYPE=yolov4 -MODEL_INPUT_NAMES=(input) - -LAYER_FUSION=1 -DECODER_FASTER=1 -DECODER_NUM_CLASS=80 -DECODER_INPUT_NAMES=(/models.138/conv94/Conv_output_0 /models.149/conv102/Conv_output_0 /models.160/conv110/Conv_output_0) -DECODER_8_ANCHOR=(12 16 19 36 40 28) -DECODER_16_ANCHOR=(36 75 76 55 72 146) -DECODER_32_ANCHOR=(142 110 192 243 459 401) - -# NMS CONFIG - # IOU_THRESH : iou阈值 - # SCORE_THRESH : bbox置信度阈值 - # MAX_BOX_PRE_IMG : 每张图片预测bbox的数量上限 - # ALL_BOX_NUM : nms接收每张图片的box数量 - # NMS_TYPE : GPU/CPU(TODO) -IOU_THRESH=0.6 -SCORE_THRESH=0.001 -MAX_BOX_PRE_IMG=1000 -ALL_BOX_NUM=10647 -NMS_TYPE=GPU - -# QUANT CONFIG (仅PRECISION为int8时生效) - # QUANT_OBSERVER : 量化策略,可选 [hist_percentile, percentile, minmax, entropy, ema] - # QUANT_BATCHSIZE : 量化时组dataloader的batchsize, 最好和onnx中的batchsize保持一致,有些op可能推导shape错误(比如Reshape) - # QUANT_STEP : 量化步数 - # QUANT_SEED : 随机种子 保证量化结果可复现 - # QUANT_EXIST_ONNX : 如果有其他来源的量化模型则填写 -QUANT_OBSERVER=hist_percentile -QUANT_BATCHSIZE=1 -QUANT_STEP=32 -QUANT_SEED=42 -DISABLE_QUANT_LIST=() -QUANT_EXIST_ONNX= \ No newline at end of file diff --git a/models/cv/object_detection/yolov4/ixrt/deploy.py b/models/cv/object_detection/yolov4/ixrt/deploy.py index ec56b7ab..6682c17f 100644 --- a/models/cv/object_detection/yolov4/ixrt/deploy.py +++ b/models/cv/object_detection/yolov4/ixrt/deploy.py @@ -1,8 +1,74 @@ # !/usr/bin/env python # -*- coding: utf-8 -*- import argparse +import copy + +from tensorrt.deploy.api import * +from tensorrt.deploy.backend.onnx.converter import default_converter +from tensorrt.deploy.backend.torch.executor.operators._operators import to_py_type +from tensorrt.deploy.ir.operator_attr import BaseOperatorAttr, EmptyAttr +from tensorrt.deploy.ir.operator_type import OperatorType as OP +from tensorrt.deploy.ir import operator_attr as attr, Operator, generate_operator_name +from tensorrt.deploy.fusion import BasePass, PatternGraph, build_sequence_graph, GraphMatcher, PassSequence +from tensorrt.deploy.ir import Graph +from tensorrt.deploy.quantizer.quant_operator.base import quant_single_input_operator +from tensorrt.deploy.backend.onnx.converter import convert_onnx_operator from tensorrt.deploy.api import GraphTransform, create_source, create_target +class FuseMishPass(BasePass): + def process(self, graph: Graph) -> Graph: + pattern = build_sequence_graph([OP.SOFTPLUS, OP.TANH, OP.MUL]) + + matcher = GraphMatcher(pattern, strict=False) + self.transform = GraphTransform(graph) + matcher.findall(graph, self.fuse_mish) + return graph + + def fuse_mish(self, graph: Graph, pattern_graph: PatternGraph): + softplus = pattern_graph.nodes[0].operator + mul = pattern_graph.nodes[-1].operator + + if not self.can_fused(graph, pattern_graph): + return + + self.transform.delete_operators_between_op_op(softplus, mul) + + mish_op = Operator( + name=generate_operator_name(graph, pattern="Mish_{idx}"), + op_type=OP.MISH, + inputs=copy.copy(softplus.inputs), + outputs=copy.copy(mul.outputs), + ) + mish_op.is_quant_operator = softplus.is_quant_operator and mul.is_quant_operator + graph.add_operator(mish_op) + + def can_fused(self, graph: Graph, pattern_graph: PatternGraph): + softplus = pattern_graph.nodes[0].operator + mul = pattern_graph.nodes[-1].operator + + # 检查 Softplus, tanh 的输出是不是只有一个 OP 使用 + # 如果有多个 OP 使用,则不能融合 + for node in pattern_graph.nodes[:2]: + next_ops = graph.get_next_operators(node.operator) + if len(next_ops) != 1: + return False + + # 检查 Mul 的输入是不是和 Softplus 是同源的 + softplus_prev_op = graph.get_previous_operators(softplus) + if len(softplus_prev_op) != 1: + return False + + mul_prev_op = graph.get_previous_operators(mul) + if len(mul_prev_op) != 2: + return False + + for op in mul_prev_op: + if op is softplus_prev_op[0]: + return True + + return False + + class Transform: def __init__(self, graph): self.t = GraphTransform(graph) @@ -86,32 +152,24 @@ def customize_ops(graph, args): outputs=["output"], axis=1 ) - elif args.with_nms: + else: graph = t.AddConcatOp( inputs=["decoder_32", "decoder_16", "decoder_8"], outputs=["output"], axis=1 ) - graph.outputs.clear() - graph.add_output("output") - graph.outputs["output"].dtype = "FLOAT" - else: - graph.outputs.clear() - graph.add_output("decoder_8") - graph.outputs["decoder_8"].dtype = "FLOAT" - graph.add_output("decoder_16") - graph.outputs["decoder_16"].dtype = "FLOAT" - graph.add_output("decoder_32") - graph.outputs["decoder_32"].dtype = "FLOAT" + graph.outputs.clear() + graph.add_output("output") + graph.outputs["output"].dtype = "FLOAT" return graph + def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("--src", type=str) parser.add_argument("--dst", type=str) parser.add_argument("--decoder_type", type=str, choices=["YoloV3Decoder", "YoloV5Decoder", "YoloV7Decoder", "YoloxDecoder"]) - parser.add_argument("--with_nms", type=bool, default=False, help="engine with nms") parser.add_argument("--decoder_input_names", nargs='+', type=str) parser.add_argument("--decoder8_anchor", nargs='*', type=int) parser.add_argument("--decoder16_anchor", nargs='*', type=int) @@ -125,10 +183,12 @@ def parse_args(): args = parser.parse_args() return args + if __name__ == "__main__": args = parse_args() graph = create_source(args.src)() graph = customize_ops(graph, args) + graph = FuseMishPass().process(graph) create_target(saved_path=args.dst).export(graph) - print("Surged onnx lies on", args.dst) \ No newline at end of file + print("Surged onnx lies on", args.dst) diff --git a/models/cv/object_detection/yolov4/ixrt/export.py b/models/cv/object_detection/yolov4/ixrt/export.py index db7e06cc..7c8bbfa5 100644 --- a/models/cv/object_detection/yolov4/ixrt/export.py +++ b/models/cv/object_detection/yolov4/ixrt/export.py @@ -32,6 +32,11 @@ def parse_args(): required=True, help="darknet weights path.") + parser.add_argument("--batchsize", + type=int, + required=True, + help="Onnx model batchsize.") + parser.add_argument("--output", type=str, required=True, @@ -44,7 +49,7 @@ def parse_args(): def main(): args = parse_args() - transform_to_onnx(args.cfg, args.weight, -1, args.output) + transform_to_onnx(args.cfg, args.weight, args.batchsize, args.output) if __name__ == "__main__": main() diff --git a/models/cv/object_detection/yolov4/ixrt/modify_batchsize.py b/models/cv/object_detection/yolov4/ixrt/modify_batchsize.py deleted file mode 100644 index f696ae55..00000000 --- a/models/cv/object_detection/yolov4/ixrt/modify_batchsize.py +++ /dev/null @@ -1,54 +0,0 @@ -import onnx -import argparse -import copy -import numpy as np - -def change_input_dim(model, bsz): - batch_size = bsz - - # The following code changes the first dimension of every input to be batch_size - # Modify as appropriate ... note that this requires all inputs to - # have the same batch_size - inputs = model.graph.input - for input in inputs: - # Checks omitted.This assumes that all inputs are tensors and have a shape with first dim. - # Add checks as needed. - dim1 = input.type.tensor_type.shape.dim[0] - # update dim to be a symbolic value - if isinstance(batch_size, str): - # set dynamic batch size - dim1.dim_param = batch_size - elif (isinstance(batch_size, str) and batch_size.isdigit()) or isinstance(batch_size, int): - # set given batch size - dim1.dim_value = int(batch_size) - else: - # set batch size of 1 - dim1.dim_value = 1 - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--batch_size", type=int) - parser.add_argument("--origin_model", type=str) - parser.add_argument("--output_model", type=str) - args = parser.parse_args() - return args - -def modify_resize_nodes(model, bsz): - print("modify resize") - for node in model.graph.node: - if node.op_type == "Resize": - if len(node.input) >= 4 and node.input[3]: - sizes_name = node.input[3] - for initializer in model.graph.initializer: - if initializer.name == sizes_name: - shape = copy.deepcopy(onnx.numpy_helper.to_array(initializer)) - shape[0] = shape[0] * bsz - new_sizes = np.array(shape, dtype=np.int64) - initializer.CopyFrom(onnx.numpy_helper.from_array(new_sizes, name=initializer.name)) - break - -args = parse_args() -model = onnx.load(args.origin_model) -change_input_dim(model, args.batch_size) -modify_resize_nodes(model, args.batch_size) -onnx.save(model, args.output_model) diff --git a/models/cv/object_detection/yolov4/ixrt/quant.py b/models/cv/object_detection/yolov4/ixrt/quant.py index d73212ca..f82d92f6 100644 --- a/models/cv/object_detection/yolov4/ixrt/quant.py +++ b/models/cv/object_detection/yolov4/ixrt/quant.py @@ -1,34 +1,35 @@ import os +import cv2 import random import argparse import numpy as np from tensorrt.deploy import static_quantize import torch -import sys -sys.path.append("/home/haoyuan.chen/temp/inferencesamples/benchmarks/cv/detection/yolov3/tensorrt") -print(sys.path) -from calibration_dataset import create_dataloaders +from torch.utils.data import DataLoader +from common import letterbox + def setseed(seed=42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) + def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("--model_name", type=str) - parser.add_argument("--model", type=str, default="yolov5s_with_decoder.onnx") - parser.add_argument("--data_process_type", type=str, default="none") + parser.add_argument("--model", type=str, default="yolov4_bs16_without_decoder.onnx") parser.add_argument("--dataset_dir", type=str, default="./coco2017/val2017") parser.add_argument("--ann_file", type=str, default="./coco2017/annotations/instances_val2017.json") parser.add_argument("--observer", type=str, choices=["hist_percentile", "percentile", "minmax", "entropy", "ema"], default="hist_percentile") parser.add_argument("--disable_quant_names", nargs='*', type=str) - parser.add_argument("--save_dir", type=str, help="save path", default=None) - parser.add_argument("--bsz", type=int, default=32) - parser.add_argument("--step", type=int, default=20) + parser.add_argument("--save_quant_model", type=str, help="save the quantization model path", default=None) + parser.add_argument("--bsz", type=int, default=16) + parser.add_argument("--step", type=int, default=32) parser.add_argument("--seed", type=int, default=42) - parser.add_argument("--imgsz", type=int, default=640) + parser.add_argument("--imgsz", type=int, default=608) + parser.add_argument("--use_letterbox", action="store_true") args = parser.parse_args() return args @@ -36,20 +37,54 @@ args = parse_args() setseed(args.seed) model_name = args.model_name -out_dir = args.save_dir -dataloader = create_dataloaders( - data_path=args.dataset_dir, - annFile=args.ann_file, - img_sz=args.imgsz, - batch_size=args.bsz, + +def get_dataloader(data_dir, step=32, batch_size=16, new_shape=[608, 608], use_letterbox=False): + num = step * batch_size + val_list = [os.path.join(data_dir, x) for x in os.listdir(data_dir)] + random.shuffle(val_list) + pic_list = val_list[:num] + + calibration_dataset = [] + for file_path in pic_list: + pic_data = cv2.imread(file_path) + org_img = pic_data + assert org_img is not None, 'Image not Found ' + file_path + h0, w0 = org_img.shape[:2] + + if use_letterbox: + img, ratio, dwdh = letterbox(org_img, new_shape=(new_shape[1], new_shape[0]), auto=False, scaleup=True) + else: + img = cv2.resize(org_img, new_shape) + img = img.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB + img = np.ascontiguousarray(img) / 255.0 # 0~1 np array + img = torch.from_numpy(img).float() + + calibration_dataset.append(img) + + calibration_dataloader = DataLoader( + calibration_dataset, + shuffle=True, + batch_size=batch_size, + drop_last=True + ) + return calibration_dataloader + +dataloader = get_dataloader( + data_dir=args.dataset_dir, step=args.step, - data_process_type=args.data_process_type + batch_size=args.bsz, + new_shape=(args.imgsz, args.imgsz), + use_letterbox=args.use_letterbox ) -# print("disable_quant_names : ", args.disable_quant_names) + +dirname = os.path.dirname(args.save_quant_model) +quant_json_path = os.path.join(dirname, f"quantized_{model_name}.json") + static_quantize(args.model, calibration_dataloader=dataloader, - save_quant_onnx_path=os.path.join(out_dir, f"quantized_{model_name}.onnx"), + save_quant_onnx_path=args.save_quant_model, + save_quant_params_path=quant_json_path, observer=args.observer, - data_preprocess=lambda x: x[0].to("cuda"), + data_preprocess=lambda x: x.to("cuda"), quant_format="qdq", - disable_quant_names=args.disable_quant_names) \ No newline at end of file + disable_quant_names=args.disable_quant_names) diff --git a/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_fp16_accuracy.sh b/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_fp16_accuracy.sh index fe7df9d6..348e5e82 100644 --- a/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_fp16_accuracy.sh +++ b/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_fp16_accuracy.sh @@ -1,185 +1,77 @@ #!/bin/bash - EXIT_STATUS=0 check_status() { - ret_code=${PIPESTATUS[0]} - if [ ${ret_code} != 0 ]; then - [[ ${ret_code} -eq 10 && "${TEST_PERF:-1}" -eq 0 ]] || EXIT_STATUS=1 + if ((${PIPESTATUS[0]} != 0));then + EXIT_STATUS=1 fi } -# Run paraments -BSZ=32 -WARM_UP=-1 -TGT=0.65 -LOOP_COUNT=-1 -RUN_MODE=MAP -PRECISION=float16 - -# Update arguments -index=0 -options=$@ -arguments=($options) -for argument in $options -do - index=`expr $index + 1` - case $argument in - --bs) BSZ=${arguments[index]};; - --tgt) TGT=${arguments[index]};; - esac -done - -source ${CONFIG_DIR} -ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} +PROJ_DIR=$(cd $(dirname $0);cd ../; pwd) +DATASETS_DIR="${PROJ_DIR}/data/coco" +COCO_GT=${DATASETS_DIR}/annotations/instances_val2017.json +EVAL_DIR=${DATASETS_DIR}/images/val2017 +CHECKPOINTS_DIR="${PROJ_DIR}/data" +RUN_DIR="${PROJ_DIR}" +ORIGINE_MODEL=${CHECKPOINTS_DIR} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} echo RUN_DIR : ${RUN_DIR} -echo CONFIG_DIR : ${CONFIG_DIR} echo ====================== Model Info ====================== -echo Model Name : ${MODEL_NAME} +echo Model Name : yolov4_darknet echo Onnx Path : ${ORIGINE_MODEL} -CHECKPOINTS_DIR=${CHECKPOINTS_DIR}/tmp -mkdir -p ${CHECKPOINTS_DIR} - -step=0 -faster=0 -CURRENT_MODEL=${ORIGINE_MODEL} -if [[ ${LAYER_FUSION} == 1 && ${DECODER_FASTER} == 1 ]];then - faster=1 -fi - -# Simplify Model -let step++ -echo [STEP ${step}] : Simplify Model -SIM_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_sim.onnx -if [ -f ${SIM_MODEL} ];then - echo " "Simplify Model skip, ${SIM_MODEL} has been existed -else - python3 ${RUN_DIR}/simplify_model.py \ - --origin_model ${CURRENT_MODEL} \ - --output_model ${SIM_MODEL} - echo " "Generate ${SIM_MODEL} -fi -CURRENT_MODEL=${SIM_MODEL} +BATCH_SIZE=16 +CURRENT_MODEL=${CHECKPOINTS_DIR}/yolov4_sim.onnx -# Cut Decoder -let step++ -echo [STEP ${step}] : Cut Decoder -NO_DECODER_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_without_decoder.onnx -if [ -f ${NO_DECODER_MODEL} ];then - echo " "Cut Decoder skip, ${SIM_MNO_DECODER_MODELODEL} has been existed +# Cut decoder part +echo "Cut decoder part" +FINAL_MODEL=${CHECKPOINTS_DIR}/yolov4_bs${BATCH_SIZE}_without_decoder.onnx +if [ -f $FINAL_MODEL ];then + echo " "CUT Model Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/cut_model.py \ - --input_model ${CURRENT_MODEL} \ - --output_model ${NO_DECODER_MODEL} \ - --input_names ${MODEL_INPUT_NAMES[@]} \ - --output_names ${DECODER_INPUT_NAMES[@]} -fi -CURRENT_MODEL=${NO_DECODER_MODEL} - -# Quant Model -if [ $PRECISION == "int8" ];then - let step++ - echo; - echo [STEP ${step}] : Quant Model - if [[ -z ${QUANT_EXIST_ONNX} ]];then - QUANT_EXIST_ONNX=$CHECKPOINTS_DIR/quantized_${MODEL_NAME}.onnx - fi - if [[ -f ${QUANT_EXIST_ONNX} ]];then - CURRENT_MODEL=${QUANT_EXIST_ONNX} - echo " "Quant Model Skip, ${QUANT_EXIST_ONNX} has been existed - else - python3 ${RUN_DIR}/quant.py \ - --model ${CURRENT_MODEL} \ - --model_name ${MODEL_NAME} \ - --dataset_dir ${EVAL_DIR} \ - --ann_file ${COCO_GT} \ - --data_process_type ${DATA_PROCESS_TYPE} \ - --observer ${QUANT_OBSERVER} \ - --disable_quant_names ${DISABLE_QUANT_LIST[@]} \ - --save_dir $CHECKPOINTS_DIR \ - --bsz ${QUANT_BATCHSIZE} \ - --step ${QUANT_STEP} \ - --seed ${QUANT_SEED} \ - --imgsz ${IMGSIZE} - echo " "Generate ${QUANT_EXIST_ONNX} - fi - CURRENT_MODEL=${QUANT_EXIST_ONNX} -fi - -# Add Decoder -if [ $LAYER_FUSION == "1" ]; then - let step++ - echo; - echo [STEP ${step}] : Add Decoder - FUSION_ONNX=${CHECKPOINTS_DIR}/${MODEL_NAME}_fusion_cancat.onnx - if [ -f $FUSION_ONNX ];then - echo " "Add Decoder Skip, $FUSION_ONNX has been existed - else - python3 ${RUN_DIR}/deploy.py \ - --src ${CURRENT_MODEL} \ - --dst ${FUSION_ONNX} \ - --decoder_type YoloV3Decoder \ - --with_nms True \ - --decoder_input_names ${DECODER_INPUT_NAMES[@]} \ - --decoder8_anchor ${DECODER_8_ANCHOR[@]} \ - --decoder16_anchor ${DECODER_16_ANCHOR[@]} \ - --decoder32_anchor ${DECODER_32_ANCHOR[@]} \ - --num_class ${DECODER_NUM_CLASS} \ - --faster ${faster} - fi - CURRENT_MODEL=${FUSION_ONNX} + python3 ${RUN_DIR}/cut_model.py \ + --input_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} \ + --input_names input \ + --output_names /models.138/conv94/Conv_output_0 /models.149/conv102/Conv_output_0 /models.160/conv110/Conv_output_0 + echo " "Generate ${FINAL_MODEL} fi +CURRENT_MODEL=${FINAL_MODEL} -# Change Batchsize -let step++ -echo; -echo [STEP ${step}] : Change Batchsize -FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_bs${BSZ}_with_nms.onnx +# add decoder op +FINAL_MODEL=${CHECKPOINTS_DIR}/yolov4_bs${BATCH_SIZE}_with_decoder.onnx if [ -f $FINAL_MODEL ];then - echo " "Change Batchsize Skip, $FINAL_MODEL has been existed + echo " "Add Decoder Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/modify_batchsize.py \ - --batch_size ${BSZ} \ - --origin_model ${CURRENT_MODEL} \ - --output_model ${FINAL_MODEL} + python3 ${RUN_DIR}/deploy.py \ + --src ${CURRENT_MODEL} \ + --dst ${FINAL_MODEL} \ + --decoder_type YoloV3Decoder \ + --decoder_input_names /models.138/conv94/Conv_output_0 /models.149/conv102/Conv_output_0 /models.160/conv110/Conv_output_0 \ + --decoder8_anchor 12 16 19 36 40 28 \ + --decoder16_anchor 36 75 76 55 72 146 \ + --decoder32_anchor 142 110 192 243 459 401 echo " "Generate ${FINAL_MODEL} fi CURRENT_MODEL=${FINAL_MODEL} # Build Engine -let step++ -echo; -echo [STEP ${step}] : Build Engine -ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}_with_nms.engine +echo Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/yolov4_fp16.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --precision ${PRECISION} \ + --precision float16 \ --model ${CURRENT_MODEL} \ --engine ${ENGINE_FILE} echo " "Generate Engine ${ENGINE_FILE} fi -if [[ ${RUN_MODE} == "MAP" && ${NMS_TYPE} == "GPU" ]];then - NMS_ENGINE=${CHECKPOINTS_DIR}/nms.engine - # Build NMS Engine - python3 ${RUN_DIR}/build_nms_engine.py \ - --bsz ${BSZ} \ - --path ${CHECKPOINTS_DIR} \ - --all_box_num ${ALL_BOX_NUM} \ - --max_box_pre_img ${MAX_BOX_PRE_IMG} \ - --iou_thresh ${IOU_THRESH} \ - --score_thresh ${SCORE_THRESH} -fi # Inference -let step++ -echo; -echo [STEP ${step}] : Inference +echo Inference RUN_BATCH_SIZE=16 python3 ${RUN_DIR}/inference.py \ --test_mode MAP \ diff --git a/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_fp16_performance.sh b/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_fp16_performance.sh index 8f34a237..f77b910c 100644 --- a/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_fp16_performance.sh +++ b/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_fp16_performance.sh @@ -1,186 +1,77 @@ #!/bin/bash - EXIT_STATUS=0 check_status() { - ret_code=${PIPESTATUS[0]} - if [ ${ret_code} != 0 ]; then - [[ ${ret_code} -eq 10 && "${TEST_PERF:-1}" -eq 0 ]] || EXIT_STATUS=1 + if ((${PIPESTATUS[0]} != 0));then + EXIT_STATUS=1 fi } -# Run paraments -BSZ=32 -WARM_UP=3 -TGT=1010 -LOOP_COUNT=100 -RUN_MODE=FPS -PRECISION=float16 - -# Update arguments -index=0 -options=$@ -arguments=($options) -for argument in $options -do - index=`expr $index + 1` - case $argument in - --bs) BSZ=${arguments[index]};; - --tgt) TGT=${arguments[index]};; - esac -done - -source ${CONFIG_DIR} -ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} +PROJ_DIR=$(cd $(dirname $0);cd ../; pwd) +DATASETS_DIR="${PROJ_DIR}/data/coco" +COCO_GT=${DATASETS_DIR}/annotations/instances_val2017.json +EVAL_DIR=${DATASETS_DIR}/images/val2017 +CHECKPOINTS_DIR="${PROJ_DIR}/data" +RUN_DIR="${PROJ_DIR}" +ORIGINE_MODEL=${CHECKPOINTS_DIR} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} echo RUN_DIR : ${RUN_DIR} -echo CONFIG_DIR : ${CONFIG_DIR} echo ====================== Model Info ====================== -echo Model Name : ${MODEL_NAME} +echo Model Name : yolov4_darknet echo Onnx Path : ${ORIGINE_MODEL} -CHECKPOINTS_DIR=${CHECKPOINTS_DIR}/tmp -mkdir -p ${CHECKPOINTS_DIR} - -step=0 -faster=0 -CURRENT_MODEL=${ORIGINE_MODEL} -if [[ ${LAYER_FUSION} == 1 && ${DECODER_FASTER} == 1 ]];then - faster=1 -fi - -# Simplify Model -let step++ -echo [STEP ${step}] : Simplify Model -SIM_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_sim.onnx -if [ -f ${SIM_MODEL} ];then - echo " "Simplify Model skip, ${SIM_MODEL} has been existed -else - python3 ${RUN_DIR}/simplify_model.py \ - --origin_model ${CURRENT_MODEL} \ - --output_model ${SIM_MODEL} - echo " "Generate ${SIM_MODEL} -fi -CURRENT_MODEL=${SIM_MODEL} +BATCH_SIZE=16 +CURRENT_MODEL=${CHECKPOINTS_DIR}/yolov4_sim.onnx -# Cut Decoder -let step++ -echo [STEP ${step}] : Cut Decoder -NO_DECODER_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_without_decoder.onnx -if [ -f ${NO_DECODER_MODEL} ];then - echo " "Cut Decoder skip, ${SIM_MNO_DECODER_MODELODEL} has been existed +# Cut decoder part +echo "Cut decoder part" +FINAL_MODEL=${CHECKPOINTS_DIR}/yolov4_bs${BATCH_SIZE}_without_decoder.onnx +if [ -f $FINAL_MODEL ];then + echo " "CUT Model Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/cut_model.py \ - --input_model ${CURRENT_MODEL} \ - --output_model ${NO_DECODER_MODEL} \ - --input_names ${MODEL_INPUT_NAMES[@]} \ - --output_names ${DECODER_INPUT_NAMES[@]} -fi -CURRENT_MODEL=${NO_DECODER_MODEL} - - -# Quant Model -if [ $PRECISION == "int8" ];then - let step++ - echo; - echo [STEP ${step}] : Quant Model - if [[ -z ${QUANT_EXIST_ONNX} ]];then - QUANT_EXIST_ONNX=$CHECKPOINTS_DIR/quantized_${MODEL_NAME}.onnx - fi - if [[ -f ${QUANT_EXIST_ONNX} ]];then - CURRENT_MODEL=${QUANT_EXIST_ONNX} - echo " "Quant Model Skip, ${QUANT_EXIST_ONNX} has been existed - else - python3 ${RUN_DIR}/quant.py \ - --model ${CURRENT_MODEL} \ - --model_name ${MODEL_NAME} \ - --dataset_dir ${EVAL_DIR} \ - --ann_file ${COCO_GT} \ - --data_process_type ${DATA_PROCESS_TYPE} \ - --observer ${QUANT_OBSERVER} \ - --disable_quant_names ${DISABLE_QUANT_LIST[@]} \ - --save_dir $CHECKPOINTS_DIR \ - --bsz ${QUANT_BATCHSIZE} \ - --step ${QUANT_STEP} \ - --seed ${QUANT_SEED} \ - --imgsz ${IMGSIZE} - echo " "Generate ${QUANT_EXIST_ONNX} - fi - CURRENT_MODEL=${QUANT_EXIST_ONNX} -fi - -# Add Decoder -if [ $LAYER_FUSION == "1" ]; then - let step++ - echo; - echo [STEP ${step}] : Add Decoder - FUSION_ONNX=${CHECKPOINTS_DIR}/${MODEL_NAME}_fusion_no_cancat.onnx - if [ -f $FUSION_ONNX ];then - echo " "Add Decoder Skip, $FUSION_ONNX has been existed - else - python3 ${RUN_DIR}/deploy.py \ - --src ${CURRENT_MODEL} \ - --dst ${FUSION_ONNX} \ - --decoder_type YoloV3Decoder \ - --with_nms False \ - --decoder_input_names ${DECODER_INPUT_NAMES[@]} \ - --decoder8_anchor ${DECODER_8_ANCHOR[@]} \ - --decoder16_anchor ${DECODER_16_ANCHOR[@]} \ - --decoder32_anchor ${DECODER_32_ANCHOR[@]} \ - --num_class ${DECODER_NUM_CLASS} \ - --faster ${faster} - fi - CURRENT_MODEL=${FUSION_ONNX} + python3 ${RUN_DIR}/cut_model.py \ + --input_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} \ + --input_names input \ + --output_names /models.138/conv94/Conv_output_0 /models.149/conv102/Conv_output_0 /models.160/conv110/Conv_output_0 + echo " "Generate ${FINAL_MODEL} fi +CURRENT_MODEL=${FINAL_MODEL} -# Change Batchsize -let step++ -echo; -echo [STEP ${step}] : Change Batchsize -FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_bs${BSZ}_without_nms.onnx +# add decoder op +FINAL_MODEL=${CHECKPOINTS_DIR}/yolov4_bs${BATCH_SIZE}_with_decoder.onnx if [ -f $FINAL_MODEL ];then - echo " "Change Batchsize Skip, $FINAL_MODEL has been existed + echo " "Add Decoder Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/modify_batchsize.py \ - --batch_size ${BSZ} \ - --origin_model ${CURRENT_MODEL} \ - --output_model ${FINAL_MODEL} + python3 ${RUN_DIR}/deploy.py \ + --src ${CURRENT_MODEL} \ + --dst ${FINAL_MODEL} \ + --decoder_type YoloV3Decoder \ + --decoder_input_names /models.138/conv94/Conv_output_0 /models.149/conv102/Conv_output_0 /models.160/conv110/Conv_output_0 \ + --decoder8_anchor 12 16 19 36 40 28 \ + --decoder16_anchor 36 75 76 55 72 146 \ + --decoder32_anchor 142 110 192 243 459 401 echo " "Generate ${FINAL_MODEL} fi CURRENT_MODEL=${FINAL_MODEL} # Build Engine -let step++ -echo; -echo [STEP ${step}] : Build Engine -ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}_without_nms.engine +echo Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/yolov4_fp16.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --precision ${PRECISION} \ + --precision float16 \ --model ${CURRENT_MODEL} \ --engine ${ENGINE_FILE} echo " "Generate Engine ${ENGINE_FILE} fi -if [[ ${RUN_MODE} == "MAP" && ${NMS_TYPE} == "GPU" ]];then - NMS_ENGINE=${CHECKPOINTS_DIR}/nms.engine - # Build NMS Engine - python3 ${RUN_DIR}/build_nms_engine.py \ - --bsz ${BSZ} \ - --path ${CHECKPOINTS_DIR} \ - --all_box_num ${ALL_BOX_NUM} \ - --max_box_pre_img ${MAX_BOX_PRE_IMG} \ - --iou_thresh ${IOU_THRESH} \ - --score_thresh ${SCORE_THRESH} -fi # Inference -let step++ -echo; -echo [STEP ${step}] : Inference +echo Inference RUN_BATCH_SIZE=16 python3 ${RUN_DIR}/inference.py \ --test_mode FPS \ diff --git a/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_int8_accuracy.sh b/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_int8_accuracy.sh index 646b115f..39497d7a 100644 --- a/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_int8_accuracy.sh +++ b/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_int8_accuracy.sh @@ -1,185 +1,95 @@ #!/bin/bash - EXIT_STATUS=0 check_status() { - ret_code=${PIPESTATUS[0]} - if [ ${ret_code} != 0 ]; then - [[ ${ret_code} -eq 10 && "${TEST_PERF:-1}" -eq 0 ]] || EXIT_STATUS=1 + if ((${PIPESTATUS[0]} != 0));then + EXIT_STATUS=1 fi } -# Run paraments -BSZ=32 -WARM_UP=-1 -TGT=0.65 -LOOP_COUNT=-1 -RUN_MODE=MAP -PRECISION=int8 - -# Update arguments -index=0 -options=$@ -arguments=($options) -for argument in $options -do - index=`expr $index + 1` - case $argument in - --bs) BSZ=${arguments[index]};; - --tgt) TGT=${arguments[index]};; - esac -done - -source ${CONFIG_DIR} -ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} +PROJ_DIR=$(cd $(dirname $0);cd ../; pwd) +DATASETS_DIR="${PROJ_DIR}/data/coco" +COCO_GT=${DATASETS_DIR}/annotations/instances_val2017.json +EVAL_DIR=${DATASETS_DIR}/images/val2017 +CHECKPOINTS_DIR="${PROJ_DIR}/data" +RUN_DIR="${PROJ_DIR}" +ORIGINE_MODEL=${CHECKPOINTS_DIR} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} echo RUN_DIR : ${RUN_DIR} -echo CONFIG_DIR : ${CONFIG_DIR} echo ====================== Model Info ====================== -echo Model Name : ${MODEL_NAME} +echo Model Name : yolov4_darknet echo Onnx Path : ${ORIGINE_MODEL} -CHECKPOINTS_DIR=${CHECKPOINTS_DIR}/tmp -mkdir -p ${CHECKPOINTS_DIR} +BATCH_SIZE=16 +CURRENT_MODEL=${CHECKPOINTS_DIR}/yolov4_sim.onnx -step=0 -faster=0 -CURRENT_MODEL=${ORIGINE_MODEL} -if [[ ${LAYER_FUSION} == 1 && ${DECODER_FASTER} == 1 ]];then - faster=1 -fi - -# Simplify Model -let step++ -echo [STEP ${step}] : Simplify Model -SIM_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_sim.onnx -if [ -f ${SIM_MODEL} ];then - echo " "Simplify Model skip, ${SIM_MODEL} has been existed +# Cut decoder part +echo "Cut decoder part" +FINAL_MODEL=${CHECKPOINTS_DIR}/yolov4_bs${BATCH_SIZE}_without_decoder.onnx +if [ -f $FINAL_MODEL ];then + echo " "CUT Model Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/simplify_model.py \ - --origin_model ${CURRENT_MODEL} \ - --output_model ${SIM_MODEL} - echo " "Generate ${SIM_MODEL} + python3 ${RUN_DIR}/cut_model.py \ + --input_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} \ + --input_names input \ + --output_names /models.138/conv94/Conv_output_0 /models.149/conv102/Conv_output_0 /models.160/conv110/Conv_output_0 + echo " "Generate ${FINAL_MODEL} fi -CURRENT_MODEL=${SIM_MODEL} +CURRENT_MODEL=${FINAL_MODEL} -# Cut Decoder -let step++ -echo [STEP ${step}] : Cut Decoder -NO_DECODER_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_without_decoder.onnx -if [ -f ${NO_DECODER_MODEL} ];then - echo " "Cut Decoder skip, ${SIM_MNO_DECODER_MODELODEL} has been existed +# quant +FINAL_MODEL=${CHECKPOINTS_DIR}/quantized_yolov4_bs${BATCH_SIZE}_without_decoder.onnx +if [ -f $FINAL_MODEL ];then + echo " "Change Batchsize Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/cut_model.py \ - --input_model ${CURRENT_MODEL} \ - --output_model ${NO_DECODER_MODEL} \ - --input_names ${MODEL_INPUT_NAMES[@]} \ - --output_names ${DECODER_INPUT_NAMES[@]} -fi -CURRENT_MODEL=${NO_DECODER_MODEL} - -# Quant Model -if [ $PRECISION == "int8" ];then - let step++ - echo; - echo [STEP ${step}] : Quant Model - if [[ -z ${QUANT_EXIST_ONNX} ]];then - QUANT_EXIST_ONNX=$CHECKPOINTS_DIR/quantized_${MODEL_NAME}.onnx - fi - if [[ -f ${QUANT_EXIST_ONNX} ]];then - CURRENT_MODEL=${QUANT_EXIST_ONNX} - echo " "Quant Model Skip, ${QUANT_EXIST_ONNX} has been existed - else - python3 ${RUN_DIR}/quant.py \ - --model ${CURRENT_MODEL} \ - --model_name ${MODEL_NAME} \ - --dataset_dir ${EVAL_DIR} \ - --ann_file ${COCO_GT} \ - --data_process_type ${DATA_PROCESS_TYPE} \ - --observer ${QUANT_OBSERVER} \ - --disable_quant_names ${DISABLE_QUANT_LIST[@]} \ - --save_dir $CHECKPOINTS_DIR \ - --bsz ${QUANT_BATCHSIZE} \ - --step ${QUANT_STEP} \ - --seed ${QUANT_SEED} \ - --imgsz ${IMGSIZE} - echo " "Generate ${QUANT_EXIST_ONNX} - fi - CURRENT_MODEL=${QUANT_EXIST_ONNX} -fi - -# Add Decoder -if [ $LAYER_FUSION == "1" ]; then - let step++ - echo; - echo [STEP ${step}] : Add Decoder - FUSION_ONNX=${CHECKPOINTS_DIR}/${MODEL_NAME}_quant_fusion_cancat.onnx - if [ -f $FUSION_ONNX ];then - echo " "Add Decoder Skip, $FUSION_ONNX has been existed - else - python3 ${RUN_DIR}/deploy.py \ - --src ${CURRENT_MODEL} \ - --dst ${FUSION_ONNX} \ - --decoder_type YoloV3Decoder \ - --with_nms True \ - --decoder_input_names ${DECODER_INPUT_NAMES[@]} \ - --decoder8_anchor ${DECODER_8_ANCHOR[@]} \ - --decoder16_anchor ${DECODER_16_ANCHOR[@]} \ - --decoder32_anchor ${DECODER_32_ANCHOR[@]} \ - --num_class ${DECODER_NUM_CLASS} \ - --faster ${faster} - fi - CURRENT_MODEL=${FUSION_ONNX} + python3 ${RUN_DIR}/quant.py \ + --model_name "YOLOV4_DARKNET" \ + --model ${CURRENT_MODEL} \ + --bsz ${BATCH_SIZE} \ + --dataset_dir ${EVAL_DIR} \ + --ann_file ${COCO_GT} \ + --observer "hist_percentile" \ + --save_quant_model ${FINAL_MODEL} \ + --imgsz 608 + echo " "Generate ${FINAL_MODEL} fi +CURRENT_MODEL=${FINAL_MODEL} -# Change Batchsize -let step++ -echo; -echo [STEP ${step}] : Change Batchsize -FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_quant_bs${BSZ}_with_nms.onnx +# add decoder op +FINAL_MODEL=${CHECKPOINTS_DIR}/quantized_yolov4_bs${BATCH_SIZE}_with_decoder.onnx if [ -f $FINAL_MODEL ];then - echo " "Change Batchsize Skip, $FINAL_MODEL has been existed + echo " "Add Decoder Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/modify_batchsize.py \ - --batch_size ${BSZ} \ - --origin_model ${CURRENT_MODEL} \ - --output_model ${FINAL_MODEL} + python3 ${RUN_DIR}/deploy.py \ + --src ${CURRENT_MODEL} \ + --dst ${FINAL_MODEL} \ + --decoder_type YoloV3Decoder \ + --decoder_input_names /models.138/conv94/Conv_output_0 /models.149/conv102/Conv_output_0 /models.160/conv110/Conv_output_0 \ + --decoder8_anchor 12 16 19 36 40 28 \ + --decoder16_anchor 36 75 76 55 72 146 \ + --decoder32_anchor 142 110 192 243 459 401 echo " "Generate ${FINAL_MODEL} fi CURRENT_MODEL=${FINAL_MODEL} # Build Engine -let step++ -echo; -echo [STEP ${step}] : Build Engine -ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}_with_nms.engine +echo Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/yolov4_int8.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --precision ${PRECISION} \ + --precision int8 \ --model ${CURRENT_MODEL} \ --engine ${ENGINE_FILE} echo " "Generate Engine ${ENGINE_FILE} fi -if [[ ${RUN_MODE} == "MAP" && ${NMS_TYPE} == "GPU" ]];then - NMS_ENGINE=${CHECKPOINTS_DIR}/nms.engine - # Build NMS Engine - python3 ${RUN_DIR}/build_nms_engine.py \ - --bsz ${BSZ} \ - --path ${CHECKPOINTS_DIR} \ - --all_box_num ${ALL_BOX_NUM} \ - --max_box_pre_img ${MAX_BOX_PRE_IMG} \ - --iou_thresh ${IOU_THRESH} \ - --score_thresh ${SCORE_THRESH} -fi # Inference -let step++ -echo; -echo [STEP ${step}] : Inference +echo Inference RUN_BATCH_SIZE=16 python3 ${RUN_DIR}/inference.py \ --test_mode MAP \ @@ -191,6 +101,6 @@ python3 ${RUN_DIR}/inference.py \ --eval_dir ${EVAL_DIR} \ --coco_gt ${COCO_GT} \ --pred_dir ${CHECKPOINTS_DIR} \ - --precision float16 \ + --precision int8 \ --map_target 0.30; check_status exit ${EXIT_STATUS} \ No newline at end of file diff --git a/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_int8_performance.sh b/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_int8_performance.sh index 4665a65f..a373336f 100644 --- a/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_int8_performance.sh +++ b/models/cv/object_detection/yolov4/ixrt/scripts/infer_yolov4_int8_performance.sh @@ -1,186 +1,95 @@ #!/bin/bash - EXIT_STATUS=0 check_status() { - ret_code=${PIPESTATUS[0]} - if [ ${ret_code} != 0 ]; then - [[ ${ret_code} -eq 10 && "${TEST_PERF:-1}" -eq 0 ]] || EXIT_STATUS=1 + if ((${PIPESTATUS[0]} != 0));then + EXIT_STATUS=1 fi } -# Run paraments -BSZ=32 -WARM_UP=3 -TGT=1010 -LOOP_COUNT=100 -RUN_MODE=FPS -PRECISION=int8 - -# Update arguments -index=0 -options=$@ -arguments=($options) -for argument in $options -do - index=`expr $index + 1` - case $argument in - --bs) BSZ=${arguments[index]};; - --tgt) TGT=${arguments[index]};; - esac -done - -source ${CONFIG_DIR} -ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} +PROJ_DIR=$(cd $(dirname $0);cd ../; pwd) +DATASETS_DIR="${PROJ_DIR}/data/coco" +COCO_GT=${DATASETS_DIR}/annotations/instances_val2017.json +EVAL_DIR=${DATASETS_DIR}/images/val2017 +CHECKPOINTS_DIR="${PROJ_DIR}/data" +RUN_DIR="${PROJ_DIR}" +ORIGINE_MODEL=${CHECKPOINTS_DIR} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} echo RUN_DIR : ${RUN_DIR} -echo CONFIG_DIR : ${CONFIG_DIR} echo ====================== Model Info ====================== -echo Model Name : ${MODEL_NAME} +echo Model Name : yolov4_darknet echo Onnx Path : ${ORIGINE_MODEL} -CHECKPOINTS_DIR=${CHECKPOINTS_DIR}/tmp -mkdir -p ${CHECKPOINTS_DIR} +BATCH_SIZE=16 +CURRENT_MODEL=${CHECKPOINTS_DIR}/yolov4_sim.onnx -step=0 -faster=0 -CURRENT_MODEL=${ORIGINE_MODEL} -if [[ ${LAYER_FUSION} == 1 && ${DECODER_FASTER} == 1 ]];then - faster=1 -fi - -# Simplify Model -let step++ -echo [STEP ${step}] : Simplify Model -SIM_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_sim.onnx -if [ -f ${SIM_MODEL} ];then - echo " "Simplify Model skip, ${SIM_MODEL} has been existed +# Cut decoder part +echo "Cut decoder part" +FINAL_MODEL=${CHECKPOINTS_DIR}/yolov4_bs${BATCH_SIZE}_without_decoder.onnx +if [ -f $FINAL_MODEL ];then + echo " "CUT Model Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/simplify_model.py \ - --origin_model ${CURRENT_MODEL} \ - --output_model ${SIM_MODEL} - echo " "Generate ${SIM_MODEL} + python3 ${RUN_DIR}/cut_model.py \ + --input_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} \ + --input_names input \ + --output_names /models.138/conv94/Conv_output_0 /models.149/conv102/Conv_output_0 /models.160/conv110/Conv_output_0 + echo " "Generate ${FINAL_MODEL} fi -CURRENT_MODEL=${SIM_MODEL} +CURRENT_MODEL=${FINAL_MODEL} -# Cut Decoder -let step++ -echo [STEP ${step}] : Cut Decoder -NO_DECODER_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_without_decoder.onnx -if [ -f ${NO_DECODER_MODEL} ];then - echo " "Cut Decoder skip, ${SIM_MNO_DECODER_MODELODEL} has been existed +# quant +FINAL_MODEL=${CHECKPOINTS_DIR}/quantized_yolov4_bs${BATCH_SIZE}_without_decoder.onnx +if [ -f $FINAL_MODEL ];then + echo " "Change Batchsize Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/cut_model.py \ - --input_model ${CURRENT_MODEL} \ - --output_model ${NO_DECODER_MODEL} \ - --input_names ${MODEL_INPUT_NAMES[@]} \ - --output_names ${DECODER_INPUT_NAMES[@]} -fi -CURRENT_MODEL=${NO_DECODER_MODEL} - - -# Quant Model -if [ $PRECISION == "int8" ];then - let step++ - echo; - echo [STEP ${step}] : Quant Model - if [[ -z ${QUANT_EXIST_ONNX} ]];then - QUANT_EXIST_ONNX=$CHECKPOINTS_DIR/quantized_${MODEL_NAME}.onnx - fi - if [[ -f ${QUANT_EXIST_ONNX} ]];then - CURRENT_MODEL=${QUANT_EXIST_ONNX} - echo " "Quant Model Skip, ${QUANT_EXIST_ONNX} has been existed - else - python3 ${RUN_DIR}/quant.py \ - --model ${CURRENT_MODEL} \ - --model_name ${MODEL_NAME} \ - --dataset_dir ${EVAL_DIR} \ - --ann_file ${COCO_GT} \ - --data_process_type ${DATA_PROCESS_TYPE} \ - --observer ${QUANT_OBSERVER} \ - --disable_quant_names ${DISABLE_QUANT_LIST[@]} \ - --save_dir $CHECKPOINTS_DIR \ - --bsz ${QUANT_BATCHSIZE} \ - --step ${QUANT_STEP} \ - --seed ${QUANT_SEED} \ - --imgsz ${IMGSIZE} - echo " "Generate ${QUANT_EXIST_ONNX} - fi - CURRENT_MODEL=${QUANT_EXIST_ONNX} -fi - -# Add Decoder -if [ $LAYER_FUSION == "1" ]; then - let step++ - echo; - echo [STEP ${step}] : Add Decoder - FUSION_ONNX=${CHECKPOINTS_DIR}/${MODEL_NAME}_quant_fusion_no_cancat.onnx - if [ -f $FUSION_ONNX ];then - echo " "Add Decoder Skip, $FUSION_ONNX has been existed - else - python3 ${RUN_DIR}/deploy.py \ - --src ${CURRENT_MODEL} \ - --dst ${FUSION_ONNX} \ - --decoder_type YoloV3Decoder \ - --with_nms False \ - --decoder_input_names ${DECODER_INPUT_NAMES[@]} \ - --decoder8_anchor ${DECODER_8_ANCHOR[@]} \ - --decoder16_anchor ${DECODER_16_ANCHOR[@]} \ - --decoder32_anchor ${DECODER_32_ANCHOR[@]} \ - --num_class ${DECODER_NUM_CLASS} \ - --faster ${faster} - fi - CURRENT_MODEL=${FUSION_ONNX} + python3 ${RUN_DIR}/quant.py \ + --model_name "YOLOV4_DARKNET" \ + --model ${CURRENT_MODEL} \ + --bsz ${BATCH_SIZE} \ + --dataset_dir ${EVAL_DIR} \ + --ann_file ${COCO_GT} \ + --observer "hist_percentile" \ + --save_quant_model ${FINAL_MODEL} \ + --imgsz 608 + echo " "Generate ${FINAL_MODEL} fi +CURRENT_MODEL=${FINAL_MODEL} -# Change Batchsize -let step++ -echo; -echo [STEP ${step}] : Change Batchsize -FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_quant_bs${BSZ}_without_nms.onnx +# add decoder op +FINAL_MODEL=${CHECKPOINTS_DIR}/quantized_yolov4_bs${BATCH_SIZE}_with_decoder.onnx if [ -f $FINAL_MODEL ];then - echo " "Change Batchsize Skip, $FINAL_MODEL has been existed + echo " "Add Decoder Skip, $FINAL_MODEL has been existed else - python3 ${RUN_DIR}/modify_batchsize.py \ - --batch_size ${BSZ} \ - --origin_model ${CURRENT_MODEL} \ - --output_model ${FINAL_MODEL} + python3 ${RUN_DIR}/deploy.py \ + --src ${CURRENT_MODEL} \ + --dst ${FINAL_MODEL} \ + --decoder_type YoloV3Decoder \ + --decoder_input_names /models.138/conv94/Conv_output_0 /models.149/conv102/Conv_output_0 /models.160/conv110/Conv_output_0 \ + --decoder8_anchor 12 16 19 36 40 28 \ + --decoder16_anchor 36 75 76 55 72 146 \ + --decoder32_anchor 142 110 192 243 459 401 echo " "Generate ${FINAL_MODEL} fi CURRENT_MODEL=${FINAL_MODEL} # Build Engine -let step++ -echo; -echo [STEP ${step}] : Build Engine -ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}_without_nms.engine +echo Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/yolov4_int8.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --precision ${PRECISION} \ + --precision int8 \ --model ${CURRENT_MODEL} \ --engine ${ENGINE_FILE} echo " "Generate Engine ${ENGINE_FILE} fi -if [[ ${RUN_MODE} == "MAP" && ${NMS_TYPE} == "GPU" ]];then - NMS_ENGINE=${CHECKPOINTS_DIR}/nms.engine - # Build NMS Engine - python3 ${RUN_DIR}/build_nms_engine.py \ - --bsz ${BSZ} \ - --path ${CHECKPOINTS_DIR} \ - --all_box_num ${ALL_BOX_NUM} \ - --max_box_pre_img ${MAX_BOX_PRE_IMG} \ - --iou_thresh ${IOU_THRESH} \ - --score_thresh ${SCORE_THRESH} -fi # Inference -let step++ -echo; -echo [STEP ${step}] : Inference +echo Inference RUN_BATCH_SIZE=16 python3 ${RUN_DIR}/inference.py \ --test_mode FPS \ @@ -192,6 +101,6 @@ python3 ${RUN_DIR}/inference.py \ --eval_dir ${EVAL_DIR} \ --coco_gt ${COCO_GT} \ --pred_dir ${CHECKPOINTS_DIR} \ - --precision float16 \ + --precision int8 \ --map_target 0.30; check_status exit ${EXIT_STATUS} \ No newline at end of file diff --git a/models/cv/object_detection/yolov4/ixrt/simplify_model.py b/models/cv/object_detection/yolov4/ixrt/simplify_model.py deleted file mode 100644 index b4254b6f..00000000 --- a/models/cv/object_detection/yolov4/ixrt/simplify_model.py +++ /dev/null @@ -1,21 +0,0 @@ -import onnx -import argparse -from onnxsim import simplify - -# Simplify -def simplify_model(args): - onnx_model = onnx.load(args.origin_model) - model_simp, check = simplify(onnx_model) - model_simp = onnx.shape_inference.infer_shapes(model_simp) - onnx.save(model_simp, args.output_model) - print(" Simplify onnx Done.") - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--origin_model", type=str) - parser.add_argument("--output_model", type=str) - args = parser.parse_args() - return args - -args = parse_args() -simplify_model(args) \ No newline at end of file -- Gitee