华为昇腾310B1平台深度学习算法模型转换

2024-05-10 11:20

本文主要是介绍华为昇腾310B1平台深度学习算法模型转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1 模型转换(集成nms算子到模型中)

1.1 基础模型说明

1.2 模型转换

1.2.1 设置环境变量

1.2.2 安装yolov5依赖(gcc需要>7.5)

1.2.3 转换fp16模型

2 模型转换(使用atc,不集成nms算子)

参考文献:


1 模型转换(集成nms算子到模型中)

1.1 基础模型说明

对于Yolov5模型,华为提供了单独的脚本执行转换,目的通过自定义的Yolov5后处理算子将NMS操作集成到离线模型中,提高推理性能。Yolov5模型转换脚本位于计算库的ascend_yolov5_pt2om,模型转换时使用官方原始yolov5s-v6.1为基础训练的人车非.pt模型,该模型有3个输出。转换工具会自动将3个输出合并为一个输出,并转为onnx模型,之后再转为om模型。默认精度为FP16。

对于INT8,当前转换工具量化后准确率有下降,对于实时性强的场景不适合,暂不使用。

ascend_yolov5_pt2om已上传到csdn资源(你自己的百度网盘里面也有一份)https://download.csdn.net/download/u013171226/89286331?spm=1001.2014.3001.5501

1.2 模型转换

模型转换主要是将.pt模型转为Ascentd可推理的.om模型,包括三种数据类型(fp16、fp32和int8),模型转换过程下。模型转换使用ascend_yolov5_pt2om工程实现。

1.2.1 设置环境变量

source /usr/local/Ascend/ascend-toolkit/set_env.sh 

1.2.2 安装yolov5依赖(gcc需要>7.5)

pip install -r requirements.txtpip install onnx
pip install onnxruntime==1.6.0
pip install onnxsimpip install opc-tool==0.1.0
pip install decorator 
pip install protobuf==3.20.3
pip install numpy

1.2.3 转换fp16模型

bash common/pth2om.sh --version 6.1 --type fp16 --model yolov5_pcb_608_out3 --img_size 608 --class_num 3 --bs 1 --soc Ascend310B1

其中pth2om.sh脚本内容如下,在ascend_yolov5_pt2om文件夹里面有

