AscendCL应用开发:CANN算子使用动态维度
视频教程链接:【经验分享】基于mindstudio的模型动态维度设置教程_哔哩哔哩_bilibili
动态维度基本概念介绍
若模型推理时包含动态维度(ND格式)特性,在模型推理时,需调用AscendCL提供的接口设置模型推理时需使用的维度值。
为了支持Transformer等网络在输入格式的维度不确定的场景,需要支持ND格式下任意维度的动态设置。
关键原理说明如下:
1.加载模型。模型加载成功后,返回标识模型的ID。
对于动态维度,模型支持哪些维度值已提前在构建模型时配置(构建模型的说明请参见《CANN 开发辅助工具指南》中的“ATC工具使用指南”章节),构建模型成功后,在生成的om模型中,会新增一个输入(下文简称动态维度输入),在模型推理时通过该新增的输入提供具体的维度值。
例如,a输入的某个维度值是动态的,在om模型中,会有与a对应的b输入来描述a的维度信息。在模型执行时,准备a输入的数据结构请参见准备模型执行的输入/输出数据结构。
2.创建aclmdlDataset类型的数据,用于描述模型执行的输入数据、输出数据,详细调用流程请参见准备模型执行的输入/输出数据,关于动态维度输入的注意点如下:
a.申请动态维度(ND格式)输入对应的内存前,需要先调用acl.mdl.get_input_index_by_name接口根据输入名称(固定为"ascend_mbatch_shape_data")获取模型中标识动态维度输入的index。
b.调用acl.mdl.get_input_size_by_index接口根据index获取输入内存大小。
c.调用acl.rt.malloc接口根据2.b中的大小申请内存。
申请动态维度输入对应的内存后,无需用户设置内存中的数据(否则可能会导致业务异常),用户调用3.b中的接口后,系统会自动向内存中填入数据。
d.调用acl.create_data_buffer接口创建aclDataBuffer类型的数据,用于存放动态维度输入数据的内存地址、内存大小。
e.调用acl.mdl.create_dataset接口创建aclmdlDataset类型的数据,并调用acl.mdl.add_dataset_buffer接口向aclmdlDataset类型的数据中增加aclDataBuffer类型的数据。
3.在成功加载模型之后,执行模型之前,设置动态维度的维度值。
调用acl.mdl.get_input_index_by_name接口根据输入名称(固定为"ascend_mbatch_shape_data")获取模型中标识动态维度输入的index。
调用acl.mdl.set_input_dynamic_dims接口设置动态维度的维度值。
此处设置的动态维度的值只能是模型转换时通过dynamic_dims参数设置的档位中的某一档
也可以调用acl.mdl.get_input_dynamic_dims接口获取指定模型支持的动态维度档位数以及每一档中的值。
想了解更多具体详见官方文档
官网开发文档合集(https://www.hiascend.com/document?tag=community-developer)
4.执行模型。
图1 设置动态维度流程图
二、Ascend昇腾开发环境极速搭建
开发环境搭建可选择A.Ubuntu环境下或者B.Windows环境下远程连接已经配置完毕的服务器
Ubuntu环境
注意分为昇腾设备和非升腾设备。非昇腾AI设备无需安装固件与驱动,仅能用于代码开发、编译等不依赖于昇腾设备的开发活动。在昇腾AI设备上安装开发环境,支持代码开发和编译,同时可以运行应用程序或进行训练脚本的迁移、开发&调试。
- 安装Ubuntu依赖
开发框架CANN开发环境支持多种操作系统,如这里的Ubuntu 18.04。请在root用户下执行如下命令检查源是否可用:
安装一些OS依赖库,具体可执行如下命令:
·apt-get install -y gcc g++ make cmake zlib1g zlib1g-dev openssl libsqlite3-dev libssl-dev libffi-dev
·sudo apt-get install -y unzip pciutils net-tools libblas-dev gfortran libblas3 libopenblas-dev libncursesw5-dev
因为此处我们已经安装过了,因此显示都已经是最新版
CANN 还依赖于Python3.7 ,因此首先确认一下本地的Python版本,执行命令python3 --version,如果python版本在3.7.0~ 3.7.11之间则可以跳过Python安装过程,默认情况下,Ubuntu 18.04安装的Python是3.6.9 。因此需要重新安装python3.7.5。在目录/home/jack/mysoft下,执行如下命令:
稍等片刻后,会在mysoft目录中下载完成此安装包Python-3.7.5.tgz。解压源码包:
进入解压后的文件夹,执行配置、编译和安装命令:
其中“--prefix”参数用于指定python安装路径,用户根据实际情况进行修改。“--enable-shared”参数用于编译出libpython3.7m.so.1.0动态库。“--enable-loadable-sqlite-extensions”参数用于加载libsqlite3-dev依赖。安装完成后,如果输入python3还是未生效,需要配置环境变量。可以执行如下命令设置python3.7.5环境变量,执行如下命令:
具体可以参考官网 https://www.hiascend.com/software/mindstudio
- Ubuntu依赖安装
之前的配置Python环境变量,只能在当前的Shell窗口有效,当开启新的命令窗口,则环境变量失效,示意如下所示:
下面设置永久的环境变量,命令如下:
增加的内容如下:
执行如下命令生效:
为后续安装CANN软件包、运行CANN软件环境变量设置脚本时能够自动配置python3.7.5环境变量,用户需提前创建好文件“use_private_python.info”,执行如下命令(root用户):
内容如下:
- 安装CANN开发工具
在基础Linux环境搭建完成后,需要登录华为相关网站(下载软件有权限要求,否则可能无法下载),并获取相关权限后,首先可以在Windows操作系统上下载两种架构(x86和aarch64)的CANN toolkit开发套件包Ascend-cann-toolkit_xxx.run 。
请根据CPU架构(x86_64、aarch64)获取对应的软件包。
例如本次安装的版本为CANN 5.1.RC1:
Ascend-cann-toolkit_5.1.RC1_linux-aarch64.run
Ascend-cann-toolkit_5.1.RC1_linux-x86_64.run
对于x86_64则: ./Ascend-cann-toolkit_{version}_linux-x86_64.run
对于运行环境为aarch64而开发环境为x86_64的场景,需同时获取两种架构的开发套件包。
({version}表示软件版本号,{arch}表示CPU架构。)
其主要用于用户开发应用、自定义算子和模型转换。开发套件包包含开发应用程序所需的库文件、开发辅助工具如ATC模型转换工具。
- 验证完整性
然后打开终端命令行,执行如下命令进行CANN toolkit安装:
./Ascend-cann-toolkit_{version}_linux-x86_64.run --check
./Ascend-cann-toolkit_{version}_linux-aarch64.run --check
./Ascend-cann-toolkit_{version}_linux-x86_64.run --install
./Ascend-cann-toolkit_{version}_linux-aarch64.run --install
输入如下命令设置可执行权限:
chmod +x Ascend-cann-toolkit_5.1.RC1_linux-aarch64.run
chmod +x Ascend-cann-toolkit_5.1.RC1_linux-x86_64.run
输入如下命令进行安装
./Ascend-cann-toolkit_5.1.RC1_linux-x86_64.run --install
安装过程如下
安装完成显示如下:
输入如下命令进行安装
./Ascend-cann-toolkit_5.1.RC1_linux-aarch64 --install
安装过程同上
- 配置交叉编译环境
最后,对于Atlas 200 AI加速模块 (RC场景)和Atlas 500 小站(运行环境aarch64架构)来说,当开发环境是一台X86 PC进行环境搭建时,需要在开发环境中安装交叉编译工具,具体命令如下:
安装成功后,再次验证,执行如下命令:
此处已经配置完成
- 安装MindStudio
去昇腾社区官网,选择对应版本,下载安装包。
网址:https://www.hiascend.com/software/mindstudio/download
将MindStudio_{version}_linux.tar.gz软件包上传至MindStudio安装服务器。并解压
使用MindStudio的安装用户进入软件包解压后的MindStudio/bin目录,执行如下命令启动:
第一次运行时会检查环境,MindStudio依赖JDK和Python3等环境,检查过程示意如下:
首先根据提示安装相关库,执行如下命令:
·apt-get -y install xterm fonts-wqy-zenhei fonts-wqy-microhei fonts-arphic-ukai fonts-arphic-uming
·pip3.7 install --user grpcio coverage gnureadline pylint matplotlib pandas xlrd==1.2.0 absl-py
- MindStudio配置
打开软件后,到setting配置CANN的路径
在里面配置MindX sdk
- 安装必要的pip包
python3 -m pip install numpy decorator sympy cffi pyyaml pathlib2 psutil protobuf scipy requests grpcio pylint absl-py --user -i https://pypi.tuna.tsinghua.edu.cn/simple
B.Windows环境
在官网选择MindStudio Windows版本进行下载
这里选择软件包下载,点击软件包下载,跳出安装界面进行安装
用户根据需要勾选安装选项
- Create Desktop Shortcut:创建桌面快捷方式,用户可根据系统配置选择“32-bit launcher”或者“64-bit launcher”。
- Update PATH variable(restart needed):将MindStudio的启动文件路径加入环境变量PATH中,可从系统命令行直接启动MindStudio。如果勾选此项,MindStudio安装配置完成后会重启操作系统。
- Update context menu:勾选“Add "Open Folder as Project"”后,右键单击文件夹,可以作为MindStudio工程打开。
- Create Associations:默认不勾选。
- 点next进入下一步
Windows SSH连接配置:
- 在菜单栏依次选择File > Settings... > Tools > SSH Configurations进入SSH连接配置。
- 在欢迎界面依次选择Customize> All Settings... > Tools > SSH Configurations进入SSH连接配置。
点击Test Connection
显示连接成功
三、动态维度设置总体流程:
- 模型选择:明确支持动态维度调整的模型(ND),即输入数据可以动态调整的模型;一般指应用Transformer模型于维度输入不确定的场景。
- 工程创建:通过MindStudio工具创建MyApp工程,根据模板创建后会自动生成模型、数据集和加载模型的运行文件的存储路径。
- 转换模型:
- 下载caffe或者pb等格式模型到指定的路径下。
- 使用MindStudio工具提供的模型转换功能将模型封装为OM格式;需要注意的是调用动态维度功能需要将模型转换选择为ND格式,同时在DynamicDims一栏中填入需要的维度档位。
- 点击模型转换,成功将模型转换为om格式。
- 加载模型:模型加载的详细流程,请参见模型推理,模型加载成功后,返回标识模型的ID。对于动态维度,模型支持哪些维度值已提前在构建模型时配置,构建模型成功后,在生成的om模型中,会新增一个输入(下文简称动态维度输入),在模型推理时通过该新增的输入提供具体的维度值。
5.创建aclmdlDataset类型的数据:用于描述模型执行的输入数据、输出数据。
6.设置动态维度:成功加载模型之后,执行模型之前,设置动态维度的维度值
注意:
对同一模型不能同时调用接口设置动态batchsize、动态分辨率和动态维度。
对同一模型,AIPP(包括静态AIPP和动态AIPP)与动态维度(ND格式)不能同时使用。
动态维度设置总体流程图
四、动态维度设置例子详解:
1.MindStudio,选择AscendApp创建工程项目
2.点击next之后我们可以选择MindStudio提供的模板进行工程创建
3.这里我们选择官网提供的自然语言处理的BERT模型的模板
4.根据readme中的教程下载BERT的原始模型,并将它放置在tmp目录下
- 点击MindStudio提供的模型转换功能进行模型转换。(这里我使用的是华为的远程推理环境,需要将模型上传到服务器进行模型转换;如果是本地环境则可以直接转换)
- 选择转换格式为ND,可以看到该模型有两个输入,shape表示输入的数据维度,-1代表可调参数;我们选择在Dynamic Dims中填写可调的维度档位。然后按next,finish进行模型转换。
- 输出提示模型转换成功,将转换好的模型放入model路径下。
- 转换成功后,打开模型的结构图,我们可以看到om模型对比原始模型,从原来的两个输入变为了三个输入,新增的输入就是用于调节可变维度设置的输入。
- 点击模型的输入,我们可以看到模型此时的输入为1,500维度的输入;而在加载模型的代码中数据预处理的函数设置的最大长度maxlen为298,因此要设置1,300的维度;因此我们需要将输入的维度调整为1,300的档位。
9.首先我们在加载模型之后和使用模型之前,调用函数找到关键参数model_id, model_desc和index。在本样例中我们选择在main函数中直接进行修改。
- 然后我们同样使用acl接口根据上文获得的model_id, model_desc和index来初始化输入和输出的数据结构,以及申请内存和缓存。并将预处理好的数据放入缓存中。
11.在准备好输入和输出的数据结构之后,我们就可以对动态维度进行设置了,如图我们可以自己定义一个current_dims,要求是符合转换模型时设置的档位;然后调用函数acl.mdl.set_input_dynamic_dims设置档位;这里顺便放上函数的详解文档图。
另外,我在代码中也写了另一种设置方法,先使用获取维度档位的函数
dims_out, ret = acl.mdl.get_input_dynamic_dims(model_desc, -1, gear_count)来获取设置好的档位,然后直接使用dims_out[i]作为档位设置.
12.在设置完维度之后,我们使用调用模型的函数对模型进行测试。点击MindStudio中的运行按钮直接运行加载模型的py文件。
14.运行结果显示如下,可以看到BERT模型已经给出判断文本的类型结果。
五、Q&A
1、模型转换失败的问题:显示Model Convert Failure的情况
解决方法:首先先检查是否使用华为的硬件进行开发环境搭建,MindStudio需要使用Ascend的soc来进行模型转换;这依赖于昇腾的硬件;没有硬件或者远程开发环境是无法进行调用MindStudio来开发的。
在确定使用昇腾硬件的基础上,output中会存在输出的日志文件的存在路径,可以根据路径找到日志文件,查看其中的报错原因。
想了解更多详见昇腾社区