From a0dd1f683c7117edda1fcbae216e49b61c1d828f Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Wed, 9 Apr 2025 14:24:58 +0800 Subject: [PATCH 01/10] Add: convnext_tiny inference script. --- .../cv/classification/convnext_tiny/README.md | 52 +++++ .../convnext_tiny/build_engine.py | 73 +++++++ .../convnext_tiny/ci/prepare.sh | 20 ++ .../cv/classification/convnext_tiny/export.py | 61 ++++++ .../classification/convnext_tiny/inference.py | 186 ++++++++++++++++++ .../convnext_tiny/requirements.txt | 2 + .../infer_convnext_tiny_fp16_accuracy.sh | 35 ++++ .../infer_convnext_tiny_fp16_performance.sh | 36 ++++ 8 files changed, 465 insertions(+) create mode 100644 models/cv/classification/convnext_tiny/README.md create mode 100644 models/cv/classification/convnext_tiny/build_engine.py create mode 100644 models/cv/classification/convnext_tiny/ci/prepare.sh create mode 100644 models/cv/classification/convnext_tiny/export.py create mode 100644 models/cv/classification/convnext_tiny/inference.py create mode 100644 models/cv/classification/convnext_tiny/requirements.txt create mode 100644 models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_accuracy.sh create mode 100644 models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_performance.sh diff --git a/models/cv/classification/convnext_tiny/README.md b/models/cv/classification/convnext_tiny/README.md new file mode 100644 index 00000000..d2848612 --- /dev/null +++ b/models/cv/classification/convnext_tiny/README.md @@ -0,0 +1,52 @@ +# ConvNeXt Tiny (IGIE) + +## Model Description + +ConvNeXt is a modern convolutional neural network architecture proposed by Facebook AI Research, designed to optimize the performance of traditional CNNs by incorporating design principles from Transformers. ConvNeXt Tiny is the lightweight version of this series, specifically designed for resource-constrained devices. + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +|--------|-----------|---------| +| MR-V100 | 4.2.0 | 25.06 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --weight convnext_tiny-983f1562.pth --output convnext_tiny.onnx +``` + +## Model Inference + +```bash +export DATASETS_DIR=/Path/to/imagenet_val/ +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_convnext_tiny_fp16_accuracy.sh +# Performance +bash scripts/infer_convnext_tiny_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +| -------------- | --------- | --------- | ------- | -------- | -------- | +| ConvNeXt Tiny | 32 | FP16 | 1128.96 | 82.104 | 95.919 | diff --git a/models/cv/classification/convnext_tiny/build_engine.py b/models/cv/classification/convnext_tiny/build_engine.py new file mode 100644 index 00000000..d3626ae7 --- /dev/null +++ b/models/cv/classification/convnext_tiny/build_engine.py @@ -0,0 +1,73 @@ +# 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 tvm +import argparse +from tvm import relay +from tvm.relay.import_model import import_model_to_igie + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--model_path", + type=str, + required=True, + help="original model path.") + + parser.add_argument("--engine_path", + type=str, + required=True, + help="igie export engine path.") + + parser.add_argument("--input", + type=str, + required=True, + help=""" + input info of the model, format should be: + input_name:input_shape + eg: --input input:1,3,224,224. + """) + + parser.add_argument("--precision", + type=str, + choices=["fp32", "fp16", "int8"], + required=True, + help="model inference precision.") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + # get input valueinfo + input_name, input_shape = args.input.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_dict = {input_name: shape} + + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + + mod, params = import_model_to_igie(args.model_path, input_dict, backend="igie") + + # build engine + lib = tvm.relay.build(mod, target=target, params=params, precision=args.precision) + + # export engine + lib.export_library(args.engine_path) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/convnext_tiny/ci/prepare.sh b/models/cv/classification/convnext_tiny/ci/prepare.sh new file mode 100644 index 00000000..4f8d29dc --- /dev/null +++ b/models/cv/classification/convnext_tiny/ci/prepare.sh @@ -0,0 +1,20 @@ +#!/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. + +set -x + +pip3 install -r requirements.txt +python3 export.py --weight convnext_tiny-983f1562.pth --output convnext_tiny.onnx \ No newline at end of file diff --git a/models/cv/classification/convnext_tiny/export.py b/models/cv/classification/convnext_tiny/export.py new file mode 100644 index 00000000..df1496cf --- /dev/null +++ b/models/cv/classification/convnext_tiny/export.py @@ -0,0 +1,61 @@ +# 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 torch +import torchvision +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--weight", + type=str, + required=True, + help="pytorch model weight.") + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + model = torchvision.models.convnext_tiny() + model.load_state_dict(torch.load(args.weight)) + model.eval() + + input_names = ['input'] + output_names = ['output'] + dynamic_axes = {'input': {0: '-1'}, 'output': {0: '-1'}} + dummy_input = torch.randn(1, 3, 224, 224) + + torch.onnx.export( + model, + dummy_input, + args.output, + input_names = input_names, + dynamic_axes = dynamic_axes, + output_names = output_names, + opset_version=13 + ) + + print("Export onnx model successfully! ") + +if __name__ == "__main__": + main() diff --git a/models/cv/classification/convnext_tiny/inference.py b/models/cv/classification/convnext_tiny/inference.py new file mode 100644 index 00000000..3aef3ec7 --- /dev/null +++ b/models/cv/classification/convnext_tiny/inference.py @@ -0,0 +1,186 @@ +# 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 sys +import argparse +import tvm +import torch +import torchvision +import numpy as np +from tvm import relay +from tqdm import tqdm +from torchvision import transforms +from torchvision.transforms.functional import InterpolationMode + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="igie engine path.") + + 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("--input_name", + type=str, + required=True, + help="input name of the model.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--num_workers", + type=int, + default=16, + help="number of workers used in pytorch dataloader.") + + 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 get_dataloader(data_path, batch_size, num_workers): + dataset = torchvision.datasets.ImageFolder( + data_path, + transforms.Compose( + [ + transforms.Resize(256, interpolation=InterpolationMode.BILINEAR), + transforms.CenterCrop(224), + transforms.PILToTensor(), + transforms.ConvertImageDtype(torch.float), + transforms.Normalize( + mean=(0.485, 0.456, 0.406), + std=(0.229, 0.224, 0.225) + ) + ] + ) + ) + + dataloader = torch.utils.data.DataLoader(dataset, batch_size, num_workers=num_workers) + + return dataloader + +def get_topk_accuracy(pred, label): + if isinstance(pred, np.ndarray): + pred = torch.from_numpy(pred) + + if isinstance(label, np.ndarray): + label = torch.from_numpy(label) + + top1_acc = 0 + top5_acc = 0 + for idx in range(len(label)): + label_value = label[idx] + if label_value == torch.topk(pred[idx].float(), 1).indices.data: + top1_acc += 1 + top5_acc += 1 + + elif label_value in torch.topk(pred[idx].float(), 5).indices.data: + top5_acc += 1 + + return top1_acc, top5_acc + +def main(): + args = parse_args() + + batch_size = args.batchsize + + # create iluvatar target & device + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + device = tvm.device(target.kind.name, 0) + + # load engine + lib = tvm.runtime.load_module(args.engine) + + # create runtime from engine + module = tvm.contrib.graph_executor.GraphModule(lib["default"](device)) + + # just run perf test + if args.perf_only: + ftimer = module.module.time_evaluator("run", device, number=100, repeat=1) + prof_res = np.array(ftimer().results) * 1000 + fps = batch_size * 1000 / np.mean(prof_res) + print(f"\n* Mean inference time: {np.mean(prof_res):.3f} ms, Mean fps: {fps:.3f}") + else: + # warm up + for _ in range(args.warmup): + module.run() + + # get dataloader + dataloader = get_dataloader(args.datasets, batch_size, args.num_workers) + + top1_acc = 0 + top5_acc = 0 + total_num = 0 + + for image, label in tqdm(dataloader): + + # pad the last batch + pad_batch = len(image) != batch_size + + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + + module.set_input(args.input_name, tvm.nd.array(image, device)) + + # run inference + module.run() + + pred = module.get_output(0).asnumpy() + + if pad_batch: + pred = pred[:origin_size] + + # get batch accuracy + batch_top1_acc, batch_top5_acc = get_topk_accuracy(pred, label) + + top1_acc += batch_top1_acc + top5_acc += batch_top5_acc + total_num += batch_size + + result_stat = {} + result_stat["acc@1"] = round(top1_acc / total_num * 100.0, 3) + result_stat["acc@5"] = round(top5_acc / total_num * 100.0, 3) + + print(f"\n* Top1 acc: {result_stat['acc@1']} %, Top5 acc: {result_stat['acc@5']} %") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/convnext_tiny/requirements.txt b/models/cv/classification/convnext_tiny/requirements.txt new file mode 100644 index 00000000..9e811126 --- /dev/null +++ b/models/cv/classification/convnext_tiny/requirements.txt @@ -0,0 +1,2 @@ +onnx +tqdm diff --git a/models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_accuracy.sh b/models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_accuracy.sh new file mode 100644 index 00000000..0a61458b --- /dev/null +++ b/models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_accuracy.sh @@ -0,0 +1,35 @@ +#!/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. + +batchsize=32 +model_path="convnext_tiny.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path convnext_tiny_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine convnext_tiny_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} diff --git a/models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_performance.sh b/models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_performance.sh new file mode 100644 index 00000000..640ca1b6 --- /dev/null +++ b/models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_performance.sh @@ -0,0 +1,36 @@ +#!/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. + +batchsize=32 +model_path="convnext_tiny.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path convnext_tiny_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine convnext_tiny_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ + --perf_only True \ No newline at end of file -- Gitee From ed7b25ef79ddb374b577b321a43f4fd9e8d0a06d Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Wed, 9 Apr 2025 14:32:47 +0800 Subject: [PATCH 02/10] Update: modify convnext_tiny directory. --- models/cv/classification/convnext_tiny/{ => igie}/README.md | 0 models/cv/classification/convnext_tiny/{ => igie}/build_engine.py | 0 models/cv/classification/convnext_tiny/{ => igie}/ci/prepare.sh | 0 models/cv/classification/convnext_tiny/{ => igie}/export.py | 0 models/cv/classification/convnext_tiny/{ => igie}/inference.py | 0 .../cv/classification/convnext_tiny/{ => igie}/requirements.txt | 0 .../{ => igie}/scripts/infer_convnext_tiny_fp16_accuracy.sh | 0 .../{ => igie}/scripts/infer_convnext_tiny_fp16_performance.sh | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename models/cv/classification/convnext_tiny/{ => igie}/README.md (100%) rename models/cv/classification/convnext_tiny/{ => igie}/build_engine.py (100%) rename models/cv/classification/convnext_tiny/{ => igie}/ci/prepare.sh (100%) rename models/cv/classification/convnext_tiny/{ => igie}/export.py (100%) rename models/cv/classification/convnext_tiny/{ => igie}/inference.py (100%) rename models/cv/classification/convnext_tiny/{ => igie}/requirements.txt (100%) rename models/cv/classification/convnext_tiny/{ => igie}/scripts/infer_convnext_tiny_fp16_accuracy.sh (100%) rename models/cv/classification/convnext_tiny/{ => igie}/scripts/infer_convnext_tiny_fp16_performance.sh (100%) diff --git a/models/cv/classification/convnext_tiny/README.md b/models/cv/classification/convnext_tiny/igie/README.md similarity index 100% rename from models/cv/classification/convnext_tiny/README.md rename to models/cv/classification/convnext_tiny/igie/README.md diff --git a/models/cv/classification/convnext_tiny/build_engine.py b/models/cv/classification/convnext_tiny/igie/build_engine.py similarity index 100% rename from models/cv/classification/convnext_tiny/build_engine.py rename to models/cv/classification/convnext_tiny/igie/build_engine.py diff --git a/models/cv/classification/convnext_tiny/ci/prepare.sh b/models/cv/classification/convnext_tiny/igie/ci/prepare.sh similarity index 100% rename from models/cv/classification/convnext_tiny/ci/prepare.sh rename to models/cv/classification/convnext_tiny/igie/ci/prepare.sh diff --git a/models/cv/classification/convnext_tiny/export.py b/models/cv/classification/convnext_tiny/igie/export.py similarity index 100% rename from models/cv/classification/convnext_tiny/export.py rename to models/cv/classification/convnext_tiny/igie/export.py diff --git a/models/cv/classification/convnext_tiny/inference.py b/models/cv/classification/convnext_tiny/igie/inference.py similarity index 100% rename from models/cv/classification/convnext_tiny/inference.py rename to models/cv/classification/convnext_tiny/igie/inference.py diff --git a/models/cv/classification/convnext_tiny/requirements.txt b/models/cv/classification/convnext_tiny/igie/requirements.txt similarity index 100% rename from models/cv/classification/convnext_tiny/requirements.txt rename to models/cv/classification/convnext_tiny/igie/requirements.txt diff --git a/models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_accuracy.sh b/models/cv/classification/convnext_tiny/igie/scripts/infer_convnext_tiny_fp16_accuracy.sh similarity index 100% rename from models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_accuracy.sh rename to models/cv/classification/convnext_tiny/igie/scripts/infer_convnext_tiny_fp16_accuracy.sh diff --git a/models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_performance.sh b/models/cv/classification/convnext_tiny/igie/scripts/infer_convnext_tiny_fp16_performance.sh similarity index 100% rename from models/cv/classification/convnext_tiny/scripts/infer_convnext_tiny_fp16_performance.sh rename to models/cv/classification/convnext_tiny/igie/scripts/infer_convnext_tiny_fp16_performance.sh -- Gitee From 2a5ff7cfe5f1cc94b6df04b72de4cc4b6446843c Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Wed, 9 Apr 2025 15:26:51 +0800 Subject: [PATCH 03/10] Add: efficientnet_b5 inference script. --- .../efficientnet_b5/igie/README.md | 52 +++++ .../efficientnet_b5/igie/build_engine.py | 73 +++++++ .../efficientnet_b5/igie/ci/prepare.sh | 20 ++ .../efficientnet_b5/igie/export.py | 61 ++++++ .../efficientnet_b5/igie/inference.py | 186 ++++++++++++++++++ .../efficientnet_b5/igie/requirements.txt | 2 + .../infer_efficientnet_b5_fp16_accuracy.sh | 35 ++++ .../infer_efficientnet_b5_fp16_performance.sh | 36 ++++ 8 files changed, 465 insertions(+) create mode 100644 models/cv/classification/efficientnet_b5/igie/README.md create mode 100644 models/cv/classification/efficientnet_b5/igie/build_engine.py create mode 100644 models/cv/classification/efficientnet_b5/igie/ci/prepare.sh create mode 100644 models/cv/classification/efficientnet_b5/igie/export.py create mode 100644 models/cv/classification/efficientnet_b5/igie/inference.py create mode 100644 models/cv/classification/efficientnet_b5/igie/requirements.txt create mode 100644 models/cv/classification/efficientnet_b5/igie/scripts/infer_efficientnet_b5_fp16_accuracy.sh create mode 100644 models/cv/classification/efficientnet_b5/igie/scripts/infer_efficientnet_b5_fp16_performance.sh diff --git a/models/cv/classification/efficientnet_b5/igie/README.md b/models/cv/classification/efficientnet_b5/igie/README.md new file mode 100644 index 00000000..ac9de97b --- /dev/null +++ b/models/cv/classification/efficientnet_b5/igie/README.md @@ -0,0 +1,52 @@ +# EfficientNet B5 (IGIE) + +## Model Description + +EfficientNet B5 is an efficient convolutional network model designed through a compound scaling strategy and NAS optimization, offering a good balance between high accuracy and computational efficiency across various vision tasks. + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +|--------|-----------|---------| +| MR-V100 | 4.2.0 | 25.06 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --weight efficientnet_b5_lukemelas-1a07897c.pth --output efficientnet_b5.onnx +``` + +## Model Inference + +```bash +export DATASETS_DIR=/Path/to/imagenet_val/ +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_efficientnet_b5_fp16_accuracy.sh +# Performance +bash scripts/infer_efficientnet_b5_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +| --------------- | --------- | --------- | -------- | -------- | -------- | +| Efficientnet_b5 | 32 | FP16 | 623.729 | 73.121 | 90.913 | diff --git a/models/cv/classification/efficientnet_b5/igie/build_engine.py b/models/cv/classification/efficientnet_b5/igie/build_engine.py new file mode 100644 index 00000000..d3626ae7 --- /dev/null +++ b/models/cv/classification/efficientnet_b5/igie/build_engine.py @@ -0,0 +1,73 @@ +# 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 tvm +import argparse +from tvm import relay +from tvm.relay.import_model import import_model_to_igie + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--model_path", + type=str, + required=True, + help="original model path.") + + parser.add_argument("--engine_path", + type=str, + required=True, + help="igie export engine path.") + + parser.add_argument("--input", + type=str, + required=True, + help=""" + input info of the model, format should be: + input_name:input_shape + eg: --input input:1,3,224,224. + """) + + parser.add_argument("--precision", + type=str, + choices=["fp32", "fp16", "int8"], + required=True, + help="model inference precision.") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + # get input valueinfo + input_name, input_shape = args.input.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_dict = {input_name: shape} + + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + + mod, params = import_model_to_igie(args.model_path, input_dict, backend="igie") + + # build engine + lib = tvm.relay.build(mod, target=target, params=params, precision=args.precision) + + # export engine + lib.export_library(args.engine_path) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/efficientnet_b5/igie/ci/prepare.sh b/models/cv/classification/efficientnet_b5/igie/ci/prepare.sh new file mode 100644 index 00000000..7484a30a --- /dev/null +++ b/models/cv/classification/efficientnet_b5/igie/ci/prepare.sh @@ -0,0 +1,20 @@ +#!/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. + +set -x + +pip3 install -r requirements.txt +python3 export.py --weight efficientnet_b5_lukemelas-1a07897c.pth --output efficientnet_b5.onnx diff --git a/models/cv/classification/efficientnet_b5/igie/export.py b/models/cv/classification/efficientnet_b5/igie/export.py new file mode 100644 index 00000000..c483ea3f --- /dev/null +++ b/models/cv/classification/efficientnet_b5/igie/export.py @@ -0,0 +1,61 @@ +# 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 torch +import torchvision +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--weight", + type=str, + required=True, + help="pytorch model weight.") + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + model = torchvision.models.efficientnet_b5() + model.load_state_dict(torch.load(args.weight)) + model.eval() + + input_names = ['input'] + output_names = ['output'] + dynamic_axes = {'input': {0: '-1'}, 'output': {0: '-1'}} + dummy_input = torch.randn(1, 3, 224, 224) + + torch.onnx.export( + model, + dummy_input, + args.output, + input_names = input_names, + dynamic_axes = dynamic_axes, + output_names = output_names, + opset_version=13 + ) + + print("Export onnx model successfully! ") + +if __name__ == "__main__": + main() diff --git a/models/cv/classification/efficientnet_b5/igie/inference.py b/models/cv/classification/efficientnet_b5/igie/inference.py new file mode 100644 index 00000000..3aef3ec7 --- /dev/null +++ b/models/cv/classification/efficientnet_b5/igie/inference.py @@ -0,0 +1,186 @@ +# 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 sys +import argparse +import tvm +import torch +import torchvision +import numpy as np +from tvm import relay +from tqdm import tqdm +from torchvision import transforms +from torchvision.transforms.functional import InterpolationMode + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="igie engine path.") + + 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("--input_name", + type=str, + required=True, + help="input name of the model.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--num_workers", + type=int, + default=16, + help="number of workers used in pytorch dataloader.") + + 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 get_dataloader(data_path, batch_size, num_workers): + dataset = torchvision.datasets.ImageFolder( + data_path, + transforms.Compose( + [ + transforms.Resize(256, interpolation=InterpolationMode.BILINEAR), + transforms.CenterCrop(224), + transforms.PILToTensor(), + transforms.ConvertImageDtype(torch.float), + transforms.Normalize( + mean=(0.485, 0.456, 0.406), + std=(0.229, 0.224, 0.225) + ) + ] + ) + ) + + dataloader = torch.utils.data.DataLoader(dataset, batch_size, num_workers=num_workers) + + return dataloader + +def get_topk_accuracy(pred, label): + if isinstance(pred, np.ndarray): + pred = torch.from_numpy(pred) + + if isinstance(label, np.ndarray): + label = torch.from_numpy(label) + + top1_acc = 0 + top5_acc = 0 + for idx in range(len(label)): + label_value = label[idx] + if label_value == torch.topk(pred[idx].float(), 1).indices.data: + top1_acc += 1 + top5_acc += 1 + + elif label_value in torch.topk(pred[idx].float(), 5).indices.data: + top5_acc += 1 + + return top1_acc, top5_acc + +def main(): + args = parse_args() + + batch_size = args.batchsize + + # create iluvatar target & device + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + device = tvm.device(target.kind.name, 0) + + # load engine + lib = tvm.runtime.load_module(args.engine) + + # create runtime from engine + module = tvm.contrib.graph_executor.GraphModule(lib["default"](device)) + + # just run perf test + if args.perf_only: + ftimer = module.module.time_evaluator("run", device, number=100, repeat=1) + prof_res = np.array(ftimer().results) * 1000 + fps = batch_size * 1000 / np.mean(prof_res) + print(f"\n* Mean inference time: {np.mean(prof_res):.3f} ms, Mean fps: {fps:.3f}") + else: + # warm up + for _ in range(args.warmup): + module.run() + + # get dataloader + dataloader = get_dataloader(args.datasets, batch_size, args.num_workers) + + top1_acc = 0 + top5_acc = 0 + total_num = 0 + + for image, label in tqdm(dataloader): + + # pad the last batch + pad_batch = len(image) != batch_size + + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + + module.set_input(args.input_name, tvm.nd.array(image, device)) + + # run inference + module.run() + + pred = module.get_output(0).asnumpy() + + if pad_batch: + pred = pred[:origin_size] + + # get batch accuracy + batch_top1_acc, batch_top5_acc = get_topk_accuracy(pred, label) + + top1_acc += batch_top1_acc + top5_acc += batch_top5_acc + total_num += batch_size + + result_stat = {} + result_stat["acc@1"] = round(top1_acc / total_num * 100.0, 3) + result_stat["acc@5"] = round(top5_acc / total_num * 100.0, 3) + + print(f"\n* Top1 acc: {result_stat['acc@1']} %, Top5 acc: {result_stat['acc@5']} %") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/efficientnet_b5/igie/requirements.txt b/models/cv/classification/efficientnet_b5/igie/requirements.txt new file mode 100644 index 00000000..9e811126 --- /dev/null +++ b/models/cv/classification/efficientnet_b5/igie/requirements.txt @@ -0,0 +1,2 @@ +onnx +tqdm diff --git a/models/cv/classification/efficientnet_b5/igie/scripts/infer_efficientnet_b5_fp16_accuracy.sh b/models/cv/classification/efficientnet_b5/igie/scripts/infer_efficientnet_b5_fp16_accuracy.sh new file mode 100644 index 00000000..ed298045 --- /dev/null +++ b/models/cv/classification/efficientnet_b5/igie/scripts/infer_efficientnet_b5_fp16_accuracy.sh @@ -0,0 +1,35 @@ +#!/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. + +batchsize=32 +model_path="efficientnet_b5.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path efficientnet_b5_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine efficientnet_b5_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ No newline at end of file diff --git a/models/cv/classification/efficientnet_b5/igie/scripts/infer_efficientnet_b5_fp16_performance.sh b/models/cv/classification/efficientnet_b5/igie/scripts/infer_efficientnet_b5_fp16_performance.sh new file mode 100644 index 00000000..d487d083 --- /dev/null +++ b/models/cv/classification/efficientnet_b5/igie/scripts/infer_efficientnet_b5_fp16_performance.sh @@ -0,0 +1,36 @@ +#!/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. + +batchsize=32 +model_path="efficientnet_b5.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path efficientnet_b5_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine efficientnet_b5_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ + --perf_only True \ No newline at end of file -- Gitee From 7b5d7dfe49510c034830b9a3429417eb641cb872 Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Wed, 9 Apr 2025 15:57:37 +0800 Subject: [PATCH 04/10] Add: mnasnet1_0 inference script. --- .../classification/mnasnet1_0/igie/README.md | 52 +++++ .../mnasnet1_0/igie/build_engine.py | 73 +++++++ .../mnasnet1_0/igie/ci/prepare.sh | 20 ++ .../classification/mnasnet1_0/igie/export.py | 61 ++++++ .../mnasnet1_0/igie/inference.py | 186 ++++++++++++++++++ .../mnasnet1_0/igie/requirements.txt | 2 + .../scripts/infer_mnasnet1_0_fp16_accuracy.sh | 35 ++++ .../infer_mnasnet1_0_fp16_performance.sh | 36 ++++ 8 files changed, 465 insertions(+) create mode 100644 models/cv/classification/mnasnet1_0/igie/README.md create mode 100644 models/cv/classification/mnasnet1_0/igie/build_engine.py create mode 100644 models/cv/classification/mnasnet1_0/igie/ci/prepare.sh create mode 100644 models/cv/classification/mnasnet1_0/igie/export.py create mode 100644 models/cv/classification/mnasnet1_0/igie/inference.py create mode 100644 models/cv/classification/mnasnet1_0/igie/requirements.txt create mode 100644 models/cv/classification/mnasnet1_0/igie/scripts/infer_mnasnet1_0_fp16_accuracy.sh create mode 100644 models/cv/classification/mnasnet1_0/igie/scripts/infer_mnasnet1_0_fp16_performance.sh diff --git a/models/cv/classification/mnasnet1_0/igie/README.md b/models/cv/classification/mnasnet1_0/igie/README.md new file mode 100644 index 00000000..4eab0f18 --- /dev/null +++ b/models/cv/classification/mnasnet1_0/igie/README.md @@ -0,0 +1,52 @@ +# MNASNet1_0 (IGIE) + +## Model Description + +**MNASNet1_0** is a lightweight convolutional neural network designed using neural architecture search (NAS) to optimize both accuracy and latency for mobile devices. Its structure incorporates depthwise separable convolutions for efficiency, Squeeze-and-Excitation (SE) modules for enhanced feature representation, and compound scaling to balance width, depth, and resolution. This makes MNASNet1_0 highly efficient and ideal for resource-constrained and real-time applications. + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +|--------|-----------|---------| +| MR-V100 | 4.2.0 | 25.06 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --weight mnasnet1.0_top1_73.512-f206786ef8.pth --output mnasnet1_0.onnx +``` + +## Model Inference + +```bash +export DATASETS_DIR=/Path/to/imagenet_val/ +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_mnasnet1_0_fp16_accuracy.sh +# Performance +bash scripts/infer_mnasnet1_0_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +| ----------------- | --------- | --------- | -------- | -------- | -------- | +| MnasNet1_0 | 32 | FP16 | 5225.057 | 73.446 | 91.483 | diff --git a/models/cv/classification/mnasnet1_0/igie/build_engine.py b/models/cv/classification/mnasnet1_0/igie/build_engine.py new file mode 100644 index 00000000..d3626ae7 --- /dev/null +++ b/models/cv/classification/mnasnet1_0/igie/build_engine.py @@ -0,0 +1,73 @@ +# 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 tvm +import argparse +from tvm import relay +from tvm.relay.import_model import import_model_to_igie + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--model_path", + type=str, + required=True, + help="original model path.") + + parser.add_argument("--engine_path", + type=str, + required=True, + help="igie export engine path.") + + parser.add_argument("--input", + type=str, + required=True, + help=""" + input info of the model, format should be: + input_name:input_shape + eg: --input input:1,3,224,224. + """) + + parser.add_argument("--precision", + type=str, + choices=["fp32", "fp16", "int8"], + required=True, + help="model inference precision.") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + # get input valueinfo + input_name, input_shape = args.input.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_dict = {input_name: shape} + + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + + mod, params = import_model_to_igie(args.model_path, input_dict, backend="igie") + + # build engine + lib = tvm.relay.build(mod, target=target, params=params, precision=args.precision) + + # export engine + lib.export_library(args.engine_path) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/mnasnet1_0/igie/ci/prepare.sh b/models/cv/classification/mnasnet1_0/igie/ci/prepare.sh new file mode 100644 index 00000000..594bb5a5 --- /dev/null +++ b/models/cv/classification/mnasnet1_0/igie/ci/prepare.sh @@ -0,0 +1,20 @@ +#!/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. + +set -x + +pip3 install -r requirements.txt +python3 export.py --weight mnasnet1.0_top1_73.512-f206786ef8.pth --output mnasnet1_0.onnx \ No newline at end of file diff --git a/models/cv/classification/mnasnet1_0/igie/export.py b/models/cv/classification/mnasnet1_0/igie/export.py new file mode 100644 index 00000000..68057f2d --- /dev/null +++ b/models/cv/classification/mnasnet1_0/igie/export.py @@ -0,0 +1,61 @@ +# 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 torch +import torchvision +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--weight", + type=str, + required=True, + help="pytorch model weight.") + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + model = torchvision.models.mnasnet1_0() + model.load_state_dict(torch.load(args.weight)) + model.eval() + + input_names = ['input'] + output_names = ['output'] + dynamic_axes = {'input': {0: '-1'}, 'output': {0: '-1'}} + dummy_input = torch.randn(1, 3, 224, 224) + + torch.onnx.export( + model, + dummy_input, + args.output, + input_names = input_names, + dynamic_axes = dynamic_axes, + output_names = output_names, + opset_version=13 + ) + + print("Export onnx model successfully! ") + +if __name__ == "__main__": + main() diff --git a/models/cv/classification/mnasnet1_0/igie/inference.py b/models/cv/classification/mnasnet1_0/igie/inference.py new file mode 100644 index 00000000..3aef3ec7 --- /dev/null +++ b/models/cv/classification/mnasnet1_0/igie/inference.py @@ -0,0 +1,186 @@ +# 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 sys +import argparse +import tvm +import torch +import torchvision +import numpy as np +from tvm import relay +from tqdm import tqdm +from torchvision import transforms +from torchvision.transforms.functional import InterpolationMode + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="igie engine path.") + + 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("--input_name", + type=str, + required=True, + help="input name of the model.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--num_workers", + type=int, + default=16, + help="number of workers used in pytorch dataloader.") + + 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 get_dataloader(data_path, batch_size, num_workers): + dataset = torchvision.datasets.ImageFolder( + data_path, + transforms.Compose( + [ + transforms.Resize(256, interpolation=InterpolationMode.BILINEAR), + transforms.CenterCrop(224), + transforms.PILToTensor(), + transforms.ConvertImageDtype(torch.float), + transforms.Normalize( + mean=(0.485, 0.456, 0.406), + std=(0.229, 0.224, 0.225) + ) + ] + ) + ) + + dataloader = torch.utils.data.DataLoader(dataset, batch_size, num_workers=num_workers) + + return dataloader + +def get_topk_accuracy(pred, label): + if isinstance(pred, np.ndarray): + pred = torch.from_numpy(pred) + + if isinstance(label, np.ndarray): + label = torch.from_numpy(label) + + top1_acc = 0 + top5_acc = 0 + for idx in range(len(label)): + label_value = label[idx] + if label_value == torch.topk(pred[idx].float(), 1).indices.data: + top1_acc += 1 + top5_acc += 1 + + elif label_value in torch.topk(pred[idx].float(), 5).indices.data: + top5_acc += 1 + + return top1_acc, top5_acc + +def main(): + args = parse_args() + + batch_size = args.batchsize + + # create iluvatar target & device + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + device = tvm.device(target.kind.name, 0) + + # load engine + lib = tvm.runtime.load_module(args.engine) + + # create runtime from engine + module = tvm.contrib.graph_executor.GraphModule(lib["default"](device)) + + # just run perf test + if args.perf_only: + ftimer = module.module.time_evaluator("run", device, number=100, repeat=1) + prof_res = np.array(ftimer().results) * 1000 + fps = batch_size * 1000 / np.mean(prof_res) + print(f"\n* Mean inference time: {np.mean(prof_res):.3f} ms, Mean fps: {fps:.3f}") + else: + # warm up + for _ in range(args.warmup): + module.run() + + # get dataloader + dataloader = get_dataloader(args.datasets, batch_size, args.num_workers) + + top1_acc = 0 + top5_acc = 0 + total_num = 0 + + for image, label in tqdm(dataloader): + + # pad the last batch + pad_batch = len(image) != batch_size + + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + + module.set_input(args.input_name, tvm.nd.array(image, device)) + + # run inference + module.run() + + pred = module.get_output(0).asnumpy() + + if pad_batch: + pred = pred[:origin_size] + + # get batch accuracy + batch_top1_acc, batch_top5_acc = get_topk_accuracy(pred, label) + + top1_acc += batch_top1_acc + top5_acc += batch_top5_acc + total_num += batch_size + + result_stat = {} + result_stat["acc@1"] = round(top1_acc / total_num * 100.0, 3) + result_stat["acc@5"] = round(top5_acc / total_num * 100.0, 3) + + print(f"\n* Top1 acc: {result_stat['acc@1']} %, Top5 acc: {result_stat['acc@5']} %") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/mnasnet1_0/igie/requirements.txt b/models/cv/classification/mnasnet1_0/igie/requirements.txt new file mode 100644 index 00000000..9e811126 --- /dev/null +++ b/models/cv/classification/mnasnet1_0/igie/requirements.txt @@ -0,0 +1,2 @@ +onnx +tqdm diff --git a/models/cv/classification/mnasnet1_0/igie/scripts/infer_mnasnet1_0_fp16_accuracy.sh b/models/cv/classification/mnasnet1_0/igie/scripts/infer_mnasnet1_0_fp16_accuracy.sh new file mode 100644 index 00000000..1143756b --- /dev/null +++ b/models/cv/classification/mnasnet1_0/igie/scripts/infer_mnasnet1_0_fp16_accuracy.sh @@ -0,0 +1,35 @@ +#!/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. + +batchsize=32 +model_path="mnasnet1_0.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path mnasnet1_0_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine mnasnet1_0_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ No newline at end of file diff --git a/models/cv/classification/mnasnet1_0/igie/scripts/infer_mnasnet1_0_fp16_performance.sh b/models/cv/classification/mnasnet1_0/igie/scripts/infer_mnasnet1_0_fp16_performance.sh new file mode 100644 index 00000000..469fd496 --- /dev/null +++ b/models/cv/classification/mnasnet1_0/igie/scripts/infer_mnasnet1_0_fp16_performance.sh @@ -0,0 +1,36 @@ +#!/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. + +batchsize=32 +model_path="mnasnet1_0.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path mnasnet1_0_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine mnasnet1_0_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ + --perf_only True \ No newline at end of file -- Gitee From 16a9b22cd017af264c5e8e530d50326190ca0d3a Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Wed, 9 Apr 2025 16:24:21 +0800 Subject: [PATCH 05/10] Add: regnet_x_3_2gf inference script. --- .../regnet_x_3_2gf/igie/README.md | 52 +++++ .../regnet_x_3_2gf/igie/build_engine.py | 73 +++++++ .../regnet_x_3_2gf/igie/ci/prepare.sh | 20 ++ .../regnet_x_3_2gf/igie/export.py | 61 ++++++ .../regnet_x_3_2gf/igie/inference.py | 186 ++++++++++++++++++ .../regnet_x_3_2gf/igie/requirements.txt | 2 + .../infer_regnet_x_3_2gf_fp16_accuracy.sh | 35 ++++ .../infer_regnet_x_3_2gf_fp16_performance.sh | 36 ++++ 8 files changed, 465 insertions(+) create mode 100644 models/cv/classification/regnet_x_3_2gf/igie/README.md create mode 100644 models/cv/classification/regnet_x_3_2gf/igie/build_engine.py create mode 100644 models/cv/classification/regnet_x_3_2gf/igie/ci/prepare.sh create mode 100644 models/cv/classification/regnet_x_3_2gf/igie/export.py create mode 100644 models/cv/classification/regnet_x_3_2gf/igie/inference.py create mode 100644 models/cv/classification/regnet_x_3_2gf/igie/requirements.txt create mode 100644 models/cv/classification/regnet_x_3_2gf/igie/scripts/infer_regnet_x_3_2gf_fp16_accuracy.sh create mode 100644 models/cv/classification/regnet_x_3_2gf/igie/scripts/infer_regnet_x_3_2gf_fp16_performance.sh diff --git a/models/cv/classification/regnet_x_3_2gf/igie/README.md b/models/cv/classification/regnet_x_3_2gf/igie/README.md new file mode 100644 index 00000000..0458ecb2 --- /dev/null +++ b/models/cv/classification/regnet_x_3_2gf/igie/README.md @@ -0,0 +1,52 @@ +# RegNet_x_3_2gf (IGIE) + +## Model Description + +RegNet_x_3_2gf is a model from the RegNet series, inspired by the paper *Designing Network Design Spaces*. It leverages a parameterized network design approach to optimize convolutional neural network structures. With features like linear width scaling, group convolutions, and bottleneck blocks, it is particularly suited for efficient applications in scenarios with moderate computational resources. + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +|--------|-----------|---------| +| MR-V100 | 4.2.0 | 25.06 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --weight regnet_x_3_2gf-f342aeae.pth --output regnet_x_3_2gf.onnx +``` + +## Model Inference + +```bash +export DATASETS_DIR=/Path/to/imagenet_val/ +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_regnet_x_3_2gf_fp16_accuracy.sh +# Performance +bash scripts/infer_regnet_x_3_2gf_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +|----------------|-----------|-----------|---------|----------|----------| +| RegNet_x_3_2gf | 32 | FP16 | 2096.88 | 78.333 | 93.962 | diff --git a/models/cv/classification/regnet_x_3_2gf/igie/build_engine.py b/models/cv/classification/regnet_x_3_2gf/igie/build_engine.py new file mode 100644 index 00000000..d3626ae7 --- /dev/null +++ b/models/cv/classification/regnet_x_3_2gf/igie/build_engine.py @@ -0,0 +1,73 @@ +# 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 tvm +import argparse +from tvm import relay +from tvm.relay.import_model import import_model_to_igie + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--model_path", + type=str, + required=True, + help="original model path.") + + parser.add_argument("--engine_path", + type=str, + required=True, + help="igie export engine path.") + + parser.add_argument("--input", + type=str, + required=True, + help=""" + input info of the model, format should be: + input_name:input_shape + eg: --input input:1,3,224,224. + """) + + parser.add_argument("--precision", + type=str, + choices=["fp32", "fp16", "int8"], + required=True, + help="model inference precision.") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + # get input valueinfo + input_name, input_shape = args.input.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_dict = {input_name: shape} + + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + + mod, params = import_model_to_igie(args.model_path, input_dict, backend="igie") + + # build engine + lib = tvm.relay.build(mod, target=target, params=params, precision=args.precision) + + # export engine + lib.export_library(args.engine_path) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/regnet_x_3_2gf/igie/ci/prepare.sh b/models/cv/classification/regnet_x_3_2gf/igie/ci/prepare.sh new file mode 100644 index 00000000..dd4da4ef --- /dev/null +++ b/models/cv/classification/regnet_x_3_2gf/igie/ci/prepare.sh @@ -0,0 +1,20 @@ +#!/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. + +set -x + +pip3 install -r requirements.txt +python3 export.py --weight regnet_x_3_2gf-f342aeae.pth --output regnet_x_3_2gf.onnx \ No newline at end of file diff --git a/models/cv/classification/regnet_x_3_2gf/igie/export.py b/models/cv/classification/regnet_x_3_2gf/igie/export.py new file mode 100644 index 00000000..20332adb --- /dev/null +++ b/models/cv/classification/regnet_x_3_2gf/igie/export.py @@ -0,0 +1,61 @@ +# 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 torch +import torchvision +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--weight", + type=str, + required=True, + help="pytorch model weight.") + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + model = torchvision.models.regnet_x_3_2gf() + model.load_state_dict(torch.load(args.weight)) + model.eval() + + input_names = ['input'] + output_names = ['output'] + dynamic_axes = {'input': {0: '-1'}, 'output': {0: '-1'}} + dummy_input = torch.randn(1, 3, 224, 224) + + torch.onnx.export( + model, + dummy_input, + args.output, + input_names = input_names, + dynamic_axes = dynamic_axes, + output_names = output_names, + opset_version=13 + ) + + print("Export onnx model successfully! ") + +if __name__ == "__main__": + main() diff --git a/models/cv/classification/regnet_x_3_2gf/igie/inference.py b/models/cv/classification/regnet_x_3_2gf/igie/inference.py new file mode 100644 index 00000000..3aef3ec7 --- /dev/null +++ b/models/cv/classification/regnet_x_3_2gf/igie/inference.py @@ -0,0 +1,186 @@ +# 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 sys +import argparse +import tvm +import torch +import torchvision +import numpy as np +from tvm import relay +from tqdm import tqdm +from torchvision import transforms +from torchvision.transforms.functional import InterpolationMode + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="igie engine path.") + + 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("--input_name", + type=str, + required=True, + help="input name of the model.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--num_workers", + type=int, + default=16, + help="number of workers used in pytorch dataloader.") + + 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 get_dataloader(data_path, batch_size, num_workers): + dataset = torchvision.datasets.ImageFolder( + data_path, + transforms.Compose( + [ + transforms.Resize(256, interpolation=InterpolationMode.BILINEAR), + transforms.CenterCrop(224), + transforms.PILToTensor(), + transforms.ConvertImageDtype(torch.float), + transforms.Normalize( + mean=(0.485, 0.456, 0.406), + std=(0.229, 0.224, 0.225) + ) + ] + ) + ) + + dataloader = torch.utils.data.DataLoader(dataset, batch_size, num_workers=num_workers) + + return dataloader + +def get_topk_accuracy(pred, label): + if isinstance(pred, np.ndarray): + pred = torch.from_numpy(pred) + + if isinstance(label, np.ndarray): + label = torch.from_numpy(label) + + top1_acc = 0 + top5_acc = 0 + for idx in range(len(label)): + label_value = label[idx] + if label_value == torch.topk(pred[idx].float(), 1).indices.data: + top1_acc += 1 + top5_acc += 1 + + elif label_value in torch.topk(pred[idx].float(), 5).indices.data: + top5_acc += 1 + + return top1_acc, top5_acc + +def main(): + args = parse_args() + + batch_size = args.batchsize + + # create iluvatar target & device + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + device = tvm.device(target.kind.name, 0) + + # load engine + lib = tvm.runtime.load_module(args.engine) + + # create runtime from engine + module = tvm.contrib.graph_executor.GraphModule(lib["default"](device)) + + # just run perf test + if args.perf_only: + ftimer = module.module.time_evaluator("run", device, number=100, repeat=1) + prof_res = np.array(ftimer().results) * 1000 + fps = batch_size * 1000 / np.mean(prof_res) + print(f"\n* Mean inference time: {np.mean(prof_res):.3f} ms, Mean fps: {fps:.3f}") + else: + # warm up + for _ in range(args.warmup): + module.run() + + # get dataloader + dataloader = get_dataloader(args.datasets, batch_size, args.num_workers) + + top1_acc = 0 + top5_acc = 0 + total_num = 0 + + for image, label in tqdm(dataloader): + + # pad the last batch + pad_batch = len(image) != batch_size + + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + + module.set_input(args.input_name, tvm.nd.array(image, device)) + + # run inference + module.run() + + pred = module.get_output(0).asnumpy() + + if pad_batch: + pred = pred[:origin_size] + + # get batch accuracy + batch_top1_acc, batch_top5_acc = get_topk_accuracy(pred, label) + + top1_acc += batch_top1_acc + top5_acc += batch_top5_acc + total_num += batch_size + + result_stat = {} + result_stat["acc@1"] = round(top1_acc / total_num * 100.0, 3) + result_stat["acc@5"] = round(top5_acc / total_num * 100.0, 3) + + print(f"\n* Top1 acc: {result_stat['acc@1']} %, Top5 acc: {result_stat['acc@5']} %") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/regnet_x_3_2gf/igie/requirements.txt b/models/cv/classification/regnet_x_3_2gf/igie/requirements.txt new file mode 100644 index 00000000..9e811126 --- /dev/null +++ b/models/cv/classification/regnet_x_3_2gf/igie/requirements.txt @@ -0,0 +1,2 @@ +onnx +tqdm diff --git a/models/cv/classification/regnet_x_3_2gf/igie/scripts/infer_regnet_x_3_2gf_fp16_accuracy.sh b/models/cv/classification/regnet_x_3_2gf/igie/scripts/infer_regnet_x_3_2gf_fp16_accuracy.sh new file mode 100644 index 00000000..c2dae8db --- /dev/null +++ b/models/cv/classification/regnet_x_3_2gf/igie/scripts/infer_regnet_x_3_2gf_fp16_accuracy.sh @@ -0,0 +1,35 @@ +#!/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. + +batchsize=32 +model_path="regnet_x_3_2gf.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path regnet_x_3_2gf_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine regnet_x_3_2gf_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ No newline at end of file diff --git a/models/cv/classification/regnet_x_3_2gf/igie/scripts/infer_regnet_x_3_2gf_fp16_performance.sh b/models/cv/classification/regnet_x_3_2gf/igie/scripts/infer_regnet_x_3_2gf_fp16_performance.sh new file mode 100644 index 00000000..33d10156 --- /dev/null +++ b/models/cv/classification/regnet_x_3_2gf/igie/scripts/infer_regnet_x_3_2gf_fp16_performance.sh @@ -0,0 +1,36 @@ +#!/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. + +batchsize=32 +model_path="regnet_x_3_2gf.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path regnet_x_3_2gf_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine regnet_x_3_2gf_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ + --perf_only True \ No newline at end of file -- Gitee From c7e0d013a00c43ad812794ee8d91531e18a02b93 Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Wed, 9 Apr 2025 16:46:35 +0800 Subject: [PATCH 06/10] Add: regnet_y_16gf inference script. --- .../regnet_y_16gf/igie/README.md | 53 +++++ .../regnet_y_16gf/igie/build_engine.py | 73 +++++++ .../regnet_y_16gf/igie/ci/prepare.sh | 20 ++ .../regnet_y_16gf/igie/export.py | 61 ++++++ .../regnet_y_16gf/igie/inference.py | 186 ++++++++++++++++++ .../regnet_y_16gf/igie/requirements.txt | 2 + .../infer_regnet_y_16gf_fp16_accuracy.sh | 35 ++++ .../infer_regnet_y_16gf_fp16_performance.sh | 36 ++++ 8 files changed, 466 insertions(+) create mode 100644 models/cv/classification/regnet_y_16gf/igie/README.md create mode 100644 models/cv/classification/regnet_y_16gf/igie/build_engine.py create mode 100644 models/cv/classification/regnet_y_16gf/igie/ci/prepare.sh create mode 100644 models/cv/classification/regnet_y_16gf/igie/export.py create mode 100644 models/cv/classification/regnet_y_16gf/igie/inference.py create mode 100644 models/cv/classification/regnet_y_16gf/igie/requirements.txt create mode 100644 models/cv/classification/regnet_y_16gf/igie/scripts/infer_regnet_y_16gf_fp16_accuracy.sh create mode 100644 models/cv/classification/regnet_y_16gf/igie/scripts/infer_regnet_y_16gf_fp16_performance.sh diff --git a/models/cv/classification/regnet_y_16gf/igie/README.md b/models/cv/classification/regnet_y_16gf/igie/README.md new file mode 100644 index 00000000..04883b79 --- /dev/null +++ b/models/cv/classification/regnet_y_16gf/igie/README.md @@ -0,0 +1,53 @@ +# RegNet_y_16gf (IGIE) + +## Model Description + +RegNet_y_16gf is an efficient convolutional neural network model in the RegNet family, proposed by Facebook AI, inspired by the paper *Designing Network Design Spaces*. The RegNet series systematically optimizes convolutional network structures through parameterized design methods, aiming to balance high performance and efficiency. RegNet_y_16gf belongs to the RegNet-Y branch, featuring approximately 16 GFLOPs of computational complexity, making it suitable for vision tasks in high-computation-resource scenarios. + + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +|--------|-----------|---------| +| MR-V100 | 4.2.0 | 25.06 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --weight regnet_y_16gf-9e6ed7dd.pth --output regnet_y_16gf.onnx +``` + +## Model Inference + +```bash +export DATASETS_DIR=/Path/to/imagenet_val/ +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_regnet_y_16gf_fp16_accuracy.sh +# Performance +bash scripts/infer_regnet_y_16gf_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +|---------------|-----------|-----------|---------|----------|----------| +| RegNet_y_16gf | 32 | FP16 | 689.918 | 80.398 | 95.214 | diff --git a/models/cv/classification/regnet_y_16gf/igie/build_engine.py b/models/cv/classification/regnet_y_16gf/igie/build_engine.py new file mode 100644 index 00000000..d3626ae7 --- /dev/null +++ b/models/cv/classification/regnet_y_16gf/igie/build_engine.py @@ -0,0 +1,73 @@ +# 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 tvm +import argparse +from tvm import relay +from tvm.relay.import_model import import_model_to_igie + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--model_path", + type=str, + required=True, + help="original model path.") + + parser.add_argument("--engine_path", + type=str, + required=True, + help="igie export engine path.") + + parser.add_argument("--input", + type=str, + required=True, + help=""" + input info of the model, format should be: + input_name:input_shape + eg: --input input:1,3,224,224. + """) + + parser.add_argument("--precision", + type=str, + choices=["fp32", "fp16", "int8"], + required=True, + help="model inference precision.") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + # get input valueinfo + input_name, input_shape = args.input.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_dict = {input_name: shape} + + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + + mod, params = import_model_to_igie(args.model_path, input_dict, backend="igie") + + # build engine + lib = tvm.relay.build(mod, target=target, params=params, precision=args.precision) + + # export engine + lib.export_library(args.engine_path) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/regnet_y_16gf/igie/ci/prepare.sh b/models/cv/classification/regnet_y_16gf/igie/ci/prepare.sh new file mode 100644 index 00000000..6cd67cab --- /dev/null +++ b/models/cv/classification/regnet_y_16gf/igie/ci/prepare.sh @@ -0,0 +1,20 @@ +#!/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. + +set -x + +pip3 install -r requirements.txt +python3 export.py --weight regnet_y_16gf-9e6ed7dd.pth --output regnet_y_16gf.onnx \ No newline at end of file diff --git a/models/cv/classification/regnet_y_16gf/igie/export.py b/models/cv/classification/regnet_y_16gf/igie/export.py new file mode 100644 index 00000000..e04ad5bf --- /dev/null +++ b/models/cv/classification/regnet_y_16gf/igie/export.py @@ -0,0 +1,61 @@ +# 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 torch +import torchvision +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--weight", + type=str, + required=True, + help="pytorch model weight.") + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + model = torchvision.models.regnet_y_16gf() + model.load_state_dict(torch.load(args.weight)) + model.eval() + + input_names = ['input'] + output_names = ['output'] + dynamic_axes = {'input': {0: '-1'}, 'output': {0: '-1'}} + dummy_input = torch.randn(1, 3, 224, 224) + + torch.onnx.export( + model, + dummy_input, + args.output, + input_names = input_names, + dynamic_axes = dynamic_axes, + output_names = output_names, + opset_version=13 + ) + + print("Export onnx model successfully! ") + +if __name__ == "__main__": + main() diff --git a/models/cv/classification/regnet_y_16gf/igie/inference.py b/models/cv/classification/regnet_y_16gf/igie/inference.py new file mode 100644 index 00000000..3aef3ec7 --- /dev/null +++ b/models/cv/classification/regnet_y_16gf/igie/inference.py @@ -0,0 +1,186 @@ +# 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 sys +import argparse +import tvm +import torch +import torchvision +import numpy as np +from tvm import relay +from tqdm import tqdm +from torchvision import transforms +from torchvision.transforms.functional import InterpolationMode + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="igie engine path.") + + 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("--input_name", + type=str, + required=True, + help="input name of the model.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--num_workers", + type=int, + default=16, + help="number of workers used in pytorch dataloader.") + + 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 get_dataloader(data_path, batch_size, num_workers): + dataset = torchvision.datasets.ImageFolder( + data_path, + transforms.Compose( + [ + transforms.Resize(256, interpolation=InterpolationMode.BILINEAR), + transforms.CenterCrop(224), + transforms.PILToTensor(), + transforms.ConvertImageDtype(torch.float), + transforms.Normalize( + mean=(0.485, 0.456, 0.406), + std=(0.229, 0.224, 0.225) + ) + ] + ) + ) + + dataloader = torch.utils.data.DataLoader(dataset, batch_size, num_workers=num_workers) + + return dataloader + +def get_topk_accuracy(pred, label): + if isinstance(pred, np.ndarray): + pred = torch.from_numpy(pred) + + if isinstance(label, np.ndarray): + label = torch.from_numpy(label) + + top1_acc = 0 + top5_acc = 0 + for idx in range(len(label)): + label_value = label[idx] + if label_value == torch.topk(pred[idx].float(), 1).indices.data: + top1_acc += 1 + top5_acc += 1 + + elif label_value in torch.topk(pred[idx].float(), 5).indices.data: + top5_acc += 1 + + return top1_acc, top5_acc + +def main(): + args = parse_args() + + batch_size = args.batchsize + + # create iluvatar target & device + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + device = tvm.device(target.kind.name, 0) + + # load engine + lib = tvm.runtime.load_module(args.engine) + + # create runtime from engine + module = tvm.contrib.graph_executor.GraphModule(lib["default"](device)) + + # just run perf test + if args.perf_only: + ftimer = module.module.time_evaluator("run", device, number=100, repeat=1) + prof_res = np.array(ftimer().results) * 1000 + fps = batch_size * 1000 / np.mean(prof_res) + print(f"\n* Mean inference time: {np.mean(prof_res):.3f} ms, Mean fps: {fps:.3f}") + else: + # warm up + for _ in range(args.warmup): + module.run() + + # get dataloader + dataloader = get_dataloader(args.datasets, batch_size, args.num_workers) + + top1_acc = 0 + top5_acc = 0 + total_num = 0 + + for image, label in tqdm(dataloader): + + # pad the last batch + pad_batch = len(image) != batch_size + + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + + module.set_input(args.input_name, tvm.nd.array(image, device)) + + # run inference + module.run() + + pred = module.get_output(0).asnumpy() + + if pad_batch: + pred = pred[:origin_size] + + # get batch accuracy + batch_top1_acc, batch_top5_acc = get_topk_accuracy(pred, label) + + top1_acc += batch_top1_acc + top5_acc += batch_top5_acc + total_num += batch_size + + result_stat = {} + result_stat["acc@1"] = round(top1_acc / total_num * 100.0, 3) + result_stat["acc@5"] = round(top5_acc / total_num * 100.0, 3) + + print(f"\n* Top1 acc: {result_stat['acc@1']} %, Top5 acc: {result_stat['acc@5']} %") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/regnet_y_16gf/igie/requirements.txt b/models/cv/classification/regnet_y_16gf/igie/requirements.txt new file mode 100644 index 00000000..9e811126 --- /dev/null +++ b/models/cv/classification/regnet_y_16gf/igie/requirements.txt @@ -0,0 +1,2 @@ +onnx +tqdm diff --git a/models/cv/classification/regnet_y_16gf/igie/scripts/infer_regnet_y_16gf_fp16_accuracy.sh b/models/cv/classification/regnet_y_16gf/igie/scripts/infer_regnet_y_16gf_fp16_accuracy.sh new file mode 100644 index 00000000..9866c217 --- /dev/null +++ b/models/cv/classification/regnet_y_16gf/igie/scripts/infer_regnet_y_16gf_fp16_accuracy.sh @@ -0,0 +1,35 @@ +#!/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. + +batchsize=32 +model_path="regnet_y_16gf.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path regnet_y_16gf_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine regnet_y_16gf_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ No newline at end of file diff --git a/models/cv/classification/regnet_y_16gf/igie/scripts/infer_regnet_y_16gf_fp16_performance.sh b/models/cv/classification/regnet_y_16gf/igie/scripts/infer_regnet_y_16gf_fp16_performance.sh new file mode 100644 index 00000000..13c58ce0 --- /dev/null +++ b/models/cv/classification/regnet_y_16gf/igie/scripts/infer_regnet_y_16gf_fp16_performance.sh @@ -0,0 +1,36 @@ +#!/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. + +batchsize=32 +model_path="regnet_y_16gf.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path regnet_y_16gf_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine regnet_y_16gf_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ + --perf_only True \ No newline at end of file -- Gitee From 4f78ef968a778f1bfdeab4303d05051ee676999f Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Wed, 9 Apr 2025 16:59:42 +0800 Subject: [PATCH 07/10] Add: squeezenet_v1_1 inference script. --- .../squeezenet_v1_1/igie/README.md | 52 +++++ .../squeezenet_v1_1/igie/build_engine.py | 73 +++++++ .../squeezenet_v1_1/igie/ci/prepare.sh | 20 ++ .../squeezenet_v1_1/igie/export.py | 61 ++++++ .../squeezenet_v1_1/igie/inference.py | 186 ++++++++++++++++++ .../squeezenet_v1_1/igie/requirements.txt | 2 + .../infer_squeezenet_v1_1_fp16_accuracy.sh | 35 ++++ .../infer_squeezenet_v1_1_fp16_performance.sh | 36 ++++ 8 files changed, 465 insertions(+) create mode 100644 models/cv/classification/squeezenet_v1_1/igie/README.md create mode 100644 models/cv/classification/squeezenet_v1_1/igie/build_engine.py create mode 100644 models/cv/classification/squeezenet_v1_1/igie/ci/prepare.sh create mode 100644 models/cv/classification/squeezenet_v1_1/igie/export.py create mode 100644 models/cv/classification/squeezenet_v1_1/igie/inference.py create mode 100644 models/cv/classification/squeezenet_v1_1/igie/requirements.txt create mode 100644 models/cv/classification/squeezenet_v1_1/igie/scripts/infer_squeezenet_v1_1_fp16_accuracy.sh create mode 100644 models/cv/classification/squeezenet_v1_1/igie/scripts/infer_squeezenet_v1_1_fp16_performance.sh diff --git a/models/cv/classification/squeezenet_v1_1/igie/README.md b/models/cv/classification/squeezenet_v1_1/igie/README.md new file mode 100644 index 00000000..0340f671 --- /dev/null +++ b/models/cv/classification/squeezenet_v1_1/igie/README.md @@ -0,0 +1,52 @@ +# SqueezeNet1_1 (IGIE) + +## Model Description + +SqueezeNet 1.1 is an improved version of SqueezeNet, designed for efficient computation in resource-constrained environments. It retains the core idea of SqueezeNet , significantly reduce the number of parameters and model size while maintaining high classification performance. Compared to SqueezeNet 1.0, version 1.1 further optimizes the network structure by reducing the number of channels, adjusting the strides of certain convolution layers, and simplifying the model design, resulting in faster inference and higher efficiency. + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +|--------|-----------|---------| +| MR-V100 | 4.2.0 | 25.03 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --weight squeezenet1_1-b8a52dc0.pth --output squeezenet1_1.onnx +``` + +## Model Inference + +```bash +export DATASETS_DIR=/Path/to/imagenet_val/ +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_squeezenet_v1_1_fp16_accuracy.sh +# Performance +bash scripts/infer_squeezenet_v1_1_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +|-----------------|-----------|-----------|---------|----------|----------| +| Squeezenet_v1_1 | 32 | FP16 | 14815.8 | 58.14 | 80.58 | diff --git a/models/cv/classification/squeezenet_v1_1/igie/build_engine.py b/models/cv/classification/squeezenet_v1_1/igie/build_engine.py new file mode 100644 index 00000000..d3626ae7 --- /dev/null +++ b/models/cv/classification/squeezenet_v1_1/igie/build_engine.py @@ -0,0 +1,73 @@ +# 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 tvm +import argparse +from tvm import relay +from tvm.relay.import_model import import_model_to_igie + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--model_path", + type=str, + required=True, + help="original model path.") + + parser.add_argument("--engine_path", + type=str, + required=True, + help="igie export engine path.") + + parser.add_argument("--input", + type=str, + required=True, + help=""" + input info of the model, format should be: + input_name:input_shape + eg: --input input:1,3,224,224. + """) + + parser.add_argument("--precision", + type=str, + choices=["fp32", "fp16", "int8"], + required=True, + help="model inference precision.") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + # get input valueinfo + input_name, input_shape = args.input.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_dict = {input_name: shape} + + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + + mod, params = import_model_to_igie(args.model_path, input_dict, backend="igie") + + # build engine + lib = tvm.relay.build(mod, target=target, params=params, precision=args.precision) + + # export engine + lib.export_library(args.engine_path) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/squeezenet_v1_1/igie/ci/prepare.sh b/models/cv/classification/squeezenet_v1_1/igie/ci/prepare.sh new file mode 100644 index 00000000..9e773412 --- /dev/null +++ b/models/cv/classification/squeezenet_v1_1/igie/ci/prepare.sh @@ -0,0 +1,20 @@ +#!/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. + +set -x + +pip3 install -r requirements.txt +python3 export.py --weight squeezenet1_1-b8a52dc0.pth --output squeezenet1_1.onnx \ No newline at end of file diff --git a/models/cv/classification/squeezenet_v1_1/igie/export.py b/models/cv/classification/squeezenet_v1_1/igie/export.py new file mode 100644 index 00000000..5ef2543a --- /dev/null +++ b/models/cv/classification/squeezenet_v1_1/igie/export.py @@ -0,0 +1,61 @@ +# 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 torch +import torchvision +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--weight", + type=str, + required=True, + help="pytorch model weight.") + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + model = torchvision.models.squeezenet1_1() + model.load_state_dict(torch.load(args.weight)) + model.eval() + + input_names = ['input'] + output_names = ['output'] + dynamic_axes = {'input': {0: '-1'}, 'output': {0: '-1'}} + dummy_input = torch.randn(1, 3, 224, 224) + + torch.onnx.export( + model, + dummy_input, + args.output, + input_names = input_names, + dynamic_axes = dynamic_axes, + output_names = output_names, + opset_version=13 + ) + + print("Export onnx model successfully! ") + +if __name__ == "__main__": + main() diff --git a/models/cv/classification/squeezenet_v1_1/igie/inference.py b/models/cv/classification/squeezenet_v1_1/igie/inference.py new file mode 100644 index 00000000..3aef3ec7 --- /dev/null +++ b/models/cv/classification/squeezenet_v1_1/igie/inference.py @@ -0,0 +1,186 @@ +# 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 sys +import argparse +import tvm +import torch +import torchvision +import numpy as np +from tvm import relay +from tqdm import tqdm +from torchvision import transforms +from torchvision.transforms.functional import InterpolationMode + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="igie engine path.") + + 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("--input_name", + type=str, + required=True, + help="input name of the model.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--num_workers", + type=int, + default=16, + help="number of workers used in pytorch dataloader.") + + 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 get_dataloader(data_path, batch_size, num_workers): + dataset = torchvision.datasets.ImageFolder( + data_path, + transforms.Compose( + [ + transforms.Resize(256, interpolation=InterpolationMode.BILINEAR), + transforms.CenterCrop(224), + transforms.PILToTensor(), + transforms.ConvertImageDtype(torch.float), + transforms.Normalize( + mean=(0.485, 0.456, 0.406), + std=(0.229, 0.224, 0.225) + ) + ] + ) + ) + + dataloader = torch.utils.data.DataLoader(dataset, batch_size, num_workers=num_workers) + + return dataloader + +def get_topk_accuracy(pred, label): + if isinstance(pred, np.ndarray): + pred = torch.from_numpy(pred) + + if isinstance(label, np.ndarray): + label = torch.from_numpy(label) + + top1_acc = 0 + top5_acc = 0 + for idx in range(len(label)): + label_value = label[idx] + if label_value == torch.topk(pred[idx].float(), 1).indices.data: + top1_acc += 1 + top5_acc += 1 + + elif label_value in torch.topk(pred[idx].float(), 5).indices.data: + top5_acc += 1 + + return top1_acc, top5_acc + +def main(): + args = parse_args() + + batch_size = args.batchsize + + # create iluvatar target & device + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + device = tvm.device(target.kind.name, 0) + + # load engine + lib = tvm.runtime.load_module(args.engine) + + # create runtime from engine + module = tvm.contrib.graph_executor.GraphModule(lib["default"](device)) + + # just run perf test + if args.perf_only: + ftimer = module.module.time_evaluator("run", device, number=100, repeat=1) + prof_res = np.array(ftimer().results) * 1000 + fps = batch_size * 1000 / np.mean(prof_res) + print(f"\n* Mean inference time: {np.mean(prof_res):.3f} ms, Mean fps: {fps:.3f}") + else: + # warm up + for _ in range(args.warmup): + module.run() + + # get dataloader + dataloader = get_dataloader(args.datasets, batch_size, args.num_workers) + + top1_acc = 0 + top5_acc = 0 + total_num = 0 + + for image, label in tqdm(dataloader): + + # pad the last batch + pad_batch = len(image) != batch_size + + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + + module.set_input(args.input_name, tvm.nd.array(image, device)) + + # run inference + module.run() + + pred = module.get_output(0).asnumpy() + + if pad_batch: + pred = pred[:origin_size] + + # get batch accuracy + batch_top1_acc, batch_top5_acc = get_topk_accuracy(pred, label) + + top1_acc += batch_top1_acc + top5_acc += batch_top5_acc + total_num += batch_size + + result_stat = {} + result_stat["acc@1"] = round(top1_acc / total_num * 100.0, 3) + result_stat["acc@5"] = round(top5_acc / total_num * 100.0, 3) + + print(f"\n* Top1 acc: {result_stat['acc@1']} %, Top5 acc: {result_stat['acc@5']} %") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/squeezenet_v1_1/igie/requirements.txt b/models/cv/classification/squeezenet_v1_1/igie/requirements.txt new file mode 100644 index 00000000..9e811126 --- /dev/null +++ b/models/cv/classification/squeezenet_v1_1/igie/requirements.txt @@ -0,0 +1,2 @@ +onnx +tqdm diff --git a/models/cv/classification/squeezenet_v1_1/igie/scripts/infer_squeezenet_v1_1_fp16_accuracy.sh b/models/cv/classification/squeezenet_v1_1/igie/scripts/infer_squeezenet_v1_1_fp16_accuracy.sh new file mode 100644 index 00000000..53b5ec37 --- /dev/null +++ b/models/cv/classification/squeezenet_v1_1/igie/scripts/infer_squeezenet_v1_1_fp16_accuracy.sh @@ -0,0 +1,35 @@ +#!/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. + +batchsize=32 +model_path="squeezenet1_1.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path squeezenet1_1_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine squeezenet1_1_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ No newline at end of file diff --git a/models/cv/classification/squeezenet_v1_1/igie/scripts/infer_squeezenet_v1_1_fp16_performance.sh b/models/cv/classification/squeezenet_v1_1/igie/scripts/infer_squeezenet_v1_1_fp16_performance.sh new file mode 100644 index 00000000..876bf88e --- /dev/null +++ b/models/cv/classification/squeezenet_v1_1/igie/scripts/infer_squeezenet_v1_1_fp16_performance.sh @@ -0,0 +1,36 @@ +#!/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. + +batchsize=32 +model_path="squeezenet1_1.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path squeezenet1_1_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine squeezenet1_1_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ + --perf_only True \ No newline at end of file -- Gitee From 9ddf8449ef647f1ad702f9145b0a28f0cd1575a4 Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Wed, 9 Apr 2025 17:13:46 +0800 Subject: [PATCH 08/10] Add: vgg19 inference script. --- models/cv/classification/vgg19/igie/README.md | 52 +++++ .../classification/vgg19/igie/build_engine.py | 73 +++++++ .../classification/vgg19/igie/ci/prepare.sh | 20 ++ models/cv/classification/vgg19/igie/export.py | 61 ++++++ .../cv/classification/vgg19/igie/inference.py | 186 ++++++++++++++++++ .../vgg19/igie/requirements.txt | 2 + .../igie/scripts/infer_vgg19_fp16_accuracy.sh | 35 ++++ .../scripts/infer_vgg19_fp16_performance.sh | 36 ++++ 8 files changed, 465 insertions(+) create mode 100644 models/cv/classification/vgg19/igie/README.md create mode 100644 models/cv/classification/vgg19/igie/build_engine.py create mode 100644 models/cv/classification/vgg19/igie/ci/prepare.sh create mode 100644 models/cv/classification/vgg19/igie/export.py create mode 100644 models/cv/classification/vgg19/igie/inference.py create mode 100644 models/cv/classification/vgg19/igie/requirements.txt create mode 100644 models/cv/classification/vgg19/igie/scripts/infer_vgg19_fp16_accuracy.sh create mode 100644 models/cv/classification/vgg19/igie/scripts/infer_vgg19_fp16_performance.sh diff --git a/models/cv/classification/vgg19/igie/README.md b/models/cv/classification/vgg19/igie/README.md new file mode 100644 index 00000000..13c52f5f --- /dev/null +++ b/models/cv/classification/vgg19/igie/README.md @@ -0,0 +1,52 @@ +# VGG19 (IGIE) + +## Model Description + +VGG19 is a member of the VGG network family, proposed by the Visual Geometry Group at the University of Oxford, originally designed for the ImageNet image classification task. Known for its deep structure and simple convolutional module design, VGG19 is one of the deepest models in the series, featuring 19 weight layers (16 convolutional layers and 3 fully connected layers). Its depth and regular network design achieved outstanding classification performance at the time. + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +|--------|-----------|---------| +| MR-V100 | 4.2.0 | 25.06 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --weight vgg19-dcbb9e9d.pth --output vgg19.onnx +``` + +## Model Inference + +```bash +export DATASETS_DIR=/Path/to/imagenet_val/ +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_vgg19_fp16_accuracy.sh +# Performance +bash scripts/infer_vgg19_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +|-------|-----------|-----------|---------|----------|----------| +| VGG19 | 32 | FP16 | 1654.54 | 72.353 | 90.853 | diff --git a/models/cv/classification/vgg19/igie/build_engine.py b/models/cv/classification/vgg19/igie/build_engine.py new file mode 100644 index 00000000..d3626ae7 --- /dev/null +++ b/models/cv/classification/vgg19/igie/build_engine.py @@ -0,0 +1,73 @@ +# 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 tvm +import argparse +from tvm import relay +from tvm.relay.import_model import import_model_to_igie + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--model_path", + type=str, + required=True, + help="original model path.") + + parser.add_argument("--engine_path", + type=str, + required=True, + help="igie export engine path.") + + parser.add_argument("--input", + type=str, + required=True, + help=""" + input info of the model, format should be: + input_name:input_shape + eg: --input input:1,3,224,224. + """) + + parser.add_argument("--precision", + type=str, + choices=["fp32", "fp16", "int8"], + required=True, + help="model inference precision.") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + # get input valueinfo + input_name, input_shape = args.input.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_dict = {input_name: shape} + + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + + mod, params = import_model_to_igie(args.model_path, input_dict, backend="igie") + + # build engine + lib = tvm.relay.build(mod, target=target, params=params, precision=args.precision) + + # export engine + lib.export_library(args.engine_path) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/vgg19/igie/ci/prepare.sh b/models/cv/classification/vgg19/igie/ci/prepare.sh new file mode 100644 index 00000000..fa5c3992 --- /dev/null +++ b/models/cv/classification/vgg19/igie/ci/prepare.sh @@ -0,0 +1,20 @@ +#!/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. + +set -x + +pip3 install -r requirements.txt +python3 export.py --weight vgg19-dcbb9e9d.pth --output vgg19.onnx diff --git a/models/cv/classification/vgg19/igie/export.py b/models/cv/classification/vgg19/igie/export.py new file mode 100644 index 00000000..924d0628 --- /dev/null +++ b/models/cv/classification/vgg19/igie/export.py @@ -0,0 +1,61 @@ +# 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 torch +import torchvision +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--weight", + type=str, + required=True, + help="pytorch model weight.") + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + model = torchvision.models.vgg19() + model.load_state_dict(torch.load(args.weight)) + model.eval() + + input_names = ['input'] + output_names = ['output'] + dynamic_axes = {'input': {0: '-1'}, 'output': {0: '-1'}} + dummy_input = torch.randn(1, 3, 224, 224) + + torch.onnx.export( + model, + dummy_input, + args.output, + input_names = input_names, + dynamic_axes = dynamic_axes, + output_names = output_names, + opset_version=13 + ) + + print("Export onnx model successfully! ") + +if __name__ == "__main__": + main() diff --git a/models/cv/classification/vgg19/igie/inference.py b/models/cv/classification/vgg19/igie/inference.py new file mode 100644 index 00000000..3aef3ec7 --- /dev/null +++ b/models/cv/classification/vgg19/igie/inference.py @@ -0,0 +1,186 @@ +# 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 sys +import argparse +import tvm +import torch +import torchvision +import numpy as np +from tvm import relay +from tqdm import tqdm +from torchvision import transforms +from torchvision.transforms.functional import InterpolationMode + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="igie engine path.") + + 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("--input_name", + type=str, + required=True, + help="input name of the model.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--num_workers", + type=int, + default=16, + help="number of workers used in pytorch dataloader.") + + 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 get_dataloader(data_path, batch_size, num_workers): + dataset = torchvision.datasets.ImageFolder( + data_path, + transforms.Compose( + [ + transforms.Resize(256, interpolation=InterpolationMode.BILINEAR), + transforms.CenterCrop(224), + transforms.PILToTensor(), + transforms.ConvertImageDtype(torch.float), + transforms.Normalize( + mean=(0.485, 0.456, 0.406), + std=(0.229, 0.224, 0.225) + ) + ] + ) + ) + + dataloader = torch.utils.data.DataLoader(dataset, batch_size, num_workers=num_workers) + + return dataloader + +def get_topk_accuracy(pred, label): + if isinstance(pred, np.ndarray): + pred = torch.from_numpy(pred) + + if isinstance(label, np.ndarray): + label = torch.from_numpy(label) + + top1_acc = 0 + top5_acc = 0 + for idx in range(len(label)): + label_value = label[idx] + if label_value == torch.topk(pred[idx].float(), 1).indices.data: + top1_acc += 1 + top5_acc += 1 + + elif label_value in torch.topk(pred[idx].float(), 5).indices.data: + top5_acc += 1 + + return top1_acc, top5_acc + +def main(): + args = parse_args() + + batch_size = args.batchsize + + # create iluvatar target & device + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + device = tvm.device(target.kind.name, 0) + + # load engine + lib = tvm.runtime.load_module(args.engine) + + # create runtime from engine + module = tvm.contrib.graph_executor.GraphModule(lib["default"](device)) + + # just run perf test + if args.perf_only: + ftimer = module.module.time_evaluator("run", device, number=100, repeat=1) + prof_res = np.array(ftimer().results) * 1000 + fps = batch_size * 1000 / np.mean(prof_res) + print(f"\n* Mean inference time: {np.mean(prof_res):.3f} ms, Mean fps: {fps:.3f}") + else: + # warm up + for _ in range(args.warmup): + module.run() + + # get dataloader + dataloader = get_dataloader(args.datasets, batch_size, args.num_workers) + + top1_acc = 0 + top5_acc = 0 + total_num = 0 + + for image, label in tqdm(dataloader): + + # pad the last batch + pad_batch = len(image) != batch_size + + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + + module.set_input(args.input_name, tvm.nd.array(image, device)) + + # run inference + module.run() + + pred = module.get_output(0).asnumpy() + + if pad_batch: + pred = pred[:origin_size] + + # get batch accuracy + batch_top1_acc, batch_top5_acc = get_topk_accuracy(pred, label) + + top1_acc += batch_top1_acc + top5_acc += batch_top5_acc + total_num += batch_size + + result_stat = {} + result_stat["acc@1"] = round(top1_acc / total_num * 100.0, 3) + result_stat["acc@5"] = round(top5_acc / total_num * 100.0, 3) + + print(f"\n* Top1 acc: {result_stat['acc@1']} %, Top5 acc: {result_stat['acc@5']} %") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/vgg19/igie/requirements.txt b/models/cv/classification/vgg19/igie/requirements.txt new file mode 100644 index 00000000..9e811126 --- /dev/null +++ b/models/cv/classification/vgg19/igie/requirements.txt @@ -0,0 +1,2 @@ +onnx +tqdm diff --git a/models/cv/classification/vgg19/igie/scripts/infer_vgg19_fp16_accuracy.sh b/models/cv/classification/vgg19/igie/scripts/infer_vgg19_fp16_accuracy.sh new file mode 100644 index 00000000..c84808c3 --- /dev/null +++ b/models/cv/classification/vgg19/igie/scripts/infer_vgg19_fp16_accuracy.sh @@ -0,0 +1,35 @@ +#!/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. + +batchsize=32 +model_path="vgg19.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path vgg19_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine vgg19_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ No newline at end of file diff --git a/models/cv/classification/vgg19/igie/scripts/infer_vgg19_fp16_performance.sh b/models/cv/classification/vgg19/igie/scripts/infer_vgg19_fp16_performance.sh new file mode 100644 index 00000000..ddb7b362 --- /dev/null +++ b/models/cv/classification/vgg19/igie/scripts/infer_vgg19_fp16_performance.sh @@ -0,0 +1,36 @@ +#!/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. + +batchsize=32 +model_path="vgg19.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path vgg19_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine vgg19_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ + --perf_only True \ No newline at end of file -- Gitee From 4241a80cf38704136ea43ada146aa974f0a37bbd Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Wed, 9 Apr 2025 17:37:08 +0800 Subject: [PATCH 09/10] Add: vgg19_bn inference script. --- .../cv/classification/vgg19_bn/igie/README.md | 52 +++++ .../vgg19_bn/igie/build_engine.py | 73 +++++++ .../vgg19_bn/igie/ci/prepare.sh | 20 ++ .../cv/classification/vgg19_bn/igie/export.py | 61 ++++++ .../classification/vgg19_bn/igie/inference.py | 186 ++++++++++++++++++ .../vgg19_bn/igie/requirements.txt | 2 + .../scripts/infer_vgg19_bn_fp16_accuracy.sh | 35 ++++ .../infer_vgg19_bn_fp16_performance.sh | 36 ++++ 8 files changed, 465 insertions(+) create mode 100644 models/cv/classification/vgg19_bn/igie/README.md create mode 100644 models/cv/classification/vgg19_bn/igie/build_engine.py create mode 100644 models/cv/classification/vgg19_bn/igie/ci/prepare.sh create mode 100644 models/cv/classification/vgg19_bn/igie/export.py create mode 100644 models/cv/classification/vgg19_bn/igie/inference.py create mode 100644 models/cv/classification/vgg19_bn/igie/requirements.txt create mode 100644 models/cv/classification/vgg19_bn/igie/scripts/infer_vgg19_bn_fp16_accuracy.sh create mode 100644 models/cv/classification/vgg19_bn/igie/scripts/infer_vgg19_bn_fp16_performance.sh diff --git a/models/cv/classification/vgg19_bn/igie/README.md b/models/cv/classification/vgg19_bn/igie/README.md new file mode 100644 index 00000000..7983ed24 --- /dev/null +++ b/models/cv/classification/vgg19_bn/igie/README.md @@ -0,0 +1,52 @@ +# VGG19_BN (IGIE) + +## Model Description + +VGG19_BN is a variant of the VGG network, based on VGG19 with the addition of Batch Normalization (BN) layers. Batch Normalization is a technique used to accelerate training and improve model stability by normalizing the activation values of each layer. Compared to the original VGG19, VGG19_BN introduces Batch Normalization layers after each convolutional layer, further enhancing the model's training performance and generalization ability. + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +|--------|-----------|---------| +| MR-V100 | 4.2.0 | 25.06 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --weight vgg19_bn-c79401a0.pth --output vgg19_bn.onnx +``` + +## Model Inference + +```bash +export DATASETS_DIR=/Path/to/imagenet_val/ +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_vgg19_bn_fp16_accuracy.sh +# Performance +bash scripts/infer_vgg19_bn_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +|----------|-----------|-----------|---------|----------|----------| +| VGG19_BN | 32 | FP16 | 1654.42 | 74.216 | 91.809 | diff --git a/models/cv/classification/vgg19_bn/igie/build_engine.py b/models/cv/classification/vgg19_bn/igie/build_engine.py new file mode 100644 index 00000000..d3626ae7 --- /dev/null +++ b/models/cv/classification/vgg19_bn/igie/build_engine.py @@ -0,0 +1,73 @@ +# 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 tvm +import argparse +from tvm import relay +from tvm.relay.import_model import import_model_to_igie + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--model_path", + type=str, + required=True, + help="original model path.") + + parser.add_argument("--engine_path", + type=str, + required=True, + help="igie export engine path.") + + parser.add_argument("--input", + type=str, + required=True, + help=""" + input info of the model, format should be: + input_name:input_shape + eg: --input input:1,3,224,224. + """) + + parser.add_argument("--precision", + type=str, + choices=["fp32", "fp16", "int8"], + required=True, + help="model inference precision.") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + # get input valueinfo + input_name, input_shape = args.input.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_dict = {input_name: shape} + + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + + mod, params = import_model_to_igie(args.model_path, input_dict, backend="igie") + + # build engine + lib = tvm.relay.build(mod, target=target, params=params, precision=args.precision) + + # export engine + lib.export_library(args.engine_path) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/vgg19_bn/igie/ci/prepare.sh b/models/cv/classification/vgg19_bn/igie/ci/prepare.sh new file mode 100644 index 00000000..436c5b0c --- /dev/null +++ b/models/cv/classification/vgg19_bn/igie/ci/prepare.sh @@ -0,0 +1,20 @@ +#!/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. + +set -x + +pip3 install -r requirements.txt +python3 export.py --weight vgg19_bn-c79401a0.pth --output vgg19_bn.onnx diff --git a/models/cv/classification/vgg19_bn/igie/export.py b/models/cv/classification/vgg19_bn/igie/export.py new file mode 100644 index 00000000..7b8a2971 --- /dev/null +++ b/models/cv/classification/vgg19_bn/igie/export.py @@ -0,0 +1,61 @@ +# 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 torch +import torchvision +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--weight", + type=str, + required=True, + help="pytorch model weight.") + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + model = torchvision.models.vgg19_bn() + model.load_state_dict(torch.load(args.weight)) + model.eval() + + input_names = ['input'] + output_names = ['output'] + dynamic_axes = {'input': {0: '-1'}, 'output': {0: '-1'}} + dummy_input = torch.randn(1, 3, 224, 224) + + torch.onnx.export( + model, + dummy_input, + args.output, + input_names = input_names, + dynamic_axes = dynamic_axes, + output_names = output_names, + opset_version=13 + ) + + print("Export onnx model successfully! ") + +if __name__ == "__main__": + main() diff --git a/models/cv/classification/vgg19_bn/igie/inference.py b/models/cv/classification/vgg19_bn/igie/inference.py new file mode 100644 index 00000000..3aef3ec7 --- /dev/null +++ b/models/cv/classification/vgg19_bn/igie/inference.py @@ -0,0 +1,186 @@ +# 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 sys +import argparse +import tvm +import torch +import torchvision +import numpy as np +from tvm import relay +from tqdm import tqdm +from torchvision import transforms +from torchvision.transforms.functional import InterpolationMode + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="igie engine path.") + + 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("--input_name", + type=str, + required=True, + help="input name of the model.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--num_workers", + type=int, + default=16, + help="number of workers used in pytorch dataloader.") + + 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 get_dataloader(data_path, batch_size, num_workers): + dataset = torchvision.datasets.ImageFolder( + data_path, + transforms.Compose( + [ + transforms.Resize(256, interpolation=InterpolationMode.BILINEAR), + transforms.CenterCrop(224), + transforms.PILToTensor(), + transforms.ConvertImageDtype(torch.float), + transforms.Normalize( + mean=(0.485, 0.456, 0.406), + std=(0.229, 0.224, 0.225) + ) + ] + ) + ) + + dataloader = torch.utils.data.DataLoader(dataset, batch_size, num_workers=num_workers) + + return dataloader + +def get_topk_accuracy(pred, label): + if isinstance(pred, np.ndarray): + pred = torch.from_numpy(pred) + + if isinstance(label, np.ndarray): + label = torch.from_numpy(label) + + top1_acc = 0 + top5_acc = 0 + for idx in range(len(label)): + label_value = label[idx] + if label_value == torch.topk(pred[idx].float(), 1).indices.data: + top1_acc += 1 + top5_acc += 1 + + elif label_value in torch.topk(pred[idx].float(), 5).indices.data: + top5_acc += 1 + + return top1_acc, top5_acc + +def main(): + args = parse_args() + + batch_size = args.batchsize + + # create iluvatar target & device + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + device = tvm.device(target.kind.name, 0) + + # load engine + lib = tvm.runtime.load_module(args.engine) + + # create runtime from engine + module = tvm.contrib.graph_executor.GraphModule(lib["default"](device)) + + # just run perf test + if args.perf_only: + ftimer = module.module.time_evaluator("run", device, number=100, repeat=1) + prof_res = np.array(ftimer().results) * 1000 + fps = batch_size * 1000 / np.mean(prof_res) + print(f"\n* Mean inference time: {np.mean(prof_res):.3f} ms, Mean fps: {fps:.3f}") + else: + # warm up + for _ in range(args.warmup): + module.run() + + # get dataloader + dataloader = get_dataloader(args.datasets, batch_size, args.num_workers) + + top1_acc = 0 + top5_acc = 0 + total_num = 0 + + for image, label in tqdm(dataloader): + + # pad the last batch + pad_batch = len(image) != batch_size + + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + + module.set_input(args.input_name, tvm.nd.array(image, device)) + + # run inference + module.run() + + pred = module.get_output(0).asnumpy() + + if pad_batch: + pred = pred[:origin_size] + + # get batch accuracy + batch_top1_acc, batch_top5_acc = get_topk_accuracy(pred, label) + + top1_acc += batch_top1_acc + top5_acc += batch_top5_acc + total_num += batch_size + + result_stat = {} + result_stat["acc@1"] = round(top1_acc / total_num * 100.0, 3) + result_stat["acc@5"] = round(top5_acc / total_num * 100.0, 3) + + print(f"\n* Top1 acc: {result_stat['acc@1']} %, Top5 acc: {result_stat['acc@5']} %") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/vgg19_bn/igie/requirements.txt b/models/cv/classification/vgg19_bn/igie/requirements.txt new file mode 100644 index 00000000..9e811126 --- /dev/null +++ b/models/cv/classification/vgg19_bn/igie/requirements.txt @@ -0,0 +1,2 @@ +onnx +tqdm diff --git a/models/cv/classification/vgg19_bn/igie/scripts/infer_vgg19_bn_fp16_accuracy.sh b/models/cv/classification/vgg19_bn/igie/scripts/infer_vgg19_bn_fp16_accuracy.sh new file mode 100644 index 00000000..780f0445 --- /dev/null +++ b/models/cv/classification/vgg19_bn/igie/scripts/infer_vgg19_bn_fp16_accuracy.sh @@ -0,0 +1,35 @@ +#!/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. + +batchsize=32 +model_path="vgg19_bn.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path vgg19_bn_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine vgg19_bn_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ No newline at end of file diff --git a/models/cv/classification/vgg19_bn/igie/scripts/infer_vgg19_bn_fp16_performance.sh b/models/cv/classification/vgg19_bn/igie/scripts/infer_vgg19_bn_fp16_performance.sh new file mode 100644 index 00000000..66edcad9 --- /dev/null +++ b/models/cv/classification/vgg19_bn/igie/scripts/infer_vgg19_bn_fp16_performance.sh @@ -0,0 +1,36 @@ +#!/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. + +batchsize=32 +model_path="vgg19_bn.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input input:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path vgg19_bn_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine vgg19_bn_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name input \ + --datasets ${datasets_path} \ + --perf_only True \ No newline at end of file -- Gitee From 8201b976ed3b4918737e89ea47c3b9867372552e Mon Sep 17 00:00:00 2001 From: YoungPeng Date: Thu, 10 Apr 2025 11:31:08 +0800 Subject: [PATCH 10/10] Add: vit inference script. --- models/cv/classification/vit/igie/README.md | 55 +++++ .../classification/vit/igie/build_engine.py | 73 +++++++ .../cv/classification/vit/igie/ci/prepare.sh | 21 ++ models/cv/classification/vit/igie/export.py | 53 +++++ .../cv/classification/vit/igie/inference.py | 192 ++++++++++++++++++ .../classification/vit/igie/requirements.txt | 4 + .../igie/scripts/infer_vit_fp16_accuracy.sh | 35 ++++ .../scripts/infer_vit_fp16_performance.sh | 36 ++++ models/cv/classification/vit/igie/test.py | 7 + 9 files changed, 476 insertions(+) create mode 100644 models/cv/classification/vit/igie/README.md create mode 100644 models/cv/classification/vit/igie/build_engine.py create mode 100644 models/cv/classification/vit/igie/ci/prepare.sh create mode 100644 models/cv/classification/vit/igie/export.py create mode 100644 models/cv/classification/vit/igie/inference.py create mode 100644 models/cv/classification/vit/igie/requirements.txt create mode 100644 models/cv/classification/vit/igie/scripts/infer_vit_fp16_accuracy.sh create mode 100644 models/cv/classification/vit/igie/scripts/infer_vit_fp16_performance.sh create mode 100644 models/cv/classification/vit/igie/test.py diff --git a/models/cv/classification/vit/igie/README.md b/models/cv/classification/vit/igie/README.md new file mode 100644 index 00000000..1853a1b6 --- /dev/null +++ b/models/cv/classification/vit/igie/README.md @@ -0,0 +1,55 @@ +# ViT (IGIE) + +## Model Description + +ViT is a novel vision model architecture proposed by Google in the paper *An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale.* ViT introduces the Transformer architecture, originally designed for natural language processing tasks, into the field of computer vision. By dividing an image into small patches (Patch) and treating them as input tokens, it leverages the self-attention mechanism to perform global feature modeling of the image. + +## Supported Environments + +| GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | +|--------|-----------|---------| +| MR-V100 | 4.2.0 | 25.06 | + +## Model Preparation + +### Prepare Resources + +Pretrained model: + +Dataset: to download the validation dataset. + +### Install Dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Model Conversion + +```bash +python3 export.py --output vit.onnx + +# Use onnxsim optimize onnx model +onnxsim vit.onnx vit_opt.onnx +``` + +## Model Inference + +```bash +export DATASETS_DIR=/Path/to/imagenet_val/ +``` + +### FP16 + +```bash +# Accuracy +bash scripts/infer_vit_fp16_accuracy.sh +# Performance +bash scripts/infer_vit_fp16_performance.sh +``` + +## Model Results + +| Model | BatchSize | Precision | FPS | Top-1(%) | Top-5(%) | +|-------|-----------|-----------|---------|----------|----------| +| ViT | 32 | FP16 | 432.257 | 81.4 | 95.977 | diff --git a/models/cv/classification/vit/igie/build_engine.py b/models/cv/classification/vit/igie/build_engine.py new file mode 100644 index 00000000..d3626ae7 --- /dev/null +++ b/models/cv/classification/vit/igie/build_engine.py @@ -0,0 +1,73 @@ +# 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 tvm +import argparse +from tvm import relay +from tvm.relay.import_model import import_model_to_igie + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--model_path", + type=str, + required=True, + help="original model path.") + + parser.add_argument("--engine_path", + type=str, + required=True, + help="igie export engine path.") + + parser.add_argument("--input", + type=str, + required=True, + help=""" + input info of the model, format should be: + input_name:input_shape + eg: --input input:1,3,224,224. + """) + + parser.add_argument("--precision", + type=str, + choices=["fp32", "fp16", "int8"], + required=True, + help="model inference precision.") + + args = parser.parse_args() + + return args + +def main(): + args = parse_args() + + # get input valueinfo + input_name, input_shape = args.input.split(":") + shape = tuple([int(s) for s in input_shape.split(",")]) + input_dict = {input_name: shape} + + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + + mod, params = import_model_to_igie(args.model_path, input_dict, backend="igie") + + # build engine + lib = tvm.relay.build(mod, target=target, params=params, precision=args.precision) + + # export engine + lib.export_library(args.engine_path) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/vit/igie/ci/prepare.sh b/models/cv/classification/vit/igie/ci/prepare.sh new file mode 100644 index 00000000..d8a05dda --- /dev/null +++ b/models/cv/classification/vit/igie/ci/prepare.sh @@ -0,0 +1,21 @@ +#!/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. + +set -x + +pip3 install -r requirements.txt +python3 export.py --output vit.onnx +onnxsim vit.onnx vit_opt.onnx diff --git a/models/cv/classification/vit/igie/export.py b/models/cv/classification/vit/igie/export.py new file mode 100644 index 00000000..4530c480 --- /dev/null +++ b/models/cv/classification/vit/igie/export.py @@ -0,0 +1,53 @@ +# 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 pathlib import Path +from transformers.onnx import export +from transformers.models.vit import ViTOnnxConfig + +from transformers import ViTImageProcessor, ViTForImageClassification + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--output", + type=str, + required=True, + help="export onnx model path.") + + args = parser.parse_args() + return args + +def main(): + args = parse_args() + + checkpoint = "google/vit-base-patch16-224" + feature_extractor = ViTImageProcessor.from_pretrained(checkpoint) + model = ViTForImageClassification.from_pretrained(checkpoint) + + save_path = Path(args.output) + onnx_config = ViTOnnxConfig(model.config) + + # export onnx model + export( + feature_extractor, model, onnx_config, + onnx_config.default_onnx_opset, save_path + ) + + print("Export onnx model successfully! ") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/vit/igie/inference.py b/models/cv/classification/vit/igie/inference.py new file mode 100644 index 00000000..ca4df371 --- /dev/null +++ b/models/cv/classification/vit/igie/inference.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 sys +import argparse +import tvm +import torch +import torchvision +import numpy as np +from tvm import relay +from tqdm import tqdm +from torchvision import transforms +from torchvision.transforms.functional import InterpolationMode + +import os +from glob import glob +from PIL import Image +from transformers import ViTImageProcessor +from torch.utils.data import Dataset, DataLoader + +def parse_args(): + parser = argparse.ArgumentParser() + + parser.add_argument("--engine", + type=str, + required=True, + help="igie engine path.") + + 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("--input_name", + type=str, + required=True, + help="input name of the model.") + + parser.add_argument("--warmup", + type=int, + default=3, + help="number of warmup before test.") + + parser.add_argument("--num_workers", + type=int, + default=16, + help="number of workers used in pytorch dataloader.") + + 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 get_dataloader(data_path, batch_size, num_workers): + dataset = torchvision.datasets.ImageFolder( + data_path, + transforms.Compose( + [ + transforms.Resize(256, interpolation=InterpolationMode.BILINEAR), + transforms.CenterCrop(224), + transforms.PILToTensor(), + transforms.ConvertImageDtype(torch.float), + transforms.Normalize( + mean=(0.5, 0.5, 0.5), + std=(0.5, 0.5, 0.5) + ) + ] + ) + ) + + dataloader = torch.utils.data.DataLoader(dataset, batch_size, num_workers=num_workers) + + return dataloader + +def get_topk_accuracy(pred, label): + if isinstance(pred, np.ndarray): + pred = torch.from_numpy(pred) + + if isinstance(label, np.ndarray): + label = torch.from_numpy(label) + + top1_acc = 0 + top5_acc = 0 + for idx in range(len(label)): + label_value = label[idx] + if label_value == torch.topk(pred[idx].float(), 1).indices.data: + top1_acc += 1 + top5_acc += 1 + + elif label_value in torch.topk(pred[idx].float(), 5).indices.data: + top5_acc += 1 + + return top1_acc, top5_acc + +def main(): + args = parse_args() + + batch_size = args.batchsize + + # create iluvatar target & device + target = tvm.target.iluvatar(model="MR", options="-libs=cudnn,cublas,ixinfer") + device = tvm.device(target.kind.name, 0) + + # load engine + lib = tvm.runtime.load_module(args.engine) + + # create runtime from engine + module = tvm.contrib.graph_executor.GraphModule(lib["default"](device)) + + # just run perf test + if args.perf_only: + ftimer = module.module.time_evaluator("run", device, number=100, repeat=1) + prof_res = np.array(ftimer().results) * 1000 + fps = batch_size * 1000 / np.mean(prof_res) + print(f"\n* Mean inference time: {np.mean(prof_res):.3f} ms, Mean fps: {fps:.3f}") + else: + # warm up + for _ in range(args.warmup): + module.run() + + # get dataloader + dataloader = get_dataloader(args.datasets, batch_size, args.num_workers) + + top1_acc = 0 + top5_acc = 0 + total_num = 0 + + for image, label in tqdm(dataloader): + + # pad the last batch + pad_batch = len(image) != batch_size + + if pad_batch: + origin_size = len(image) + image = np.resize(image, (batch_size, *image.shape[1:])) + + module.set_input(args.input_name, tvm.nd.array(image, device)) + + # run inference + module.run() + + pred = module.get_output(0).asnumpy() + + if pad_batch: + pred = pred[:origin_size] + + # get batch accuracy + batch_top1_acc, batch_top5_acc = get_topk_accuracy(pred, label) + + top1_acc += batch_top1_acc + top5_acc += batch_top5_acc + total_num += batch_size + + result_stat = {} + result_stat["acc@1"] = round(top1_acc / total_num * 100.0, 3) + result_stat["acc@5"] = round(top5_acc / total_num * 100.0, 3) + + print(f"\n* Top1 acc: {result_stat['acc@1']} %, Top5 acc: {result_stat['acc@5']} %") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/models/cv/classification/vit/igie/requirements.txt b/models/cv/classification/vit/igie/requirements.txt new file mode 100644 index 00000000..53db3078 --- /dev/null +++ b/models/cv/classification/vit/igie/requirements.txt @@ -0,0 +1,4 @@ +onnx +tqdm +onnxsim +transformers==4.37.1 diff --git a/models/cv/classification/vit/igie/scripts/infer_vit_fp16_accuracy.sh b/models/cv/classification/vit/igie/scripts/infer_vit_fp16_accuracy.sh new file mode 100644 index 00000000..03959c3d --- /dev/null +++ b/models/cv/classification/vit/igie/scripts/infer_vit_fp16_accuracy.sh @@ -0,0 +1,35 @@ +#!/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. + +batchsize=32 +model_path="vit_opt.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input pixel_values:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path vit_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine vit_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name pixel_values \ + --datasets ${datasets_path} \ No newline at end of file diff --git a/models/cv/classification/vit/igie/scripts/infer_vit_fp16_performance.sh b/models/cv/classification/vit/igie/scripts/infer_vit_fp16_performance.sh new file mode 100644 index 00000000..035b4c03 --- /dev/null +++ b/models/cv/classification/vit/igie/scripts/infer_vit_fp16_performance.sh @@ -0,0 +1,36 @@ +#!/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. + +batchsize=32 +model_path="vit_opt.onnx" +datasets_path=${DATASETS_DIR} + +# build engine +python3 build_engine.py \ + --model_path ${model_path} \ + --input pixel_values:${batchsize},3,224,224 \ + --precision fp16 \ + --engine_path vit_bs_${batchsize}_fp16.so + + +# inference +python3 inference.py \ + --engine vit_bs_${batchsize}_fp16.so \ + --batchsize ${batchsize} \ + --input_name pixel_values \ + --datasets ${datasets_path} \ + --perf_only True \ No newline at end of file diff --git a/models/cv/classification/vit/igie/test.py b/models/cv/classification/vit/igie/test.py new file mode 100644 index 00000000..4b85deec --- /dev/null +++ b/models/cv/classification/vit/igie/test.py @@ -0,0 +1,7 @@ +from transformers import ViTImageProcessor, ViTForImageClassification +model = ViTForImageClassification.from_pretrained('google/vit-base-patch16-224') + +processor = ViTImageProcessor.from_pretrained('google/vit-base-patch16-224') +model = ViTForImageClassification.from_pretrained('google/vit-base-patch16-224') + +print(model) -- Gitee