## 帮助信息
### === Model Options ===
###  --version      yolov5 tags [2.0/3.1/4.0/5.0/6.0/6.1], default: 6.1
###  --model        yolov5[n/s/m/l/x], default: yolov5s
###  --bs           batch size, default: 4
### === Build Options ===
###  --type         data type [fp16/int8], default: fp16
###  --calib_bs     batch size of calibration data (int8 use only), default: 16
### === Inference Options ===
###  --mode         infer/val, default: infer
###  --conf         confidence threshold, default: 0.4
###  --iou          NMS IOU threshold, default: 0.5
###  --output_dir   output dir, default: output
### === Environment Options ===
###  --soc          soc version [Ascend310/Ascend310P?], default: Ascend310
### === Help Options ===
###  -h             print this messagehelp() {sed -rn 's/^### ?//;T;p;' "$0"
}## 参数设置
GETOPT_ARGS=`getopt -o 'h' -al version:,model:,img_size:,channel_num:,bs:,class_num:,type:,calib_bs:,mode:,conf:,iou:,output_dir:,soc: -- "$@"`
eval set -- "$GETOPT_ARGS"
while [ -n "$1" ]
docase "$1" in-h) help; exit 0 ;; --version) version=$2; shift 2;;--model) model=$2; shift 2;;--img_size) img_size=$2; shift 2;;--channel_num) channel_num=$2; shift 2;;--bs) bs=$2; shift 2;;--class_num) class_num=$2; shift 2;;--type) type=$2; shift 2;;--calib_bs) calib_bs=$2; shift 2;;--mode) mode=$2; shift 2;;--conf) conf=$2; shift 2;;--iou) iou=$2; shift 2;;--output_dir) output_dir=$2; shift 2;;--soc) soc=$2; shift 2;;--) break ;;esac
doneif [[ -z $version ]]; then version=6.1; fi
if [[ -z $model ]]; then model=yolov5s; fi
if [[ -z $img_size ]]; then img_size=608; fi
if [[ -z $channel_num ]]; then channel_num=3; fi
if [[ -z $bs ]]; then bs=4; fi
if [[ -z $class_num ]]; then class_num=3; fi
if [[ -z $type ]]; then type=fp16; fi
if [[ -z $calib_bs ]]; then calib_bs=16; fi
if [[ -z $mode ]]; then mode=infer; fi
if [[ -z $conf ]]; then conf=0.4; fi
if [[ -z $iou ]]; then iou=0.5; fi
if [[ -z $output_dir ]]; then output_dir=output; fi
if [[ -z $soc ]]; then echo "error: missing 1 required argument: 'soc'"; exit 1 ; fiif [[ ${type} == fp16 ]] ; thenargs_info="=== pth2om args === \n version: $version \n model: $model \n bs: $bs \n type: $type \n mode: $mode \n conf: $conf \n iou: $iou \n output_dir: $output_dir \n soc: $soc"echo -e $args_info
elseargs_info="=== pth2om args === \nversion: $version \n model: $model \n bs: $bs \n type: $type \n calib_bs: $calib_bs \n mode: $mode \n conf: $conf \n iou: $iou \n output_dir: $output_dir \n soc: $soc"echo -e $args_info
fiif [ ! -d ${output_dir} ]; thenmkdir ${output_dir}
fi## pt导出om模型
echo "Starting 修改pytorch源码"
git checkout . && git checkout v${version}
git apply v${version}/v${version}.patchecho "Starting 导出onnx模型并简化"
if [[ ${version} == 6* ]] ; thenpython3 export.py --weights=${model}.pt --imgsz=${img_size} --batch-size=${bs} --opset=11 --dynamic || exit 1
elsepython3 models/export.py --weights=${model}.pt --img-size=${img_size} --batch-size=${bs} --opset=11 --dynamic || exit 1
fi
python3 -m onnxsim ${model}.onnx ${model}.onnx --dynamic-input-shape --input-shape images:${bs},${channel_num},${img_size},${img_size} || exit 1
model_tmp=${model}if [ ${type} == int8 ] ; thenecho "Starting 生成量化数据"python3 common/quantize/generate_data.py --img_info_file=common/quantize/img_info_amct.txt --save_path=amct_data --batch_size=${calib_bs} --img_size=${img_size} || exit 1if [[ ${version} == 6.1 && ${model} == yolov5[nl] ]] ; thenecho "Starting pre_amct"python3 common/quantize/calibration_scale.py --input=${model}.onnx --output=${model}_cali.onnx --mode=pre_amct || exit 1echo "Starting onnx模型量化"bash common/quantize/amct.sh ${model}_cali.onnx || exit 1if [[ -f ${output_dir}/result_deploy_model.onnx ]];thenmv ${output_dir}/result_deploy_model.onnx ${model}_amct.onnxfirm -rf ${model}_cali.onnxecho "Starting after_amct"python3 common/quantize/calibration_scale.py --input=${model}_amct.onnx --output=${model}_amct.onnx --mode=after_amct || exit 1elseecho "Starting onnx模型量化"bash common/quantize/amct.sh ${model}.onnx || exit 1if [[ -f ${output_dir}/result_deploy_model.onnx ]];thenmv ${output_dir}/result_deploy_model.onnx ${model}_amct.onnxfifimodel_tmp=${model}_amctif [[ -f ${output_dir}/result_* ]];thenrm -rf  ${output_dir}/result_result_fake_quant_model.onnxrm -rf  ${output_dir}/result_quant.jsonfi
fiecho "Starting 修改onnx模型,添加NMS后处理算子"
python3 common/util/modify_model.py --pt=${model}.pt --onnx=${model_tmp}.onnx --img-size=${img_size} --class-num=${class_num} --conf-thres=${conf} --iou-thres=${iou} || exit 1echo "Starting onnx导出om模型(有后处理)"
bash common/util/atc.sh infer ${model_tmp}_nms.onnx ${output_dir}/${model_tmp}_nms ${img_size} ${channel_num} ${bs} ${soc} || exit 1
rm -rf ${model_tmp}_nms.onnxif [[ ${mode} == val ]] ; thenecho "Starting onnx导出om模型(无后处理)"bash common/util/atc.sh val ${model_tmp}.onnx ${output_dir}/${model_tmp} ${bs} ${soc} || exit 1rm -rf ${model_tmp}.onnx
fiecho -e "pth导出om模型 Success \n"

然后atc.sh脚本内容如下,在ascend_yolov5_pt2om文件夹里面也有

