diff --git a/models/cv/object_detection/fcos/ixrt/README.md b/models/cv/object_detection/fcos/ixrt/README.md index b11d07f0cf0a97f3a5bd99ccad9d562e56634160..721fed1552fa6acee11ec5cc089a6aefbb7614cd 100755 --- a/models/cv/object_detection/fcos/ixrt/README.md +++ b/models/cv/object_detection/fcos/ixrt/README.md @@ -34,48 +34,23 @@ apt install -y libgl1-mesa-glx pip3 install -r requirements.txt ``` -The inference of the FCOS model requires a dependency on a well-adapted mmcv-v1.7.0 library. Please inquire with the staff to obtain the relevant libraries. - -You can follow the script [prepare_mmcv.sh](https://gitee.com/deep-spark/deepsparkhub/blob/master/toolbox/MMDetection/prepare_mmcv.sh) to build: - -```bash -cd mmcv -sh build_mmcv.sh -sh install_mmcv.sh -``` - ### Model Conversion MMDetection is an open source object detection toolbox based on PyTorch. It is a part of the OpenMMLab project.It is utilized for model conversion. In MMDetection, Execute model conversion command, and the checkpoints folder needs to be created, (mkdir checkpoints) in project ```bash mkdir -p checkpoints -git clone -b v2.25.0 https://github.com/open-mmlab/mmdetection.git -cd mmdetection -python3 tools/deployment/pytorch2onnx.py \ - /Path/to/fcos/ixrt/fcos_center-normbbox-centeronreg-giou_r50_caffe_fpn_gn-head_1x_coco.py \ - checkpoints/fcos_center-normbbox-centeronreg-giou_r50_caffe_fpn_gn-head_1x_coco-0a0d75a8.pth \ - --output-file /Path/To/ixrt/data/checkpoints/r50_fcos.onnx \ - --input-img demo/demo.jpg \ - --test-img tests/data/color.jpg \ - --shape 800 800 \ - --show \ - --verify \ - --skip-postprocess \ - --dynamic-export \ - --cfg-options \ - model.test_cfg.deploy_nms_pre=-1 +cd checkpoints +wget http://files.deepspark.org.cn:880/deepspark/fcos_opt.onnx ``` -If there are issues such as input parameter mismatch during model export, it may be due to ONNX version. To resolve this, please delete the last parameter (dynamic_slice) from the return value of the_slice_helper function in the /usr/local/lib/python3.10/site-packages/mmcv/onnx/onnx_utils/symbolic_helper.py file. - ## Model Inference ```bash export PROJ_DIR=./ -export DATASETS_DIR=/Path/to/coco/ -export CHECKPOINTS_DIR=/Path/to/checkpoints -export RUN_DIR=./ +export DATASETS_DIR=./coco/ +export CHECKPOINTS_DIR=./checkpoints +export RUN_DIR=../../ixrt_common ``` ### FP16 diff --git a/models/cv/object_detection/fcos/ixrt/build_engine.py b/models/cv/object_detection/fcos/ixrt/build_engine.py deleted file mode 100755 index af649916756a27bde0aea18b9f3572a430a424d9..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/fcos/ixrt/build_engine.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import cv2 -import argparse -import numpy as np - -import torch -import tensorrt -from calibration_dataset import getdataloader -import cuda.cudart as cudart - -def assertSuccess(err): - assert(err == cudart.cudaError_t.cudaSuccess) - -class EngineCalibrator(tensorrt.IInt8EntropyCalibrator2): - - def __init__(self, cache_file, datasets_dir, loop_count=10, bsz=1, img_sz=800): - super().__init__() - self.cache_file = cache_file - self.image_batcher = getdataloader(datasets_dir, loop_count, batch_size=bsz, img_sz=img_sz) - self.batch_generator = iter(self.image_batcher) - size = img_sz*img_sz*3*bsz - __import__('pdb').set_trace() - err, self.batch_allocation = cudart.cudaMalloc(size) - assertSuccess(err) - - def __del__(self): - err,= cudart.cudaFree(self.batch_allocation) - assertSuccess(err) - - def get_batch_size(self): - return self.image_batcher.batch_size - - def get_batch(self, names): - try: - batch, _ = next(self.batch_generator) - batch = batch.numpy() - __import__('pdb').set_trace() - cudart.cudaMemcpy(self.batch_allocation, - np.ascontiguousarray(batch), - batch.nbytes, - cudart.cudaMemcpyKind.cudaMemcpyHostToDevice) - return [int(self.batch_allocation)] - 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) - -def main(config): - IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.VERBOSE) - builder = tensorrt.Builder(IXRT_LOGGER) - EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) - network = builder.create_network(EXPLICIT_BATCH) - build_config = builder.create_builder_config() - parser = tensorrt.OnnxParser(network, IXRT_LOGGER) - parser.parse_from_file(config.model) - - precision = tensorrt.BuilderFlag.FP16 - print("precision : ", precision) - build_config.set_flag(precision) - - plan = builder.build_serialized_network(network, build_config) - engine_file_path = config.engine - with open(engine_file_path, "wb") as f: - f.write(plan) - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--model", type=str) - parser.add_argument("--engine", type=str, default=None) - parser.add_argument( - "--datasets_dir", - type=str, - default="", - help="ImageNet dir", - ) - args = parser.parse_args() - return args - -if __name__ == "__main__": - args = parse_args() - main(args) \ No newline at end of file diff --git a/models/cv/object_detection/fcos/ixrt/calibration_dataset.py b/models/cv/object_detection/fcos/ixrt/calibration_dataset.py deleted file mode 100644 index d7525d5136168cc8fb1d24a28f1b71b85ce4cc92..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/fcos/ixrt/calibration_dataset.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os - -import torch -import torchvision.datasets -from torch.utils.data import DataLoader -from torchvision import models -from torchvision import transforms as T - - -class CalibrationImageNet(torchvision.datasets.ImageFolder): - def __init__(self, *args, **kwargs): - super(CalibrationImageNet, self).__init__(*args, **kwargs) - img2label_path = os.path.join(self.root, "val_map.txt") - if not os.path.exists(img2label_path): - raise FileNotFoundError(f"Not found label file `{img2label_path}`.") - - self.img2label_map = self.make_img2label_map(img2label_path) - - def make_img2label_map(self, path): - with open(path) as f: - lines = f.readlines() - - img2lable_map = dict() - for line in lines: - line = line.lstrip().rstrip().split("\t") - if len(line) != 2: - continue - img_name, label = line - img_name = img_name.strip() - if img_name in [None, ""]: - continue - label = int(label.strip()) - img2lable_map[img_name] = label - return img2lable_map - - def __getitem__(self, index): - path, target = self.samples[index] - sample = self.loader(path) - if self.transform is not None: - sample = self.transform(sample) - # if self.target_transform is not None: - # target = self.target_transform(target) - img_name = os.path.basename(path) - target = self.img2label_map[img_name] - - return sample, target - - -def create_dataloaders(data_path, num_samples=1024, img_sz=224, batch_size=2, workers=0): - dataset = CalibrationImageNet( - data_path, - transform=T.Compose( - [ - T.Resize(256), - T.CenterCrop(img_sz), - T.ToTensor(), - T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), - ] - ), - ) - - calibration_dataset = dataset - if num_samples is not None: - 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, - ) - - verify_dataloader = DataLoader( - dataset, - shuffle=False, - batch_size=batch_size, - drop_last=False, - num_workers=workers, - ) - - return calibration_dataloader, verify_dataloader - - -def getdataloader(dataset_dir, step=20, batch_size=32, workers=2, img_sz=224, total_sample=50000): - num_samples = min(total_sample, step * batch_size) - if step < 0: - num_samples = None - calibration_dataloader, _ = create_dataloaders( - dataset_dir, - img_sz=img_sz, - batch_size=batch_size, - workers=workers, - num_samples=num_samples, - ) - return calibration_dataloader \ No newline at end of file diff --git a/models/cv/object_detection/fcos/ixrt/ci/prepare.sh b/models/cv/object_detection/fcos/ixrt/ci/prepare.sh index a19f48112c37f0e4219772b902d69eed56477392..a04697754cb74c96dbec50e56bcb3a207fcb3b58 100644 --- a/models/cv/object_detection/fcos/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/fcos/ixrt/ci/prepare.sh @@ -25,36 +25,6 @@ else echo "Not Support Os" fi pip3 install -r requirements.txt -cp -r /root/data/3rd_party/mmcv-v1.7.1 ./mmcv -cp -r -T /root/data/repos/deepsparkhub/toolbox/MMDetection/patch/mmcv/v1.7.1 ./mmcv -cd mmcv -rm -rf mmcv/ops/csrc/common/cuda/spconv/ mmcv/ops/csrc/common/utils/spconv/ -rm -f mmcv/ops/csrc/pytorch/cpu/sparse_* -rm -f mmcv/ops/csrc/pytorch/cuda/fused_spconv_ops_cuda.cu -rm -f mmcv/ops/csrc/pytorch/cuda/spconv_ops_cuda.cu -rm -f mmcv/ops/csrc/pytorch/cuda/sparse_* -rm -f mmcv/ops/csrc/pytorch/sp* - -sed -i 's/return _slice(g, input, axes, starts, ends, steps, dynamic_slice)/return _slice(g, input, axes, starts, ends, steps)/' mmcv/onnx/onnx_utils/symbolic_helper.py - -bash clean_mmcv.sh -bash build_mmcv.sh -bash install_mmcv.sh -cd .. - +pip install /root/data/install/mmcv_full-1.7.0+corex.20250108131027-cp310-cp310-linux_x86_64.whl mkdir -p checkpoints -cp -r /root/data/3rd_party/mmdetection-v2.25.0 ./mmdetection -cd mmdetection -python3 tools/deployment/pytorch2onnx.py \ - ../fcos_center-normbbox-centeronreg-giou_r50_caffe_fpn_gn-head_1x_coco.py \ - /root/data/checkpoints/fcos_center-normbbox-centeronreg-giou_r50_caffe_fpn_gn-head_1x_coco-0a0d75a8.pth \ - --output-file ../checkpoints/r50_fcos.onnx \ - --input-img demo/demo.jpg \ - --test-img tests/data/color.jpg \ - --shape 800 800 \ - --show \ - --verify \ - --skip-postprocess \ - --dynamic-export \ - --cfg-options \ - model.test_cfg.deploy_nms_pre=-1 \ No newline at end of file +cp /root/data/checkpoints/fcos_opt.onnx checkpoints/ diff --git a/models/cv/object_detection/fcos/ixrt/common.py b/models/cv/object_detection/fcos/ixrt/common.py deleted file mode 100644 index b18a24394c934c40f1f1ab761ff946edbf69f53a..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/fcos/ixrt/common.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import numpy as np -from tqdm import tqdm - -import tensorrt -import pycuda.driver as cuda - -# input : [bsz, box_num, 5(cx, cy, w, h, conf) + class_num(prob[0], prob[1], ...)] -# output : [bsz, box_num, 6(left_top_x, left_top_y, right_bottom_x, right_bottom_y, class_id, max_prob*conf)] -def box_class85to6(input): - center_x_y = input[:, :2] - side = input[:, 2:4] - conf = input[:, 4:5] - class_id = np.argmax(input[:, 5:], axis = -1) - class_id = class_id.astype(np.float32).reshape(-1, 1) + 1 - max_prob = np.max(input[:, 5:], axis = -1).reshape(-1, 1) - x1_y1 = center_x_y - 0.5 * side - x2_y2 = center_x_y + 0.5 * side - nms_input = np.concatenate([x1_y1, x2_y2, class_id, max_prob*conf], axis = -1) - return nms_input - -def save2json(batch_img_id, pred_boxes, json_result): - for i, boxes in enumerate(pred_boxes): - image_id = int(batch_img_id) - if boxes is not None: - x, y, w, h, c, p = boxes - if image_id!=-1: - - x, y, w, h, p = float(x), float(y), float(w), float(h), float(p) - c = int(c) - json_result.append( - { - "image_id": image_id, - "category_id": c, - "bbox": [x, y, w, h], - "score": p, - } - ) - -def create_engine_context(engine_path, logger): - with open(engine_path, "rb") as f: - runtime = tensorrt.Runtime(logger) - assert runtime - engine = runtime.deserialize_cuda_engine(f.read()) - assert engine - context = engine.create_execution_context() - assert context - - return engine, context - -def get_io_bindings(engine): - # Setup I/O bindings - inputs = [] - outputs = [] - allocations = [] - - for i in range(engine.num_bindings): - is_input = False - if engine.binding_is_input(i): - is_input = True - name = engine.get_binding_name(i) - dtype = engine.get_binding_dtype(i) - shape = engine.get_binding_shape(i) - if is_input: - batch_size = shape[0] - size = np.dtype(tensorrt.nptype(dtype)).itemsize - for s in shape: - size *= s - allocation = cuda.mem_alloc(size) - binding = { - "index": i, - "name": name, - "dtype": np.dtype(tensorrt.nptype(dtype)), - "shape": list(shape), - "allocation": allocation, - } - # print(f"binding {i}, name : {name} dtype : {np.dtype(tensorrt.nptype(dtype))} shape : {list(shape)}") - allocations.append(allocation) - if engine.binding_is_input(i): - inputs.append(binding) - else: - outputs.append(binding) - return inputs, outputs, allocations \ No newline at end of file diff --git a/models/cv/object_detection/fcos/ixrt/fcos_center-normbbox-centeronreg-giou_r50_caffe_fpn_gn-head_1x_coco.py b/models/cv/object_detection/fcos/ixrt/fcos_center-normbbox-centeronreg-giou_r50_caffe_fpn_gn-head_1x_coco.py deleted file mode 100644 index 72d17de86f01b3f4b1b39e8ea6fb0dfa32abfe0a..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/fcos/ixrt/fcos_center-normbbox-centeronreg-giou_r50_caffe_fpn_gn-head_1x_coco.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -_base_ = 'fcos_r50_caffe_fpn_gn-head_1x_coco.py' - -model = dict( - backbone=dict( - init_cfg=dict( - type='Pretrained', - checkpoint='open-mmlab://detectron2/resnet50_caffe')), - bbox_head=dict( - norm_on_bbox=True, - centerness_on_reg=True, - dcn_on_last_conv=False, - center_sampling=True, - conv_bias=True, - loss_bbox=dict(type='GIoULoss', loss_weight=1.0)), - # training and testing settings - test_cfg=dict(nms=dict(type='nms', iou_threshold=0.6))) - -# dataset settings -img_norm_cfg = dict( - mean=[103.530, 116.280, 123.675], std=[1.0, 1.0, 1.0], to_rgb=False) -train_pipeline = [ - dict(type='LoadImageFromFile'), - dict(type='LoadAnnotations', with_bbox=True), - dict(type='Resize', img_scale=(1333, 800), keep_ratio=True), - dict(type='RandomFlip', flip_ratio=0.5), - dict(type='Normalize', **img_norm_cfg), - dict(type='Pad', size_divisor=32), - dict(type='DefaultFormatBundle'), - dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']), -] -test_pipeline = [ - dict(type='LoadImageFromFile'), - dict( - type='MultiScaleFlipAug', - img_scale=(1333, 800), - flip=False, - transforms=[ - dict(type='Resize', keep_ratio=True), - dict(type='RandomFlip'), - dict(type='Normalize', **img_norm_cfg), - dict(type='Pad', size_divisor=32), - dict(type='ImageToTensor', keys=['img']), - dict(type='Collect', keys=['img']), - ]) -] -data = dict( - samples_per_gpu=2, - workers_per_gpu=2, - train=dict(pipeline=train_pipeline), - val=dict(pipeline=test_pipeline), - test=dict(pipeline=test_pipeline)) -optimizer_config = dict(_delete_=True, grad_clip=None) - -lr_config = dict(warmup='linear') \ No newline at end of file diff --git a/models/cv/object_detection/fcos/ixrt/fcos_ixrt_inference.py b/models/cv/object_detection/fcos/ixrt/fcos_ixrt_inference.py deleted file mode 100644 index 9218ea3a2d5ac16be9e1bc11ba7ee4e4e7c0c3f2..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/fcos/ixrt/fcos_ixrt_inference.py +++ /dev/null @@ -1,202 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import sys -from tqdm import tqdm -import numpy as np - -import argparse - -import torch -import mmcv -from mmdet.datasets import build_dataloader, build_dataset -from mmdet.models import build_detector -from mmdet.core import bbox2result -import cv2 -import numpy as np -import onnxruntime as rt - -import time - -import os -import copy -from common import create_engine_context, get_io_bindings -import pycuda.autoinit -import pycuda.driver as cuda -import tensorrt -from tensorrt import Dims - -def check_target(inference, target): - satisfied = False - if inference > target: - satisfied = True - return satisfied - -def get_dataloder(args): - cfg_path = args.cfg_file - cfg = mmcv.Config.fromfile(cfg_path) - datasets_path = args.data_path - cfg['data']['val']['img_prefix'] = os.path.join(datasets_path, 'val2017') - cfg['data']['val']['ann_file'] = os.path.join(datasets_path, 'annotations/instances_val2017.json') - dataset = build_dataset(cfg.data.val) - data_loader = build_dataloader(dataset, samples_per_gpu=args.batch_size, workers_per_gpu=args.num_workers, shuffle=False) - model = build_detector(cfg.model, test_cfg=cfg.get('test_cfg')) - return dataset, data_loader, model - -def eval_coco(args, inputs, outputs, allocations, context): - dataset, dataloader, model = get_dataloder(args) - - # Prepare the output data - outputs_651 = np.zeros(outputs[0]["shape"], outputs[0]["dtype"]) - outputs_766 = np.zeros(outputs[1]["shape"], outputs[1]["dtype"]) - outputs_881 = np.zeros(outputs[2]["shape"], outputs[2]["dtype"]) - outputs_996 = np.zeros(outputs[3]["shape"], outputs[3]["dtype"]) - outputs_1111 = np.zeros(outputs[4]["shape"], outputs[4]["dtype"]) - outputs_713 = np.zeros(outputs[5]["shape"], outputs[5]["dtype"]) - outputs_828 = np.zeros(outputs[6]["shape"], outputs[6]["dtype"]) - outputs_943 = np.zeros(outputs[7]["shape"], outputs[7]["dtype"]) - outputs_1058 = np.zeros(outputs[8]["shape"], outputs[8]["dtype"]) - outputs_1173 = np.zeros(outputs[9]["shape"], outputs[9]["dtype"]) - outputs_705 = np.zeros(outputs[10]["shape"], outputs[10]["dtype"]) - outputs_820 = np.zeros(outputs[11]["shape"], outputs[11]["dtype"]) - outputs_935 = np.zeros(outputs[12]["shape"], outputs[12]["dtype"]) - outputs_1050 = np.zeros(outputs[13]["shape"], outputs[13]["dtype"]) - outputs_1165 = np.zeros(outputs[14]["shape"], outputs[14]["dtype"]) - - preds = [] - for batch in tqdm(dataloader): - image = batch['img'][0].data.numpy() - image = image.astype(inputs[0]["dtype"]) - # Set input - image = np.ascontiguousarray(image) - cuda.memcpy_htod(inputs[0]["allocation"], image) - context.execute_v2(allocations) - # # Fetch output - cuda.memcpy_dtoh(outputs_651, outputs[0]["allocation"]) - cuda.memcpy_dtoh(outputs_766, outputs[1]["allocation"]) - cuda.memcpy_dtoh(outputs_881, outputs[2]["allocation"]) - cuda.memcpy_dtoh(outputs_996, outputs[3]["allocation"]) - cuda.memcpy_dtoh(outputs_1111, outputs[4]["allocation"]) - cuda.memcpy_dtoh(outputs_713, outputs[5]["allocation"]) - cuda.memcpy_dtoh(outputs_828, outputs[6]["allocation"]) - cuda.memcpy_dtoh(outputs_943, outputs[7]["allocation"]) - cuda.memcpy_dtoh(outputs_1058, outputs[8]["allocation"]) - cuda.memcpy_dtoh(outputs_1173, outputs[9]["allocation"]) - cuda.memcpy_dtoh(outputs_705, outputs[10]["allocation"]) - cuda.memcpy_dtoh(outputs_820, outputs[11]["allocation"]) - cuda.memcpy_dtoh(outputs_935, outputs[12]["allocation"]) - cuda.memcpy_dtoh(outputs_1050, outputs[13]["allocation"]) - cuda.memcpy_dtoh(outputs_1165, outputs[14]["allocation"]) - - cls_score = [] - box_reg = [] - score_factors = [] - cls_score.append(torch.from_numpy(outputs_651)) - cls_score.append(torch.from_numpy(outputs_766)) - cls_score.append(torch.from_numpy(outputs_881)) - cls_score.append(torch.from_numpy(outputs_996)) - cls_score.append(torch.from_numpy(outputs_1111)) - - box_reg.append(torch.from_numpy(outputs_713)) - box_reg.append(torch.from_numpy(outputs_828)) - box_reg.append(torch.from_numpy(outputs_943)) - box_reg.append(torch.from_numpy(outputs_1058)) - box_reg.append(torch.from_numpy(outputs_1173)) - - score_factors.append(torch.from_numpy(outputs_705)) - score_factors.append(torch.from_numpy(outputs_820)) - score_factors.append(torch.from_numpy(outputs_935)) - score_factors.append(torch.from_numpy(outputs_1050)) - score_factors.append(torch.from_numpy(outputs_1165)) - - cls_score.sort(key=lambda x: x.shape[3],reverse=True) - box_reg.sort(key=lambda x: x.shape[3],reverse=True) - score_factors.sort(key=lambda x: x.shape[3],reverse=True) - - pred = model.bbox_head.get_bboxes(cls_score, box_reg, score_factors=score_factors, img_metas=batch['img_metas'][0].data[0], rescale=True) - bbox_results = [ - bbox2result(det_bboxes, det_labels, model.bbox_head.num_classes) - for det_bboxes, det_labels in pred - ] - preds.extend(bbox_results) - eval_results = dataset.evaluate(preds, metric=['bbox']) - print(eval_results) - - map50 = eval_results['bbox_mAP_50'] - return map50 - -def parse_args(): - parser = argparse.ArgumentParser() - # engine args - parser.add_argument("--engine", type=str, default="./r50_fcos.engine") - parser.add_argument("--cfg_file", type=str, default="fcos_r50_caffe_fpn_gn-head_1x_coco.py") - parser.add_argument("--data_path", type=str, default="/home/datasets/cv/coco") - parser.add_argument("--batch_size", type=int, default=16) - parser.add_argument("--num_workers", type=int, default=4) - parser.add_argument("--image_file", type=str, default="/home/fangjian.hu/workspace/ixrt/data/fcos_test/test_800.jpg") - parser.add_argument("--warp_up", type=int, default=40) - parser.add_argument("--loop_count", type=int, default=50) - - parser.add_argument("--target_map", default=0.56, type=float, help="target map0.5") - parser.add_argument("--target_fps", default=50, type=float, help="target fps") - parser.add_argument("--task", default="precision", type=str, help="precision or pref") - - - args = parser.parse_args() - return args - -def main(): - args= parse_args() - host_mem = tensorrt.IHostMemory - logger = tensorrt.Logger(tensorrt.Logger.ERROR) - - # Load Engine - engine, context = create_engine_context(args.engine, logger) - inputs, outputs, allocations = get_io_bindings(engine) - - if args.task=="precision": - start_time = time.time() - map50= eval_coco(args,inputs, outputs, allocations, context) - end_time = time.time() - e2e_time = end_time - start_time - print(F"E2E time : {e2e_time:.3f} seconds") - - print("="*40) - print("MAP50:{0}".format(round(map50,3))) - print("="*40) - print(f"Check MAP50 Test : {round(map50,3)} Target:{args.target_map} State : {'Pass' if round(map50,3) >= args.target_map else 'Fail'}") - status_map = check_target(map50, args.target_map) - sys.exit(int(not (status_map))) - - else: - torch.cuda.synchronize() - start_time = time.time() - for i in range(args.loop_count): - context.execute_v2(allocations) - torch.cuda.synchronize() - end_time = time.time() - forward_time = end_time - start_time - fps = args.loop_count * args.batch_size / forward_time - print("="*40) - print("fps:{0}".format(round(fps,2))) - print("="*40) - print(f"Check fps Test : {round(fps,3)} Target:{args.target_fps} State : {'Pass' if fps >= args.target_fps else 'Fail'}") - status_fps = check_target(fps, args.target_fps) - sys.exit(int(not (status_fps))) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/models/cv/object_detection/fcos/ixrt/fcos_r50_caffe_fpn_gn-head_1x_coco.py b/models/cv/object_detection/fcos/ixrt/fcos_r50_caffe_fpn_gn-head_1x_coco.py deleted file mode 100644 index 758d1d88571ac49ae26bc124f0052716bbf761d4..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/fcos/ixrt/fcos_r50_caffe_fpn_gn-head_1x_coco.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# model settings -model = dict( - type='FCOS', - backbone=dict( - type='ResNet', - depth=50, - num_stages=4, - out_indices=(0, 1, 2, 3), - frozen_stages=1, - norm_cfg=dict(type='BN', requires_grad=False), - norm_eval=True, - style='caffe', - init_cfg=dict( - type='Pretrained', - checkpoint='open-mmlab://detectron/resnet50_caffe')), - neck=dict( - type='FPN', - in_channels=[256, 512, 1024, 2048], - out_channels=256, - start_level=1, - add_extra_convs='on_output', # use P5 - num_outs=5, - relu_before_extra_convs=True), - bbox_head=dict( - type='FCOSHead', - num_classes=80, - in_channels=256, - stacked_convs=4, - feat_channels=256, - strides=[8, 16, 32, 64, 128], - loss_cls=dict( - type='FocalLoss', - use_sigmoid=True, - gamma=2.0, - alpha=0.25, - loss_weight=1.0), - loss_bbox=dict(type='IoULoss', loss_weight=1.0), - loss_centerness=dict( - type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)), - # training and testing settings - train_cfg=dict( - assigner=dict( - type='MaxIoUAssigner', - pos_iou_thr=0.5, - neg_iou_thr=0.4, - min_pos_iou=0, - ignore_iof_thr=-1), - allowed_border=-1, - pos_weight=-1, - debug=False), - test_cfg=dict( - nms_pre=1000, - min_bbox_size=0, - score_thr=0.05, - nms=dict(type='nms', iou_threshold=0.5), - max_per_img=100)) - -# dataset settings -dataset_type = 'CocoDataset' -data_root = 'data/coco/' -img_norm_cfg = dict( - mean=[102.9801, 115.9465, 122.7717], std=[1.0, 1.0, 1.0], to_rgb=False) - -test_pipeline = [ - dict(type='LoadImageFromFile'), - dict( - type='MultiScaleFlipAug', - img_scale=(800, 800), - flip=False, - transforms=[ - dict(type='Resize', keep_ratio=True), - dict(type='RandomFlip'), - dict(type='Normalize', **img_norm_cfg), - dict(type='Pad', size=(800, 800)), - dict(type='ImageToTensor', keys=['img']), - dict(type='Collect', keys=['img']), - ]) -] -data = dict( - samples_per_gpu=32, - workers_per_gpu=1, - val=dict( - type=dataset_type, - ann_file=data_root + 'annotations/instances_val2017.json', - img_prefix=data_root + 'images/val2017/', - pipeline=test_pipeline) - ) -evaluation = dict(interval=1, metric='bbox') \ No newline at end of file diff --git a/models/cv/object_detection/fcos/ixrt/requirements.txt b/models/cv/object_detection/fcos/ixrt/requirements.txt index a0763974b54feecde9c5a7654327122855e85eed..c6f9129a7799504d38ae80fd0468dc8ac3ba50a8 100644 --- a/models/cv/object_detection/fcos/ixrt/requirements.txt +++ b/models/cv/object_detection/fcos/ixrt/requirements.txt @@ -1,10 +1,9 @@ +yapf==0.40.2 +addict==2.4.0 +mmdet==3.3.0 tqdm onnx onnxsim -ultralytics pycocotools -addict -yapf -pycuda -mmdet==2.28.2 -opencv-python==4.6.0.66 \ No newline at end of file +opencv-python==4.6.0.66 +mmengine \ No newline at end of file diff --git a/models/cv/object_detection/fcos/ixrt/scripts/infer_fcos_fp16_accuracy.sh b/models/cv/object_detection/fcos/ixrt/scripts/infer_fcos_fp16_accuracy.sh index b6ccfe626f4a0f1ab6247aac4c4dc14f1998d3cb..aa081403bd07c008644e2db01e03332945fa4155 100755 --- a/models/cv/object_detection/fcos/ixrt/scripts/infer_fcos_fp16_accuracy.sh +++ b/models/cv/object_detection/fcos/ixrt/scripts/infer_fcos_fp16_accuracy.sh @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - #!/bin/bash EXIT_STATUS=0 @@ -24,7 +9,7 @@ check_status() } # Run paraments -BSZ=1 +BSZ=32 WARM_UP=-1 TGT=-1 LOOP_COUNT=-1 @@ -44,15 +29,15 @@ do esac done -MODEL_NAME="r50_fcos" +MODEL_NAME="fcos_opt" +ORIGINE_MODEL="${CHECKPOINTS_DIR}/fcos_opt.onnx" -echo PROJ_DIR ${PROJ_DIR} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} echo RUN_DIR : ${RUN_DIR} step=0 - +CURRENT_MODEL=${ORIGINE_MODEL} # Simplify Model let step++ echo; @@ -62,22 +47,40 @@ if [ -f ${SIM_MODEL} ];then echo " "Simplify Model Skipped, ${SIM_MODEL} has been existed else python3 ${RUN_DIR}/simplify_model.py \ - --origin_model ${CHECKPOINTS_DIR}/${MODEL_NAME}.onnx \ + --origin_model ${CURRENT_MODEL} \ --output_model ${SIM_MODEL} echo " "Generate ${SIM_MODEL} fi +CURRENT_MODEL=${SIM_MODEL} + +# Change Batchsize +let step++ +echo; +echo [STEP ${step}] : Change Batchsize +FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_bs${BSZ}.onnx +if [ -f $FINAL_MODEL ];then + echo " "Change Batchsize Skip, $FINAL_MODEL has been existed +else + python3 ${RUN_DIR}/modify_batchsize.py \ + --batch_size ${BSZ} \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} + 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}.engine +ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs{BSZ}.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --model ${SIM_MODEL} \ + --model ${CURRENT_MODEL} \ --engine ${ENGINE_FILE} echo " "Generate Engine ${ENGINE_FILE} fi @@ -86,11 +89,10 @@ fi let step++ echo; echo [STEP ${step}] : Inference -python3 ${RUN_DIR}/fcos_ixrt_inference.py \ +python3 ${RUN_DIR}/inference_mmdet.py \ --engine ${ENGINE_FILE} \ --cfg_file ${RUN_DIR}/fcos_r50_caffe_fpn_gn-head_1x_coco.py \ - --task "precision" \ - --data_path ${DATASETS_DIR} \ - --batch_size 1 \ - --target_map 0.54; check_status + --datasets ${DATASETS_DIR} \ + --batchsize ${BSZ} \ + --acc_target ${TGT}; check_status exit ${EXIT_STATUS} \ No newline at end of file diff --git a/models/cv/object_detection/fcos/ixrt/scripts/infer_fcos_fp16_performance.sh b/models/cv/object_detection/fcos/ixrt/scripts/infer_fcos_fp16_performance.sh index 2bcf4d56b3fde440ecfdefd56be02cb1b673e428..26a6bc83fd13e3d1e28a1569e299de9dc7f2b4ad 100755 --- a/models/cv/object_detection/fcos/ixrt/scripts/infer_fcos_fp16_performance.sh +++ b/models/cv/object_detection/fcos/ixrt/scripts/infer_fcos_fp16_performance.sh @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - #!/bin/bash EXIT_STATUS=0 @@ -24,7 +9,7 @@ check_status() } # Run paraments -BSZ=1 +BSZ=32 WARM_UP=-1 TGT=-1 LOOP_COUNT=-1 @@ -44,15 +29,15 @@ do esac done -MODEL_NAME="r50_fcos" +MODEL_NAME="fcos_opt" +ORIGINE_MODEL="${CHECKPOINTS_DIR}/fcos_opt.onnx" -echo PROJ_DIR ${PROJ_DIR} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} echo RUN_DIR : ${RUN_DIR} step=0 - +CURRENT_MODEL=${ORIGINE_MODEL} # Simplify Model let step++ echo; @@ -62,22 +47,40 @@ if [ -f ${SIM_MODEL} ];then echo " "Simplify Model Skipped, ${SIM_MODEL} has been existed else python3 ${RUN_DIR}/simplify_model.py \ - --origin_model ${CHECKPOINTS_DIR}/${MODEL_NAME}.onnx \ + --origin_model ${CURRENT_MODEL} \ --output_model ${SIM_MODEL} echo " "Generate ${SIM_MODEL} fi +CURRENT_MODEL=${SIM_MODEL} + +# Change Batchsize +let step++ +echo; +echo [STEP ${step}] : Change Batchsize +FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_bs${BSZ}.onnx +if [ -f $FINAL_MODEL ];then + echo " "Change Batchsize Skip, $FINAL_MODEL has been existed +else + python3 ${RUN_DIR}/modify_batchsize.py \ + --batch_size ${BSZ} \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} + 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}.engine +ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs{BSZ}.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --model ${SIM_MODEL} \ + --model ${CURRENT_MODEL} \ --engine ${ENGINE_FILE} echo " "Generate Engine ${ENGINE_FILE} fi @@ -86,10 +89,11 @@ fi let step++ echo; echo [STEP ${step}] : Inference -python3 ${RUN_DIR}/fcos_ixrt_inference.py \ +python3 ${RUN_DIR}/inference_mmdet.py \ --engine ${ENGINE_FILE} \ --cfg_file ${RUN_DIR}/fcos_r50_caffe_fpn_gn-head_1x_coco.py \ - --task "pref" \ - --batch_size 1 \ - --target_fps 40; check_status + --perf_only True \ + --datasets ${DATASETS_DIR} \ + --batchsize ${BSZ} \ + --fps_target ${TGT}; check_status exit ${EXIT_STATUS} \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/build_engine.py b/models/cv/object_detection/ixrt_common/build_engine.py similarity index 67% rename from models/cv/object_detection/yolov7/ixrt/build_engine.py rename to models/cv/object_detection/ixrt_common/build_engine.py index a919bdd0183197ce125aa5492ec83e58e035675d..d47e45e518cc0bd35d2fd27f19f7da17bec44abf 100644 --- a/models/cv/object_detection/yolov7/ixrt/build_engine.py +++ b/models/cv/object_detection/ixrt_common/build_engine.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import os import cv2 import argparse diff --git a/models/cv/object_detection/yolov5/ixrt/build_nms_engine.py b/models/cv/object_detection/ixrt_common/build_nms_engine.py similarity index 78% rename from models/cv/object_detection/yolov5/ixrt/build_nms_engine.py rename to models/cv/object_detection/ixrt_common/build_nms_engine.py index 3be0d83d0d966018f59b87d22f628b9b1ddf9b21..d260fe48fc85f6d2add2051a063a90048e9d831f 100644 --- a/models/cv/object_detection/yolov5/ixrt/build_nms_engine.py +++ b/models/cv/object_detection/ixrt_common/build_nms_engine.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import os import argparse import torch @@ -20,10 +5,12 @@ import onnx from onnx import helper from onnx import TensorProto, numpy_helper import tensorrt +from os.path import dirname, exists, join +import ctypes def create_onnx(args): nms = helper.make_node( - "NMS", + "DetectionNMS_IxRT", name="NMS", inputs=["nms_input"], outputs=["nms_output0", "nms_output1"], @@ -57,10 +44,24 @@ def create_onnx(args): model = onnx.helper.make_model(graph, opset_imports=[op]) onnx_path = args.path + "/nms.onnx" onnx.save(model, onnx_path) + +def load_ixrt_plugin( + logger=tensorrt.Logger(tensorrt.Logger.WARNING), namespace="", dynamic_path="" +): + if not dynamic_path: + dynamic_path = join(dirname(tensorrt.__file__), "lib", "libixrt_plugin.so") + if not exists(dynamic_path): + raise FileNotFoundError( + f"The ixrt_plugin lib {dynamic_path} is not existed, please provided effective plugin path!" + ) + ctypes.CDLL(dynamic_path, mode=ctypes.RTLD_GLOBAL) + tensorrt.init_libnvinfer_plugins(logger, namespace) + print(f"Loaded plugin from {dynamic_path}") def build_engine(args): onnx_path = args.path + "/nms.onnx" IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) + load_ixrt_plugin(IXRT_LOGGER) builder = tensorrt.Builder(IXRT_LOGGER) EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) network = builder.create_network(EXPLICIT_BATCH) diff --git a/models/cv/object_detection/yolov5/ixrt/calibration_dataset.py b/models/cv/object_detection/ixrt_common/calibration_dataset.py similarity index 55% rename from models/cv/object_detection/yolov5/ixrt/calibration_dataset.py rename to models/cv/object_detection/ixrt_common/calibration_dataset.py index de37775a0c617fdefca4342423a6a47bdc9b9c41..2473f7d0933035ef2731dd928f75cb8fea72d2f3 100644 --- a/models/cv/object_detection/yolov5/ixrt/calibration_dataset.py +++ b/models/cv/object_detection/ixrt_common/calibration_dataset.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import os import torch import torchvision.datasets diff --git a/models/cv/object_detection/yolov3/ixrt/coco_labels.py b/models/cv/object_detection/ixrt_common/coco_labels.py similarity index 71% rename from models/cv/object_detection/yolov3/ixrt/coco_labels.py rename to models/cv/object_detection/ixrt_common/coco_labels.py index 43f5bd82cd257efdcab2bdba6bad64d9bb90416e..69d38878ff16d66dfe7550fcd170ac91d0862318 100644 --- a/models/cv/object_detection/yolov3/ixrt/coco_labels.py +++ b/models/cv/object_detection/ixrt_common/coco_labels.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - labels = [ "person", "bicycle", diff --git a/models/cv/object_detection/yolov5s/ixrt/common.py b/models/cv/object_detection/ixrt_common/common.py similarity index 78% rename from models/cv/object_detection/yolov5s/ixrt/common.py rename to models/cv/object_detection/ixrt_common/common.py index 695e05ba9605a8b251d74567830ecbeb86387b4c..7d9a078eebf15a788c55cc5b657b352a33707a31 100644 --- a/models/cv/object_detection/yolov5s/ixrt/common.py +++ b/models/cv/object_detection/ixrt_common/common.py @@ -1,22 +1,8 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. import numpy as np from tqdm import tqdm import tensorrt -import pycuda.driver as cuda +from cuda import cuda, cudart # input : [bsz, box_num, 5(cx, cy, w, h, conf) + class_num(prob[0], prob[1], ...)] # output : [bsz, box_num, 6(left_top_x, left_top_y, right_bottom_x, right_bottom_y, class_id, max_prob*conf)] @@ -50,6 +36,23 @@ def save2json(batch_img_id, pred_boxes, json_result, class_trans): "score": p, } ) +def save2json_nonms(batch_img_id, pred_boxes, json_result): + for i, boxes in enumerate(pred_boxes): + image_id = int(batch_img_id) + if boxes is not None: + x, y, w, h, c, p = boxes + if image_id!=-1: + + x, y, w, h, p = float(x), float(y), float(w), float(h), float(p) + c = int(c) + json_result.append( + { + "image_id": image_id, + "category_id": c, + "bbox": [x, y, w, h], + "score": p, + } + ) def create_engine_context(engine_path, logger): with open(engine_path, "rb") as f: @@ -80,13 +83,15 @@ def get_io_bindings(engine): size = np.dtype(tensorrt.nptype(dtype)).itemsize for s in shape: size *= s - allocation = cuda.mem_alloc(size) + err, allocation = cudart.cudaMalloc(size) + assert err == cudart.cudaError_t.cudaSuccess binding = { "index": i, "name": name, "dtype": np.dtype(tensorrt.nptype(dtype)), "shape": list(shape), "allocation": allocation, + "nbytes": size, } print(f"binding {i}, name : {name} dtype : {np.dtype(tensorrt.nptype(dtype))} shape : {list(shape)}") allocations.append(allocation) diff --git a/models/cv/object_detection/yolov3/ixrt/config/YOLOV3_CONFIG b/models/cv/object_detection/ixrt_common/config/YOLOV3_CONFIG similarity index 73% rename from models/cv/object_detection/yolov3/ixrt/config/YOLOV3_CONFIG rename to models/cv/object_detection/ixrt_common/config/YOLOV3_CONFIG index 8cbd0f490342f6a7f5e06fa1087bc65cc98afb55..9b1fe49135bbec6e05aee94ea89a871e04371494 100644 --- a/models/cv/object_detection/yolov3/ixrt/config/YOLOV3_CONFIG +++ b/models/cv/object_detection/ixrt_common/config/YOLOV3_CONFIG @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - # BSZ : 构建engine以及推理时的batchsize # IMGSIZE : 模型输入hw大小 # RUN_MODE : [FPS, MAP] diff --git a/models/cv/object_detection/yolov5/ixrt/config/YOLOV5_CONFIG b/models/cv/object_detection/ixrt_common/config/YOLOV5M_CONFIG similarity index 73% rename from models/cv/object_detection/yolov5/ixrt/config/YOLOV5_CONFIG rename to models/cv/object_detection/ixrt_common/config/YOLOV5M_CONFIG index d6342be3715685c6c76bd63fbcc09ea8cf57209a..3eddc4f789033694b21330cce740bd229c1d9c6d 100644 --- a/models/cv/object_detection/yolov5/ixrt/config/YOLOV5_CONFIG +++ b/models/cv/object_detection/ixrt_common/config/YOLOV5M_CONFIG @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - # BSZ : 构建engine以及推理时的batchsize # IMGSIZE : 模型输入hw大小 # RUN_MODE : [FPS, MAP] diff --git a/models/cv/object_detection/yolov5s/ixrt/config/YOLOV5S_CONFIG b/models/cv/object_detection/ixrt_common/config/YOLOV5S_CONFIG old mode 100755 new mode 100644 similarity index 73% rename from models/cv/object_detection/yolov5s/ixrt/config/YOLOV5S_CONFIG rename to models/cv/object_detection/ixrt_common/config/YOLOV5S_CONFIG index 8aa23b8e276963cf63247b252962ddf521b66dfd..c3f46cf87029af585f8c40a6b5e435b4a41fc956 --- a/models/cv/object_detection/yolov5s/ixrt/config/YOLOV5S_CONFIG +++ b/models/cv/object_detection/ixrt_common/config/YOLOV5S_CONFIG @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - # BSZ : 构建engine以及推理时的batchsize # IMGSIZE : 模型输入hw大小 # RUN_MODE : [FPS, MAP] diff --git a/models/cv/object_detection/yolov7/ixrt/config/YOLOV7_CONFIG b/models/cv/object_detection/ixrt_common/config/YOLOV7_CONFIG similarity index 73% rename from models/cv/object_detection/yolov7/ixrt/config/YOLOV7_CONFIG rename to models/cv/object_detection/ixrt_common/config/YOLOV7_CONFIG index e6cb457d7bd09f941e5fba164265838af0ab5cb0..4803e368f3e4fa20cf05576e1cd5f12594f5d102 100644 --- a/models/cv/object_detection/yolov7/ixrt/config/YOLOV7_CONFIG +++ b/models/cv/object_detection/ixrt_common/config/YOLOV7_CONFIG @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - # BSZ : 构建engine以及推理时的batchsize # IMGSIZE : 模型输入hw大小 # RUN_MODE : [FPS, MAP] @@ -34,7 +19,6 @@ LAYER_FUSION=1 DECODER_FASTER=1 DECODER_NUM_CLASS=80 DECODER_INPUT_NAMES=(/model/model.105/m.0/Conv_output_0 /model/model.105/m.1/Conv_output_0 /model/model.105/m.2/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) diff --git a/models/cv/object_detection/yolov5s/ixrt/cut_model.py b/models/cv/object_detection/ixrt_common/cut_model.py similarity index 44% rename from models/cv/object_detection/yolov5s/ixrt/cut_model.py rename to models/cv/object_detection/ixrt_common/cut_model.py index e9ee19aadf0809fe1b97e3225d09150fb54513f7..af0a3a4f0cc3caf05b95be3c77dea7728c931e3f 100644 --- a/models/cv/object_detection/yolov5s/ixrt/cut_model.py +++ b/models/cv/object_detection/ixrt_common/cut_model.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import onnx import argparse from onnxsim import simplify diff --git a/models/cv/object_detection/ixrt_common/datasets/__init__.py b/models/cv/object_detection/ixrt_common/datasets/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/models/cv/object_detection/yolov5s/ixrt/datasets/coco.py b/models/cv/object_detection/ixrt_common/datasets/coco.py old mode 100755 new mode 100644 similarity index 86% rename from models/cv/object_detection/yolov5s/ixrt/datasets/coco.py rename to models/cv/object_detection/ixrt_common/datasets/coco.py index 73c5df54761b917ecd0127fb56b61d9bd34c1196..7f355b8444e2bc8d38d5c89cb3217328c497420e --- a/models/cv/object_detection/yolov5s/ixrt/datasets/coco.py +++ b/models/cv/object_detection/ixrt_common/datasets/coco.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import os.path from typing import Any, Callable, List, Optional, Tuple diff --git a/models/cv/object_detection/yolov5s/ixrt/datasets/common.py b/models/cv/object_detection/ixrt_common/datasets/common.py old mode 100755 new mode 100644 similarity index 78% rename from models/cv/object_detection/yolov5s/ixrt/datasets/common.py rename to models/cv/object_detection/ixrt_common/datasets/common.py index ef36eba394917bc05af46f33be48463df50f540d..a8e5e6e7fbd958b2f9dfa83da1b0f8c5bc727041 --- a/models/cv/object_detection/yolov5s/ixrt/datasets/common.py +++ b/models/cv/object_detection/ixrt_common/datasets/common.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import cv2 import math import numpy as np @@ -78,4 +63,6 @@ def scale_boxes(net_shape, boxes, ori_shape, use_letterbox=False): def clip_boxes(boxes, shape): boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1]) # x1, x2 - boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2 \ No newline at end of file + boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2 + + return boxes \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/datasets/post_process.py b/models/cv/object_detection/ixrt_common/datasets/post_process.py similarity index 68% rename from models/cv/object_detection/yolov5/ixrt/datasets/post_process.py rename to models/cv/object_detection/ixrt_common/datasets/post_process.py index 8590816a0df18b6ef296ebe305b15b81240ab1d0..7b411a50f075bd88ad0b17fb43a5455ef9e7c088 100644 --- a/models/cv/object_detection/yolov5/ixrt/datasets/post_process.py +++ b/models/cv/object_detection/ixrt_common/datasets/post_process.py @@ -1,21 +1,8 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import cv2 import math import numpy as np +import torch +import torch.nn.functional as F from .common import letterbox, scale_boxes, clip_boxes @@ -26,6 +13,8 @@ def get_post_process(data_process_type): return Yolov3Postprocess elif data_process_type == "yolox": return YoloxPostprocess + elif data_process_type == "detr": + return DetrPostprocess return None def Yolov3Postprocess( @@ -127,4 +116,42 @@ def YoloxPostprocess( all_box.append(boxes) data_offset += max_det * 6 - return all_box \ No newline at end of file + return all_box + +def box_cxcywh_to_xyxy(x): + x_c, y_c, w, h = x.unbind(-1) + b = [(x_c - 0.5 * w), (y_c - 0.5 * h), + (x_c + 0.5 * w), (y_c + 0.5 * h)] + return torch.stack(b, dim=-1) + + +def convert_to_xywh(boxes): + xmin, ymin, xmax, ymax = boxes.unbind(-1) + return torch.stack((xmin, ymin, xmax - xmin, ymax - ymin), dim=1) + +def DetrPostprocess(pred_logits, pred_boxes, target_sizes): + + out_logits = torch.from_numpy(pred_logits) + out_bbox = torch.from_numpy(pred_boxes) + assert len(target_sizes) == 2 + + prob = F.softmax(out_logits, -1) + scores, labels = prob[..., :-1].max(-1) + + # convert to [x0, y0, x1, y1] format + boxes = box_cxcywh_to_xyxy(out_bbox) + # and from relative [0, 1] to absolute [0, height] coordinates + img_w, img_h = target_sizes + scale_fct = torch.tensor([img_w, img_h, img_w, img_h]) + boxes = boxes * scale_fct + + boxes = clip_boxes(boxes, target_sizes) + boxes = convert_to_xywh(boxes) + + labels = labels.unsqueeze(1) + scores =scores.unsqueeze(1) + pred_boxes = torch.cat([ + boxes, + labels, + scores], dim=1).numpy().tolist() + return pred_boxes \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/datasets/pre_process.py b/models/cv/object_detection/ixrt_common/datasets/pre_process.py similarity index 73% rename from models/cv/object_detection/yolov3/ixrt/datasets/pre_process.py rename to models/cv/object_detection/ixrt_common/datasets/pre_process.py index c651f8adb7c8190c214fbbbb7769c7d0713e9619..e5b4ddfba9d1357cdada22b8c50b7d9b6d423998 100644 --- a/models/cv/object_detection/yolov3/ixrt/datasets/pre_process.py +++ b/models/cv/object_detection/ixrt_common/datasets/pre_process.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import cv2 import math import numpy as np @@ -26,6 +11,8 @@ def get_post_process(data_process_type): return Yolov3Preprocess elif data_process_type == "yolox": return YoloxPreprocess + elif data_process_type == "detr": + return DetrPreprocess return None def Yolov3Preprocess(image, img_size): @@ -68,4 +55,22 @@ def YoloxPreprocess(img, img_size, swap=(2,0,1)): padded_img = padded_img.transpose(swap) padded_img = np.ascontiguousarray(padded_img, dtype=np.float32) - return padded_img \ No newline at end of file + return padded_img + +def DetrPreprocess(image, img_size): + # img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) + # img = img.resize((img_size, img_size)) + + std = [0.485, 0.456, 0.406] + mean = [0.229, 0.224, 0.225] + + image = cv2.resize(image, (img_size, img_size)) + image = image.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB + image = np.ascontiguousarray(image).astype(np.float32) / 255.0 # 0~1 np array + + image[0,:,:] = (image[0,:,:]- std[0])/mean[0] + image[1,:,:] = (image[1,:,:]- std[1])/mean[1] + image[2,:,:] = (image[2,:,:]- std[2])/mean[2] + + return image + \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/datasets/vision.py b/models/cv/object_detection/ixrt_common/datasets/vision.py similarity index 89% rename from models/cv/object_detection/yolov5/ixrt/datasets/vision.py rename to models/cv/object_detection/ixrt_common/datasets/vision.py index eadefb2c5b35abd0a11fa85c65891461a210aef8..32da4a789767939efc1e83d89f2955145798a5f3 100644 --- a/models/cv/object_detection/yolov5/ixrt/datasets/vision.py +++ b/models/cv/object_detection/ixrt_common/datasets/vision.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import os from typing import Any, Callable, List, Optional, Tuple diff --git a/models/cv/object_detection/yolov5s/ixrt/deploy.py b/models/cv/object_detection/ixrt_common/deploy.py similarity index 82% rename from models/cv/object_detection/yolov5s/ixrt/deploy.py rename to models/cv/object_detection/ixrt_common/deploy.py index 37c5f9ac9d1893978f09f1717d99b5857274121e..a686f4ffe459ceec571cd390ba2588aca14ee868 100644 --- a/models/cv/object_detection/yolov5s/ixrt/deploy.py +++ b/models/cv/object_detection/ixrt_common/deploy.py @@ -1,20 +1,5 @@ # !/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import argparse from tensorrt.deploy.api import GraphTransform, create_source, create_target @@ -129,10 +114,10 @@ def parse_args(): parser.add_argument("--dst", type=str) parser.add_argument("--decoder_type", type=str, choices=["YoloV3Decoder", "YoloV5Decoder", "YoloV7Decoder", "YoloxDecoder"]) 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) - parser.add_argument("--decoder32_anchor", nargs='*', type=int) - parser.add_argument("--decoder64_anchor", nargs='*', type=int, default=None) + parser.add_argument("--decoder8_anchor", nargs='*', type=float) + parser.add_argument("--decoder16_anchor", nargs='*', type=float) + parser.add_argument("--decoder32_anchor", nargs='*', type=float) + parser.add_argument("--decoder64_anchor", nargs='*', type=float, default=None) parser.add_argument("--num_class", type=int, default=80) parser.add_argument("--faster", type=int, default=1) parser.add_argument("--focus_input", type=str, default=None) diff --git a/models/cv/object_detection/ixrt_common/fcos_r50_caffe_fpn_gn-head_1x_coco.py b/models/cv/object_detection/ixrt_common/fcos_r50_caffe_fpn_gn-head_1x_coco.py new file mode 100644 index 0000000000000000000000000000000000000000..07b17960b31e7b46fffec2989c89b83ad397060c --- /dev/null +++ b/models/cv/object_detection/ixrt_common/fcos_r50_caffe_fpn_gn-head_1x_coco.py @@ -0,0 +1,253 @@ +auto_scale_lr = dict(base_batch_size=16, enable=False) +backend_args = None +data_root = 'data/coco/' +dataset_type = 'CocoDataset' +default_hooks = dict( + checkpoint=dict(interval=1, type='CheckpointHook'), + logger=dict(interval=50, type='LoggerHook'), + param_scheduler=dict(type='ParamSchedulerHook'), + sampler_seed=dict(type='DistSamplerSeedHook'), + timer=dict(type='IterTimerHook'), + visualization=dict(type='DetVisualizationHook')) +default_scope = 'mmdet' +env_cfg = dict( + cudnn_benchmark=False, + dist_cfg=dict(backend='nccl'), + mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0)) +load_from = None +log_level = 'ERROR' +log_processor = dict(by_epoch=True, type='LogProcessor', window_size=50) +model = dict( + backbone=dict( + depth=50, + frozen_stages=1, + init_cfg=dict( + checkpoint='open-mmlab://detectron/resnet50_caffe', + type='Pretrained'), + norm_cfg=dict(requires_grad=False, type='BN'), + norm_eval=True, + num_stages=4, + out_indices=( + 0, + 1, + 2, + 3, + ), + style='caffe', + type='ResNet'), + bbox_head=dict( + feat_channels=256, + in_channels=256, + loss_bbox=dict(loss_weight=1.0, type='IoULoss'), + loss_centerness=dict( + loss_weight=1.0, type='CrossEntropyLoss', use_sigmoid=True), + loss_cls=dict( + alpha=0.25, + gamma=2.0, + loss_weight=1.0, + type='FocalLoss', + use_sigmoid=True), + num_classes=80, + stacked_convs=4, + strides=[ + 8, + 16, + 32, + 64, + 128, + ], + type='FCOSHead'), + data_preprocessor=dict( + bgr_to_rgb=False, + mean=[ + 102.9801, + 115.9465, + 122.7717, + ], + pad_size_divisor=32, + std=[ + 1.0, + 1.0, + 1.0, + ], + type='DetDataPreprocessor'), + neck=dict( + add_extra_convs='on_output', + in_channels=[ + 256, + 512, + 1024, + 2048, + ], + num_outs=5, + out_channels=256, + relu_before_extra_convs=True, + start_level=1, + type='FPN'), + test_cfg=dict( + max_per_img=100, + min_bbox_size=0, + nms=dict(iou_threshold=0.5, type='nms'), + nms_pre=1000, + score_thr=0.05), + type='FCOS') +optim_wrapper = dict( + clip_grad=dict(max_norm=35, norm_type=2), + optimizer=dict(lr=0.01, momentum=0.9, type='SGD', weight_decay=0.0001), + paramwise_cfg=dict(bias_decay_mult=0.0, bias_lr_mult=2.0), + type='OptimWrapper') +param_scheduler = [ + dict( + begin=0, + by_epoch=False, + end=500, + factor=0.3333333333333333, + type='ConstantLR'), + dict( + begin=0, + by_epoch=True, + end=12, + gamma=0.1, + milestones=[ + 8, + 11, + ], + type='MultiStepLR'), +] +resume = False +test_cfg = dict(type='TestLoop') +test_dataloader = dict( + batch_size=32, + dataset=dict( + ann_file='annotations/instances_val2017.json', + backend_args=None, + data_prefix=dict(img='val2017/'), + data_root='/home/xiaomei.wang/ixrt-modelzoo-new/data/datasets/coco2017', + pipeline=[ + dict(backend_args=None, type='LoadImageFromFile'), + dict(keep_ratio=True, scale=( + 800, + 800, + ), type='Resize'), + dict(type='LoadAnnotations', with_bbox=True), + dict( + meta_keys=( + 'img_id', + 'img_path', + 'ori_shape', + 'img_shape', + 'scale_factor', + ), + type='PackDetInputs'), + ], + test_mode=True, + type='CocoDataset'), + drop_last=False, + num_workers=2, + persistent_workers=True, + sampler=dict(shuffle=False, type='DefaultSampler')) +test_evaluator = dict( + ann_file= + '/home/xiaomei.wang/ixrt-modelzoo-new/data/datasets/coco2017/annotations/instances_val2017.json', + backend_args=None, + format_only=False, + metric='bbox', + type='CocoMetric') +test_pipeline = [ + dict(backend_args=None, type='LoadImageFromFile'), + dict(keep_ratio=False, scale=( + 800, + 800, + ), type='Resize'), + dict(type='LoadAnnotations', with_bbox=True), + dict( + meta_keys=( + 'img_id', + 'img_path', + 'ori_shape', + 'img_shape', + 'scale_factor', + ), + type='PackDetInputs'), +] +train_cfg = dict(max_epochs=12, type='EpochBasedTrainLoop', val_interval=1) +train_dataloader = dict( + batch_sampler=dict(type='AspectRatioBatchSampler'), + batch_size=2, + dataset=dict( + ann_file='annotations/instances_train2017.json', + backend_args=None, + data_prefix=dict(img='train2017/'), + data_root='data/coco/', + filter_cfg=dict(filter_empty_gt=True, min_size=32), + pipeline=[ + dict(backend_args=None, type='LoadImageFromFile'), + dict(type='LoadAnnotations', with_bbox=True), + dict(keep_ratio=True, scale=( + 1333, + 800, + ), type='Resize'), + dict(prob=0.5, type='RandomFlip'), + dict(type='PackDetInputs'), + ], + type='CocoDataset'), + num_workers=2, + persistent_workers=True, + sampler=dict(shuffle=True, type='DefaultSampler')) +train_pipeline = [ + dict(backend_args=None, type='LoadImageFromFile'), + dict(type='LoadAnnotations', with_bbox=True), + dict(keep_ratio=True, scale=( + 1333, + 800, + ), type='Resize'), + dict(prob=0.5, type='RandomFlip'), + dict(type='PackDetInputs'), +] +val_cfg = dict(type='ValLoop') +val_dataloader = dict( + batch_size=1, + dataset=dict( + ann_file='annotations/instances_val2017.json', + backend_args=None, + data_prefix=dict(img='val2017/'), + data_root='data/coco/', + pipeline=[ + dict(backend_args=None, type='LoadImageFromFile'), + dict(keep_ratio=False, scale=( + 800, + 800, + ), type='Resize'), + dict(type='LoadAnnotations', with_bbox=True), + dict( + meta_keys=( + 'img_id', + 'img_path', + 'ori_shape', + 'img_shape', + 'scale_factor', + ), + type='PackDetInputs'), + ], + test_mode=True, + type='CocoDataset'), + drop_last=False, + num_workers=2, + persistent_workers=True, + sampler=dict(shuffle=False, type='DefaultSampler')) +val_evaluator = dict( + ann_file='data/coco/annotations/instances_val2017.json', + backend_args=None, + format_only=False, + metric='bbox', + type='CocoMetric') +vis_backends = [ + dict(type='LocalVisBackend'), +] +visualizer = dict( + name='visualizer', + type='DetLocalVisualizer', + vis_backends=[ + dict(type='LocalVisBackend'), + ]) +work_dir = './' \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/inference.py b/models/cv/object_detection/ixrt_common/inference.py similarity index 74% rename from models/cv/object_detection/yolov5s/ixrt/inference.py rename to models/cv/object_detection/ixrt_common/inference.py index ad87fe1ec0c2b9e5fa4271c31018a174fef370d5..99f22322e31e28d5f21219c754edce9e843e8db6 100644 --- a/models/cv/object_detection/yolov5s/ixrt/inference.py +++ b/models/cv/object_detection/ixrt_common/inference.py @@ -1,21 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import argparse import glob import json @@ -25,11 +10,10 @@ import sys import torch import numpy as np -import pycuda.autoinit -import pycuda.driver as cuda +from cuda import cuda, cudart from coco_labels import coco80_to_coco91_class, labels -from common import save2json, box_class85to6 +from common import save2json, save2json_nonms, box_class85to6 from common import create_engine_context, get_io_bindings from calibration_dataset import create_dataloaders from datasets.post_process import get_post_process @@ -82,7 +66,7 @@ def main(config): inputs, outputs, allocations = get_io_bindings(engine) # Load nms_engine - if config.test_mode == "MAP" and config.nms_type == "GPU": + if config.test_mode == "MAP" and config.nms_type == "GPU" and not config.no_nms: nms_engine, nms_context = create_engine_context(config.nms_engine, logger) nms_inputs, nms_outputs, nms_allocations = get_io_bindings(nms_engine) nms_output0 = np.zeros(nms_outputs[0]["shape"], nms_outputs[0]["dtype"]) @@ -98,8 +82,14 @@ def main(config): print("Warm Done.") # Prepare the output data - output = np.zeros(outputs[0]["shape"], outputs[0]["dtype"]) - print(f"output shape : {output.shape} output type : {output.dtype}") + if config.no_nms: + batch_pred_logits = np.zeros(outputs[0]["shape"], outputs[0]["dtype"]) + batch_pred_boxes = np.zeros(outputs[1]["shape"], outputs[1]["dtype"]) + print(f"pred_logits shape : {batch_pred_logits.shape} pred_logits type : {batch_pred_logits.dtype}") + print(f"pred_boxes shape : {batch_pred_boxes.shape} pred_boxes type : {batch_pred_boxes.dtype}") + else: + output = np.zeros(outputs[0]["shape"], outputs[0]["dtype"]) + print(f"output shape : {output.shape} output type : {output.dtype}") for batch_data, batch_img_shape, batch_img_id in tqdm(dataloader): batch_data = batch_data.numpy() @@ -109,7 +99,8 @@ def main(config): cur_bsz_sample = batch_data.shape[0] # Set input - cuda.memcpy_htod(inputs[0]["allocation"], batch_data) + err, = cuda.cuMemcpyHtoD(inputs[0]["allocation"], batch_data, batch_data.nbytes) + assert(err == cuda.CUresult.CUDA_SUCCESS) # Forward start_time = time.time() @@ -117,9 +108,10 @@ def main(config): end_time = time.time() forward_time += end_time - start_time - if config.test_mode == "MAP": + if config.test_mode == "MAP" and not config.no_nms: # Fetch output - cuda.memcpy_dtoh(output, outputs[0]["allocation"]) + err, = cuda.cuMemcpyDtoH(output, outputs[0]["allocation"], outputs[0]["nbytes"]) + assert(err == cuda.CUresult.CUDA_SUCCESS) # Step 1 : prepare data to nms _, box_num, box_unit = output.shape @@ -138,10 +130,14 @@ def main(config): if config.nms_type == "GPU": # Set nms input - cuda.memcpy_htod(nms_inputs[0]["allocation"], nms_input) + + err, = cuda.cuMemcpyHtoD(nms_inputs[0]["allocation"], nms_input, nms_input.nbytes) + assert(err == cuda.CUresult.CUDA_SUCCESS) nms_context.execute_v2(nms_allocations) - cuda.memcpy_dtoh(nms_output0, nms_outputs[0]["allocation"]) - cuda.memcpy_dtoh(nms_output1, nms_outputs[1]["allocation"]) + err, = cuda.cuMemcpyDtoH(nms_output0, nms_outputs[0]["allocation"], nms_outputs[0]["nbytes"]) + assert(err == cuda.CUresult.CUDA_SUCCESS) + err, = cuda.cuMemcpyDtoH(nms_output1, nms_outputs[1]["allocation"], nms_outputs[1]["nbytes"]) + assert(err == cuda.CUresult.CUDA_SUCCESS) # Step 3 : post process + save pred_boxes = post_process_func( @@ -153,6 +149,27 @@ def main(config): max_det=config.max_det ) save2json(batch_img_id, pred_boxes, json_result, class_map) + elif config.test_mode == "MAP" and config.no_nms: + # Fetch output + err, = cuda.cuMemcpyDtoH(batch_pred_logits, outputs[0]["allocation"], outputs[0]["nbytes"]) + assert(err == cuda.CUresult.CUDA_SUCCESS) + err, = cuda.cuMemcpyDtoH(batch_pred_boxes, outputs[1]["allocation"], outputs[1]["nbytes"]) + assert(err == cuda.CUresult.CUDA_SUCCESS) + + for (pred_logits, pred_boxes, img_h, img_w, img_id) in zip( + batch_pred_logits, + batch_pred_boxes, + batch_img_shape[0], + batch_img_shape[1], + batch_img_id): + pred_boxes = post_process_func(pred_logits, pred_boxes, [img_w, img_h]) + # print(img_id) + # print(img_w, img_h) + + # import ipdb + # ipdb.set_trace() + + save2json_nonms(img_id, pred_boxes, json_result) fps = num_samples / forward_time @@ -180,7 +197,6 @@ def main(config): with open(pred_json, "w") as f: json.dump(json_result, f) - start_time = time.time() anno_json = config.coco_gt anno = COCO(anno_json) # init annotations api pred = anno.loadRes(pred_json) # init predictions api @@ -192,12 +208,10 @@ def main(config): f"==============================eval {config.model_name} {config.precision} coco map ==============================" ) eval.summarize() - e2e_time = time.time() - start_time + map, map50 = eval.stats[:2] - print(F"E2E time : {e2e_time:.3f} seconds") print("MAP@0.5 : ", map50) print(f"Accuracy Check : Test {map50} >= target {config.map_target}") - print(F"E2E time : {e2e_time:.3f} seconds") if map50 >= config.map_target: print("pass!") exit() @@ -257,6 +271,7 @@ def parse_config(): parser.add_argument("--fps_target", type=float, default=-1.0, help="target fps") parser.add_argument("--decoder_faster", type=int, default=0, help="decoder faster can use gpu nms directly") parser.add_argument("--nms_type", type=str, default="GPU", help="GPU/CPU") + parser.add_argument("--no_nms", type=bool, default=False, help="NMS") config = parser.parse_args() print("config:", config) diff --git a/models/cv/object_detection/ixrt_common/inference_mmdet.py b/models/cv/object_detection/ixrt_common/inference_mmdet.py new file mode 100644 index 0000000000000000000000000000000000000000..18fd47550db7a5d816b2b9dacc9b912c12de03a9 --- /dev/null +++ b/models/cv/object_detection/ixrt_common/inference_mmdet.py @@ -0,0 +1,192 @@ +# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os +import time +import argparse +import tensorrt +import torch +import torchvision +import numpy as np +from tensorrt import Dims +from cuda import cuda, cudart +from tqdm import tqdm +from mmdet.registry import RUNNERS +from mmengine.config import Config + +from common import create_engine_context, get_io_bindings + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="ixrt engine path.") + + # parser.add_argument("--model_name", type=str, default="") + + parser.add_argument("--cfg_file", type=str, default="") + + parser.add_argument("--batchsize", + type=int, + required=True, + help="inference batch size.") + + parser.add_argument("--datasets", + type=str, + required=True, + help="datasets path.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--acc_target", + type=float, + default=None, + help="Model inference Accuracy target.") + + parser.add_argument("--fps_target", + type=float, + default=None, + help="Model inference FPS target.") + + parser.add_argument("--perf_only", + type=bool, + default=False, + help="Run performance test only") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + batch_size = args.batchsize + + host_mem = tensorrt.IHostMemory + logger = tensorrt.Logger(tensorrt.Logger.ERROR) + + # Load Engine && I/O bindings + engine, context = create_engine_context(args.engine, logger) + inputs, outputs, allocations = get_io_bindings(engine) + + if args.warmup > 0: + print("\nWarm Start.") + for i in range(args.warmup): + context.execute_v2(allocations) + print("Warm Done.") + + # just run perf test + if args.perf_only: + torch.cuda.synchronize() + start_time = time.time() + + for i in range(10): + context.execute_v2(allocations) + + torch.cuda.synchronize() + end_time = time.time() + forward_time = end_time - start_time + num_samples = 10 * args.batchsize + fps = num_samples / forward_time + + print("FPS : ", fps) + print(f"Performance Check : Test {fps} >= target {args.fps_target}") + if fps >= args.fps_target: + print("pass!") + exit() + else: + print("failed!") + exit(1) + else: + # Runner config + cfg = Config.fromfile(args.cfg_file) + cfg.work_dir = "./" + + cfg['test_dataloader']['batch_size'] = batch_size + cfg['test_dataloader']['dataset']['data_root'] = args.datasets + cfg['test_dataloader']['dataset']['data_prefix']['img'] = 'val2017/' + cfg['test_evaluator']['ann_file'] = os.path.join(args.datasets, 'annotations/instances_val2017.json') + cfg['log_level'] = 'ERROR' + + runner = RUNNERS.build(cfg) + + for input_data in tqdm(runner.test_dataloader): + + input_data = runner.model.data_preprocessor(input_data, False) + image = input_data['inputs'].cpu() + image = image.numpy().astype(inputs[0]["dtype"]) + pad_batch = len(image) != batch_size + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + image = np.ascontiguousarray(image) + + (err,) = cudart.cudaMemcpy( + inputs[0]["allocation"], + image, + image.nbytes, + cudart.cudaMemcpyKind.cudaMemcpyHostToDevice, + ) + assert err == cudart.cudaError_t.cudaSuccess + + context.execute_v2(allocations) + + cls_score = [] + box_reg = [] + score_factors = [] + for i in range(len(outputs)): + output = np.zeros(outputs[i]["shape"], outputs[i]["dtype"]) + (err,) = cudart.cudaMemcpy( + output, + outputs[i]["allocation"], + outputs[i]["nbytes"], + cudart.cudaMemcpyKind.cudaMemcpyDeviceToHost, + ) + assert err == cudart.cudaError_t.cudaSuccess + + if pad_batch: + output = output[:origin_size] + + output = torch.from_numpy(output) + + if output.shape[1] == 80: + cls_score.append(output) + elif output.shape[1] == 4: + box_reg.append(output) + else: + score_factors.append(output) + + batch_img_metas = [ + data_samples.metainfo for data_samples in input_data['data_samples'] + ] + + if "fovea_r50" or "fsaf" in args.cfg_file: + results_list = runner.model.bbox_head.predict_by_feat(cls_score, box_reg, batch_img_metas=batch_img_metas, rescale=True) + else: + results_list = runner.model.bbox_head.predict_by_feat(cls_score, box_reg, score_factors, batch_img_metas=batch_img_metas, rescale=True) + + batch_data_samples = runner.model.add_pred_to_datasample(input_data['data_samples'], results_list) + + runner.test_evaluator.process(data_samples=batch_data_samples, data_batch=input_data) + + metrics = runner.test_evaluator.evaluate(len(runner.test_dataloader.dataset)) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/load_ixrt_plugin.py b/models/cv/object_detection/ixrt_common/load_ixrt_plugin.py similarity index 46% rename from models/cv/object_detection/yolov3/ixrt/load_ixrt_plugin.py rename to models/cv/object_detection/ixrt_common/load_ixrt_plugin.py index ae47dc8e854b6bea1f768e65c4dd481048bfebce..932efbdfd1a4e91d8ddfd363adf6bce989df1709 100644 --- a/models/cv/object_detection/yolov3/ixrt/load_ixrt_plugin.py +++ b/models/cv/object_detection/ixrt_common/load_ixrt_plugin.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import ctypes import tensorrt from os.path import join, dirname, exists diff --git a/models/cv/object_detection/yolov5/ixrt/modify_batchsize.py b/models/cv/object_detection/ixrt_common/modify_batchsize.py similarity index 66% rename from models/cv/object_detection/yolov5/ixrt/modify_batchsize.py rename to models/cv/object_detection/ixrt_common/modify_batchsize.py index 3a88c1603bd6f457fd4965257627dc29edcda4d1..00ed65dd16bf19445396df7f72d81d653eed756d 100644 --- a/models/cv/object_detection/yolov5/ixrt/modify_batchsize.py +++ b/models/cv/object_detection/ixrt_common/modify_batchsize.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import onnx import argparse diff --git a/models/cv/object_detection/yolov3/ixrt/quant.py b/models/cv/object_detection/ixrt_common/quant.py similarity index 74% rename from models/cv/object_detection/yolov3/ixrt/quant.py rename to models/cv/object_detection/ixrt_common/quant.py index 36fd39a13c2e1e40f4dc0098f042e66e4bd0d26a..bcf5d9b6f73ee58fee41e27252425e7b9dc4e6fb 100644 --- a/models/cv/object_detection/yolov3/ixrt/quant.py +++ b/models/cv/object_detection/ixrt_common/quant.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import os import random import argparse diff --git a/models/cv/object_detection/yolov3/ixrt/requirements.txt b/models/cv/object_detection/ixrt_common/requirements.txt similarity index 82% rename from models/cv/object_detection/yolov3/ixrt/requirements.txt rename to models/cv/object_detection/ixrt_common/requirements.txt index b0f4374b2b778c81875da50d088fecedd01689c9..46ef4ec8d824eadb4dbce5a88a997abbd38a6747 100644 --- a/models/cv/object_detection/yolov3/ixrt/requirements.txt +++ b/models/cv/object_detection/ixrt_common/requirements.txt @@ -4,4 +4,5 @@ onnxsim ultralytics pycocotools opencv-python==4.6.0.66 -pycuda \ No newline at end of file +pycuda +seaborn \ No newline at end of file diff --git a/models/cv/object_detection/fcos/ixrt/simplify_model.py b/models/cv/object_detection/ixrt_common/simplify_model.py similarity index 46% rename from models/cv/object_detection/fcos/ixrt/simplify_model.py rename to models/cv/object_detection/ixrt_common/simplify_model.py index 1400fd81ddb4b3fae1b20d0fd35082a692f5d292..b4254b6f903cb5f8775e43b2f80d5572bf45b1d6 100644 --- a/models/cv/object_detection/fcos/ixrt/simplify_model.py +++ b/models/cv/object_detection/ixrt_common/simplify_model.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import onnx import argparse from onnxsim import simplify diff --git a/models/cv/object_detection/yolov3/ixrt/README.md b/models/cv/object_detection/yolov3/ixrt/README.md index c4fd306f99e24253e0123b4e192803082ebdde20..dc7dad6fcd6db1b3da0d60ea92c3eff7b1543b57 100644 --- a/models/cv/object_detection/yolov3/ixrt/README.md +++ b/models/cv/object_detection/yolov3/ixrt/README.md @@ -30,7 +30,7 @@ yum install -y mesa-libGL ## Ubuntu apt install -y libgl1-mesa-glx -pip3 install -r requirements.txt +pip3 install -r ../../ixrt_common/requirements.txt ``` ### Model Conversion @@ -50,13 +50,13 @@ mv weights/export.onnx /Path/to/checkpoints/yolov3.onnx ## Model Inference ```bash -export PROJ_DIR=/Path/to/yolov3/ixrt -export DATASETS_DIR=/Path/to/coco2017/ +export PROJ_DIR=./ +export DATASETS_DIR=/Path/to/coco/ export CHECKPOINTS_DIR=./checkpoints export COCO_GT=./coco/annotations/instances_val2017.json -export EVAL_DIR=./coco/val2017 -export RUN_DIR=/Path/to/yolov3/ixrt -export CONFIG_DIR=config/YOLOV3_CONFIG +export EVAL_DIR=./coco/images/val2017 +export RUN_DIR=../../ixrt_common +export CONFIG_DIR=../../ixrt_common/config/YOLOV3_CONFIG ``` ### FP16 diff --git a/models/cv/object_detection/yolov3/ixrt/build_engine.py b/models/cv/object_detection/yolov3/ixrt/build_engine.py deleted file mode 100644 index a919bdd0183197ce125aa5492ec83e58e035675d..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/build_engine.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import cv2 -import argparse -import numpy as np - -import torch -import tensorrt - -from load_ixrt_plugin import load_ixrt_plugin -load_ixrt_plugin() - -def main(config): - IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) - builder = tensorrt.Builder(IXRT_LOGGER) - EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) - network = builder.create_network(EXPLICIT_BATCH) - build_config = builder.create_builder_config() - 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) - - plan = builder.build_serialized_network(network, build_config) - engine_file_path = config.engine - with open(engine_file_path, "wb") as f: - f.write(plan) - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--model", type=str) - parser.add_argument("--precision", type=str, choices=["float16", "int8", "float32"], default="int8", - help="The precision of datatype") - # engine args - parser.add_argument("--engine", type=str, default=None) - - args = parser.parse_args() - return args - -if __name__ == "__main__": - args = parse_args() - main(args) \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/build_nms_engine.py b/models/cv/object_detection/yolov3/ixrt/build_nms_engine.py deleted file mode 100644 index 3be0d83d0d966018f59b87d22f628b9b1ddf9b21..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/build_nms_engine.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import argparse -import torch -import onnx -from onnx import helper -from onnx import TensorProto, numpy_helper -import tensorrt - -def create_onnx(args): - nms = helper.make_node( - "NMS", - name="NMS", - inputs=["nms_input"], - outputs=["nms_output0", "nms_output1"], - nMaxKeep=args.max_box_pre_img, - fIoUThresh=args.iou_thresh, - fScoreThresh=args.score_thresh - ) - graph = helper.make_graph( - nodes=[nms], - name="gpu_nms", - inputs=[ - helper.make_tensor_value_info( - "nms_input", onnx.TensorProto.FLOAT, (args.bsz, args.all_box_num, 6) - ) - ], - outputs=[ - helper.make_tensor_value_info( - "nms_output0", onnx.TensorProto.FLOAT, (args.bsz, args.max_box_pre_img, 6) - ), - helper.make_tensor_value_info( - "nms_output1", onnx.TensorProto.INT32, (args.bsz,) - ) - ], - initializer=[] - ) - - op = onnx.OperatorSetIdProto() - op.version = 13 - model = onnx.helper.make_model(graph) - - model = onnx.helper.make_model(graph, opset_imports=[op]) - onnx_path = args.path + "/nms.onnx" - onnx.save(model, onnx_path) - -def build_engine(args): - onnx_path = args.path + "/nms.onnx" - IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) - builder = tensorrt.Builder(IXRT_LOGGER) - EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) - network = builder.create_network(EXPLICIT_BATCH) - build_config = builder.create_builder_config() - parser = tensorrt.OnnxParser(network, IXRT_LOGGER) - parser.parse_from_file(onnx_path) - plan = builder.build_serialized_network(network, build_config) - - engine_path = args.path + "/nms.engine" - with open(engine_path, "wb") as f: - f.write(plan) - -def main(args): - create_onnx(args) - build_engine(args) - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--bsz", type=int, default=1, help="batch size") - parser.add_argument("--path", type=str) - parser.add_argument("--all_box_num", type=int, default=25200) - parser.add_argument("--max_box_pre_img", type=int, default=1000) - parser.add_argument("--iou_thresh", type=float, default=0.6) - parser.add_argument("--score_thresh", type=float, default=0.001) - - args = parser.parse_args() - return args - -if __name__ == "__main__": - args = parse_args() - main(args) \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/calibration_dataset.py b/models/cv/object_detection/yolov3/ixrt/calibration_dataset.py deleted file mode 100644 index de37775a0c617fdefca4342423a6a47bdc9b9c41..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/calibration_dataset.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -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/yolov3/ixrt/ci/prepare.sh b/models/cv/object_detection/yolov3/ixrt/ci/prepare.sh index 9fb652f13b4e02f2077b955a6a51ab1ccf8c8eb6..7d6d6fba9efd91fd2192fc1e5d46bbb927e12115 100644 --- a/models/cv/object_detection/yolov3/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/yolov3/ixrt/ci/prepare.sh @@ -25,7 +25,7 @@ else echo "Not Support Os" fi -pip3 install -r requirements.txt +pip3 install -r ../../ixrt_common/requirements.txt mkdir checkpoints unzip -q /root/data/3rd_party/onnx_tflite_yolov3.zip -d ./ cp /root/data/checkpoints/yolov3.weights onnx_tflite_yolov3/weights diff --git a/models/cv/object_detection/yolov3/ixrt/common.py b/models/cv/object_detection/yolov3/ixrt/common.py deleted file mode 100644 index aba2117c9942d6823abf73bf3ab94c291a7705e2..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/common.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import numpy as np -from tqdm import tqdm - -import tensorrt -import pycuda.driver as cuda - -# input : [bsz, box_num, 5(cx, cy, w, h, conf) + class_num(prob[0], prob[1], ...)] -# output : [bsz, box_num, 6(left_top_x, left_top_y, right_bottom_x, right_bottom_y, class_id, max_prob*conf)] -def box_class85to6(input): - center_x_y = input[:, :2] - side = input[:, 2:4] - conf = input[:, 4:5] - class_id = np.argmax(input[:, 5:], axis = -1) - class_id = class_id.astype(np.float32).reshape(-1, 1) + 1 - max_prob = np.max(input[:, 5:], axis = -1).reshape(-1, 1) - x1_y1 = center_x_y - 0.5 * side - x2_y2 = center_x_y + 0.5 * side - nms_input = np.concatenate([x1_y1, x2_y2, class_id, max_prob*conf], axis = -1) - return nms_input - -def save2json(batch_img_id, pred_boxes, json_result, class_trans): - for i, boxes in enumerate(pred_boxes): - if boxes is not None: - image_id = int(batch_img_id[i]) - # have no target - if image_id == -1: - continue - for x, y, w, h, c, p in boxes: - x, y, w, h, p = float(x), float(y), float(w), float(h), float(p) - c = int(c) - json_result.append( - { - "image_id": image_id, - "category_id": class_trans[c - 1], - "bbox": [x, y, w, h], - "score": p, - } - ) - -def create_engine_context(engine_path, logger): - with open(engine_path, "rb") as f: - runtime = tensorrt.Runtime(logger) - assert runtime - engine = runtime.deserialize_cuda_engine(f.read()) - assert engine - context = engine.create_execution_context() - assert context - - return engine, context - -def get_io_bindings(engine): - # Setup I/O bindings - inputs = [] - outputs = [] - allocations = [] - - for i in range(engine.num_bindings): - is_input = False - if engine.binding_is_input(i): - is_input = True - name = engine.get_binding_name(i) - dtype = engine.get_binding_dtype(i) - shape = engine.get_binding_shape(i) - if is_input: - batch_size = shape[0] - size = np.dtype(tensorrt.nptype(dtype)).itemsize - for s in shape: - size *= s - allocation = cuda.mem_alloc(size) - binding = { - "index": i, - "name": name, - "dtype": np.dtype(tensorrt.nptype(dtype)), - "shape": list(shape), - "allocation": allocation, - } - print(f"binding {i}, name : {name} dtype : {np.dtype(tensorrt.nptype(dtype))} shape : {list(shape)}") - allocations.append(allocation) - if engine.binding_is_input(i): - inputs.append(binding) - else: - outputs.append(binding) - return inputs, outputs, allocations \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/cut_model.py b/models/cv/object_detection/yolov3/ixrt/cut_model.py deleted file mode 100644 index e9ee19aadf0809fe1b97e3225d09150fb54513f7..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/cut_model.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import onnx -import argparse -from onnxsim import simplify - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--input_model", type=str) - parser.add_argument("--output_model", type=str) - parser.add_argument("--input_names", nargs='+', type=str) - parser.add_argument("--output_names", nargs='+', type=str) - args = parser.parse_args() - return args - -args = parse_args() -onnx.utils.extract_model(args.input_model, args.output_model, args.input_names, args.output_names) -print(" Cut Model Done.") \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/datasets/__init__.py b/models/cv/object_detection/yolov3/ixrt/datasets/__init__.py deleted file mode 100644 index 162e24b462289dcee7b7a2888b93fad1115def81..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/datasets/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/datasets/coco.py b/models/cv/object_detection/yolov3/ixrt/datasets/coco.py deleted file mode 100644 index 73c5df54761b917ecd0127fb56b61d9bd34c1196..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/datasets/coco.py +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os.path -from typing import Any, Callable, List, Optional, Tuple - -import cv2 - -from .vision import VisionDataset -from .pre_process import get_post_process -class CocoDetection(VisionDataset): - """`MS Coco Detection `_ Dataset. - - It requires the `COCO API to be installed `_. - - Args: - root (string): Root directory where images are downloaded to. - annFile (string): Path to json annotation file. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.PILToTensor`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - transforms (callable, optional): A function/transform that takes input sample and its target as entry - and returns a transformed version. - """ - - def __init__( - self, - root: str, - annFile: str, - img_size: int, - data_process_type: str, - transform: Optional[Callable] = None, - target_transform: Optional[Callable] = None, - transforms: Optional[Callable] = None, - - ) -> None: - super().__init__(root, transforms, transform, target_transform) - from pycocotools.coco import COCO - - self.coco = COCO(annFile) - self.ids = list(sorted(self.coco.imgs.keys())) - self.img_size = img_size - - self.transforms = get_post_process(data_process_type) - - def _load_image(self, id: int): - path = self.coco.loadImgs(id)[0]["file_name"] - data = cv2.imread(os.path.join(self.root, path)) - return data - - def _load_target(self, id: int) -> List[Any]: - return self.coco.loadAnns(self.coco.getAnnIds(id)) - - def __getitem__(self, index: int) -> Tuple[Any, Any]: - id = self.ids[index] - image = self._load_image(id) - target = self._load_target(id) - origin_shape = image.shape[:2] - - if self.transforms is not None: - image = self.transforms(image, self.img_size) - - if len(target) > 0: - image_id = target[0]["image_id"] - else: - # have no target - image_id = -1 - return image, origin_shape, image_id - - def __len__(self) -> int: - return len(self.ids) - - -class CocoCaptions(CocoDetection): - """`MS Coco Captions `_ Dataset. - - It requires the `COCO API to be installed `_. - - Args: - root (string): Root directory where images are downloaded to. - annFile (string): Path to json annotation file. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.PILToTensor`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - transforms (callable, optional): A function/transform that takes input sample and its target as entry - and returns a transformed version. - - Example: - - .. code:: python - - import torchvision.datasets as dset - import torchvision.transforms as transforms - cap = dset.CocoCaptions(root = 'dir where images are', - annFile = 'json annotation file', - transform=transforms.PILToTensor()) - - print('Number of samples: ', len(cap)) - img, target = cap[3] # load 4th sample - - print("Image Size: ", img.size()) - print(target) - - Output: :: - - Number of samples: 82783 - Image Size: (3L, 427L, 640L) - [u'A plane emitting smoke stream flying over a mountain.', - u'A plane darts across a bright blue sky behind a mountain covered in snow', - u'A plane leaves a contrail above the snowy mountain top.', - u'A mountain that has a plane flying overheard in the distance.', - u'A mountain view with a plume of smoke in the background'] - - """ - - def _load_target(self, id: int) -> List[str]: - return [ann["caption"] for ann in super()._load_target(id)] diff --git a/models/cv/object_detection/yolov3/ixrt/datasets/common.py b/models/cv/object_detection/yolov3/ixrt/datasets/common.py deleted file mode 100644 index ef36eba394917bc05af46f33be48463df50f540d..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/datasets/common.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import cv2 -import math -import numpy as np - -def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32): - # Resize and pad image while meeting stride-multiple constraints - shape = im.shape[:2] # current shape [height, width] - if isinstance(new_shape, int): - new_shape = (new_shape, new_shape) - - # Scale ratio (new / old) - r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) - if not scaleup: # only scale down, do not scale up (for better val mAP) - r = min(r, 1.0) - - # Compute padding - ratio = r, r # width, height ratios - new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) - dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding - if auto: # minimum rectangle - dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding - elif scaleFill: # stretch - dw, dh = 0.0, 0.0 - new_unpad = (new_shape[1], new_shape[0]) - ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios - - dw /= 2 # divide padding into 2 sides - dh /= 2 - - if shape[::-1] != new_unpad: # resize - im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR) - top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) - left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) - im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border - return im, ratio, (dw, dh) - -def scale_boxes(net_shape, boxes, ori_shape, use_letterbox=False): - # Rescale boxes (xyxy) from net_shape to ori_shape - - if use_letterbox: - - gain = min( - net_shape[0] / ori_shape[0], net_shape[1] / ori_shape[1] - ) # gain = new / old - pad = (net_shape[1] - ori_shape[1] * gain) / 2, ( - net_shape[0] - ori_shape[0] * gain - ) / 2.0 - - boxes[:, [0, 2]] -= pad[0] # x padding - boxes[:, [1, 3]] -= pad[1] # y padding - boxes[:, :4] /= gain - else: - x_scale, y_scale = net_shape[1] / ori_shape[1], net_shape[0] / ori_shape[0] - - boxes[:, 0] /= x_scale - boxes[:, 1] /= y_scale - boxes[:, 2] /= x_scale - boxes[:, 3] /= y_scale - - clip_boxes(boxes, ori_shape) - return boxes - -def clip_boxes(boxes, shape): - - boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1]) # x1, x2 - boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2 \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/datasets/post_process.py b/models/cv/object_detection/yolov3/ixrt/datasets/post_process.py deleted file mode 100644 index 8590816a0df18b6ef296ebe305b15b81240ab1d0..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/datasets/post_process.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import cv2 -import math -import numpy as np - -from .common import letterbox, scale_boxes, clip_boxes - -def get_post_process(data_process_type): - if data_process_type == "yolov5": - return Yolov5Postprocess - elif data_process_type == "yolov3": - return Yolov3Postprocess - elif data_process_type == "yolox": - return YoloxPostprocess - return None - -def Yolov3Postprocess( - ori_img_shape, - imgsz, - box_datas, - box_nums, - sample_num, - max_det=1000, -): - all_box = [] - data_offset = 0 - - box_datas = box_datas.flatten() - box_nums = box_nums.flatten() - - for i in range(sample_num): - box_num = box_nums[i] - if box_num == 0: - boxes = None - else: - cur_box = box_datas[data_offset : data_offset + box_num * 6].reshape(-1, 6) - boxes = scale_boxes( - (imgsz[0], imgsz[1]), - cur_box, - (ori_img_shape[0][i], ori_img_shape[1][i]), - use_letterbox=False - ) - # xyxy2xywh - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - - all_box.append(boxes) - data_offset += max_det * 6 - - return all_box - -def Yolov5Postprocess( - ori_img_shape, - imgsz, - box_datas, - box_nums, - sample_num, - max_det=1000, -): - all_box = [] - data_offset = 0 - - box_datas = box_datas.flatten() - box_nums = box_nums.flatten() - - for i in range(sample_num): - box_num = box_nums[i] - if box_num == 0: - boxes = None - else: - cur_box = box_datas[data_offset : data_offset + box_num * 6].reshape(-1, 6) - boxes = scale_boxes( - (imgsz[0], imgsz[1]), - cur_box, - (ori_img_shape[0][i], ori_img_shape[1][i]), - use_letterbox=True - ) - # xyxy2xywh - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - - all_box.append(boxes) - data_offset += max_det * 6 - - return all_box - -def YoloxPostprocess( - ori_img_shape, - imgsz, - box_datas, - box_nums, - sample_num, - max_det=1000, -): - all_box = [] - data_offset = 0 - box_datas = box_datas.flatten() - box_nums = box_nums.flatten() - - for i in range(sample_num): - box_num = box_nums[i] - if box_num == 0: - boxes = None - else: - boxes = box_datas[data_offset : data_offset + box_num * 6].reshape(-1, 6) - r = min(imgsz[0]/ori_img_shape[0][i], imgsz[1]/ori_img_shape[1][i]) - boxes[:, :4] /= r - # xyxy2xywh - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - clip_boxes(boxes, (ori_img_shape[0][i], ori_img_shape[1][i])) - - all_box.append(boxes) - data_offset += max_det * 6 - - return all_box \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/datasets/vision.py b/models/cv/object_detection/yolov3/ixrt/datasets/vision.py deleted file mode 100644 index eadefb2c5b35abd0a11fa85c65891461a210aef8..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/datasets/vision.py +++ /dev/null @@ -1,151 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -from typing import Any, Callable, List, Optional, Tuple - -import torch -import torch.utils.data as data - -from types import FunctionType - -def _log_api_usage_once(obj: Any) -> None: - - """ - Logs API usage(module and name) within an organization. - In a large ecosystem, it's often useful to track the PyTorch and - TorchVision APIs usage. This API provides the similar functionality to the - logging module in the Python stdlib. It can be used for debugging purpose - to log which methods are used and by default it is inactive, unless the user - manually subscribes a logger via the `SetAPIUsageLogger method `_. - Please note it is triggered only once for the same API call within a process. - It does not collect any data from open-source users since it is no-op by default. - For more information, please refer to - * PyTorch note: https://pytorch.org/docs/stable/notes/large_scale_deployments.html#api-usage-logging; - * Logging policy: https://github.com/pytorch/vision/issues/5052; - - Args: - obj (class instance or method): an object to extract info from. - """ - module = obj.__module__ - if not module.startswith("torchvision"): - module = f"torchvision.internal.{module}" - name = obj.__class__.__name__ - if isinstance(obj, FunctionType): - name = obj.__name__ - torch._C._log_api_usage_once(f"{module}.{name}") - -class VisionDataset(data.Dataset): - """ - Base Class For making datasets which are compatible with torchvision. - It is necessary to override the ``__getitem__`` and ``__len__`` method. - - Args: - root (string): Root directory of dataset. - transforms (callable, optional): A function/transforms that takes in - an image and a label and returns the transformed versions of both. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.RandomCrop`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - - .. note:: - - :attr:`transforms` and the combination of :attr:`transform` and :attr:`target_transform` are mutually exclusive. - """ - - _repr_indent = 4 - - def __init__( - self, - root: str, - transforms: Optional[Callable] = None, - transform: Optional[Callable] = None, - target_transform: Optional[Callable] = None, - ) -> None: - _log_api_usage_once(self) - if isinstance(root, str): - root = os.path.expanduser(root) - self.root = root - - has_transforms = transforms is not None - has_separate_transform = transform is not None or target_transform is not None - if has_transforms and has_separate_transform: - raise ValueError("Only transforms or transform/target_transform can be passed as argument") - - # for backwards-compatibility - self.transform = transform - self.target_transform = target_transform - - if has_separate_transform: - transforms = StandardTransform(transform, target_transform) - self.transforms = transforms - - def __getitem__(self, index: int) -> Any: - """ - Args: - index (int): Index - - Returns: - (Any): Sample and meta data, optionally transformed by the respective transforms. - """ - raise NotImplementedError - - def __len__(self) -> int: - raise NotImplementedError - - def __repr__(self) -> str: - head = "Dataset " + self.__class__.__name__ - body = [f"Number of datapoints: {self.__len__()}"] - if self.root is not None: - body.append(f"Root location: {self.root}") - body += self.extra_repr().splitlines() - if hasattr(self, "transforms") and self.transforms is not None: - body += [repr(self.transforms)] - lines = [head] + [" " * self._repr_indent + line for line in body] - return "\n".join(lines) - - def _format_transform_repr(self, transform: Callable, head: str) -> List[str]: - lines = transform.__repr__().splitlines() - return [f"{head}{lines[0]}"] + ["{}{}".format(" " * len(head), line) for line in lines[1:]] - - def extra_repr(self) -> str: - return "" - - -class StandardTransform: - def __init__(self, transform: Optional[Callable] = None, target_transform: Optional[Callable] = None) -> None: - self.transform = transform - self.target_transform = target_transform - - def __call__(self, input: Any, target: Any) -> Tuple[Any, Any]: - if self.transform is not None: - input = self.transform(input) - if self.target_transform is not None: - target = self.target_transform(target) - return input, target - - def _format_transform_repr(self, transform: Callable, head: str) -> List[str]: - lines = transform.__repr__().splitlines() - return [f"{head}{lines[0]}"] + ["{}{}".format(" " * len(head), line) for line in lines[1:]] - - def __repr__(self) -> str: - body = [self.__class__.__name__] - if self.transform is not None: - body += self._format_transform_repr(self.transform, "Transform: ") - if self.target_transform is not None: - body += self._format_transform_repr(self.target_transform, "Target transform: ") - - return "\n".join(body) diff --git a/models/cv/object_detection/yolov3/ixrt/deploy.py b/models/cv/object_detection/yolov3/ixrt/deploy.py deleted file mode 100644 index 8c2cc424f699e01bc88dab98a29dc4c83e4d9b9e..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/deploy.py +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# !/usr/bin/env python -# -*- coding: utf-8 -*- -import argparse -from tensorrt.deploy.api import GraphTransform, create_source, create_target - -class Transform: - def __init__(self, graph): - self.t = GraphTransform(graph) - self.graph = graph - - def ReplaceFocus(self, input_edge, outputs, to_op): - input_var = self.graph.get_variable(input_edge) - op = self.graph.get_operator(to_op) - self.t.delete_operators_between_var_op( - from_var=input_var, to_op=op - ) - self.t.make_operator( - "Focus", inputs=input_edge, outputs=outputs - ) - return self.graph - - def AddYoloDecoderOp(self, inputs: list, outputs: list, op_type, **attributes): - if attributes["anchor"] is None: - del attributes["anchor"] - self.t.make_operator( - op_type, inputs=inputs, outputs=outputs, **attributes - ) - return self.graph - - def AddConcatOp(self, inputs: list, outputs, **attributes): - self.t.make_operator( - "Concat", inputs=inputs, outputs=outputs, **attributes - ) - return self.graph - -def customize_ops(graph, args): - t = Transform(graph) - fuse_focus = args.focus_input is not None and args.focus_output is not None and args.focus_last_node is not None - if fuse_focus: - graph = t.ReplaceFocus( - input_edge=args.focus_input, - outputs=args.focus_output, - to_op=args.focus_last_node - ) - decoder_input = args.decoder_input_names - num = len(decoder_input) // 3 - graph = t.AddYoloDecoderOp( - inputs=decoder_input[:num], - outputs=["decoder_8"], - op_type=args.decoder_type, - anchor=args.decoder8_anchor, - num_class=args.num_class, - stride=8, - faster_impl=args.faster - ) - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num:num*2], - outputs=["decoder_16"], - op_type=args.decoder_type, - anchor=args.decoder16_anchor, - num_class=args.num_class, - stride=16, - faster_impl=args.faster - ) - - if args.decoder64_anchor is not None: - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num*2:num*2+1], - outputs=["decoder_32"], - op_type=args.decoder_type, - anchor=args.decoder32_anchor, - num_class=args.num_class, - stride=32, - faster_impl=args.faster - ) - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num*2+1:], - outputs=["decoder_64"], - op_type=args.decoder_type, - anchor=args.decoder64_anchor, - num_class=args.num_class, - stride=64, - faster_impl=args.faster - ) - graph = t.AddConcatOp( - inputs=["decoder_8", "decoder_16", "decoder_32", "decoder_64"], - outputs=["output"], - axis=1 - ) - else: - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num*2:], - outputs=["decoder_32"], - op_type=args.decoder_type, - anchor=args.decoder32_anchor, - num_class=args.num_class, - stride=32, - faster_impl=args.faster - ) - 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" - 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("--decoder_input_names", nargs='+', type=str) - parser.add_argument("--decoder8_anchor", nargs='*', type=int) - parser.add_argument("--decoder16_anchor", nargs='*', type=int) - parser.add_argument("--decoder32_anchor", nargs='*', type=int) - parser.add_argument("--decoder64_anchor", nargs='*', type=int, default=None) - parser.add_argument("--num_class", type=int, default=80) - parser.add_argument("--faster", type=int, default=1) - parser.add_argument("--focus_input", type=str, default=None) - parser.add_argument("--focus_output", type=str, default=None) - parser.add_argument("--focus_last_node", type=str, default=None) - args = parser.parse_args() - return args - -if __name__ == "__main__": - - args = parse_args() - graph = create_source(args.src)() - graph = customize_ops(graph, args) - create_target(saved_path=args.dst).export(graph) - print("Surged onnx lies on", args.dst) \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/inference.py b/models/cv/object_detection/yolov3/ixrt/inference.py deleted file mode 100644 index 4241328227c174d29ab093d4317e5591ab920b88..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/inference.py +++ /dev/null @@ -1,265 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import argparse -import glob -import json -import os -import time -import sys - -import torch -import numpy as np -import pycuda.autoinit -import pycuda.driver as cuda - -from coco_labels import coco80_to_coco91_class, labels -from common import save2json, box_class85to6 -from common import create_engine_context, get_io_bindings -from calibration_dataset import create_dataloaders -from datasets.post_process import get_post_process - -from pycocotools.coco import COCO -from pycocotools.cocoeval import COCOeval -from tqdm import tqdm -from tqdm.contrib import tzip - -import tensorrt - -from load_ixrt_plugin import load_ixrt_plugin -load_ixrt_plugin() - -def main(config): - - # Load dataloader - dataloader = create_dataloaders( - data_path=config.eval_dir, - annFile=config.coco_gt, - img_sz=config.imgsz, - batch_size=config.bsz, - step=config.loop_count, - data_process_type=config.data_process_type - ) - - # Load post process func - if config.test_mode == "MAP": - post_process_func = get_post_process(config.data_process_type) - - bsz = config.bsz - num_samples = 5000 - if config.loop_count > 0 and config.loop_count < num_samples/bsz : - num_samples = bsz * config.loop_count - num_batch = len(dataloader) - print("=" * 30) - print(f"Test Mode : {'Asynchronous' if config.use_async else 'Synchronous'}") - print(f"Total sample : {num_samples}\nBatch_size : {bsz}\nRun Batch : {num_batch}") - print("=" * 30) - - json_result = [] - forward_time = 0.0 - class_map = coco80_to_coco91_class() - - host_mem = tensorrt.IHostMemory - logger = tensorrt.Logger(tensorrt.Logger.ERROR) - - # Load Engine - engine, context = create_engine_context(config.model_engine, logger) - inputs, outputs, allocations = get_io_bindings(engine) - - # Load nms_engine - if config.test_mode == "MAP" and config.nms_type == "GPU": - nms_engine, nms_context = create_engine_context(config.nms_engine, logger) - nms_inputs, nms_outputs, nms_allocations = get_io_bindings(nms_engine) - nms_output0 = np.zeros(nms_outputs[0]["shape"], nms_outputs[0]["dtype"]) - nms_output1 = np.zeros(nms_outputs[1]["shape"], nms_outputs[1]["dtype"]) - print(f"nms_output0 shape : {nms_output0.shape} nms_output0 type : {nms_output0.dtype}") - print(f"nms_output1 shape : {nms_output1.shape} nms_output1 type : {nms_output1.dtype}") - - # Warm up - if config.warm_up > 0: - print("\nWarm Start.") - for i in range(config.warm_up): - context.execute_v2(allocations) - print("Warm Done.") - - # Prepare the output data - output = np.zeros(outputs[0]["shape"], outputs[0]["dtype"]) - print(f"output shape : {output.shape} output type : {output.dtype}") - - for batch_data, batch_img_shape, batch_img_id in tqdm(dataloader): - batch_data = batch_data.numpy() - batch_img_shape = [batch_img_shape[0].numpy(), batch_img_shape[1].numpy()] - # batch_img_id = batch_img_id.numpy() - - cur_bsz_sample = batch_data.shape[0] - - # Set input - cuda.memcpy_htod(inputs[0]["allocation"], batch_data) - - # Forward - start_time = time.time() - context.execute_v2(allocations) - end_time = time.time() - forward_time += end_time - start_time - - if config.test_mode == "MAP": - # Fetch output - cuda.memcpy_dtoh(output, outputs[0]["allocation"]) - - # Step 1 : prepare data to nms - _, box_num, box_unit = output.shape - if config.debug: - print(f"[Debug] box_num(25200) : {box_num}, box_unit(6) : {box_unit}") - - if config.decoder_faster == 0: - nms_input = box_class85to6(output.reshape(-1, box_unit)) - else: - nms_input = output - - # Step 2 : nms - # cpu nms(TODO) - - # gpu nms - if config.nms_type == "GPU": - - # Set nms input - cuda.memcpy_htod(nms_inputs[0]["allocation"], nms_input) - nms_context.execute_v2(nms_allocations) - cuda.memcpy_dtoh(nms_output0, nms_outputs[0]["allocation"]) - cuda.memcpy_dtoh(nms_output1, nms_outputs[1]["allocation"]) - - # Step 3 : post process + save - pred_boxes = post_process_func( - ori_img_shape=batch_img_shape, - imgsz=(config.imgsz, config.imgsz), - box_datas=nms_output0, - box_nums=nms_output1, - sample_num=cur_bsz_sample, - max_det=config.max_det - ) - save2json(batch_img_id, pred_boxes, json_result, class_map) - fps = num_samples / forward_time - - if config.test_mode == "FPS": - print("FPS : ", fps) - print(f"Performance Check : Test {fps} >= target {config.fps_target}") - if fps >= config.fps_target: - print("pass!") - exit() - else: - print("failed!") - exit(1) - - if config.test_mode == "MAP": - if len(json_result) == 0: - print("Predict zero box!") - exit(1) - - if not os.path.exists(config.pred_dir): - os.makedirs(config.pred_dir) - - pred_json = os.path.join( - config.pred_dir, f"{config.model_name}_{config.precision}_preds.json" - ) - with open(pred_json, "w") as f: - json.dump(json_result, f) - - start_time = time.time() - anno_json = config.coco_gt - anno = COCO(anno_json) # init annotations api - pred = anno.loadRes(pred_json) # init predictions api - eval = COCOeval(anno, pred, "bbox") - - eval.evaluate() - eval.accumulate() - print( - f"==============================eval {config.model_name} {config.precision} coco map ==============================" - ) - eval.summarize() - e2e_time = time.time() - start_time - map, map50 = eval.stats[:2] - print("MAP@0.5 : ", map50) - print(f"Accuracy Check : Test {map50} >= target {config.map_target}") - print(F"E2E time : {e2e_time:.3f} seconds") - if map50 >= config.map_target: - print("pass!") - exit() - else: - print("failed!") - exit(1) - -def parse_config(): - parser = argparse.ArgumentParser() - parser.add_argument( - "--model_name", type=str, default="YOLOV5s", help="YOLOV3 YOLOV5 YOLOV7 YOLOX" - ) - parser.add_argument("--precision", type=str, choices=["float16", "int8", "float32"], default="int8", - help="The precision of datatype") - parser.add_argument("--test_mode", type=str, default="FPS", help="FPS MAP") - parser.add_argument( - "--model_engine", - type=str, - default="", - help="model engine path", - ) - parser.add_argument( - "--nms_engine", - type=str, - default="", - help="nms engine path", - ) - parser.add_argument( - "--coco_gt", - type=str, - default="data/datasets/cv/coco2017/annotations/instances_val2017.json", - help="coco instances_val2017.json", - ) - parser.add_argument("--warm_up", type=int, default=3, help="warm_up count") - parser.add_argument("--loop_count", type=int, default=-1, help="loop count") - parser.add_argument( - "--eval_dir", - type=str, - default="data/datasets/cv/coco2017/val2017", - help="coco image dir", - ) - parser.add_argument("--bsz", type=int, default=32, help="test batch size") - parser.add_argument( - "--imgsz", - "--img", - "--img-size", - type=int, - default=640, - help="inference size h,w", - ) - parser.add_argument("--max_det", type=int, default=1000, help="maximum detections per image") - parser.add_argument("--data_process_type", type=str, default="none") - parser.add_argument("--use_async", action="store_true") - parser.add_argument("--debug", action="store_true") - parser.add_argument("--pred_dir", type=str, default=".", help="pred save json dirs") - parser.add_argument("--map_target", type=float, default=0.56, help="target mAP") - parser.add_argument("--fps_target", type=float, default=-1.0, help="target fps") - parser.add_argument("--decoder_faster", type=int, default=0, help="decoder faster can use gpu nms directly") - parser.add_argument("--nms_type", type=str, default="GPU", help="GPU/CPU") - - config = parser.parse_args() - print("config:", config) - return config - -if __name__ == "__main__": - config = parse_config() - main(config) \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/modify_batchsize.py b/models/cv/object_detection/yolov3/ixrt/modify_batchsize.py deleted file mode 100644 index 3a88c1603bd6f457fd4965257627dc29edcda4d1..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/modify_batchsize.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import onnx -import argparse - -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 - -args = parse_args() -model = onnx.load(args.origin_model) -change_input_dim(model, args.batch_size) -onnx.save(model, args.output_model) \ No newline at end of file diff --git a/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_fp16_accuracy.sh b/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_fp16_accuracy.sh index 7d6a609e03064b8334da1d3e91b958ead081686f..81f27858bba76f9ac497b7144883d0b3fd045f3d 100644 --- a/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_fp16_accuracy.sh +++ b/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_fp16_accuracy.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_fp16_performance.sh b/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_fp16_performance.sh index 4fdf2ada533a5ff82d0b68bf8c41648cca6d1eec..357fb10ba605e56bcaa853037c40213b6be09609 100644 --- a/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_fp16_performance.sh +++ b/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_fp16_performance.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() @@ -46,7 +32,6 @@ done source ${CONFIG_DIR} ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} -echo PROJ_DIR : ${PROJ_DIR} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} echo RUN_DIR : ${RUN_DIR} diff --git a/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_int8_accuracy.sh b/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_int8_accuracy.sh index e216261271056f05c59ee49373c5389726c9097b..a0961b5c1d63687a5c99d4ddaeba10237ea72f99 100644 --- a/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_int8_accuracy.sh +++ b/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_int8_accuracy.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_int8_performance.sh b/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_int8_performance.sh index 7faed28cd3cea40673078c1bbb0eac4311e2c9a6..d0f1f48a3d42c655cff6130aad715fc56048b2e0 100644 --- a/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_int8_performance.sh +++ b/models/cv/object_detection/yolov3/ixrt/scripts/infer_yolov3_int8_performance.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov3/ixrt/simplify_model.py b/models/cv/object_detection/yolov3/ixrt/simplify_model.py deleted file mode 100644 index 1400fd81ddb4b3fae1b20d0fd35082a692f5d292..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov3/ixrt/simplify_model.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -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 diff --git a/models/cv/object_detection/yolov4/ixrt/README.md b/models/cv/object_detection/yolov4/ixrt/README.md index e425710b4b003898dd90c276f2ee6177ccf881dd..f6bd831e431a4c70064a9d348d143e397bd8889e 100644 --- a/models/cv/object_detection/yolov4/ixrt/README.md +++ b/models/cv/object_detection/yolov4/ixrt/README.md @@ -38,21 +38,26 @@ pip3 install -r requirements.txt git clone https://github.com/Tianxiaomo/pytorch-YOLOv4.git yolov4 # download weight -mkdir data -wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights -P data +mkdir checkpoints +wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights -P checkpoints # export onnx model -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 - -# Use onnxsim optimize onnx model -onnxsim data/yolov4.onnx data/yolov4_sim.onnx - -# Make sure the dataset path is "data/coco" +python3 export.py --cfg yolov4/cfg/yolov4.cfg --weight yolov4.weights --output yolov4.onnx +mv yolov4.onnx checkpoints/yolov4.onnx ``` ## Model Inference +```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 +``` + ### 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 ec4080edd3c275a4595cbfb407a21cebdada7fa7..d47e45e518cc0bd35d2fd27f19f7da17bec44abf 100644 --- a/models/cv/object_detection/yolov4/ixrt/build_engine.py +++ b/models/cv/object_detection/yolov4/ixrt/build_engine.py @@ -1,17 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. import os import cv2 import argparse @@ -19,13 +5,11 @@ import numpy as np import torch import tensorrt -from tensorrt import Dims from load_ixrt_plugin import load_ixrt_plugin load_ixrt_plugin() - -def build_engine_trtapi_staticshape(config): +def main(config): IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) builder = tensorrt.Builder(IXRT_LOGGER) EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) @@ -42,42 +26,6 @@ def build_engine_trtapi_staticshape(config): engine_file_path = config.engine with open(engine_file_path, "wb") as f: f.write(plan) - print("Build static shape engine done!") - - -def build_engine_trtapi_dynamicshape(config): - IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) - builder = tensorrt.Builder(IXRT_LOGGER) - 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([1, 3, 608, 608]), - Dims([32, 3, 608, 608]), - Dims([64, 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([-1, 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() @@ -90,8 +38,6 @@ def parse_args(): args = parser.parse_args() return args - if __name__ == "__main__": args = parse_args() - build_engine_trtapi_staticshape(args) - # build_engine_trtapi_dynamicshape(args) + main(args) \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/calibration_dataset.py b/models/cv/object_detection/yolov4/ixrt/calibration_dataset.py similarity index 55% rename from models/cv/object_detection/yolov5s/ixrt/calibration_dataset.py rename to models/cv/object_detection/yolov4/ixrt/calibration_dataset.py index de37775a0c617fdefca4342423a6a47bdc9b9c41..578e013db932c53f0cfa2790e375d7b699081168 100644 --- a/models/cv/object_detection/yolov5s/ixrt/calibration_dataset.py +++ b/models/cv/object_detection/yolov4/ixrt/calibration_dataset.py @@ -1,22 +1,10 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - 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"): diff --git a/models/cv/object_detection/yolov4/ixrt/ci/prepare.sh b/models/cv/object_detection/yolov4/ixrt/ci/prepare.sh index f5381ef3db88f61e26d50b601f58b046ffa79317..63b534209dc77e84945c8f442bb7c201e9905171 100644 --- a/models/cv/object_detection/yolov4/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/yolov4/ixrt/ci/prepare.sh @@ -30,10 +30,8 @@ pip3 install -r requirements.txt # clone yolov4 cp -r /root/data/3rd_party/yolov4 ./ -mkdir data +mkdir checkpoints # export onnx model -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 +python3 export.py --cfg yolov4/cfg/yolov4.cfg --weight /root/data/checkpoints/yolov4.weights --output yolov4.onnx +mv yolov4.onnx checkpoints/yolov4.onnx -# Use onnxsim optimize onnx model -onnxsim data/yolov4.onnx data/yolov4_sim.onnx diff --git a/models/cv/object_detection/yolov4/ixrt/coco_labels.py b/models/cv/object_detection/yolov4/ixrt/coco_labels.py index 5fc21282c7fa393e9d15e8bdc16c741dc7e78448..69d38878ff16d66dfe7550fcd170ac91d0862318 100644 --- a/models/cv/object_detection/yolov4/ixrt/coco_labels.py +++ b/models/cv/object_detection/yolov4/ixrt/coco_labels.py @@ -1,17 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. labels = [ "person", "bicycle", diff --git a/models/cv/object_detection/yolov4/ixrt/config/YOLOV4_CONFIG b/models/cv/object_detection/yolov4/ixrt/config/YOLOV4_CONFIG new file mode 100644 index 0000000000000000000000000000000000000000..c04994949f0f65d799f77fb9f2ec62b96c0becbe --- /dev/null +++ b/models/cv/object_detection/yolov4/ixrt/config/YOLOV4_CONFIG @@ -0,0 +1,49 @@ +# 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/cut_model.py b/models/cv/object_detection/yolov4/ixrt/cut_model.py index cf4f88dae926b8d15356c7f6b48d89fe80dc9f2a..af0a3a4f0cc3caf05b95be3c77dea7728c931e3f 100644 --- a/models/cv/object_detection/yolov4/ixrt/cut_model.py +++ b/models/cv/object_detection/yolov4/ixrt/cut_model.py @@ -1,17 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. import onnx import argparse from onnxsim import simplify @@ -27,4 +13,4 @@ def parse_args(): args = parse_args() onnx.utils.extract_model(args.input_model, args.output_model, args.input_names, args.output_names) -print(" Cut Model Done.") +print(" Cut Model Done.") \ 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 084356ec8cb14a0604bf994faca4ce15834e4b15..ec56b7ab83c6b271c92de6e5c36153927f629887 100644 --- a/models/cv/object_detection/yolov4/ixrt/deploy.py +++ b/models/cv/object_detection/yolov4/ixrt/deploy.py @@ -1,90 +1,8 @@ # !/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. import argparse -import copy - -from typing import Union, Callable, List - -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) @@ -168,24 +86,32 @@ def customize_ops(graph, args): outputs=["output"], axis=1 ) - else: + elif args.with_nms: 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" + 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" 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) @@ -199,12 +125,10 @@ 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) + print("Surged onnx lies on", args.dst) \ No newline at end of file diff --git a/models/cv/object_detection/yolov4/ixrt/export.py b/models/cv/object_detection/yolov4/ixrt/export.py index 7c8bbfa5aa79f1a982c340690658325d23fa4b54..db7e06cc9bfc5dd2b301c75f2472271222efa446 100644 --- a/models/cv/object_detection/yolov4/ixrt/export.py +++ b/models/cv/object_detection/yolov4/ixrt/export.py @@ -32,11 +32,6 @@ 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, @@ -49,7 +44,7 @@ def parse_args(): def main(): args = parse_args() - transform_to_onnx(args.cfg, args.weight, args.batchsize, args.output) + transform_to_onnx(args.cfg, args.weight, -1, args.output) if __name__ == "__main__": main() diff --git a/models/cv/object_detection/yolov4/ixrt/load_ixrt_plugin.py b/models/cv/object_detection/yolov4/ixrt/load_ixrt_plugin.py index 2bb0abc21bd5806c51d6b908e3e3407cfdb62cc8..932efbdfd1a4e91d8ddfd363adf6bce989df1709 100644 --- a/models/cv/object_detection/yolov4/ixrt/load_ixrt_plugin.py +++ b/models/cv/object_detection/yolov4/ixrt/load_ixrt_plugin.py @@ -1,17 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. import ctypes import tensorrt from os.path import join, dirname, exists @@ -23,4 +9,4 @@ def load_ixrt_plugin(logger=tensorrt.Logger(tensorrt.Logger.INFO), namespace="", f"The ixrt_plugin lib {dynamic_path} is not existed, please provided effective plugin path!") ctypes.CDLL(dynamic_path) tensorrt.init_libnvinfer_plugins(logger, namespace) - print(f"Loaded plugin from {dynamic_path}") + print(f"Loaded plugin from {dynamic_path}") \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/modify_batchsize.py b/models/cv/object_detection/yolov4/ixrt/modify_batchsize.py similarity index 62% rename from models/cv/object_detection/yolov5s/ixrt/modify_batchsize.py rename to models/cv/object_detection/yolov4/ixrt/modify_batchsize.py index 3a88c1603bd6f457fd4965257627dc29edcda4d1..f696ae5517dfb15c020c533332c02a2b6b06c873 100644 --- a/models/cv/object_detection/yolov5s/ixrt/modify_batchsize.py +++ b/models/cv/object_detection/yolov4/ixrt/modify_batchsize.py @@ -1,20 +1,7 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import onnx import argparse +import copy +import numpy as np def change_input_dim(model, bsz): batch_size = bsz @@ -46,7 +33,22 @@ def parse_args(): 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) -onnx.save(model, args.output_model) \ No newline at end of file +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 70265cbc25d24d4ed41640c76f78a1839555f749..d73212ca60a4985cc036f67e8fb0b3c70ba24e4d 100644 --- a/models/cv/object_detection/yolov4/ixrt/quant.py +++ b/models/cv/object_detection/yolov4/ixrt/quant.py @@ -1,50 +1,34 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. import os -import cv2 import random import argparse import numpy as np from tensorrt.deploy import static_quantize import torch -import torchvision.datasets -from torch.utils.data import DataLoader -from common import letterbox - +import sys +sys.path.append("/home/haoyuan.chen/temp/inferencesamples/benchmarks/cv/detection/yolov3/tensorrt") +print(sys.path) +from calibration_dataset import create_dataloaders 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="yolov4_bs16_without_decoder.onnx") + parser.add_argument("--model", type=str, default="yolov5s_with_decoder.onnx") + parser.add_argument("--data_process_type", type=str, default="none") 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_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("--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("--seed", type=int, default=42) - parser.add_argument("--imgsz", type=int, default=608) - parser.add_argument("--use_letterbox", action="store_true") + parser.add_argument("--imgsz", type=int, default=640) args = parser.parse_args() return args @@ -52,54 +36,20 @@ args = parse_args() setseed(args.seed) model_name = args.model_name - -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, +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, - new_shape=(args.imgsz, args.imgsz), - use_letterbox=args.use_letterbox + step=args.step, + data_process_type=args.data_process_type ) - -dirname = os.path.dirname(args.save_quant_model) -quant_json_path = os.path.join(dirname, f"quantized_{model_name}.json") - +# print("disable_quant_names : ", args.disable_quant_names) static_quantize(args.model, calibration_dataloader=dataloader, - save_quant_onnx_path=args.save_quant_model, - save_quant_params_path=quant_json_path, + save_quant_onnx_path=os.path.join(out_dir, f"quantized_{model_name}.onnx"), observer=args.observer, - data_preprocess=lambda x: x.to("cuda"), + data_preprocess=lambda x: x[0].to("cuda"), quant_format="qdq", - disable_quant_names=args.disable_quant_names) + disable_quant_names=args.disable_quant_names) \ No newline at end of file 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 c33dc591362e34df05378869f4254190ef5a6985..c86762e0f22e64a37813310851799c39d9dfed21 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,92 +1,185 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() { - if ((${PIPESTATUS[0]} != 0));then - EXIT_STATUS=1 + ret_code=${PIPESTATUS[0]} + if [ ${ret_code} != 0 ]; then + [[ ${ret_code} -eq 10 && "${TEST_PERF:-1}" -eq 0 ]] || EXIT_STATUS=1 fi } -PROJ_DIR=$(cd $(dirname $0);cd ../; pwd) -DATASETS_DIR=${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} +# 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} 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 : yolov4_darknet +echo Model Name : ${MODEL_NAME} echo Onnx Path : ${ORIGINE_MODEL} -BATCH_SIZE=16 -CURRENT_MODEL=${CHECKPOINTS_DIR}/yolov4_sim.onnx +CHECKPOINTS_DIR=${CHECKPOINTS_DIR}/tmp +mkdir -p ${CHECKPOINTS_DIR} -# 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 +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}/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} + python3 ${RUN_DIR}/simplify_model.py \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${SIM_MODEL} + echo " "Generate ${SIM_MODEL} +fi +CURRENT_MODEL=${SIM_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 +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 -CURRENT_MODEL=${FINAL_MODEL} -# add decoder op -FINAL_MODEL=${CHECKPOINTS_DIR}/yolov4_bs${BATCH_SIZE}_with_decoder.onnx +# 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} +fi + +# Change Batchsize +let step++ +echo; +echo [STEP ${step}] : Change Batchsize +FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_quant_bs${BSZ}_with_nms.onnx if [ -f $FINAL_MODEL ];then - echo " "Add Decoder Skip, $FINAL_MODEL has been existed + echo " "Change Batchsize Skip, $FINAL_MODEL has been existed else - 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 + python3 ${RUN_DIR}/modify_batchsize.py \ + --batch_size ${BSZ} \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} echo " "Generate ${FINAL_MODEL} fi CURRENT_MODEL=${FINAL_MODEL} # Build Engine -echo Build Engine -ENGINE_FILE=${CHECKPOINTS_DIR}/yolov4_fp16.engine +let step++ +echo; +echo [STEP ${step}] : Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}_with_nms.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --precision float16 \ + --precision ${PRECISION} \ --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 -echo Inference +let step++ +echo; +echo [STEP ${step}] : Inference RUN_BATCH_SIZE=16 python3 ${RUN_DIR}/inference.py \ --test_mode MAP \ @@ -100,4 +193,4 @@ python3 ${RUN_DIR}/inference.py \ --pred_dir ${CHECKPOINTS_DIR} \ --precision float16 \ --map_target 0.30; check_status -exit ${EXIT_STATUS} +exit ${EXIT_STATUS} \ No newline at end of file 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 a4a83ce72e715997ca64cf35b0b0ff0e8bd351a5..dabe655b7b15af873888208ebd1a3d1a2b36c441 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,92 +1,186 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() { - if ((${PIPESTATUS[0]} != 0));then - EXIT_STATUS=1 + ret_code=${PIPESTATUS[0]} + if [ ${ret_code} != 0 ]; then + [[ ${ret_code} -eq 10 && "${TEST_PERF:-1}" -eq 0 ]] || EXIT_STATUS=1 fi } -PROJ_DIR=$(cd $(dirname $0);cd ../; pwd) -DATASETS_DIR=${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} +# 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} 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 : yolov4_darknet +echo Model Name : ${MODEL_NAME} echo Onnx Path : ${ORIGINE_MODEL} -BATCH_SIZE=16 -CURRENT_MODEL=${CHECKPOINTS_DIR}/yolov4_sim.onnx +CHECKPOINTS_DIR=${CHECKPOINTS_DIR}/tmp +mkdir -p ${CHECKPOINTS_DIR} -# 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 +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}/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} + python3 ${RUN_DIR}/simplify_model.py \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${SIM_MODEL} + echo " "Generate ${SIM_MODEL} fi -CURRENT_MODEL=${FINAL_MODEL} +CURRENT_MODEL=${SIM_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 +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} -# add decoder op -FINAL_MODEL=${CHECKPOINTS_DIR}/yolov4_bs${BATCH_SIZE}_with_decoder.onnx + +# 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} +fi + +# Change Batchsize +let step++ +echo; +echo [STEP ${step}] : Change Batchsize +FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_quant_bs${BSZ}_without_nms.onnx if [ -f $FINAL_MODEL ];then - echo " "Add Decoder Skip, $FINAL_MODEL has been existed + echo " "Change Batchsize Skip, $FINAL_MODEL has been existed else - 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 + python3 ${RUN_DIR}/modify_batchsize.py \ + --batch_size ${BSZ} \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} echo " "Generate ${FINAL_MODEL} fi CURRENT_MODEL=${FINAL_MODEL} # Build Engine -echo Build Engine -ENGINE_FILE=${CHECKPOINTS_DIR}/yolov4_fp16.engine +let step++ +echo; +echo [STEP ${step}] : Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}_without_nms.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --precision float16 \ + --precision ${PRECISION} \ --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 -echo Inference +let step++ +echo; +echo [STEP ${step}] : Inference RUN_BATCH_SIZE=16 python3 ${RUN_DIR}/inference.py \ --test_mode FPS \ @@ -100,4 +194,4 @@ python3 ${RUN_DIR}/inference.py \ --pred_dir ${CHECKPOINTS_DIR} \ --precision float16 \ --map_target 0.30; check_status -exit ${EXIT_STATUS} +exit ${EXIT_STATUS} \ No newline at end of file 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 20e593785bc25bb06b8c0f2e537542981cc65c00..646b115f5232dd0fd3fa873398537b3c5f5c823a 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,110 +1,185 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() { - if ((${PIPESTATUS[0]} != 0));then - EXIT_STATUS=1 + ret_code=${PIPESTATUS[0]} + if [ ${ret_code} != 0 ]; then + [[ ${ret_code} -eq 10 && "${TEST_PERF:-1}" -eq 0 ]] || EXIT_STATUS=1 fi } -PROJ_DIR=$(cd $(dirname $0);cd ../; pwd) -DATASETS_DIR=${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} +# 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} 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 : yolov4_darknet +echo Model Name : ${MODEL_NAME} echo Onnx Path : ${ORIGINE_MODEL} -BATCH_SIZE=16 -CURRENT_MODEL=${CHECKPOINTS_DIR}/yolov4_sim.onnx +CHECKPOINTS_DIR=${CHECKPOINTS_DIR}/tmp +mkdir -p ${CHECKPOINTS_DIR} -# 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 +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}/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} + python3 ${RUN_DIR}/simplify_model.py \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${SIM_MODEL} + echo " "Generate ${SIM_MODEL} fi -CURRENT_MODEL=${FINAL_MODEL} +CURRENT_MODEL=${SIM_MODEL} -# 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 +# 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 else - 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} + 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 -CURRENT_MODEL=${FINAL_MODEL} -# add decoder op -FINAL_MODEL=${CHECKPOINTS_DIR}/quantized_yolov4_bs${BATCH_SIZE}_with_decoder.onnx +# 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} +fi + +# Change Batchsize +let step++ +echo; +echo [STEP ${step}] : Change Batchsize +FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_quant_bs${BSZ}_with_nms.onnx if [ -f $FINAL_MODEL ];then - echo " "Add Decoder Skip, $FINAL_MODEL has been existed + echo " "Change Batchsize Skip, $FINAL_MODEL has been existed else - 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 + python3 ${RUN_DIR}/modify_batchsize.py \ + --batch_size ${BSZ} \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} echo " "Generate ${FINAL_MODEL} fi CURRENT_MODEL=${FINAL_MODEL} # Build Engine -echo Build Engine -ENGINE_FILE=${CHECKPOINTS_DIR}/yolov4_int8.engine +let step++ +echo; +echo [STEP ${step}] : Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}_with_nms.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --precision int8 \ + --precision ${PRECISION} \ --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 -echo Inference +let step++ +echo; +echo [STEP ${step}] : Inference RUN_BATCH_SIZE=16 python3 ${RUN_DIR}/inference.py \ --test_mode MAP \ @@ -116,6 +191,6 @@ python3 ${RUN_DIR}/inference.py \ --eval_dir ${EVAL_DIR} \ --coco_gt ${COCO_GT} \ --pred_dir ${CHECKPOINTS_DIR} \ - --precision int8 \ + --precision float16 \ --map_target 0.30; check_status -exit ${EXIT_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 7f11038651ffe1e27c8e57f40e7b6f74b67e1945..4665a65f6f8b3052b2beabb6221364a3b927b7bc 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,110 +1,186 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() { - if ((${PIPESTATUS[0]} != 0));then - EXIT_STATUS=1 + ret_code=${PIPESTATUS[0]} + if [ ${ret_code} != 0 ]; then + [[ ${ret_code} -eq 10 && "${TEST_PERF:-1}" -eq 0 ]] || EXIT_STATUS=1 fi } -PROJ_DIR=$(cd $(dirname $0);cd ../; pwd) -DATASETS_DIR=${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} +# 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} 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 : yolov4_darknet +echo Model Name : ${MODEL_NAME} echo Onnx Path : ${ORIGINE_MODEL} -BATCH_SIZE=16 -CURRENT_MODEL=${CHECKPOINTS_DIR}/yolov4_sim.onnx +CHECKPOINTS_DIR=${CHECKPOINTS_DIR}/tmp +mkdir -p ${CHECKPOINTS_DIR} -# 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 +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}/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} + python3 ${RUN_DIR}/simplify_model.py \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${SIM_MODEL} + echo " "Generate ${SIM_MODEL} fi -CURRENT_MODEL=${FINAL_MODEL} +CURRENT_MODEL=${SIM_MODEL} -# 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 +# 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 else - 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} + 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=${FINAL_MODEL} +CURRENT_MODEL=${NO_DECODER_MODEL} -# add decoder op -FINAL_MODEL=${CHECKPOINTS_DIR}/quantized_yolov4_bs${BATCH_SIZE}_with_decoder.onnx + +# 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} +fi + +# Change Batchsize +let step++ +echo; +echo [STEP ${step}] : Change Batchsize +FINAL_MODEL=${CHECKPOINTS_DIR}/${MODEL_NAME}_quant_bs${BSZ}_without_nms.onnx if [ -f $FINAL_MODEL ];then - echo " "Add Decoder Skip, $FINAL_MODEL has been existed + echo " "Change Batchsize Skip, $FINAL_MODEL has been existed else - 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 + python3 ${RUN_DIR}/modify_batchsize.py \ + --batch_size ${BSZ} \ + --origin_model ${CURRENT_MODEL} \ + --output_model ${FINAL_MODEL} echo " "Generate ${FINAL_MODEL} fi CURRENT_MODEL=${FINAL_MODEL} # Build Engine -echo Build Engine -ENGINE_FILE=${CHECKPOINTS_DIR}/yolov4_int8.engine +let step++ +echo; +echo [STEP ${step}] : Build Engine +ENGINE_FILE=${CHECKPOINTS_DIR}/${MODEL_NAME}_${PRECISION}_bs${BSZ}_without_nms.engine if [ -f $ENGINE_FILE ];then echo " "Build Engine Skip, $ENGINE_FILE has been existed else python3 ${RUN_DIR}/build_engine.py \ - --precision int8 \ + --precision ${PRECISION} \ --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 -echo Inference +let step++ +echo; +echo [STEP ${step}] : Inference RUN_BATCH_SIZE=16 python3 ${RUN_DIR}/inference.py \ --test_mode FPS \ @@ -116,6 +192,6 @@ python3 ${RUN_DIR}/inference.py \ --eval_dir ${EVAL_DIR} \ --coco_gt ${COCO_GT} \ --pred_dir ${CHECKPOINTS_DIR} \ - --precision int8 \ + --precision float16 \ --map_target 0.30; check_status -exit ${EXIT_STATUS} +exit ${EXIT_STATUS} \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/simplify_model.py b/models/cv/object_detection/yolov4/ixrt/simplify_model.py similarity index 46% rename from models/cv/object_detection/yolov5/ixrt/simplify_model.py rename to models/cv/object_detection/yolov4/ixrt/simplify_model.py index 1400fd81ddb4b3fae1b20d0fd35082a692f5d292..b4254b6f903cb5f8775e43b2f80d5572bf45b1d6 100644 --- a/models/cv/object_detection/yolov5/ixrt/simplify_model.py +++ b/models/cv/object_detection/yolov4/ixrt/simplify_model.py @@ -1,18 +1,3 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - import onnx import argparse from onnxsim import simplify diff --git a/models/cv/object_detection/yolov5/ixrt/README.md b/models/cv/object_detection/yolov5/ixrt/README.md index 6870c7d070549070236f8ad1a40f81489ce9b60e..69f568404f9abe717223373f3a76746cbc48d2a7 100644 --- a/models/cv/object_detection/yolov5/ixrt/README.md +++ b/models/cv/object_detection/yolov5/ixrt/README.md @@ -30,7 +30,7 @@ yum install -y mesa-libGL ## Ubuntu apt install -y libgl1-mesa-glx -pip3 install -r requirements.txt +pip3 install -r ../../ixrt_common/requirements.txt ``` ### Model Conversion @@ -54,13 +54,13 @@ mv yolov5m.onnx /Path/to/checkpoints ## Model Inference ```bash -export PROJ_DIR=/Path/to/yolov5/ixrt -export DATASETS_DIR=/Path/to/coco2017/ +export PROJ_DIR=./ +export DATASETS_DIR=/Path/to/coco/ export CHECKPOINTS_DIR=./checkpoints export COCO_GT=${DATASETS_DIR}/annotations/instances_val2017.json -export EVAL_DIR=${DATASETS_DIR}/val2017 -export RUN_DIR=/Path/to/yolov5/ixrt -export CONFIG_DIR=config/YOLOV5_CONFIG +export EVAL_DIR=${DATASETS_DIR}/images/val2017 +export RUN_DIR=../../ixrt_common +export CONFIG_DIR=../../ixrt_common/config/YOLOV5M_CONFIG ``` ### FP16 diff --git a/models/cv/object_detection/yolov5/ixrt/build_engine.py b/models/cv/object_detection/yolov5/ixrt/build_engine.py deleted file mode 100644 index a919bdd0183197ce125aa5492ec83e58e035675d..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/build_engine.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import cv2 -import argparse -import numpy as np - -import torch -import tensorrt - -from load_ixrt_plugin import load_ixrt_plugin -load_ixrt_plugin() - -def main(config): - IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) - builder = tensorrt.Builder(IXRT_LOGGER) - EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) - network = builder.create_network(EXPLICIT_BATCH) - build_config = builder.create_builder_config() - 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) - - plan = builder.build_serialized_network(network, build_config) - engine_file_path = config.engine - with open(engine_file_path, "wb") as f: - f.write(plan) - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--model", type=str) - parser.add_argument("--precision", type=str, choices=["float16", "int8", "float32"], default="int8", - help="The precision of datatype") - # engine args - parser.add_argument("--engine", type=str, default=None) - - args = parser.parse_args() - return args - -if __name__ == "__main__": - args = parse_args() - main(args) \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/ci/prepare.sh b/models/cv/object_detection/yolov5/ixrt/ci/prepare.sh index b66c06b56fd42240b3578ef2a764a39c5fe06b03..b99ab99d2fccb0f83ceadda8983ac202ff3f4268 100644 --- a/models/cv/object_detection/yolov5/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/yolov5/ixrt/ci/prepare.sh @@ -25,7 +25,7 @@ else echo "Not Support Os" fi -pip3 install -r requirements.txt +pip3 install -r ../../ixrt_common/requirements.txt mkdir checkpoints cp -r /root/data/3rd_party/yolov5 ./ diff --git a/models/cv/object_detection/yolov5/ixrt/coco_labels.py b/models/cv/object_detection/yolov5/ixrt/coco_labels.py deleted file mode 100644 index 43f5bd82cd257efdcab2bdba6bad64d9bb90416e..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/coco_labels.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -labels = [ - "person", - "bicycle", - "car", - "motorcycle", - "airplane", - "bus", - "train", - "truck", - "boat", - "traffic light", - "fire hydrant", - "stop sign", - "parking meter", - "bench", - "bird", - "cat", - "dog", - "horse", - "sheep", - "cow", - "elephant", - "bear", - "zebra", - "giraffe", - "backpack", - "umbrella", - "handbag", - "tie", - "suitcase", - "frisbee", - "skis", - "snowboard", - "sports ball", - "kite", - "baseball bat", - "baseball glove", - "skateboard", - "surfboard", - "tennis racket", - "bottle", - "wine glass", - "cup", - "fork", - "knife", - "spoon", - "bowl", - "banana", - "apple", - "sandwich", - "orange", - "broccoli", - "carrot", - "hot dog", - "pizza", - "donut", - "cake", - "chair", - "couch", - "potted plant", - "bed", - "dining table", - "toilet", - "tv", - "laptop", - "mouse", - "remote", - "keyboard", - "cell phone", - "microwave", - "oven", - "toaster", - "sink", - "refrigerator", - "book", - "clock", - "vase", - "scissors", - "teddy bear", - "hair drier", - "toothbrush", -] -def coco80_to_coco91_class(): # converts 80-index (val2014) to 91-index (paper) - return [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90] - -__all__ = ["labels"] diff --git a/models/cv/object_detection/yolov5/ixrt/common.py b/models/cv/object_detection/yolov5/ixrt/common.py deleted file mode 100644 index aba2117c9942d6823abf73bf3ab94c291a7705e2..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/common.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import numpy as np -from tqdm import tqdm - -import tensorrt -import pycuda.driver as cuda - -# input : [bsz, box_num, 5(cx, cy, w, h, conf) + class_num(prob[0], prob[1], ...)] -# output : [bsz, box_num, 6(left_top_x, left_top_y, right_bottom_x, right_bottom_y, class_id, max_prob*conf)] -def box_class85to6(input): - center_x_y = input[:, :2] - side = input[:, 2:4] - conf = input[:, 4:5] - class_id = np.argmax(input[:, 5:], axis = -1) - class_id = class_id.astype(np.float32).reshape(-1, 1) + 1 - max_prob = np.max(input[:, 5:], axis = -1).reshape(-1, 1) - x1_y1 = center_x_y - 0.5 * side - x2_y2 = center_x_y + 0.5 * side - nms_input = np.concatenate([x1_y1, x2_y2, class_id, max_prob*conf], axis = -1) - return nms_input - -def save2json(batch_img_id, pred_boxes, json_result, class_trans): - for i, boxes in enumerate(pred_boxes): - if boxes is not None: - image_id = int(batch_img_id[i]) - # have no target - if image_id == -1: - continue - for x, y, w, h, c, p in boxes: - x, y, w, h, p = float(x), float(y), float(w), float(h), float(p) - c = int(c) - json_result.append( - { - "image_id": image_id, - "category_id": class_trans[c - 1], - "bbox": [x, y, w, h], - "score": p, - } - ) - -def create_engine_context(engine_path, logger): - with open(engine_path, "rb") as f: - runtime = tensorrt.Runtime(logger) - assert runtime - engine = runtime.deserialize_cuda_engine(f.read()) - assert engine - context = engine.create_execution_context() - assert context - - return engine, context - -def get_io_bindings(engine): - # Setup I/O bindings - inputs = [] - outputs = [] - allocations = [] - - for i in range(engine.num_bindings): - is_input = False - if engine.binding_is_input(i): - is_input = True - name = engine.get_binding_name(i) - dtype = engine.get_binding_dtype(i) - shape = engine.get_binding_shape(i) - if is_input: - batch_size = shape[0] - size = np.dtype(tensorrt.nptype(dtype)).itemsize - for s in shape: - size *= s - allocation = cuda.mem_alloc(size) - binding = { - "index": i, - "name": name, - "dtype": np.dtype(tensorrt.nptype(dtype)), - "shape": list(shape), - "allocation": allocation, - } - print(f"binding {i}, name : {name} dtype : {np.dtype(tensorrt.nptype(dtype))} shape : {list(shape)}") - allocations.append(allocation) - if engine.binding_is_input(i): - inputs.append(binding) - else: - outputs.append(binding) - return inputs, outputs, allocations \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/cut_model.py b/models/cv/object_detection/yolov5/ixrt/cut_model.py deleted file mode 100644 index e9ee19aadf0809fe1b97e3225d09150fb54513f7..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/cut_model.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import onnx -import argparse -from onnxsim import simplify - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--input_model", type=str) - parser.add_argument("--output_model", type=str) - parser.add_argument("--input_names", nargs='+', type=str) - parser.add_argument("--output_names", nargs='+', type=str) - args = parser.parse_args() - return args - -args = parse_args() -onnx.utils.extract_model(args.input_model, args.output_model, args.input_names, args.output_names) -print(" Cut Model Done.") \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/datasets/__init__.py b/models/cv/object_detection/yolov5/ixrt/datasets/__init__.py deleted file mode 100644 index 162e24b462289dcee7b7a2888b93fad1115def81..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/datasets/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/datasets/coco.py b/models/cv/object_detection/yolov5/ixrt/datasets/coco.py deleted file mode 100644 index 73c5df54761b917ecd0127fb56b61d9bd34c1196..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/datasets/coco.py +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os.path -from typing import Any, Callable, List, Optional, Tuple - -import cv2 - -from .vision import VisionDataset -from .pre_process import get_post_process -class CocoDetection(VisionDataset): - """`MS Coco Detection `_ Dataset. - - It requires the `COCO API to be installed `_. - - Args: - root (string): Root directory where images are downloaded to. - annFile (string): Path to json annotation file. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.PILToTensor`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - transforms (callable, optional): A function/transform that takes input sample and its target as entry - and returns a transformed version. - """ - - def __init__( - self, - root: str, - annFile: str, - img_size: int, - data_process_type: str, - transform: Optional[Callable] = None, - target_transform: Optional[Callable] = None, - transforms: Optional[Callable] = None, - - ) -> None: - super().__init__(root, transforms, transform, target_transform) - from pycocotools.coco import COCO - - self.coco = COCO(annFile) - self.ids = list(sorted(self.coco.imgs.keys())) - self.img_size = img_size - - self.transforms = get_post_process(data_process_type) - - def _load_image(self, id: int): - path = self.coco.loadImgs(id)[0]["file_name"] - data = cv2.imread(os.path.join(self.root, path)) - return data - - def _load_target(self, id: int) -> List[Any]: - return self.coco.loadAnns(self.coco.getAnnIds(id)) - - def __getitem__(self, index: int) -> Tuple[Any, Any]: - id = self.ids[index] - image = self._load_image(id) - target = self._load_target(id) - origin_shape = image.shape[:2] - - if self.transforms is not None: - image = self.transforms(image, self.img_size) - - if len(target) > 0: - image_id = target[0]["image_id"] - else: - # have no target - image_id = -1 - return image, origin_shape, image_id - - def __len__(self) -> int: - return len(self.ids) - - -class CocoCaptions(CocoDetection): - """`MS Coco Captions `_ Dataset. - - It requires the `COCO API to be installed `_. - - Args: - root (string): Root directory where images are downloaded to. - annFile (string): Path to json annotation file. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.PILToTensor`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - transforms (callable, optional): A function/transform that takes input sample and its target as entry - and returns a transformed version. - - Example: - - .. code:: python - - import torchvision.datasets as dset - import torchvision.transforms as transforms - cap = dset.CocoCaptions(root = 'dir where images are', - annFile = 'json annotation file', - transform=transforms.PILToTensor()) - - print('Number of samples: ', len(cap)) - img, target = cap[3] # load 4th sample - - print("Image Size: ", img.size()) - print(target) - - Output: :: - - Number of samples: 82783 - Image Size: (3L, 427L, 640L) - [u'A plane emitting smoke stream flying over a mountain.', - u'A plane darts across a bright blue sky behind a mountain covered in snow', - u'A plane leaves a contrail above the snowy mountain top.', - u'A mountain that has a plane flying overheard in the distance.', - u'A mountain view with a plume of smoke in the background'] - - """ - - def _load_target(self, id: int) -> List[str]: - return [ann["caption"] for ann in super()._load_target(id)] diff --git a/models/cv/object_detection/yolov5/ixrt/datasets/common.py b/models/cv/object_detection/yolov5/ixrt/datasets/common.py deleted file mode 100644 index ef36eba394917bc05af46f33be48463df50f540d..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/datasets/common.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import cv2 -import math -import numpy as np - -def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32): - # Resize and pad image while meeting stride-multiple constraints - shape = im.shape[:2] # current shape [height, width] - if isinstance(new_shape, int): - new_shape = (new_shape, new_shape) - - # Scale ratio (new / old) - r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) - if not scaleup: # only scale down, do not scale up (for better val mAP) - r = min(r, 1.0) - - # Compute padding - ratio = r, r # width, height ratios - new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) - dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding - if auto: # minimum rectangle - dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding - elif scaleFill: # stretch - dw, dh = 0.0, 0.0 - new_unpad = (new_shape[1], new_shape[0]) - ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios - - dw /= 2 # divide padding into 2 sides - dh /= 2 - - if shape[::-1] != new_unpad: # resize - im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR) - top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) - left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) - im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border - return im, ratio, (dw, dh) - -def scale_boxes(net_shape, boxes, ori_shape, use_letterbox=False): - # Rescale boxes (xyxy) from net_shape to ori_shape - - if use_letterbox: - - gain = min( - net_shape[0] / ori_shape[0], net_shape[1] / ori_shape[1] - ) # gain = new / old - pad = (net_shape[1] - ori_shape[1] * gain) / 2, ( - net_shape[0] - ori_shape[0] * gain - ) / 2.0 - - boxes[:, [0, 2]] -= pad[0] # x padding - boxes[:, [1, 3]] -= pad[1] # y padding - boxes[:, :4] /= gain - else: - x_scale, y_scale = net_shape[1] / ori_shape[1], net_shape[0] / ori_shape[0] - - boxes[:, 0] /= x_scale - boxes[:, 1] /= y_scale - boxes[:, 2] /= x_scale - boxes[:, 3] /= y_scale - - clip_boxes(boxes, ori_shape) - return boxes - -def clip_boxes(boxes, shape): - - boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1]) # x1, x2 - boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2 \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/datasets/pre_process.py b/models/cv/object_detection/yolov5/ixrt/datasets/pre_process.py deleted file mode 100644 index c651f8adb7c8190c214fbbbb7769c7d0713e9619..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/datasets/pre_process.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import cv2 -import math -import numpy as np - -from .common import letterbox - -def get_post_process(data_process_type): - if data_process_type == "yolov5": - return Yolov5Preprocess - elif data_process_type == "yolov3": - return Yolov3Preprocess - elif data_process_type == "yolox": - return YoloxPreprocess - return None - -def Yolov3Preprocess(image, img_size): - - h0, w0 = image.shape[:2] # orig hw - r = img_size / max(h0, w0) # ratio - - image = cv2.resize(image, (img_size, img_size)) - image = image.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - image = np.ascontiguousarray(image).astype(np.float32) / 255.0 # 0~1 np array - return image - -def Yolov5Preprocess(image, img_size, augment=False): - - h0, w0 = image.shape[:2] # orig hw - r = img_size / max(h0, w0) # ratio - - if r != 1: # if sizes are not equal - interp = cv2.INTER_LINEAR if (augment or r > 1) else cv2.INTER_AREA - image = cv2.resize(image, (math.ceil(w0 * r), math.ceil(h0 * r)), interpolation=interp) - - # shape = self.batch_shapes[self.batch[index]] if self.rect else self.img_size rect == True - - image, ratio, dwdh = letterbox(image, new_shape=img_size, auto=False, scaleup=False) - image = image.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - image = np.ascontiguousarray(image).astype(np.float32) / 255.0 # 0~1 np array - return image - -def YoloxPreprocess(img, img_size, swap=(2,0,1)): - - padded_img = np.ones((img_size, img_size, 3), dtype=np.uint8) * 114 - r = min(img_size / img.shape[0], img_size / img.shape[1]) - resized_img = cv2.resize( - img, - (int(img.shape[1] * r), int(img.shape[0] * r)), - interpolation=cv2.INTER_LINEAR, - ).astype(np.uint8) - - padded_img[: int(img.shape[0] * r), : int(img.shape[1] * r)] = resized_img - padded_img = padded_img.transpose(swap) - padded_img = np.ascontiguousarray(padded_img, dtype=np.float32) - - return padded_img \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/deploy.py b/models/cv/object_detection/yolov5/ixrt/deploy.py deleted file mode 100644 index 8c2cc424f699e01bc88dab98a29dc4c83e4d9b9e..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/deploy.py +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# !/usr/bin/env python -# -*- coding: utf-8 -*- -import argparse -from tensorrt.deploy.api import GraphTransform, create_source, create_target - -class Transform: - def __init__(self, graph): - self.t = GraphTransform(graph) - self.graph = graph - - def ReplaceFocus(self, input_edge, outputs, to_op): - input_var = self.graph.get_variable(input_edge) - op = self.graph.get_operator(to_op) - self.t.delete_operators_between_var_op( - from_var=input_var, to_op=op - ) - self.t.make_operator( - "Focus", inputs=input_edge, outputs=outputs - ) - return self.graph - - def AddYoloDecoderOp(self, inputs: list, outputs: list, op_type, **attributes): - if attributes["anchor"] is None: - del attributes["anchor"] - self.t.make_operator( - op_type, inputs=inputs, outputs=outputs, **attributes - ) - return self.graph - - def AddConcatOp(self, inputs: list, outputs, **attributes): - self.t.make_operator( - "Concat", inputs=inputs, outputs=outputs, **attributes - ) - return self.graph - -def customize_ops(graph, args): - t = Transform(graph) - fuse_focus = args.focus_input is not None and args.focus_output is not None and args.focus_last_node is not None - if fuse_focus: - graph = t.ReplaceFocus( - input_edge=args.focus_input, - outputs=args.focus_output, - to_op=args.focus_last_node - ) - decoder_input = args.decoder_input_names - num = len(decoder_input) // 3 - graph = t.AddYoloDecoderOp( - inputs=decoder_input[:num], - outputs=["decoder_8"], - op_type=args.decoder_type, - anchor=args.decoder8_anchor, - num_class=args.num_class, - stride=8, - faster_impl=args.faster - ) - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num:num*2], - outputs=["decoder_16"], - op_type=args.decoder_type, - anchor=args.decoder16_anchor, - num_class=args.num_class, - stride=16, - faster_impl=args.faster - ) - - if args.decoder64_anchor is not None: - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num*2:num*2+1], - outputs=["decoder_32"], - op_type=args.decoder_type, - anchor=args.decoder32_anchor, - num_class=args.num_class, - stride=32, - faster_impl=args.faster - ) - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num*2+1:], - outputs=["decoder_64"], - op_type=args.decoder_type, - anchor=args.decoder64_anchor, - num_class=args.num_class, - stride=64, - faster_impl=args.faster - ) - graph = t.AddConcatOp( - inputs=["decoder_8", "decoder_16", "decoder_32", "decoder_64"], - outputs=["output"], - axis=1 - ) - else: - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num*2:], - outputs=["decoder_32"], - op_type=args.decoder_type, - anchor=args.decoder32_anchor, - num_class=args.num_class, - stride=32, - faster_impl=args.faster - ) - 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" - 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("--decoder_input_names", nargs='+', type=str) - parser.add_argument("--decoder8_anchor", nargs='*', type=int) - parser.add_argument("--decoder16_anchor", nargs='*', type=int) - parser.add_argument("--decoder32_anchor", nargs='*', type=int) - parser.add_argument("--decoder64_anchor", nargs='*', type=int, default=None) - parser.add_argument("--num_class", type=int, default=80) - parser.add_argument("--faster", type=int, default=1) - parser.add_argument("--focus_input", type=str, default=None) - parser.add_argument("--focus_output", type=str, default=None) - parser.add_argument("--focus_last_node", type=str, default=None) - args = parser.parse_args() - return args - -if __name__ == "__main__": - - args = parse_args() - graph = create_source(args.src)() - graph = customize_ops(graph, args) - create_target(saved_path=args.dst).export(graph) - print("Surged onnx lies on", args.dst) \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/inference.py b/models/cv/object_detection/yolov5/ixrt/inference.py deleted file mode 100644 index c0476b899ba0ec51ab4aedc0596f19cb283952ab..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/inference.py +++ /dev/null @@ -1,267 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import argparse -import glob -import json -import os -import time -import sys - -import torch -import numpy as np -import pycuda.autoinit -import pycuda.driver as cuda - -from coco_labels import coco80_to_coco91_class, labels -from common import save2json, box_class85to6 -from common import create_engine_context, get_io_bindings -from calibration_dataset import create_dataloaders -from datasets.post_process import get_post_process - -from pycocotools.coco import COCO -from pycocotools.cocoeval import COCOeval -from tqdm import tqdm -from tqdm.contrib import tzip - -import tensorrt - -from load_ixrt_plugin import load_ixrt_plugin -load_ixrt_plugin() - -def main(config): - - # Load dataloader - dataloader = create_dataloaders( - data_path=config.eval_dir, - annFile=config.coco_gt, - img_sz=config.imgsz, - batch_size=config.bsz, - step=config.loop_count, - data_process_type=config.data_process_type - ) - - # Load post process func - if config.test_mode == "MAP": - post_process_func = get_post_process(config.data_process_type) - - bsz = config.bsz - num_samples = 5000 - if config.loop_count > 0 and config.loop_count < num_samples/bsz : - num_samples = bsz * config.loop_count - num_batch = len(dataloader) - print("=" * 30) - print(f"Test Mode : {'Asynchronous' if config.use_async else 'Synchronous'}") - print(f"Total sample : {num_samples}\nBatch_size : {bsz}\nRun Batch : {num_batch}") - print("=" * 30) - - json_result = [] - forward_time = 0.0 - class_map = coco80_to_coco91_class() - - host_mem = tensorrt.IHostMemory - logger = tensorrt.Logger(tensorrt.Logger.ERROR) - - # Load Engine - engine, context = create_engine_context(config.model_engine, logger) - inputs, outputs, allocations = get_io_bindings(engine) - - # Load nms_engine - if config.test_mode == "MAP" and config.nms_type == "GPU": - nms_engine, nms_context = create_engine_context(config.nms_engine, logger) - nms_inputs, nms_outputs, nms_allocations = get_io_bindings(nms_engine) - nms_output0 = np.zeros(nms_outputs[0]["shape"], nms_outputs[0]["dtype"]) - nms_output1 = np.zeros(nms_outputs[1]["shape"], nms_outputs[1]["dtype"]) - print(f"nms_output0 shape : {nms_output0.shape} nms_output0 type : {nms_output0.dtype}") - print(f"nms_output1 shape : {nms_output1.shape} nms_output1 type : {nms_output1.dtype}") - - # Warm up - if config.warm_up > 0: - print("\nWarm Start.") - for i in range(config.warm_up): - context.execute_v2(allocations) - print("Warm Done.") - - # Prepare the output data - output = np.zeros(outputs[0]["shape"], outputs[0]["dtype"]) - print(f"output shape : {output.shape} output type : {output.dtype}") - - for batch_data, batch_img_shape, batch_img_id in tqdm(dataloader): - batch_data = batch_data.numpy() - batch_img_shape = [batch_img_shape[0].numpy(), batch_img_shape[1].numpy()] - # batch_img_id = batch_img_id.numpy() - - cur_bsz_sample = batch_data.shape[0] - - # Set input - cuda.memcpy_htod(inputs[0]["allocation"], batch_data) - - # Forward - start_time = time.time() - context.execute_v2(allocations) - end_time = time.time() - forward_time += end_time - start_time - - if config.test_mode == "MAP": - # Fetch output - cuda.memcpy_dtoh(output, outputs[0]["allocation"]) - - # Step 1 : prepare data to nms - _, box_num, box_unit = output.shape - if config.debug: - print(f"[Debug] box_num(25200) : {box_num}, box_unit(6) : {box_unit}") - - if config.decoder_faster == 0: - nms_input = box_class85to6(output.reshape(-1, box_unit)) - else: - nms_input = output - - # Step 2 : nms - # cpu nms(TODO) - - # gpu nms - if config.nms_type == "GPU": - - # Set nms input - cuda.memcpy_htod(nms_inputs[0]["allocation"], nms_input) - nms_context.execute_v2(nms_allocations) - cuda.memcpy_dtoh(nms_output0, nms_outputs[0]["allocation"]) - cuda.memcpy_dtoh(nms_output1, nms_outputs[1]["allocation"]) - - # Step 3 : post process + save - pred_boxes = post_process_func( - ori_img_shape=batch_img_shape, - imgsz=(config.imgsz, config.imgsz), - box_datas=nms_output0, - box_nums=nms_output1, - sample_num=cur_bsz_sample, - max_det=config.max_det - ) - save2json(batch_img_id, pred_boxes, json_result, class_map) - - fps = num_samples / forward_time - - if config.test_mode == "FPS": - print("FPS : ", fps) - print(f"Performance Check : Test {fps} >= target {config.fps_target}") - if fps >= config.fps_target: - print("pass!") - exit() - else: - print("failed!") - exit(1) - - if config.test_mode == "MAP": - if len(json_result) == 0: - print("Predict zero box!") - exit(1) - - if not os.path.exists(config.pred_dir): - os.makedirs(config.pred_dir) - - pred_json = os.path.join( - config.pred_dir, f"{config.model_name}_{config.precision}_preds.json" - ) - with open(pred_json, "w") as f: - json.dump(json_result, f) - - start_time = time.time() - anno_json = config.coco_gt - anno = COCO(anno_json) # init annotations api - pred = anno.loadRes(pred_json) # init predictions api - eval = COCOeval(anno, pred, "bbox") - - eval.evaluate() - eval.accumulate() - print( - f"==============================eval {config.model_name} {config.precision} coco map ==============================" - ) - eval.summarize() - e2e_time = time.time() - start_time - map, map50 = eval.stats[:2] - print(F"E2E time : {e2e_time:.3f} seconds") - print("MAP@0.5 : ", map50) - print(f"Accuracy Check : Test {map50} >= target {config.map_target}") - print(F"E2E time : {e2e_time:.3f} seconds") - if map50 >= config.map_target: - print("pass!") - exit() - else: - print("failed!") - exit(1) - -def parse_config(): - parser = argparse.ArgumentParser() - parser.add_argument( - "--model_name", type=str, default="YOLOV5s", help="YOLOV3 YOLOV5 YOLOV7 YOLOX" - ) - parser.add_argument("--precision", type=str, choices=["float16", "int8", "float32"], default="int8", - help="The precision of datatype") - parser.add_argument("--test_mode", type=str, default="FPS", help="FPS MAP") - parser.add_argument( - "--model_engine", - type=str, - default="", - help="model engine path", - ) - parser.add_argument( - "--nms_engine", - type=str, - default="", - help="nms engine path", - ) - parser.add_argument( - "--coco_gt", - type=str, - default="data/datasets/cv/coco2017/annotations/instances_val2017.json", - help="coco instances_val2017.json", - ) - parser.add_argument("--warm_up", type=int, default=3, help="warm_up count") - parser.add_argument("--loop_count", type=int, default=-1, help="loop count") - parser.add_argument( - "--eval_dir", - type=str, - default="data/datasets/cv/coco2017/val2017", - help="coco image dir", - ) - parser.add_argument("--bsz", type=int, default=32, help="test batch size") - parser.add_argument( - "--imgsz", - "--img", - "--img-size", - type=int, - default=640, - help="inference size h,w", - ) - parser.add_argument("--max_det", type=int, default=1000, help="maximum detections per image") - parser.add_argument("--data_process_type", type=str, default="none") - parser.add_argument("--use_async", action="store_true") - parser.add_argument("--debug", action="store_true") - parser.add_argument("--pred_dir", type=str, default=".", help="pred save json dirs") - parser.add_argument("--map_target", type=float, default=0.56, help="target mAP") - parser.add_argument("--fps_target", type=float, default=-1.0, help="target fps") - parser.add_argument("--decoder_faster", type=int, default=0, help="decoder faster can use gpu nms directly") - parser.add_argument("--nms_type", type=str, default="GPU", help="GPU/CPU") - - config = parser.parse_args() - print("config:", config) - return config - -if __name__ == "__main__": - config = parse_config() - main(config) \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/load_ixrt_plugin.py b/models/cv/object_detection/yolov5/ixrt/load_ixrt_plugin.py deleted file mode 100644 index ae47dc8e854b6bea1f768e65c4dd481048bfebce..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/load_ixrt_plugin.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ctypes -import tensorrt -from os.path import join, dirname, exists -def load_ixrt_plugin(logger=tensorrt.Logger(tensorrt.Logger.INFO), namespace="", dynamic_path=""): - if not dynamic_path: - dynamic_path = join(dirname(tensorrt.__file__), "lib", "libixrt_plugin.so") - if not exists(dynamic_path): - raise FileNotFoundError( - f"The ixrt_plugin lib {dynamic_path} is not existed, please provided effective plugin path!") - ctypes.CDLL(dynamic_path) - tensorrt.init_libnvinfer_plugins(logger, namespace) - print(f"Loaded plugin from {dynamic_path}") \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/quant.py b/models/cv/object_detection/yolov5/ixrt/quant.py deleted file mode 100644 index 36fd39a13c2e1e40f4dc0098f042e66e4bd0d26a..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/quant.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import random -import argparse -import numpy as np -from tensorrt.deploy import static_quantize - -import torch -from calibration_dataset import create_dataloaders - -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("--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("--seed", type=int, default=42) - parser.add_argument("--imgsz", type=int, default=640) - args = parser.parse_args() - return args - -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, - step=args.step, - data_process_type=args.data_process_type -) -# print("disable_quant_names : ", args.disable_quant_names) -static_quantize(args.model, - calibration_dataloader=dataloader, - save_quant_onnx_path=os.path.join(out_dir, f"quantized_{model_name}.onnx"), - observer=args.observer, - data_preprocess=lambda x: x[0].to("cuda"), - quant_format="qdq", - disable_quant_names=args.disable_quant_names) \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/requirements.txt b/models/cv/object_detection/yolov5/ixrt/requirements.txt deleted file mode 100644 index 10a9fba6a70545eee20ab0db7bb740b1d4807f95..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5/ixrt/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -tqdm -onnx -onnxsim -ultralytics==8.3.97 -pycocotools -opencv-python==4.6.0.66 -pycuda \ No newline at end of file diff --git a/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_fp16_accuracy.sh b/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_fp16_accuracy.sh index 140ab8ace521610303cbfc0582e0c5eaf6188c62..52ec959f1ea4b6b192b111c5b837904183d17876 100644 --- a/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_fp16_accuracy.sh +++ b/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_fp16_accuracy.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_fp16_performance.sh b/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_fp16_performance.sh index 01542134796eda4a0d46c33e3d28c23120e690ba..5e2f97fb43b1480fcce35669e7d2346f63eb64a8 100644 --- a/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_fp16_performance.sh +++ b/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_fp16_performance.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_int8_accuracy.sh b/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_int8_accuracy.sh index 18d11eff42fc5ecf60ae3338ae1c4688ff252127..606fc94c8c7f11a517b7bf3fe1fcf22ccb6d68d1 100644 --- a/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_int8_accuracy.sh +++ b/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_int8_accuracy.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_int8_performance.sh b/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_int8_performance.sh index 08525d287a6e850b7ee253bb13dc165c2253f045..b29836695881a184603d63159e0872c508d94486 100644 --- a/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_int8_performance.sh +++ b/models/cv/object_detection/yolov5/ixrt/scripts/infer_yolov5_int8_performance.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov5s/ixrt/README.md b/models/cv/object_detection/yolov5s/ixrt/README.md index 079c9644b671b5137d64627173657430e9b22ef3..88f55f22a1f9ed3f815bd23e6f07cbb80c37e192 100755 --- a/models/cv/object_detection/yolov5s/ixrt/README.md +++ b/models/cv/object_detection/yolov5s/ixrt/README.md @@ -27,7 +27,7 @@ yum install -y mesa-libGL ## Ubuntu apt install -y libgl1-mesa-glx -pip3 install -r requirements.txt +pip3 install -r ../../ixrt_common/requirements.txt ``` ### Model Conversion @@ -53,13 +53,13 @@ popd ## Model Inference ```bash -export PROJ_DIR=/Path/to/yolov5s/ixrt -export DATASETS_DIR=/Path/to/coco2017/ +export PROJ_DIR=./ +export DATASETS_DIR=/Path/to/coco/ export CHECKPOINTS_DIR=./checkpoints export COCO_GT=${DATASETS_DIR}/annotations/instances_val2017.json -export EVAL_DIR=${DATASETS_DIR}/val2017 -export RUN_DIR=${PROJ_DIR}/ -export CONFIG_DIR=config/YOLOV5S_CONFIG +export EVAL_DIR=${DATASETS_DIR}/images/val2017 +export RUN_DIR=../../ixrt_common +export CONFIG_DIR=../../ixrt_common/config/YOLOV5S_CONFIG ``` ### FP16 diff --git a/models/cv/object_detection/yolov5s/ixrt/build_engine.py b/models/cv/object_detection/yolov5s/ixrt/build_engine.py deleted file mode 100644 index a919bdd0183197ce125aa5492ec83e58e035675d..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/build_engine.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import cv2 -import argparse -import numpy as np - -import torch -import tensorrt - -from load_ixrt_plugin import load_ixrt_plugin -load_ixrt_plugin() - -def main(config): - IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) - builder = tensorrt.Builder(IXRT_LOGGER) - EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) - network = builder.create_network(EXPLICIT_BATCH) - build_config = builder.create_builder_config() - 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) - - plan = builder.build_serialized_network(network, build_config) - engine_file_path = config.engine - with open(engine_file_path, "wb") as f: - f.write(plan) - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--model", type=str) - parser.add_argument("--precision", type=str, choices=["float16", "int8", "float32"], default="int8", - help="The precision of datatype") - # engine args - parser.add_argument("--engine", type=str, default=None) - - args = parser.parse_args() - return args - -if __name__ == "__main__": - args = parse_args() - main(args) \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/build_nms_engine.py b/models/cv/object_detection/yolov5s/ixrt/build_nms_engine.py deleted file mode 100644 index 3be0d83d0d966018f59b87d22f628b9b1ddf9b21..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/build_nms_engine.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import argparse -import torch -import onnx -from onnx import helper -from onnx import TensorProto, numpy_helper -import tensorrt - -def create_onnx(args): - nms = helper.make_node( - "NMS", - name="NMS", - inputs=["nms_input"], - outputs=["nms_output0", "nms_output1"], - nMaxKeep=args.max_box_pre_img, - fIoUThresh=args.iou_thresh, - fScoreThresh=args.score_thresh - ) - graph = helper.make_graph( - nodes=[nms], - name="gpu_nms", - inputs=[ - helper.make_tensor_value_info( - "nms_input", onnx.TensorProto.FLOAT, (args.bsz, args.all_box_num, 6) - ) - ], - outputs=[ - helper.make_tensor_value_info( - "nms_output0", onnx.TensorProto.FLOAT, (args.bsz, args.max_box_pre_img, 6) - ), - helper.make_tensor_value_info( - "nms_output1", onnx.TensorProto.INT32, (args.bsz,) - ) - ], - initializer=[] - ) - - op = onnx.OperatorSetIdProto() - op.version = 13 - model = onnx.helper.make_model(graph) - - model = onnx.helper.make_model(graph, opset_imports=[op]) - onnx_path = args.path + "/nms.onnx" - onnx.save(model, onnx_path) - -def build_engine(args): - onnx_path = args.path + "/nms.onnx" - IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) - builder = tensorrt.Builder(IXRT_LOGGER) - EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) - network = builder.create_network(EXPLICIT_BATCH) - build_config = builder.create_builder_config() - parser = tensorrt.OnnxParser(network, IXRT_LOGGER) - parser.parse_from_file(onnx_path) - plan = builder.build_serialized_network(network, build_config) - - engine_path = args.path + "/nms.engine" - with open(engine_path, "wb") as f: - f.write(plan) - -def main(args): - create_onnx(args) - build_engine(args) - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--bsz", type=int, default=1, help="batch size") - parser.add_argument("--path", type=str) - parser.add_argument("--all_box_num", type=int, default=25200) - parser.add_argument("--max_box_pre_img", type=int, default=1000) - parser.add_argument("--iou_thresh", type=float, default=0.6) - parser.add_argument("--score_thresh", type=float, default=0.001) - - args = parser.parse_args() - return args - -if __name__ == "__main__": - args = parse_args() - main(args) \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/ci/prepare.sh b/models/cv/object_detection/yolov5s/ixrt/ci/prepare.sh index b9f3a57f9d4bb7c25c55aa5621b8eb378093bd03..a08c47d7053f6c3a910a533b81e4331e8dbf3dfc 100644 --- a/models/cv/object_detection/yolov5s/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/yolov5s/ixrt/ci/prepare.sh @@ -25,7 +25,7 @@ else echo "Not Support Os" fi -pip3 install -r requirements.txt +pip3 install -r ../../ixrt_common/requirements.txt mkdir -p checkpoints cp -r /root/data/3rd_party/yolov5 ./ diff --git a/models/cv/object_detection/yolov5s/ixrt/coco_labels.py b/models/cv/object_detection/yolov5s/ixrt/coco_labels.py deleted file mode 100644 index 43f5bd82cd257efdcab2bdba6bad64d9bb90416e..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/coco_labels.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -labels = [ - "person", - "bicycle", - "car", - "motorcycle", - "airplane", - "bus", - "train", - "truck", - "boat", - "traffic light", - "fire hydrant", - "stop sign", - "parking meter", - "bench", - "bird", - "cat", - "dog", - "horse", - "sheep", - "cow", - "elephant", - "bear", - "zebra", - "giraffe", - "backpack", - "umbrella", - "handbag", - "tie", - "suitcase", - "frisbee", - "skis", - "snowboard", - "sports ball", - "kite", - "baseball bat", - "baseball glove", - "skateboard", - "surfboard", - "tennis racket", - "bottle", - "wine glass", - "cup", - "fork", - "knife", - "spoon", - "bowl", - "banana", - "apple", - "sandwich", - "orange", - "broccoli", - "carrot", - "hot dog", - "pizza", - "donut", - "cake", - "chair", - "couch", - "potted plant", - "bed", - "dining table", - "toilet", - "tv", - "laptop", - "mouse", - "remote", - "keyboard", - "cell phone", - "microwave", - "oven", - "toaster", - "sink", - "refrigerator", - "book", - "clock", - "vase", - "scissors", - "teddy bear", - "hair drier", - "toothbrush", -] -def coco80_to_coco91_class(): # converts 80-index (val2014) to 91-index (paper) - return [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90] - -__all__ = ["labels"] diff --git a/models/cv/object_detection/yolov5s/ixrt/datasets/__init__.py b/models/cv/object_detection/yolov5s/ixrt/datasets/__init__.py deleted file mode 100755 index 162e24b462289dcee7b7a2888b93fad1115def81..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/datasets/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/datasets/post_process.py b/models/cv/object_detection/yolov5s/ixrt/datasets/post_process.py deleted file mode 100755 index 8590816a0df18b6ef296ebe305b15b81240ab1d0..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/datasets/post_process.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import cv2 -import math -import numpy as np - -from .common import letterbox, scale_boxes, clip_boxes - -def get_post_process(data_process_type): - if data_process_type == "yolov5": - return Yolov5Postprocess - elif data_process_type == "yolov3": - return Yolov3Postprocess - elif data_process_type == "yolox": - return YoloxPostprocess - return None - -def Yolov3Postprocess( - ori_img_shape, - imgsz, - box_datas, - box_nums, - sample_num, - max_det=1000, -): - all_box = [] - data_offset = 0 - - box_datas = box_datas.flatten() - box_nums = box_nums.flatten() - - for i in range(sample_num): - box_num = box_nums[i] - if box_num == 0: - boxes = None - else: - cur_box = box_datas[data_offset : data_offset + box_num * 6].reshape(-1, 6) - boxes = scale_boxes( - (imgsz[0], imgsz[1]), - cur_box, - (ori_img_shape[0][i], ori_img_shape[1][i]), - use_letterbox=False - ) - # xyxy2xywh - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - - all_box.append(boxes) - data_offset += max_det * 6 - - return all_box - -def Yolov5Postprocess( - ori_img_shape, - imgsz, - box_datas, - box_nums, - sample_num, - max_det=1000, -): - all_box = [] - data_offset = 0 - - box_datas = box_datas.flatten() - box_nums = box_nums.flatten() - - for i in range(sample_num): - box_num = box_nums[i] - if box_num == 0: - boxes = None - else: - cur_box = box_datas[data_offset : data_offset + box_num * 6].reshape(-1, 6) - boxes = scale_boxes( - (imgsz[0], imgsz[1]), - cur_box, - (ori_img_shape[0][i], ori_img_shape[1][i]), - use_letterbox=True - ) - # xyxy2xywh - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - - all_box.append(boxes) - data_offset += max_det * 6 - - return all_box - -def YoloxPostprocess( - ori_img_shape, - imgsz, - box_datas, - box_nums, - sample_num, - max_det=1000, -): - all_box = [] - data_offset = 0 - box_datas = box_datas.flatten() - box_nums = box_nums.flatten() - - for i in range(sample_num): - box_num = box_nums[i] - if box_num == 0: - boxes = None - else: - boxes = box_datas[data_offset : data_offset + box_num * 6].reshape(-1, 6) - r = min(imgsz[0]/ori_img_shape[0][i], imgsz[1]/ori_img_shape[1][i]) - boxes[:, :4] /= r - # xyxy2xywh - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - clip_boxes(boxes, (ori_img_shape[0][i], ori_img_shape[1][i])) - - all_box.append(boxes) - data_offset += max_det * 6 - - return all_box \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/datasets/pre_process.py b/models/cv/object_detection/yolov5s/ixrt/datasets/pre_process.py deleted file mode 100755 index c651f8adb7c8190c214fbbbb7769c7d0713e9619..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/datasets/pre_process.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import cv2 -import math -import numpy as np - -from .common import letterbox - -def get_post_process(data_process_type): - if data_process_type == "yolov5": - return Yolov5Preprocess - elif data_process_type == "yolov3": - return Yolov3Preprocess - elif data_process_type == "yolox": - return YoloxPreprocess - return None - -def Yolov3Preprocess(image, img_size): - - h0, w0 = image.shape[:2] # orig hw - r = img_size / max(h0, w0) # ratio - - image = cv2.resize(image, (img_size, img_size)) - image = image.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - image = np.ascontiguousarray(image).astype(np.float32) / 255.0 # 0~1 np array - return image - -def Yolov5Preprocess(image, img_size, augment=False): - - h0, w0 = image.shape[:2] # orig hw - r = img_size / max(h0, w0) # ratio - - if r != 1: # if sizes are not equal - interp = cv2.INTER_LINEAR if (augment or r > 1) else cv2.INTER_AREA - image = cv2.resize(image, (math.ceil(w0 * r), math.ceil(h0 * r)), interpolation=interp) - - # shape = self.batch_shapes[self.batch[index]] if self.rect else self.img_size rect == True - - image, ratio, dwdh = letterbox(image, new_shape=img_size, auto=False, scaleup=False) - image = image.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - image = np.ascontiguousarray(image).astype(np.float32) / 255.0 # 0~1 np array - return image - -def YoloxPreprocess(img, img_size, swap=(2,0,1)): - - padded_img = np.ones((img_size, img_size, 3), dtype=np.uint8) * 114 - r = min(img_size / img.shape[0], img_size / img.shape[1]) - resized_img = cv2.resize( - img, - (int(img.shape[1] * r), int(img.shape[0] * r)), - interpolation=cv2.INTER_LINEAR, - ).astype(np.uint8) - - padded_img[: int(img.shape[0] * r), : int(img.shape[1] * r)] = resized_img - padded_img = padded_img.transpose(swap) - padded_img = np.ascontiguousarray(padded_img, dtype=np.float32) - - return padded_img \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/datasets/vision.py b/models/cv/object_detection/yolov5s/ixrt/datasets/vision.py deleted file mode 100755 index eadefb2c5b35abd0a11fa85c65891461a210aef8..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/datasets/vision.py +++ /dev/null @@ -1,151 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -from typing import Any, Callable, List, Optional, Tuple - -import torch -import torch.utils.data as data - -from types import FunctionType - -def _log_api_usage_once(obj: Any) -> None: - - """ - Logs API usage(module and name) within an organization. - In a large ecosystem, it's often useful to track the PyTorch and - TorchVision APIs usage. This API provides the similar functionality to the - logging module in the Python stdlib. It can be used for debugging purpose - to log which methods are used and by default it is inactive, unless the user - manually subscribes a logger via the `SetAPIUsageLogger method `_. - Please note it is triggered only once for the same API call within a process. - It does not collect any data from open-source users since it is no-op by default. - For more information, please refer to - * PyTorch note: https://pytorch.org/docs/stable/notes/large_scale_deployments.html#api-usage-logging; - * Logging policy: https://github.com/pytorch/vision/issues/5052; - - Args: - obj (class instance or method): an object to extract info from. - """ - module = obj.__module__ - if not module.startswith("torchvision"): - module = f"torchvision.internal.{module}" - name = obj.__class__.__name__ - if isinstance(obj, FunctionType): - name = obj.__name__ - torch._C._log_api_usage_once(f"{module}.{name}") - -class VisionDataset(data.Dataset): - """ - Base Class For making datasets which are compatible with torchvision. - It is necessary to override the ``__getitem__`` and ``__len__`` method. - - Args: - root (string): Root directory of dataset. - transforms (callable, optional): A function/transforms that takes in - an image and a label and returns the transformed versions of both. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.RandomCrop`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - - .. note:: - - :attr:`transforms` and the combination of :attr:`transform` and :attr:`target_transform` are mutually exclusive. - """ - - _repr_indent = 4 - - def __init__( - self, - root: str, - transforms: Optional[Callable] = None, - transform: Optional[Callable] = None, - target_transform: Optional[Callable] = None, - ) -> None: - _log_api_usage_once(self) - if isinstance(root, str): - root = os.path.expanduser(root) - self.root = root - - has_transforms = transforms is not None - has_separate_transform = transform is not None or target_transform is not None - if has_transforms and has_separate_transform: - raise ValueError("Only transforms or transform/target_transform can be passed as argument") - - # for backwards-compatibility - self.transform = transform - self.target_transform = target_transform - - if has_separate_transform: - transforms = StandardTransform(transform, target_transform) - self.transforms = transforms - - def __getitem__(self, index: int) -> Any: - """ - Args: - index (int): Index - - Returns: - (Any): Sample and meta data, optionally transformed by the respective transforms. - """ - raise NotImplementedError - - def __len__(self) -> int: - raise NotImplementedError - - def __repr__(self) -> str: - head = "Dataset " + self.__class__.__name__ - body = [f"Number of datapoints: {self.__len__()}"] - if self.root is not None: - body.append(f"Root location: {self.root}") - body += self.extra_repr().splitlines() - if hasattr(self, "transforms") and self.transforms is not None: - body += [repr(self.transforms)] - lines = [head] + [" " * self._repr_indent + line for line in body] - return "\n".join(lines) - - def _format_transform_repr(self, transform: Callable, head: str) -> List[str]: - lines = transform.__repr__().splitlines() - return [f"{head}{lines[0]}"] + ["{}{}".format(" " * len(head), line) for line in lines[1:]] - - def extra_repr(self) -> str: - return "" - - -class StandardTransform: - def __init__(self, transform: Optional[Callable] = None, target_transform: Optional[Callable] = None) -> None: - self.transform = transform - self.target_transform = target_transform - - def __call__(self, input: Any, target: Any) -> Tuple[Any, Any]: - if self.transform is not None: - input = self.transform(input) - if self.target_transform is not None: - target = self.target_transform(target) - return input, target - - def _format_transform_repr(self, transform: Callable, head: str) -> List[str]: - lines = transform.__repr__().splitlines() - return [f"{head}{lines[0]}"] + ["{}{}".format(" " * len(head), line) for line in lines[1:]] - - def __repr__(self) -> str: - body = [self.__class__.__name__] - if self.transform is not None: - body += self._format_transform_repr(self.transform, "Transform: ") - if self.target_transform is not None: - body += self._format_transform_repr(self.target_transform, "Target transform: ") - - return "\n".join(body) diff --git a/models/cv/object_detection/yolov5s/ixrt/load_ixrt_plugin.py b/models/cv/object_detection/yolov5s/ixrt/load_ixrt_plugin.py deleted file mode 100644 index ae47dc8e854b6bea1f768e65c4dd481048bfebce..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/load_ixrt_plugin.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ctypes -import tensorrt -from os.path import join, dirname, exists -def load_ixrt_plugin(logger=tensorrt.Logger(tensorrt.Logger.INFO), namespace="", dynamic_path=""): - if not dynamic_path: - dynamic_path = join(dirname(tensorrt.__file__), "lib", "libixrt_plugin.so") - if not exists(dynamic_path): - raise FileNotFoundError( - f"The ixrt_plugin lib {dynamic_path} is not existed, please provided effective plugin path!") - ctypes.CDLL(dynamic_path) - tensorrt.init_libnvinfer_plugins(logger, namespace) - print(f"Loaded plugin from {dynamic_path}") \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/quant.py b/models/cv/object_detection/yolov5s/ixrt/quant.py deleted file mode 100644 index 36fd39a13c2e1e40f4dc0098f042e66e4bd0d26a..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/quant.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import random -import argparse -import numpy as np -from tensorrt.deploy import static_quantize - -import torch -from calibration_dataset import create_dataloaders - -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("--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("--seed", type=int, default=42) - parser.add_argument("--imgsz", type=int, default=640) - args = parser.parse_args() - return args - -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, - step=args.step, - data_process_type=args.data_process_type -) -# print("disable_quant_names : ", args.disable_quant_names) -static_quantize(args.model, - calibration_dataloader=dataloader, - save_quant_onnx_path=os.path.join(out_dir, f"quantized_{model_name}.onnx"), - observer=args.observer, - data_preprocess=lambda x: x[0].to("cuda"), - quant_format="qdq", - disable_quant_names=args.disable_quant_names) \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/requirements.txt b/models/cv/object_detection/yolov5s/ixrt/requirements.txt deleted file mode 100644 index b1a10ab060644ea96d6ad77b36dbc4367a632591..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -tqdm -onnx -onnxsim -ultralytics==8.3.97 -pycocotools -pycuda \ No newline at end of file diff --git a/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_fp16_accuracy.sh b/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_fp16_accuracy.sh index 81b32fd1ec2538faad36dc432817cd8036032a95..52ec959f1ea4b6b192b111c5b837904183d17876 100644 --- a/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_fp16_accuracy.sh +++ b/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_fp16_accuracy.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() @@ -48,8 +34,6 @@ ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} -echo COCO_GT : ${COCO_GT} -echo EVAL_DIR : ${EVAL_DIR} echo RUN_DIR : ${RUN_DIR} echo CONFIG_DIR : ${CONFIG_DIR} echo ====================== Model Info ====================== @@ -98,7 +82,7 @@ if [ $PRECISION == "int8" ];then echo; echo [STEP ${step}] : Quant Model if [[ -z ${QUANT_EXIST_ONNX} ]];then - QUANT_EXIST_ONNX=${CHECKPOINTS_DIR}/quantized_${MODEL_NAME}.onnx + QUANT_EXIST_ONNX=$CHECKPOINTS_DIR/quantized_${MODEL_NAME}.onnx fi if [[ -f ${QUANT_EXIST_ONNX} ]];then CURRENT_MODEL=${QUANT_EXIST_ONNX} @@ -112,7 +96,7 @@ if [ $PRECISION == "int8" ];then --data_process_type ${DATA_PROCESS_TYPE} \ --observer ${QUANT_OBSERVER} \ --disable_quant_names ${DISABLE_QUANT_LIST[@]} \ - --save_dir ${CHECKPOINTS_DIR} \ + --save_dir $CHECKPOINTS_DIR \ --bsz ${QUANT_BATCHSIZE} \ --step ${QUANT_STEP} \ --seed ${QUANT_SEED} \ diff --git a/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_fp16_performance.sh b/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_fp16_performance.sh index 4ab4f9e413d156ac4b2b669240f55f09cf5eb14a..5e2f97fb43b1480fcce35669e7d2346f63eb64a8 100644 --- a/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_fp16_performance.sh +++ b/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_fp16_performance.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() @@ -48,8 +34,6 @@ ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} -echo COCO_GT : ${COCO_GT} -echo EVAL_DIR : ${EVAL_DIR} echo RUN_DIR : ${RUN_DIR} echo CONFIG_DIR : ${CONFIG_DIR} echo ====================== Model Info ====================== @@ -112,7 +96,7 @@ if [ $PRECISION == "int8" ];then --data_process_type ${DATA_PROCESS_TYPE} \ --observer ${QUANT_OBSERVER} \ --disable_quant_names ${DISABLE_QUANT_LIST[@]} \ - --save_dir ${CHECKPOINTS_DIR} \ + --save_dir $CHECKPOINTS_DIR \ --bsz ${QUANT_BATCHSIZE} \ --step ${QUANT_STEP} \ --seed ${QUANT_SEED} \ diff --git a/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_int8_accuracy.sh b/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_int8_accuracy.sh index fc7988dfd37e36039a8d1d835dbc558d9da2ffe5..606fc94c8c7f11a517b7bf3fe1fcf22ccb6d68d1 100644 --- a/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_int8_accuracy.sh +++ b/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_int8_accuracy.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() @@ -48,8 +34,6 @@ ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} -echo COCO_GT : ${COCO_GT} -echo EVAL_DIR : ${EVAL_DIR} echo RUN_DIR : ${RUN_DIR} echo CONFIG_DIR : ${CONFIG_DIR} echo ====================== Model Info ====================== @@ -98,7 +82,7 @@ if [ $PRECISION == "int8" ];then echo; echo [STEP ${step}] : Quant Model if [[ -z ${QUANT_EXIST_ONNX} ]];then - QUANT_EXIST_ONNX=${CHECKPOINTS_DIR}/quantized_${MODEL_NAME}.onnx + QUANT_EXIST_ONNX=$CHECKPOINTS_DIR/quantized_${MODEL_NAME}.onnx fi if [[ -f ${QUANT_EXIST_ONNX} ]];then CURRENT_MODEL=${QUANT_EXIST_ONNX} @@ -112,7 +96,7 @@ if [ $PRECISION == "int8" ];then --data_process_type ${DATA_PROCESS_TYPE} \ --observer ${QUANT_OBSERVER} \ --disable_quant_names ${DISABLE_QUANT_LIST[@]} \ - --save_dir ${CHECKPOINTS_DIR} \ + --save_dir $CHECKPOINTS_DIR \ --bsz ${QUANT_BATCHSIZE} \ --step ${QUANT_STEP} \ --seed ${QUANT_SEED} \ diff --git a/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_int8_performance.sh b/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_int8_performance.sh index dc912fa9873e9ced8683a41c6f9600a8e5a80b62..b29836695881a184603d63159e0872c508d94486 100644 --- a/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_int8_performance.sh +++ b/models/cv/object_detection/yolov5s/ixrt/scripts/infer_yolov5s_int8_performance.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() @@ -48,8 +34,6 @@ ORIGINE_MODEL=${CHECKPOINTS_DIR}/${ORIGINE_MODEL} echo CHECKPOINTS_DIR : ${CHECKPOINTS_DIR} echo DATASETS_DIR : ${DATASETS_DIR} -echo COCO_GT : ${COCO_GT} -echo EVAL_DIR : ${EVAL_DIR} echo RUN_DIR : ${RUN_DIR} echo CONFIG_DIR : ${CONFIG_DIR} echo ====================== Model Info ====================== @@ -113,7 +97,7 @@ if [ $PRECISION == "int8" ];then --data_process_type ${DATA_PROCESS_TYPE} \ --observer ${QUANT_OBSERVER} \ --disable_quant_names ${DISABLE_QUANT_LIST[@]} \ - --save_dir ${CHECKPOINTS_DIR} \ + --save_dir $CHECKPOINTS_DIR \ --bsz ${QUANT_BATCHSIZE} \ --step ${QUANT_STEP} \ --seed ${QUANT_SEED} \ diff --git a/models/cv/object_detection/yolov5s/ixrt/simplify_model.py b/models/cv/object_detection/yolov5s/ixrt/simplify_model.py deleted file mode 100644 index 1400fd81ddb4b3fae1b20d0fd35082a692f5d292..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov5s/ixrt/simplify_model.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -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 diff --git a/models/cv/object_detection/yolov7/ixrt/README.md b/models/cv/object_detection/yolov7/ixrt/README.md index b366ce6e10956385815e45002227931df0cc73a6..8ff917cc0f74b5a72c4f60e9818a932fd24f5f87 100644 --- a/models/cv/object_detection/yolov7/ixrt/README.md +++ b/models/cv/object_detection/yolov7/ixrt/README.md @@ -30,7 +30,7 @@ yum install -y mesa-libGL ## Ubuntu apt install -y libgl1-mesa-glx -pip3 install -r requirements.txt +pip3 install -r ../../ixrt_common/requirements.txt ``` ### Model Conversion @@ -47,13 +47,13 @@ mv yolov7.onnx /Path/to/checkpoints/yolov7m.onnx ## Model Inference ```bash -export PROJ_DIR=/Path/to/yolov7/ixrt -export DATASETS_DIR=/Path/to/coco2017/ +export PROJ_DIR=./ +export DATASETS_DIR=/Path/to/coco/ export CHECKPOINTS_DIR=./checkpoints export COCO_GT=${DATASETS_DIR}/annotations/instances_val2017.json -export EVAL_DIR=${DATASETS_DIR}/val2017 -export RUN_DIR=/Path/to/yolov7/ixrt -export CONFIG_DIR=config/YOLOV7_CONFIG +export EVAL_DIR=${DATASETS_DIR}/images/val2017 +export RUN_DIR=../../ixrt_common +export CONFIG_DIR=../../ixrt_common/config/YOLOV7_CONFIG ``` ### FP16 diff --git a/models/cv/object_detection/yolov7/ixrt/build_nms_engine.py b/models/cv/object_detection/yolov7/ixrt/build_nms_engine.py deleted file mode 100644 index 3be0d83d0d966018f59b87d22f628b9b1ddf9b21..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/build_nms_engine.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import argparse -import torch -import onnx -from onnx import helper -from onnx import TensorProto, numpy_helper -import tensorrt - -def create_onnx(args): - nms = helper.make_node( - "NMS", - name="NMS", - inputs=["nms_input"], - outputs=["nms_output0", "nms_output1"], - nMaxKeep=args.max_box_pre_img, - fIoUThresh=args.iou_thresh, - fScoreThresh=args.score_thresh - ) - graph = helper.make_graph( - nodes=[nms], - name="gpu_nms", - inputs=[ - helper.make_tensor_value_info( - "nms_input", onnx.TensorProto.FLOAT, (args.bsz, args.all_box_num, 6) - ) - ], - outputs=[ - helper.make_tensor_value_info( - "nms_output0", onnx.TensorProto.FLOAT, (args.bsz, args.max_box_pre_img, 6) - ), - helper.make_tensor_value_info( - "nms_output1", onnx.TensorProto.INT32, (args.bsz,) - ) - ], - initializer=[] - ) - - op = onnx.OperatorSetIdProto() - op.version = 13 - model = onnx.helper.make_model(graph) - - model = onnx.helper.make_model(graph, opset_imports=[op]) - onnx_path = args.path + "/nms.onnx" - onnx.save(model, onnx_path) - -def build_engine(args): - onnx_path = args.path + "/nms.onnx" - IXRT_LOGGER = tensorrt.Logger(tensorrt.Logger.WARNING) - builder = tensorrt.Builder(IXRT_LOGGER) - EXPLICIT_BATCH = 1 << (int)(tensorrt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) - network = builder.create_network(EXPLICIT_BATCH) - build_config = builder.create_builder_config() - parser = tensorrt.OnnxParser(network, IXRT_LOGGER) - parser.parse_from_file(onnx_path) - plan = builder.build_serialized_network(network, build_config) - - engine_path = args.path + "/nms.engine" - with open(engine_path, "wb") as f: - f.write(plan) - -def main(args): - create_onnx(args) - build_engine(args) - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--bsz", type=int, default=1, help="batch size") - parser.add_argument("--path", type=str) - parser.add_argument("--all_box_num", type=int, default=25200) - parser.add_argument("--max_box_pre_img", type=int, default=1000) - parser.add_argument("--iou_thresh", type=float, default=0.6) - parser.add_argument("--score_thresh", type=float, default=0.001) - - args = parser.parse_args() - return args - -if __name__ == "__main__": - args = parse_args() - main(args) \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/calibration_dataset.py b/models/cv/object_detection/yolov7/ixrt/calibration_dataset.py deleted file mode 100644 index de37775a0c617fdefca4342423a6a47bdc9b9c41..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/calibration_dataset.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -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/yolov7/ixrt/ci/prepare.sh b/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh index 310566fb8b6ddbba24aecc3fdace7d7146063f3d..611fcd19698a0d5642730f04c95da79f27711711 100644 --- a/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh +++ b/models/cv/object_detection/yolov7/ixrt/ci/prepare.sh @@ -25,7 +25,7 @@ else echo "Not Support Os" fi -pip3 install -r requirements.txt +pip3 install -r ../../ixrt_common/requirements.txt mkdir -p checkpoints cp -r /root/data/3rd_party/yolov7 ./ cd yolov7 diff --git a/models/cv/object_detection/yolov7/ixrt/coco_labels.py b/models/cv/object_detection/yolov7/ixrt/coco_labels.py deleted file mode 100644 index 43f5bd82cd257efdcab2bdba6bad64d9bb90416e..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/coco_labels.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -labels = [ - "person", - "bicycle", - "car", - "motorcycle", - "airplane", - "bus", - "train", - "truck", - "boat", - "traffic light", - "fire hydrant", - "stop sign", - "parking meter", - "bench", - "bird", - "cat", - "dog", - "horse", - "sheep", - "cow", - "elephant", - "bear", - "zebra", - "giraffe", - "backpack", - "umbrella", - "handbag", - "tie", - "suitcase", - "frisbee", - "skis", - "snowboard", - "sports ball", - "kite", - "baseball bat", - "baseball glove", - "skateboard", - "surfboard", - "tennis racket", - "bottle", - "wine glass", - "cup", - "fork", - "knife", - "spoon", - "bowl", - "banana", - "apple", - "sandwich", - "orange", - "broccoli", - "carrot", - "hot dog", - "pizza", - "donut", - "cake", - "chair", - "couch", - "potted plant", - "bed", - "dining table", - "toilet", - "tv", - "laptop", - "mouse", - "remote", - "keyboard", - "cell phone", - "microwave", - "oven", - "toaster", - "sink", - "refrigerator", - "book", - "clock", - "vase", - "scissors", - "teddy bear", - "hair drier", - "toothbrush", -] -def coco80_to_coco91_class(): # converts 80-index (val2014) to 91-index (paper) - return [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90] - -__all__ = ["labels"] diff --git a/models/cv/object_detection/yolov7/ixrt/common.py b/models/cv/object_detection/yolov7/ixrt/common.py deleted file mode 100644 index aba2117c9942d6823abf73bf3ab94c291a7705e2..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/common.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import numpy as np -from tqdm import tqdm - -import tensorrt -import pycuda.driver as cuda - -# input : [bsz, box_num, 5(cx, cy, w, h, conf) + class_num(prob[0], prob[1], ...)] -# output : [bsz, box_num, 6(left_top_x, left_top_y, right_bottom_x, right_bottom_y, class_id, max_prob*conf)] -def box_class85to6(input): - center_x_y = input[:, :2] - side = input[:, 2:4] - conf = input[:, 4:5] - class_id = np.argmax(input[:, 5:], axis = -1) - class_id = class_id.astype(np.float32).reshape(-1, 1) + 1 - max_prob = np.max(input[:, 5:], axis = -1).reshape(-1, 1) - x1_y1 = center_x_y - 0.5 * side - x2_y2 = center_x_y + 0.5 * side - nms_input = np.concatenate([x1_y1, x2_y2, class_id, max_prob*conf], axis = -1) - return nms_input - -def save2json(batch_img_id, pred_boxes, json_result, class_trans): - for i, boxes in enumerate(pred_boxes): - if boxes is not None: - image_id = int(batch_img_id[i]) - # have no target - if image_id == -1: - continue - for x, y, w, h, c, p in boxes: - x, y, w, h, p = float(x), float(y), float(w), float(h), float(p) - c = int(c) - json_result.append( - { - "image_id": image_id, - "category_id": class_trans[c - 1], - "bbox": [x, y, w, h], - "score": p, - } - ) - -def create_engine_context(engine_path, logger): - with open(engine_path, "rb") as f: - runtime = tensorrt.Runtime(logger) - assert runtime - engine = runtime.deserialize_cuda_engine(f.read()) - assert engine - context = engine.create_execution_context() - assert context - - return engine, context - -def get_io_bindings(engine): - # Setup I/O bindings - inputs = [] - outputs = [] - allocations = [] - - for i in range(engine.num_bindings): - is_input = False - if engine.binding_is_input(i): - is_input = True - name = engine.get_binding_name(i) - dtype = engine.get_binding_dtype(i) - shape = engine.get_binding_shape(i) - if is_input: - batch_size = shape[0] - size = np.dtype(tensorrt.nptype(dtype)).itemsize - for s in shape: - size *= s - allocation = cuda.mem_alloc(size) - binding = { - "index": i, - "name": name, - "dtype": np.dtype(tensorrt.nptype(dtype)), - "shape": list(shape), - "allocation": allocation, - } - print(f"binding {i}, name : {name} dtype : {np.dtype(tensorrt.nptype(dtype))} shape : {list(shape)}") - allocations.append(allocation) - if engine.binding_is_input(i): - inputs.append(binding) - else: - outputs.append(binding) - return inputs, outputs, allocations \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/cut_model.py b/models/cv/object_detection/yolov7/ixrt/cut_model.py deleted file mode 100644 index e9ee19aadf0809fe1b97e3225d09150fb54513f7..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/cut_model.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import onnx -import argparse -from onnxsim import simplify - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--input_model", type=str) - parser.add_argument("--output_model", type=str) - parser.add_argument("--input_names", nargs='+', type=str) - parser.add_argument("--output_names", nargs='+', type=str) - args = parser.parse_args() - return args - -args = parse_args() -onnx.utils.extract_model(args.input_model, args.output_model, args.input_names, args.output_names) -print(" Cut Model Done.") \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/datasets/__init__.py b/models/cv/object_detection/yolov7/ixrt/datasets/__init__.py deleted file mode 100644 index 162e24b462289dcee7b7a2888b93fad1115def81..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/datasets/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/datasets/coco.py b/models/cv/object_detection/yolov7/ixrt/datasets/coco.py deleted file mode 100644 index 73c5df54761b917ecd0127fb56b61d9bd34c1196..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/datasets/coco.py +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os.path -from typing import Any, Callable, List, Optional, Tuple - -import cv2 - -from .vision import VisionDataset -from .pre_process import get_post_process -class CocoDetection(VisionDataset): - """`MS Coco Detection `_ Dataset. - - It requires the `COCO API to be installed `_. - - Args: - root (string): Root directory where images are downloaded to. - annFile (string): Path to json annotation file. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.PILToTensor`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - transforms (callable, optional): A function/transform that takes input sample and its target as entry - and returns a transformed version. - """ - - def __init__( - self, - root: str, - annFile: str, - img_size: int, - data_process_type: str, - transform: Optional[Callable] = None, - target_transform: Optional[Callable] = None, - transforms: Optional[Callable] = None, - - ) -> None: - super().__init__(root, transforms, transform, target_transform) - from pycocotools.coco import COCO - - self.coco = COCO(annFile) - self.ids = list(sorted(self.coco.imgs.keys())) - self.img_size = img_size - - self.transforms = get_post_process(data_process_type) - - def _load_image(self, id: int): - path = self.coco.loadImgs(id)[0]["file_name"] - data = cv2.imread(os.path.join(self.root, path)) - return data - - def _load_target(self, id: int) -> List[Any]: - return self.coco.loadAnns(self.coco.getAnnIds(id)) - - def __getitem__(self, index: int) -> Tuple[Any, Any]: - id = self.ids[index] - image = self._load_image(id) - target = self._load_target(id) - origin_shape = image.shape[:2] - - if self.transforms is not None: - image = self.transforms(image, self.img_size) - - if len(target) > 0: - image_id = target[0]["image_id"] - else: - # have no target - image_id = -1 - return image, origin_shape, image_id - - def __len__(self) -> int: - return len(self.ids) - - -class CocoCaptions(CocoDetection): - """`MS Coco Captions `_ Dataset. - - It requires the `COCO API to be installed `_. - - Args: - root (string): Root directory where images are downloaded to. - annFile (string): Path to json annotation file. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.PILToTensor`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - transforms (callable, optional): A function/transform that takes input sample and its target as entry - and returns a transformed version. - - Example: - - .. code:: python - - import torchvision.datasets as dset - import torchvision.transforms as transforms - cap = dset.CocoCaptions(root = 'dir where images are', - annFile = 'json annotation file', - transform=transforms.PILToTensor()) - - print('Number of samples: ', len(cap)) - img, target = cap[3] # load 4th sample - - print("Image Size: ", img.size()) - print(target) - - Output: :: - - Number of samples: 82783 - Image Size: (3L, 427L, 640L) - [u'A plane emitting smoke stream flying over a mountain.', - u'A plane darts across a bright blue sky behind a mountain covered in snow', - u'A plane leaves a contrail above the snowy mountain top.', - u'A mountain that has a plane flying overheard in the distance.', - u'A mountain view with a plume of smoke in the background'] - - """ - - def _load_target(self, id: int) -> List[str]: - return [ann["caption"] for ann in super()._load_target(id)] diff --git a/models/cv/object_detection/yolov7/ixrt/datasets/common.py b/models/cv/object_detection/yolov7/ixrt/datasets/common.py deleted file mode 100644 index ef36eba394917bc05af46f33be48463df50f540d..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/datasets/common.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import cv2 -import math -import numpy as np - -def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32): - # Resize and pad image while meeting stride-multiple constraints - shape = im.shape[:2] # current shape [height, width] - if isinstance(new_shape, int): - new_shape = (new_shape, new_shape) - - # Scale ratio (new / old) - r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) - if not scaleup: # only scale down, do not scale up (for better val mAP) - r = min(r, 1.0) - - # Compute padding - ratio = r, r # width, height ratios - new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) - dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding - if auto: # minimum rectangle - dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding - elif scaleFill: # stretch - dw, dh = 0.0, 0.0 - new_unpad = (new_shape[1], new_shape[0]) - ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios - - dw /= 2 # divide padding into 2 sides - dh /= 2 - - if shape[::-1] != new_unpad: # resize - im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR) - top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) - left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) - im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border - return im, ratio, (dw, dh) - -def scale_boxes(net_shape, boxes, ori_shape, use_letterbox=False): - # Rescale boxes (xyxy) from net_shape to ori_shape - - if use_letterbox: - - gain = min( - net_shape[0] / ori_shape[0], net_shape[1] / ori_shape[1] - ) # gain = new / old - pad = (net_shape[1] - ori_shape[1] * gain) / 2, ( - net_shape[0] - ori_shape[0] * gain - ) / 2.0 - - boxes[:, [0, 2]] -= pad[0] # x padding - boxes[:, [1, 3]] -= pad[1] # y padding - boxes[:, :4] /= gain - else: - x_scale, y_scale = net_shape[1] / ori_shape[1], net_shape[0] / ori_shape[0] - - boxes[:, 0] /= x_scale - boxes[:, 1] /= y_scale - boxes[:, 2] /= x_scale - boxes[:, 3] /= y_scale - - clip_boxes(boxes, ori_shape) - return boxes - -def clip_boxes(boxes, shape): - - boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1]) # x1, x2 - boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2 \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/datasets/post_process.py b/models/cv/object_detection/yolov7/ixrt/datasets/post_process.py deleted file mode 100644 index 8590816a0df18b6ef296ebe305b15b81240ab1d0..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/datasets/post_process.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import cv2 -import math -import numpy as np - -from .common import letterbox, scale_boxes, clip_boxes - -def get_post_process(data_process_type): - if data_process_type == "yolov5": - return Yolov5Postprocess - elif data_process_type == "yolov3": - return Yolov3Postprocess - elif data_process_type == "yolox": - return YoloxPostprocess - return None - -def Yolov3Postprocess( - ori_img_shape, - imgsz, - box_datas, - box_nums, - sample_num, - max_det=1000, -): - all_box = [] - data_offset = 0 - - box_datas = box_datas.flatten() - box_nums = box_nums.flatten() - - for i in range(sample_num): - box_num = box_nums[i] - if box_num == 0: - boxes = None - else: - cur_box = box_datas[data_offset : data_offset + box_num * 6].reshape(-1, 6) - boxes = scale_boxes( - (imgsz[0], imgsz[1]), - cur_box, - (ori_img_shape[0][i], ori_img_shape[1][i]), - use_letterbox=False - ) - # xyxy2xywh - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - - all_box.append(boxes) - data_offset += max_det * 6 - - return all_box - -def Yolov5Postprocess( - ori_img_shape, - imgsz, - box_datas, - box_nums, - sample_num, - max_det=1000, -): - all_box = [] - data_offset = 0 - - box_datas = box_datas.flatten() - box_nums = box_nums.flatten() - - for i in range(sample_num): - box_num = box_nums[i] - if box_num == 0: - boxes = None - else: - cur_box = box_datas[data_offset : data_offset + box_num * 6].reshape(-1, 6) - boxes = scale_boxes( - (imgsz[0], imgsz[1]), - cur_box, - (ori_img_shape[0][i], ori_img_shape[1][i]), - use_letterbox=True - ) - # xyxy2xywh - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - - all_box.append(boxes) - data_offset += max_det * 6 - - return all_box - -def YoloxPostprocess( - ori_img_shape, - imgsz, - box_datas, - box_nums, - sample_num, - max_det=1000, -): - all_box = [] - data_offset = 0 - box_datas = box_datas.flatten() - box_nums = box_nums.flatten() - - for i in range(sample_num): - box_num = box_nums[i] - if box_num == 0: - boxes = None - else: - boxes = box_datas[data_offset : data_offset + box_num * 6].reshape(-1, 6) - r = min(imgsz[0]/ori_img_shape[0][i], imgsz[1]/ori_img_shape[1][i]) - boxes[:, :4] /= r - # xyxy2xywh - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - clip_boxes(boxes, (ori_img_shape[0][i], ori_img_shape[1][i])) - - all_box.append(boxes) - data_offset += max_det * 6 - - return all_box \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/datasets/pre_process.py b/models/cv/object_detection/yolov7/ixrt/datasets/pre_process.py deleted file mode 100644 index c651f8adb7c8190c214fbbbb7769c7d0713e9619..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/datasets/pre_process.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import cv2 -import math -import numpy as np - -from .common import letterbox - -def get_post_process(data_process_type): - if data_process_type == "yolov5": - return Yolov5Preprocess - elif data_process_type == "yolov3": - return Yolov3Preprocess - elif data_process_type == "yolox": - return YoloxPreprocess - return None - -def Yolov3Preprocess(image, img_size): - - h0, w0 = image.shape[:2] # orig hw - r = img_size / max(h0, w0) # ratio - - image = cv2.resize(image, (img_size, img_size)) - image = image.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - image = np.ascontiguousarray(image).astype(np.float32) / 255.0 # 0~1 np array - return image - -def Yolov5Preprocess(image, img_size, augment=False): - - h0, w0 = image.shape[:2] # orig hw - r = img_size / max(h0, w0) # ratio - - if r != 1: # if sizes are not equal - interp = cv2.INTER_LINEAR if (augment or r > 1) else cv2.INTER_AREA - image = cv2.resize(image, (math.ceil(w0 * r), math.ceil(h0 * r)), interpolation=interp) - - # shape = self.batch_shapes[self.batch[index]] if self.rect else self.img_size rect == True - - image, ratio, dwdh = letterbox(image, new_shape=img_size, auto=False, scaleup=False) - image = image.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - image = np.ascontiguousarray(image).astype(np.float32) / 255.0 # 0~1 np array - return image - -def YoloxPreprocess(img, img_size, swap=(2,0,1)): - - padded_img = np.ones((img_size, img_size, 3), dtype=np.uint8) * 114 - r = min(img_size / img.shape[0], img_size / img.shape[1]) - resized_img = cv2.resize( - img, - (int(img.shape[1] * r), int(img.shape[0] * r)), - interpolation=cv2.INTER_LINEAR, - ).astype(np.uint8) - - padded_img[: int(img.shape[0] * r), : int(img.shape[1] * r)] = resized_img - padded_img = padded_img.transpose(swap) - padded_img = np.ascontiguousarray(padded_img, dtype=np.float32) - - return padded_img \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/datasets/vision.py b/models/cv/object_detection/yolov7/ixrt/datasets/vision.py deleted file mode 100644 index eadefb2c5b35abd0a11fa85c65891461a210aef8..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/datasets/vision.py +++ /dev/null @@ -1,151 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -from typing import Any, Callable, List, Optional, Tuple - -import torch -import torch.utils.data as data - -from types import FunctionType - -def _log_api_usage_once(obj: Any) -> None: - - """ - Logs API usage(module and name) within an organization. - In a large ecosystem, it's often useful to track the PyTorch and - TorchVision APIs usage. This API provides the similar functionality to the - logging module in the Python stdlib. It can be used for debugging purpose - to log which methods are used and by default it is inactive, unless the user - manually subscribes a logger via the `SetAPIUsageLogger method `_. - Please note it is triggered only once for the same API call within a process. - It does not collect any data from open-source users since it is no-op by default. - For more information, please refer to - * PyTorch note: https://pytorch.org/docs/stable/notes/large_scale_deployments.html#api-usage-logging; - * Logging policy: https://github.com/pytorch/vision/issues/5052; - - Args: - obj (class instance or method): an object to extract info from. - """ - module = obj.__module__ - if not module.startswith("torchvision"): - module = f"torchvision.internal.{module}" - name = obj.__class__.__name__ - if isinstance(obj, FunctionType): - name = obj.__name__ - torch._C._log_api_usage_once(f"{module}.{name}") - -class VisionDataset(data.Dataset): - """ - Base Class For making datasets which are compatible with torchvision. - It is necessary to override the ``__getitem__`` and ``__len__`` method. - - Args: - root (string): Root directory of dataset. - transforms (callable, optional): A function/transforms that takes in - an image and a label and returns the transformed versions of both. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.RandomCrop`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - - .. note:: - - :attr:`transforms` and the combination of :attr:`transform` and :attr:`target_transform` are mutually exclusive. - """ - - _repr_indent = 4 - - def __init__( - self, - root: str, - transforms: Optional[Callable] = None, - transform: Optional[Callable] = None, - target_transform: Optional[Callable] = None, - ) -> None: - _log_api_usage_once(self) - if isinstance(root, str): - root = os.path.expanduser(root) - self.root = root - - has_transforms = transforms is not None - has_separate_transform = transform is not None or target_transform is not None - if has_transforms and has_separate_transform: - raise ValueError("Only transforms or transform/target_transform can be passed as argument") - - # for backwards-compatibility - self.transform = transform - self.target_transform = target_transform - - if has_separate_transform: - transforms = StandardTransform(transform, target_transform) - self.transforms = transforms - - def __getitem__(self, index: int) -> Any: - """ - Args: - index (int): Index - - Returns: - (Any): Sample and meta data, optionally transformed by the respective transforms. - """ - raise NotImplementedError - - def __len__(self) -> int: - raise NotImplementedError - - def __repr__(self) -> str: - head = "Dataset " + self.__class__.__name__ - body = [f"Number of datapoints: {self.__len__()}"] - if self.root is not None: - body.append(f"Root location: {self.root}") - body += self.extra_repr().splitlines() - if hasattr(self, "transforms") and self.transforms is not None: - body += [repr(self.transforms)] - lines = [head] + [" " * self._repr_indent + line for line in body] - return "\n".join(lines) - - def _format_transform_repr(self, transform: Callable, head: str) -> List[str]: - lines = transform.__repr__().splitlines() - return [f"{head}{lines[0]}"] + ["{}{}".format(" " * len(head), line) for line in lines[1:]] - - def extra_repr(self) -> str: - return "" - - -class StandardTransform: - def __init__(self, transform: Optional[Callable] = None, target_transform: Optional[Callable] = None) -> None: - self.transform = transform - self.target_transform = target_transform - - def __call__(self, input: Any, target: Any) -> Tuple[Any, Any]: - if self.transform is not None: - input = self.transform(input) - if self.target_transform is not None: - target = self.target_transform(target) - return input, target - - def _format_transform_repr(self, transform: Callable, head: str) -> List[str]: - lines = transform.__repr__().splitlines() - return [f"{head}{lines[0]}"] + ["{}{}".format(" " * len(head), line) for line in lines[1:]] - - def __repr__(self) -> str: - body = [self.__class__.__name__] - if self.transform is not None: - body += self._format_transform_repr(self.transform, "Transform: ") - if self.target_transform is not None: - body += self._format_transform_repr(self.target_transform, "Target transform: ") - - return "\n".join(body) diff --git a/models/cv/object_detection/yolov7/ixrt/deploy.py b/models/cv/object_detection/yolov7/ixrt/deploy.py deleted file mode 100644 index 8c2cc424f699e01bc88dab98a29dc4c83e4d9b9e..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/deploy.py +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# !/usr/bin/env python -# -*- coding: utf-8 -*- -import argparse -from tensorrt.deploy.api import GraphTransform, create_source, create_target - -class Transform: - def __init__(self, graph): - self.t = GraphTransform(graph) - self.graph = graph - - def ReplaceFocus(self, input_edge, outputs, to_op): - input_var = self.graph.get_variable(input_edge) - op = self.graph.get_operator(to_op) - self.t.delete_operators_between_var_op( - from_var=input_var, to_op=op - ) - self.t.make_operator( - "Focus", inputs=input_edge, outputs=outputs - ) - return self.graph - - def AddYoloDecoderOp(self, inputs: list, outputs: list, op_type, **attributes): - if attributes["anchor"] is None: - del attributes["anchor"] - self.t.make_operator( - op_type, inputs=inputs, outputs=outputs, **attributes - ) - return self.graph - - def AddConcatOp(self, inputs: list, outputs, **attributes): - self.t.make_operator( - "Concat", inputs=inputs, outputs=outputs, **attributes - ) - return self.graph - -def customize_ops(graph, args): - t = Transform(graph) - fuse_focus = args.focus_input is not None and args.focus_output is not None and args.focus_last_node is not None - if fuse_focus: - graph = t.ReplaceFocus( - input_edge=args.focus_input, - outputs=args.focus_output, - to_op=args.focus_last_node - ) - decoder_input = args.decoder_input_names - num = len(decoder_input) // 3 - graph = t.AddYoloDecoderOp( - inputs=decoder_input[:num], - outputs=["decoder_8"], - op_type=args.decoder_type, - anchor=args.decoder8_anchor, - num_class=args.num_class, - stride=8, - faster_impl=args.faster - ) - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num:num*2], - outputs=["decoder_16"], - op_type=args.decoder_type, - anchor=args.decoder16_anchor, - num_class=args.num_class, - stride=16, - faster_impl=args.faster - ) - - if args.decoder64_anchor is not None: - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num*2:num*2+1], - outputs=["decoder_32"], - op_type=args.decoder_type, - anchor=args.decoder32_anchor, - num_class=args.num_class, - stride=32, - faster_impl=args.faster - ) - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num*2+1:], - outputs=["decoder_64"], - op_type=args.decoder_type, - anchor=args.decoder64_anchor, - num_class=args.num_class, - stride=64, - faster_impl=args.faster - ) - graph = t.AddConcatOp( - inputs=["decoder_8", "decoder_16", "decoder_32", "decoder_64"], - outputs=["output"], - axis=1 - ) - else: - graph = t.AddYoloDecoderOp( - inputs=decoder_input[num*2:], - outputs=["decoder_32"], - op_type=args.decoder_type, - anchor=args.decoder32_anchor, - num_class=args.num_class, - stride=32, - faster_impl=args.faster - ) - 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" - 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("--decoder_input_names", nargs='+', type=str) - parser.add_argument("--decoder8_anchor", nargs='*', type=int) - parser.add_argument("--decoder16_anchor", nargs='*', type=int) - parser.add_argument("--decoder32_anchor", nargs='*', type=int) - parser.add_argument("--decoder64_anchor", nargs='*', type=int, default=None) - parser.add_argument("--num_class", type=int, default=80) - parser.add_argument("--faster", type=int, default=1) - parser.add_argument("--focus_input", type=str, default=None) - parser.add_argument("--focus_output", type=str, default=None) - parser.add_argument("--focus_last_node", type=str, default=None) - args = parser.parse_args() - return args - -if __name__ == "__main__": - - args = parse_args() - graph = create_source(args.src)() - graph = customize_ops(graph, args) - create_target(saved_path=args.dst).export(graph) - print("Surged onnx lies on", args.dst) \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/inference.py b/models/cv/object_detection/yolov7/ixrt/inference.py deleted file mode 100644 index c0476b899ba0ec51ab4aedc0596f19cb283952ab..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/inference.py +++ /dev/null @@ -1,267 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import argparse -import glob -import json -import os -import time -import sys - -import torch -import numpy as np -import pycuda.autoinit -import pycuda.driver as cuda - -from coco_labels import coco80_to_coco91_class, labels -from common import save2json, box_class85to6 -from common import create_engine_context, get_io_bindings -from calibration_dataset import create_dataloaders -from datasets.post_process import get_post_process - -from pycocotools.coco import COCO -from pycocotools.cocoeval import COCOeval -from tqdm import tqdm -from tqdm.contrib import tzip - -import tensorrt - -from load_ixrt_plugin import load_ixrt_plugin -load_ixrt_plugin() - -def main(config): - - # Load dataloader - dataloader = create_dataloaders( - data_path=config.eval_dir, - annFile=config.coco_gt, - img_sz=config.imgsz, - batch_size=config.bsz, - step=config.loop_count, - data_process_type=config.data_process_type - ) - - # Load post process func - if config.test_mode == "MAP": - post_process_func = get_post_process(config.data_process_type) - - bsz = config.bsz - num_samples = 5000 - if config.loop_count > 0 and config.loop_count < num_samples/bsz : - num_samples = bsz * config.loop_count - num_batch = len(dataloader) - print("=" * 30) - print(f"Test Mode : {'Asynchronous' if config.use_async else 'Synchronous'}") - print(f"Total sample : {num_samples}\nBatch_size : {bsz}\nRun Batch : {num_batch}") - print("=" * 30) - - json_result = [] - forward_time = 0.0 - class_map = coco80_to_coco91_class() - - host_mem = tensorrt.IHostMemory - logger = tensorrt.Logger(tensorrt.Logger.ERROR) - - # Load Engine - engine, context = create_engine_context(config.model_engine, logger) - inputs, outputs, allocations = get_io_bindings(engine) - - # Load nms_engine - if config.test_mode == "MAP" and config.nms_type == "GPU": - nms_engine, nms_context = create_engine_context(config.nms_engine, logger) - nms_inputs, nms_outputs, nms_allocations = get_io_bindings(nms_engine) - nms_output0 = np.zeros(nms_outputs[0]["shape"], nms_outputs[0]["dtype"]) - nms_output1 = np.zeros(nms_outputs[1]["shape"], nms_outputs[1]["dtype"]) - print(f"nms_output0 shape : {nms_output0.shape} nms_output0 type : {nms_output0.dtype}") - print(f"nms_output1 shape : {nms_output1.shape} nms_output1 type : {nms_output1.dtype}") - - # Warm up - if config.warm_up > 0: - print("\nWarm Start.") - for i in range(config.warm_up): - context.execute_v2(allocations) - print("Warm Done.") - - # Prepare the output data - output = np.zeros(outputs[0]["shape"], outputs[0]["dtype"]) - print(f"output shape : {output.shape} output type : {output.dtype}") - - for batch_data, batch_img_shape, batch_img_id in tqdm(dataloader): - batch_data = batch_data.numpy() - batch_img_shape = [batch_img_shape[0].numpy(), batch_img_shape[1].numpy()] - # batch_img_id = batch_img_id.numpy() - - cur_bsz_sample = batch_data.shape[0] - - # Set input - cuda.memcpy_htod(inputs[0]["allocation"], batch_data) - - # Forward - start_time = time.time() - context.execute_v2(allocations) - end_time = time.time() - forward_time += end_time - start_time - - if config.test_mode == "MAP": - # Fetch output - cuda.memcpy_dtoh(output, outputs[0]["allocation"]) - - # Step 1 : prepare data to nms - _, box_num, box_unit = output.shape - if config.debug: - print(f"[Debug] box_num(25200) : {box_num}, box_unit(6) : {box_unit}") - - if config.decoder_faster == 0: - nms_input = box_class85to6(output.reshape(-1, box_unit)) - else: - nms_input = output - - # Step 2 : nms - # cpu nms(TODO) - - # gpu nms - if config.nms_type == "GPU": - - # Set nms input - cuda.memcpy_htod(nms_inputs[0]["allocation"], nms_input) - nms_context.execute_v2(nms_allocations) - cuda.memcpy_dtoh(nms_output0, nms_outputs[0]["allocation"]) - cuda.memcpy_dtoh(nms_output1, nms_outputs[1]["allocation"]) - - # Step 3 : post process + save - pred_boxes = post_process_func( - ori_img_shape=batch_img_shape, - imgsz=(config.imgsz, config.imgsz), - box_datas=nms_output0, - box_nums=nms_output1, - sample_num=cur_bsz_sample, - max_det=config.max_det - ) - save2json(batch_img_id, pred_boxes, json_result, class_map) - - fps = num_samples / forward_time - - if config.test_mode == "FPS": - print("FPS : ", fps) - print(f"Performance Check : Test {fps} >= target {config.fps_target}") - if fps >= config.fps_target: - print("pass!") - exit() - else: - print("failed!") - exit(1) - - if config.test_mode == "MAP": - if len(json_result) == 0: - print("Predict zero box!") - exit(1) - - if not os.path.exists(config.pred_dir): - os.makedirs(config.pred_dir) - - pred_json = os.path.join( - config.pred_dir, f"{config.model_name}_{config.precision}_preds.json" - ) - with open(pred_json, "w") as f: - json.dump(json_result, f) - - start_time = time.time() - anno_json = config.coco_gt - anno = COCO(anno_json) # init annotations api - pred = anno.loadRes(pred_json) # init predictions api - eval = COCOeval(anno, pred, "bbox") - - eval.evaluate() - eval.accumulate() - print( - f"==============================eval {config.model_name} {config.precision} coco map ==============================" - ) - eval.summarize() - e2e_time = time.time() - start_time - map, map50 = eval.stats[:2] - print(F"E2E time : {e2e_time:.3f} seconds") - print("MAP@0.5 : ", map50) - print(f"Accuracy Check : Test {map50} >= target {config.map_target}") - print(F"E2E time : {e2e_time:.3f} seconds") - if map50 >= config.map_target: - print("pass!") - exit() - else: - print("failed!") - exit(1) - -def parse_config(): - parser = argparse.ArgumentParser() - parser.add_argument( - "--model_name", type=str, default="YOLOV5s", help="YOLOV3 YOLOV5 YOLOV7 YOLOX" - ) - parser.add_argument("--precision", type=str, choices=["float16", "int8", "float32"], default="int8", - help="The precision of datatype") - parser.add_argument("--test_mode", type=str, default="FPS", help="FPS MAP") - parser.add_argument( - "--model_engine", - type=str, - default="", - help="model engine path", - ) - parser.add_argument( - "--nms_engine", - type=str, - default="", - help="nms engine path", - ) - parser.add_argument( - "--coco_gt", - type=str, - default="data/datasets/cv/coco2017/annotations/instances_val2017.json", - help="coco instances_val2017.json", - ) - parser.add_argument("--warm_up", type=int, default=3, help="warm_up count") - parser.add_argument("--loop_count", type=int, default=-1, help="loop count") - parser.add_argument( - "--eval_dir", - type=str, - default="data/datasets/cv/coco2017/val2017", - help="coco image dir", - ) - parser.add_argument("--bsz", type=int, default=32, help="test batch size") - parser.add_argument( - "--imgsz", - "--img", - "--img-size", - type=int, - default=640, - help="inference size h,w", - ) - parser.add_argument("--max_det", type=int, default=1000, help="maximum detections per image") - parser.add_argument("--data_process_type", type=str, default="none") - parser.add_argument("--use_async", action="store_true") - parser.add_argument("--debug", action="store_true") - parser.add_argument("--pred_dir", type=str, default=".", help="pred save json dirs") - parser.add_argument("--map_target", type=float, default=0.56, help="target mAP") - parser.add_argument("--fps_target", type=float, default=-1.0, help="target fps") - parser.add_argument("--decoder_faster", type=int, default=0, help="decoder faster can use gpu nms directly") - parser.add_argument("--nms_type", type=str, default="GPU", help="GPU/CPU") - - config = parser.parse_args() - print("config:", config) - return config - -if __name__ == "__main__": - config = parse_config() - main(config) \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/load_ixrt_plugin.py b/models/cv/object_detection/yolov7/ixrt/load_ixrt_plugin.py deleted file mode 100644 index ae47dc8e854b6bea1f768e65c4dd481048bfebce..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/load_ixrt_plugin.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ctypes -import tensorrt -from os.path import join, dirname, exists -def load_ixrt_plugin(logger=tensorrt.Logger(tensorrt.Logger.INFO), namespace="", dynamic_path=""): - if not dynamic_path: - dynamic_path = join(dirname(tensorrt.__file__), "lib", "libixrt_plugin.so") - if not exists(dynamic_path): - raise FileNotFoundError( - f"The ixrt_plugin lib {dynamic_path} is not existed, please provided effective plugin path!") - ctypes.CDLL(dynamic_path) - tensorrt.init_libnvinfer_plugins(logger, namespace) - print(f"Loaded plugin from {dynamic_path}") \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/modify_batchsize.py b/models/cv/object_detection/yolov7/ixrt/modify_batchsize.py deleted file mode 100644 index 3a88c1603bd6f457fd4965257627dc29edcda4d1..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/modify_batchsize.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import onnx -import argparse - -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 - -args = parse_args() -model = onnx.load(args.origin_model) -change_input_dim(model, args.batch_size) -onnx.save(model, args.output_model) \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/quant.py b/models/cv/object_detection/yolov7/ixrt/quant.py deleted file mode 100644 index 36fd39a13c2e1e40f4dc0098f042e66e4bd0d26a..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/quant.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import random -import argparse -import numpy as np -from tensorrt.deploy import static_quantize - -import torch -from calibration_dataset import create_dataloaders - -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("--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("--seed", type=int, default=42) - parser.add_argument("--imgsz", type=int, default=640) - args = parser.parse_args() - return args - -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, - step=args.step, - data_process_type=args.data_process_type -) -# print("disable_quant_names : ", args.disable_quant_names) -static_quantize(args.model, - calibration_dataloader=dataloader, - save_quant_onnx_path=os.path.join(out_dir, f"quantized_{model_name}.onnx"), - observer=args.observer, - data_preprocess=lambda x: x[0].to("cuda"), - quant_format="qdq", - disable_quant_names=args.disable_quant_names) \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/requirements.txt b/models/cv/object_detection/yolov7/ixrt/requirements.txt deleted file mode 100644 index 10a9fba6a70545eee20ab0db7bb740b1d4807f95..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -tqdm -onnx -onnxsim -ultralytics==8.3.97 -pycocotools -opencv-python==4.6.0.66 -pycuda \ No newline at end of file diff --git a/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_fp16_accuracy.sh b/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_fp16_accuracy.sh index 140ab8ace521610303cbfc0582e0c5eaf6188c62..52ec959f1ea4b6b192b111c5b837904183d17876 100644 --- a/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_fp16_accuracy.sh +++ b/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_fp16_accuracy.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_fp16_performance.sh b/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_fp16_performance.sh index 01542134796eda4a0d46c33e3d28c23120e690ba..5e2f97fb43b1480fcce35669e7d2346f63eb64a8 100644 --- a/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_fp16_performance.sh +++ b/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_fp16_performance.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_int8_accuracy.sh b/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_int8_accuracy.sh index 18d11eff42fc5ecf60ae3338ae1c4688ff252127..606fc94c8c7f11a517b7bf3fe1fcf22ccb6d68d1 100644 --- a/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_int8_accuracy.sh +++ b/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_int8_accuracy.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_int8_performance.sh b/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_int8_performance.sh index 08525d287a6e850b7ee253bb13dc165c2253f045..b29836695881a184603d63159e0872c508d94486 100644 --- a/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_int8_performance.sh +++ b/models/cv/object_detection/yolov7/ixrt/scripts/infer_yolov7_int8_performance.sh @@ -1,18 +1,4 @@ #!/bin/bash -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. EXIT_STATUS=0 check_status() diff --git a/models/cv/object_detection/yolov7/ixrt/simplify_model.py b/models/cv/object_detection/yolov7/ixrt/simplify_model.py deleted file mode 100644 index 1400fd81ddb4b3fae1b20d0fd35082a692f5d292..0000000000000000000000000000000000000000 --- a/models/cv/object_detection/yolov7/ixrt/simplify_model.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -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 diff --git a/models/cv/object_detection/yolox/ixrt/scripts/infer_yolox_fp16_accuracy.sh b/models/cv/object_detection/yolox/ixrt/scripts/infer_yolox_fp16_accuracy.sh index ed40e8dcaf19993516b1c25f1d99b2b06c45f606..455a54831e2cfbfecd8e38bbad0f6a4900065262 100644 --- a/models/cv/object_detection/yolox/ixrt/scripts/infer_yolox_fp16_accuracy.sh +++ b/models/cv/object_detection/yolox/ixrt/scripts/infer_yolox_fp16_accuracy.sh @@ -18,7 +18,7 @@ batchsize=${BATCH_SIZE:-"32"} model_path="yolox" datasets_path=${DATASETS_DIR} -DECODER_INPUT_NAMES="/head/obj_preds.0/Conv_output_0 /head/obj_preds.0/Conv_output_0 /head/cls_preds.0/Conv_output_0 /head/reg_preds.1/Conv_output_0 /head/reg_preds.1/Conv_output_0 /head/cls_preds.1/Conv_output_0 /head/reg_preds.2/Conv_output_0 /head/obj_preds.2/Conv_output_0 /head/cls_preds.2/Conv_output_0" +DECODER_INPUT_NAMES="/head/obj_preds.0/Conv_output_0 /head/cls_preds.0/Conv_output_0 /head/reg_preds.1/Conv_output_0 /head/cls_preds.1/Conv_output_0 /head/reg_preds.2/Conv_output_0 /head/obj_preds.2/Conv_output_0 /head/cls_preds.2/Conv_output_0" # cut onnx python3 python/cut_model.py \ diff --git a/models/cv/object_detection/yolox/ixrt/scripts/infer_yolox_fp16_performance.sh b/models/cv/object_detection/yolox/ixrt/scripts/infer_yolox_fp16_performance.sh index c66562d69bb27800259f159fc9afc3f6ac63194b..913d97295cf68aec424c650564f86887279a3f02 100644 --- a/models/cv/object_detection/yolox/ixrt/scripts/infer_yolox_fp16_performance.sh +++ b/models/cv/object_detection/yolox/ixrt/scripts/infer_yolox_fp16_performance.sh @@ -18,7 +18,7 @@ batchsize=${BATCH_SIZE:-"32"} model_path="yolox" datasets_path=${DATASETS_DIR} -DECODER_INPUT_NAMES="/head/obj_preds.0/Conv_output_0 /head/obj_preds.0/Conv_output_0 /head/cls_preds.0/Conv_output_0 /head/reg_preds.1/Conv_output_0 /head/reg_preds.1/Conv_output_0 /head/cls_preds.1/Conv_output_0 /head/reg_preds.2/Conv_output_0 /head/obj_preds.2/Conv_output_0 /head/cls_preds.2/Conv_output_0" +DECODER_INPUT_NAMES="/head/obj_preds.0/Conv_output_0 /head/cls_preds.0/Conv_output_0 /head/reg_preds.1/Conv_output_0 /head/cls_preds.1/Conv_output_0 /head/reg_preds.2/Conv_output_0 /head/obj_preds.2/Conv_output_0 /head/cls_preds.2/Conv_output_0" # cut onnx python3 python/cut_model.py \ diff --git a/models/multimodal/diffusion_model/stable-diffusion/diffusers/ci/prepare.sh b/models/multimodal/diffusion_model/stable-diffusion/diffusers/ci/prepare.sh index b9140aa3524dfab2af3249dee4e6ab89948b3607..f256bc1ddb0984f905c46165c59a2244bea77425 100644 --- a/models/multimodal/diffusion_model/stable-diffusion/diffusers/ci/prepare.sh +++ b/models/multimodal/diffusion_model/stable-diffusion/diffusers/ci/prepare.sh @@ -24,5 +24,5 @@ else echo "Not Support Os" fi -pip3 install http://files.deepspark.org.cn:880/deepspark/add-ons/diffusers-0.31.0-py3-none-any.whl +pip3 install /mnt/deepspark/data/3rd_party/diffusers-0.31.0-py3-none-any.whl pip3 install -r requirements.txt \ No newline at end of file diff --git a/tests/model_info.json b/tests/model_info.json index a717db6791a98170231e4ccb96bd446488356c65..3ba5daddaca87e7c8a5aac03e05f39a4617e40f6 100644 --- a/tests/model_info.json +++ b/tests/model_info.json @@ -1519,7 +1519,7 @@ "github_branch": "", "github_path": "", "datasets": "", - "download_url": "", + "download_url": "http://data.lip6.fr/cadene/pretrainedmodels/inceptionresnetv2-520b38e4.pth", "need_third_part": "", "precisions": [ "fp16", diff --git a/tests/run_ixrt.py b/tests/run_ixrt.py index 0bf60dbc2df9e2c1b336a31254fb966f80f2ad1d..eb25acab7388ad14c509fd48a0862ff0bbec7f32 100644 --- a/tests/run_ixrt.py +++ b/tests/run_ixrt.py @@ -259,25 +259,41 @@ def run_detec_testcase(model): run_script(prepare_script) config_name = model_name.upper() + if model_name == "yolov5": + config_name = "YOLOV5M" for prec in model["precisions"]: logging.info(f"Start running {model_name} {prec} test case") - script = f""" - cd ../{model['model_path']} - export DATASETS_DIR=./{dataset_n}/ - - export MODEL_PATH=./{model_name}.onnx - - export PROJ_DIR=./ - export CHECKPOINTS_DIR=./checkpoints - export COCO_GT=./{dataset_n}/annotations/instances_val2017.json - export EVAL_DIR=./{dataset_n}/val2017 - export RUN_DIR=./ - export CONFIG_DIR=config/{config_name}_CONFIG - - bash scripts/infer_{model_name}_{prec}_accuracy.sh - bash scripts/infer_{model_name}_{prec}_performance.sh - """ + result["result"].setdefault(prec, {}) + result["result"].setdefault(prec, {"status": "FAIL"}) + if model_name in ["yolov3", "yolov5", "yolov5s", "yolov7"]: + script = f""" + cd ../{model['model_path']} + export DATASETS_DIR=./{dataset_n}/ + export MODEL_PATH=./{model_name}.onnx + export PROJ_DIR=./ + export CHECKPOINTS_DIR=./checkpoints + export COCO_GT=./{dataset_n}/annotations/instances_val2017.json + export EVAL_DIR=./{dataset_n}/images/val2017 + export RUN_DIR=../../ixrt_common + export CONFIG_DIR=../../ixrt_common/config/{config_name}_CONFIG + bash scripts/infer_{model_name}_{prec}_accuracy.sh + bash scripts/infer_{model_name}_{prec}_performance.sh + """ + else: + script = f""" + cd ../{model['model_path']} + export DATASETS_DIR=./{dataset_n}/ + export MODEL_PATH=./{model_name}.onnx + export PROJ_DIR=./ + export CHECKPOINTS_DIR=./checkpoints + export COCO_GT=./{dataset_n}/annotations/instances_val2017.json + export EVAL_DIR=./{dataset_n}/images/val2017 + export RUN_DIR=./ + export CONFIG_DIR=config/{config_name}_CONFIG + bash scripts/infer_{model_name}_{prec}_accuracy.sh + bash scripts/infer_{model_name}_{prec}_performance.sh + """ if model_name == "rtmpose": script = f""" @@ -292,7 +308,6 @@ def run_detec_testcase(model): combined_pattern = re.compile(f"{fps_pattern}|{e2e_pattern}") matchs = combined_pattern.finditer(sout) for match in matchs: - result["result"].setdefault(prec, {"status": "FAIL"}) for name, value in match.groupdict().items(): if value: try: @@ -304,7 +319,6 @@ def run_detec_testcase(model): pattern = r"Average Precision \(AP\) @\[ (IoU=0.50[:\d.]*)\s*\| area= all \| maxDets=\s?\d+\s?\] =\s*([\d.]+)" matchs = re.findall(pattern, sout) for m in matchs: - result["result"].setdefault(prec, {}) try: result["result"][prec][m[0]] = float(m[1]) except ValueError: @@ -316,7 +330,6 @@ def run_detec_testcase(model): pattern = METRIC_PATTERN matchs = re.findall(pattern, sout) if matchs and len(matchs) == 1: - result["result"].setdefault(prec, {}) result["result"][prec].update(get_metric_result(matchs[0])) result["result"][prec]["status"] = "PASS" result["result"][prec]["Cost time (s)"] = t @@ -376,6 +389,23 @@ def run_segmentation_and_face_testcase(model): result["result"][prec].update(get_metric_result(m)) if len(matchs) == 2: result["result"][prec]["status"] = "PASS" + else: + patterns = { + "FPS": r"FPS\s*:\s*(\d+\.?\d*)", + "Accuracy": r"Accuracy\s*:\s*(\d+\.?\d*)" + } + + combined_pattern = re.compile("|".join(f"(?P<{name}>{pattern})" for name, pattern in patterns.items())) + matchs = combined_pattern.finditer(sout) + match_count = 0 + for match in matchs: + for name, value in match.groupdict().items(): + if value: + match_count += 1 + result["result"][prec][name] = float(f"{float(value.split(':')[1].strip()):.3f}") + break + if match_count == len(patterns): + result["result"][prec]["status"] = "PASS" result["result"][prec]["Cost time (s)"] = t logging.debug(f"matchs:\n{matchs}")