mode=$1
onnx=$2
om=$3
img_size=$4
channel_num=$5
bs=$6
soc=$7if [ ${mode} == val ];theninput_shape="images:${bs},${channel_num},${img_size},${img_size}"input_fp16_nodes="images"
elif [ ${mode} == infer ];theninput_shape="images:${bs},${channel_num},${img_size},${img_size};img_info:${bs},4"input_fp16_nodes="images;img_info"
fiif [[ ${soc} == Ascend310 ]];thenatc --model=${onnx} \--framework=5 \--output=${om}_bs${bs} \--input_format=NCHW \--input_shape=${input_shape} \--log=error \--soc_version=${soc} \--input_fp16_nodes=${input_fp16_nodes} \--output_type=FP16
fiif [[ ${soc} == Ascend310B1 ]];thenatc --model=${onnx} \--framework=5 \--output=${om}_bs${bs} \--input_format=NCHW \--input_shape=${input_shape} \--log=error \--soc_version=${soc} \--optypelist_for_implmode="Sigmoid" \--op_select_implmode=high_performance \--fusion_switch_file=common/util/fusion.cfg \--insert_op_conf=aipp_yolov5.cfg#--input_fp16_nodes=${input_fp16_nodes} #--output_type=FP16 
fiif [[ ${soc} == Ascend310P? ]];thenatc --model=${onnx} \--framework=5 \--output=${om}_bs${bs} \--input_format=NCHW \--input_shape=${input_shape} \--log=error \--soc_version=${soc} \--optypelist_for_implmode="Sigmoid" \--op_select_implmode=high_performance \--fusion_switch_file=common/util/fusion.cfg \--insert_op_conf=aipp_yolov5.cfg#--input_fp16_nodes=${input_fp16_nodes} #--output_type=FP16 
fiif [[ ${soc} == Ascend710 ]];thenatc --model=${onnx} \--framework=5 \--output=${om}_bs${bs} \--input_format=NCHW \--input_shape=${input_shape} \--log=error \--soc_version=${soc} \--optypelist_for_implmode="Sigmoid" \--op_select_implmode=high_performance \--fusion_switch_file=common/util/fusion.cfg #--insert_op_conf=aipp_yolov5.cfg
#       --insert_op_conf=aipp.cfg
#       --insert_op_conf=aipp_yolov5.cfg
fiif [[ ${soc} == Ascend910 ]];thenatc --model=${onnx} \--framework=5 \--output=${om}_bs${bs} \--input_format=NCHW \--input_shape=${input_shape} \--log=error \--soc_version=${soc} \--optypelist_for_implmode="Sigmoid" \--op_select_implmode=high_performance \--fusion_switch_file=common/util/fusion.cfg #--insert_op_conf=aipp_yolov5.cfg
#       --insert_op_conf=aipp.cfg
#       --insert_op_conf=aipp_yolov5.cfg
fi

2 模型转换(使用atc,不集成nms算子)

      上述模型转换都是基于.pt文件转换为.om模型文件。另外,还可以直接应用atc工具将onnx模型转为.om模型。

bash common/util/atc.sh infer yolov5_pcb_608_out3_nms.onnx output/yolov5_pcb_608_out3_nms 1 Ascend310B1

或者直接使用atc工具转换

      (1)人车非模型
        atc --model=yolov5_pcb_608_out3_nms.onnx \
            --framework=5 \
            --output=yolov5_pcb_608_out3_bs4 \
            --input_format=NCHW \
            --input_shape="images:1,3,640,640;img_info:1,4" \
            --log=error \
            --soc_version=Ascend710 \
            --optypelist_for_implmode="Sigmoid" \
            --op_select_implmode=high_performance 
        
      (2)行人结构化模型
        atc --model=pedes_structure.onnx \
            --framework=5 \
            --output=pedes_structure \
            --input_format=NCHW \
            --input_shape="x:-1,3,224,224" \
            --dynamic_batch_size="1,2,4,8" \
            --log=error \
            --soc_version=Ascend710 \
            --optypelist_for_implmode="Sigmoid" \
            --op_select_implmode=high_performance 

参考文献:

海思Hi3519 DV500 部署yolov5并加速优化_dv500移植yolov5-CSDN博客

samples: CANN Samples - Gitee.com

这篇关于华为昇腾310B1平台深度学习算法模型转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/976294

相关文章

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧

深度解析Spring Boot拦截器Interceptor与过滤器Filter的区别与实战指南

《深度解析SpringBoot拦截器Interceptor与过滤器Filter的区别与实战指南》本文深度解析SpringBoot中拦截器与过滤器的区别,涵盖执行顺序、依赖关系、异常处理等核心差异,并... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

SpringBoot开发中十大常见陷阱深度解析与避坑指南

《SpringBoot开发中十大常见陷阱深度解析与避坑指南》在SpringBoot的开发过程中,即使是经验丰富的开发者也难免会遇到各种棘手的问题,本文将针对SpringBoot开发中十大常见的“坑... 目录引言一、配置总出错?是不是同时用了.properties和.yml?二、换个位置配置就失效?搞清楚加

利用Python脚本实现批量将图片转换为WebP格式

《利用Python脚本实现批量将图片转换为WebP格式》Python语言的简洁语法和库支持使其成为图像处理的理想选择,本文将介绍如何利用Python实现批量将图片转换为WebP格式的脚本,WebP作为... 目录简介1. python在图像处理中的应用2. WebP格式的原理和优势2.1 WebP格式与传统

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c