• [其他] 浅学R-CNN目标检测上的算法
    R-CNN的全称是Region-CNN,是第一个成功将深度学习应用到目标检测上的算法。R-CNN基于卷积神经网络(CNN),线性回归,和支持向量机(SVM)等算法,实现目标检测技术。R-CNN的全称是Region-CNN,它可以说是第一个成功将深度学习应用到目标检测上的算法。传统的目标检测方法大多以图像识别为基础。 一般可以在图片上使用穷举法选出所有物体可能出现的区域框,对这些区域框提取特征并使用图像识别方法分类, 得到所有分类成功的区域后,通过非极大值抑制(Non-maximumsuppression)输出结果。R-CNN遵循传统目标检测的思路,同样采用提取框,对每个框提取特征、图像分类、 非极大值抑制四个步骤进行目标检测。只不过在提取特征这一步,将传统的特征(如 SIFT、HOG 特征等)换成了深度卷积网络提取的特征。R-CNN 体框架如图1所示。对于一张图片,R-CNN基于selective search方法大约生成2000个候选区域,然后每个候选区域被resize成固定大小,并送入一个CNN模型中,最后得到一个特征向量。然后这个特征向量被送入一个多类别SVM分类器中,预测出候选区域中所含物体的属于每个类的概率值。每个类别训练一个SVM分类器,从特征向量中推断其属于该类别的概率大小。为了提升定位准确性,R-CNN最后又训练了一个边界框回归模型,通过边框回归模型对框的准确位置进行修正。
  • [MindX SDK] Overlap-Recovery重叠文本还原设计案例
    MindX SDK-Overlap-Recovery重叠文本还原参考设计1 介绍本开发样例使用自研算法完成重叠文本的还原任务,供用户参考。 本系统基于昇腾Ascend310卡。本仓库是重叠文本识别任务(Overlap-CRNN)的上游任务,即完成对重叠文本还原并输出文本实例的mask。1.1 支持的产品本系统采用Ascend 310作为实验验证的推理硬件平台,训练硬件平台支持Ascend和GPU。1.2 支持的版本推理代码支持的版本为MindX SDK 3.0RC3,Ascend-CANN-toolkit 6.0.RC1。1.3 软件方案介绍软件方案主要为文本还原的系统,子系统功能具体描述请参考 表1.1 系统方案各子系统功能描述。重叠文本还原子系统可以实现还原重叠文本并得到各个文本实例的mask,本方案选择使用基于分割的算法并提出一种重叠区域感知的模块来恢复出重叠文本实例。系统方案中各模块功能如表1.2 所示。表1.1 系统方案各子系统功能描述:序号子系统功能描述1重叠文本还原子系统重叠文本还原子系统将得到重叠文本实例的mask的结果,之后将结果送入到下游的文字识别模型进行文字识别。表1.2 系统方案中各模块功能:序号子系统功能描述1输入图像将图像(JPG/PNG格式)通过Pillow库读入。2图像解码通过Pillow第三方库对图像解码。3图像放缩模型的输入为固定尺寸,所以需要对输入图片进行等比例放缩。4文字还原在图像放缩后,将缓存区数据送入文字还原模型。本方案选用自研算法进行文本还原5结果可视化通过Pillow库可视化单张图像的预测的文本实例mask。1.4 代码目录结构与说明eg:本sample工程名称为Overlap-Recovery,工程根目录如下图所示:├── train #训练代码的文件夹 ├── inference #推理代码的文件夹其中,Overlap-Recovery/train工程目录如下图所示,训练部分代码下载链接。├── eval.py #精度测试 ├── train.py #模型训练主函数 ├── export.py #将ckpt模型导出为onnx格式的模型 ├── __init__.py ├── src #模型源码及相关辅助函数 │ ├── __init__.py │ ├── dataset #数据集加载、预处理等相关函数 │ │ ├── __init__.py │ │ ├── base_dataset.py #dataset类的基类 │ │ ├── build_dataset.py #提供接口构造dataset对象 │ │ ├── data_process.py #数据预处理相关函数 │ │ ├── real_dataset.py #用于测试数据的dataset类 │ │ ├── synth_dataset.py #用于训练数据的dataset类 │ │ ├── utils.py #dataset构造所需的辅助函数 │ ├── deoccluder #去重叠算法相关代码 │ │ ├── __init__.py │ │ ├── deoccluder_r50.py #模型主结构代码 │ │ ├── fpn_neck.py # FPN模块代码 │ │ ├── resnet.py # resnet-50 backbone代码 │ │ ├── utils.py # 辅助函数 │ │ ├── rpn # kernel初始化相关 │ │ │ ├── __init__.py │ │ │ ├── kernel_head.py # kernel初始化相关函数 │ │ │ ├── positional_encoding.py # 位置编码函数 │ │ │ ├── semantic_fpn_warpper.py # 语义fpn编码 │ │ ├── roi # kernel更新相关 │ │ │ ├── __init__.py │ │ │ ├── custom_kernel_iter_head.py # kernel迭代函数 │ │ │ ├── custom_kernel_update_head.py # kernel更新函数 │ │ │ ├── kernel_update_head.py # kernel更新函数基类 │ │ │ ├── kernel_updator.py # kernel更新辅助函数 │ │ ├── custom_cells # 算法组件 │ │ │ ├── __init__.py │ │ │ ├── custom_assigner.py # 标签分配函数 │ │ │ ├── custom_blocks.py # 自定义模块 │ │ │ ├── custom_losses.py # 自定义损失函数 │ │ │ ├── custom_match_cost.py # 自定义匹配代价评估函数 │ │ │ ├── custom_operations.py # 自定义算子 │ │ │ ├── custom_samplers.py # 自定义采样函数 │ ├── model_utils # 模型训练相关代码 │ │ ├── __init__.py │ │ ├── device_adapter.py │ │ ├── local_adapter.py │ │ ├── moxing_adapter.py │ │ ├── configs # 配置文件函数 │ │ │ ├── __init__.py │ │ │ ├── config_base.py │ │ │ ├── config_model.py │ ├── utils # 将pytorch权重转为mindspore权重 │ │ └── pth2ckpt.py ├── scripts # scripts文件 │ ├── convert_resnet.sh # 将pytorch的resnet权重转为mindspore权重 │ └── train.sh # 训练指令 ├── resource_utils # 转换pytorch权重所需的相关材料 │ └──resnet50_dict.json其中,Overlap-Recovery/inference工程目录如下图所示:├── eval.py #精度测试 ├── eval_utils.py #指标计算的辅助函数 ├── load_ann.py #加载测试集 ├── load_img_data.py #加载图片数据 ├── ominfer.py #单张图片推理 ├── preprocess_utils.py #加载图片做预处理的辅助函数 ├── README.md ├── models #不同类型的模型文件 │ ├── best_iou.onnx │ └── best_iou.ckpt │ └── best_iou.om ├── dataset #测试数据集 │ ├── img │ └── annotation.json1.5 技术实现流程图实现流程图如下图所示:1.6 特性及适用场景本案例中的还原模型适用于常规图像的文本,并可以返回测试图像的文本区域的IOU指标。本模型在以下几种情况还原效果良好:图像中文字清晰可见、排版工整、字符大小适中等。在以下几种情况去噪效果不太好:图像中文字模糊、排版随意、字符较小等。1.7 代码地址本项目的代码地址为:cid:link_22 环境依赖下面列出环境依赖软件和版本。推荐系统为ubuntu 18.04或centos 7.6。2.1 训练环境训练支持Ascend和GPU硬件。其中GPU环境下依赖的软件和版本如下表:软件名称版本CUDA11.1ubuntu18.04.1 LTSpython3.9.2MindSpore1.9.0opencv-python4.6.0.66numpy1.23.1pillow9.1.0mmcv0.2.14loguru0.2.14tqdm4.64.1imagesize1.4.1terminaltables3.1.10其中Ascend环境下依赖的软件和版本如下表:软件名称版本Ascend-CANN-toolkit6.0.RC1ubuntu18.04.1 LTSpython3.9.2MindSpore1.9.0opencv-python4.6.0.66numpy1.23.1pillow9.1.0mmcv0.2.14loguru0.2.14tqdm4.64.1imagesize1.4.1terminaltables3.1.102.2 推理环境推理环境依赖软件和版本如下表:软件名称版本MindX SDK3.0RC3Ascend-CANN-toolkit6.0.RC1ubuntu18.04.1 LTSpython3.9.2cv24.5.5.64numpy1.23.1pillow9.1.0mmcv-full1.7.0在运行推理项目前,需要设置环境变量:环境变量介绍. ${sdk_path}/set_env.sh . ${ascend_toolkit_path}/set_env.sh3 模型训练步骤0 下载训练部分的源码放置到Overlap-Recovery/train文件夹下。步骤1 从pytorch官方下载resnet-50预训练权重 ,并利用脚本转换成mindspore支持的格式# 准备好logs保存路径 mkdir train/logs # 运行转换脚本 sh train/scripts/convert_resnet.sh PATH-TO-PYTORCH-WEIGHT PATH-TO-MINDSPORE-WEIGHT步骤2 修改训练相关的配置参数在train/src/model_utils/config_base.py中,完成下述参数的修改:a) 设置训练设备类型:设置103行的device_target选择在GPU或者Ascend设备上训练。b) 修改105行mindrecord_dir为预期的log输出和模型保存路径。c) 修改预训练backbone路径:将107行的pretrained_r50改为步骤1中转换后的backbone权重路径。# 用于训练的设备 ['GPU', 'Ascend'] device_target='GPU', # 训练时的log文件和权重的保存路径 mindrecord_dir='path-for-saving-logs-and-files', # 预训练backbone的权重路径 pretrained_r50='path-to-pretrained-model',d) 修改数据集路径:参考测试数据的格式准备好训练数据,修改synth_data_root和real_data_root参数为训练集、测试集的根目录。# 39行的训练集的根目录 SYNTH_DATA_ROOT = "root-directory-to-train-data" # 41行的测试集的根目录 REAL_DATA_ROOT = "root-directory-to-test-data"e) 修改训练的epoch数量: 将94行的total_epoch根据训练集数据量调整为合适的数值。在本案例中total_epoch设置为了60,但训练数据量较大,所以在训练到第2个epoch时性能就满足要求,也可以提前终止训练。步骤3 按照2.1节环境依赖要求配置好训练所需运行环境后,执行如下命令启动模型训练。python train/train.py注:在Ascend上如需指定特定设备序号,可在训练命令前加上DEVICE_ID=X。在GPU上如需指定特定设备序号,可在训练命令前加上CUDA_VISIBLE_DEVICES=X。步骤4 使用训练好的mindspore模型直接推理修改train/src/model_utils/config_base.py中112行checkpoint_path参数为要测评的checkpoint的路径,执行如下命令推理。python train/eval.py4 模型转换通过第三节的训练后得到ckpt模型文件,在项目运行前需要先将ckpt文件通过 export.py 转换成ONNX模型文件,然后在本代码仓下通过ATC将ONNX转换成om模型,其中ckpt->onnx的转换在训练环境下进行(参考第2.1节所述),onnx->om的转换在推理环境下进行(参考第2.2节所述)。模型转换工具(ATC)相关介绍如下:ATC介绍具体步骤如下:准备好训练得到的ckpt模型文件,放至服务器上Overlap-Recovery/train/models文件夹下,环境同训练环境相同(硬件包含CPU,参考第2.1节所述)。进入Overlap-Recovery/train文件夹下,修改export.py文件中ckpt_file_path和file_name参数为自己的路径,执行如下命令完成ckpt->onnx的模型转换:cd train python export.py将生成的ONNX模型转移到推理服务器,放至在Overlap-Recovery/inference/models路径下,环境同推理环境相同(硬件为Ascend 310,参考第2.2节述所)。进入推理服务器执行如下命令(修改onnx_model_path和output_model_path参数为自己的路径)完成onnx->om的模型转换:cd inference/models atc --model=[onnx_model_path] --framework=5 --output=[output_model_path] --soc_version=Ascend310 --input_shape="img:1,3,768,768" --precision_mode=force_fp32执行该命令会在当前目录下生成项目需要的模型文件[output_model].om。执行后终端输出为:ATC start working now, please wait for a moment. ATC run success, welcome to the next use.表示命令执行成功。相关模型的下载链接如下:models.zip。 将模型按照提供的文件夹目录放至即可。5 模型推理当已有模型的om文件,保存在Overlap-Recovery/inference/models/下,推理所需环境如第2.2节所述。示例步骤如下:步骤1 将任意一张待预测的图片存到当前目录下(./Overlap-Recovery/inference),文件名修改为test。步骤2 按照第4节模型转换获取om模型,放置在Overlap-Recovery/inference/models/路径下。若未自行转换模型,使用的是仓库提供的模型,则无需修改相关文件,否则修改ominfer.py中相关配置,将model_path对象的路径改成实际的om模型的路径;img_prefix和img_name对象的路径改成实际的测试图片的路径;save_path对象设置成需要保存可视化图像的路径。步骤3 在命令行输入 如下命令运行单张图片模型推理:cd inference python ominfer.py步骤4 运行结束输出test文件夹,预测的mask可视化结果保存在test文件夹下。6 测试精度步骤1 在Overlap-Recovery/inference/dataset/路径下准备相同格式的数据集(已提供测试用的数据集,按照文件目录放至即可:dataset.zip)步骤2 在命令行输入 如下命令运行精度测试:cd inference python eval.py模型在测试集上的精度达标,最终模型的的精度为87.0%,满足精度要求(≥80%)。
  • [应用开发] 如何升级CANN
    我用的硬件是MDC300,用的CANN版本是Ascend-cann-toolkit_5.0.mdc300_linux-x86_64.run,在onnx转om过程中出现算子不支持的情况,是否升级在最新版本,算子就可以支持,如何升级最新版本呢?
  • [问题求助] 如何升级CANN
    现在用的是MDC300平台,安装的cann版本是Ascend-cann-toolkit_5.0.mdc300_linux-x86_64.run,但是在onnnx转om文件时,用到了不支持的算子,如何解决不支持的算子呢?如果升级cann,需要卸载原来的cann吗?如何升级cann呢?
  • [技术干货] 如何全面掌握图机器学习?最新《图学习》全面综述
    图学习旨在学习现实世界中常见的复杂节点关系和图的拓扑结构,如社交网络、学术网络和电子商务网络等。这些关系使得图数据与传统的表格数据不同,其中节点依赖于非欧氏空间,包含了丰富的信息。图学习从图论发展到图数据挖掘,现在被赋予表示学习的能力,使其在各种场景中取得了出色的性能,甚至包括文本、图像、化学和生物。由于在现实世界中的广泛应用前景,图学习已经成为机器学习中一个热门且有前景的领域。近年来,已有成千上万的研究成果被提出用于解决图学习中的各种问题,引起了学术界越来越多的关注,因此对已有的有价值的研究成果进行综述变得至关重要。尽管一些研究人员已经注意到这种现象,并完成了关于图学习的令人印象深刻的调研。然而,由于图学习的快速扩展,它们未能以更合乎逻辑的方式将相关目标、方法和应用联系起来,并涵盖当前丰富的场景和具有挑战性的问题。1. 引言图学习旨在对图进行建模,图是一种广泛存在于真实场景中的非欧氏数据,与以往机器学习中的数据结构有很大不同,如社交网络[1]、[2]、[3],学术网络[4]、[5]、[6],电子商务网络[7]、[8]、[9],企业知识图谱[10]、[11]、[12]等。挖掘图中节点间复杂连接关系和拓扑结构中蕴含的丰富信息,对于图上的许多任务和应用具有重要意义。此外,传统应用也可以转换为图数据(如计算机视觉[13]、[14]、[15]、语言模型[16]、[17]、[18]、物理[19]、[20]和化学[21]、[22])。重点假设不同实体之间存在许多未直接观察到的潜在联系。这使得图学习不仅是一种处理自然图结构的方法,而且是一种思考各种问题的方式。由于图学习具有广阔的应用前景,因此在国内外引起了广泛的关注。尽管之前关于图的理论工作帮助人们理解图上的各种字符,并提供了基本的分析框架。这些工作通常集中在较小的模拟图上,这限制了它们在真实场景中的应用,特别是当图上存在复杂的关系和结构时。尽管在这一领域已经有了一些显著而详细的调查。目前还缺乏一个综合的、将相关的目标、方法和应用联系起来,形成一个有机的、逻辑的综述。此外,每年在顶级会议上都有数百篇关于图学习的研究,并且数量还在高速增长。由于其发展迅速,缺乏涵盖最新趋势和挑战的全面调研。图2按时间顺序展示了有影响力的图学习方法。这些方法主要分为3类(图挖掘方法、图表示方法和深度图学习方法)。在图学习早期,大多数方法集中于图的字符[1]或利用图的结构信息在小图[25]、[26]上完成一些下游任务。图表示学习目前占据主流地位,可归纳为图嵌入方法和图神经网络方法两大类。这两类方法都旨在学习节点、边或图的语义表示。前者直接优化嵌入,可以减少图结构信息的损失;后者利用深度神经网络,在图上建模信息传递过程。如图3所示,在本综述中,我们从图学习目标的角度提供了一个直观的分类法。根据图的元素(即节点、边和图结构)对以前对图的工作进行排序。基于这种逻辑,综述了图上的相关方法和任务。展示了图学习在现实世界中的各种应用上的出色性能。最后,提出了图学习的发展趋势和挑战,以期进一步推动该领域的研究。本综述的主要贡献总结如下。提供了一个新的分类法,以调查以前关于数据、模型和任务的研究。总结了当前图学习在现实世界中的应用。提出了图学习的当前趋势和挑战。本文的其余部分组织如下。第2节从数据、模型和任务3个角度,基于节点、边和图结构对已有工作进行了直观的分类。第3节展示了用于图学习的主要方法和当前的研究趋势。第四部分总结了该方法在实际中的应用。第5节提出了当今图学习面临的挑战。2 方法在本节中,我们将当前的模型分为两大类(即传统模型和图神经网络)。传统模型可以进一步分为3类(即矩阵分解模型、基于随机游走的模型和基于自编码器的模型)。首先回顾了传统模型,其中一些仍然活跃或与GNN相结合,并给出了当前模型的许多启示。在大多数场景下,与传统模型相比,GNN表现出更高的表达能力和出色的性能。本文将GNN归纳为两个方面。3 应用介绍当前图学习在现实世界中的主要应用,包括传统的机器学习场景,如推荐系统、自然语言处理、计算机视觉和金融科技,以及科学场景中的新兴应用,如化学、生物、物理和数学。最后,总结了图学习中流行的数据集。
  • [经验分享] 使用MindStudio进行MindX SDK 财务票据OCR 开发
    一、任务介绍1.1任务描述在本系统中,目的是基于MindX SDK,在昇腾平台上,开发端到端财务票据OCR识别的参考设计,实现对财务票据中的文本信息进行OCR识别的功能,达到功能要求。视频演示过程:【使用MindStudio进行MindX SDK 财务票据OCR 开发】https://www.bilibili.com/video/BV1644y1m7Qe/?share_source=copy_web&vd_source=2a40c54eb5f208ef5b1c3cb38321c4121.2 任务目标样例输入:财务票据jpg图片样例输出:框出主要文本信息并标记文本内容以及票据类型的jpg图片1.3 环境信息开发环境:Windows 10 + MindStudio 5.0.RC2昇腾芯片:Ascend 310服务器环境依赖软件和版本如下表:软件名称版本Ubantu18.04.1 LTSMindX SDK2.0.4Python3.9.2CANN5.1RC2二、模型介绍本文开发选用了ResNet-50模型实现财务数据分类,通过DB模型实现端到端文本框识别、采用CRNN模型进行抠图以及框内文本内容识别。财务数据识别流程图如下图所示: 票据识别的SDK流程图如下图所示:2.1 票据分类本文开发选用了ResNet-50模型对图片进行分类。ResNet-50模型相关文件可在此处下载: cid:link_2ResNet是ImageNet竞赛中分类问题效果比较好的网络,它引入了残差学习的概念,通过增加直连通道来保护信息的完整性,解决信息丢失、梯度消失、梯度爆炸等问题,让很深的网络也得以训练。ResNet有不同的网络层数,常用的有18-layer、34-layer、50-layer、101-layer、152-layer。支持的特性包括:1、分布式并行训练;2、混合精度训练。2.2 文本框识别本文开发选用db模型对图片进行文本框识别。论文连接:cid:link_11模型相关文件链接:cid:link_3DBNet是基于分割的文本检测算法,算法将可微分二值化模块引入了分割模型,使得分割模型能够通过自适应的阈值进行二值化。经过验证,该方案不仅简化了后处理过程而且提升了文本检测的效果。相较于其他文本检测模型,DBNet在效果和性能上都有比较大的优势,是当前常用的文本检测算法。DB文本检测模型可以分为三个部分:Backbone网络,负责提取图像的特征;FPN网络,特征金子塔结构增强特征;Head网络,计算文本区域概率图。其模型结构如下图所示:2.3 文本内容识别本文使用CRNN模型对文本内容进行识别。CRNN模型相关文件可在此处下载:cid:link_4CRNN是一种基于图像序列识别的神经网络及其在场景文本识别中的应用,本文研究了场景文本识别问题,这是基于图像序列识别中最重要和最具挑战性的任务之一。提出了一种新的神经网络体系结构,将特征提取、序列建模和转录集成到一个统一的框架中。与以前的场景文本识别系统相比,所提出的体系结构具有四个独特的特性:它是端到端可训练的,与大多数现有算法相比,这些算法的组件是单独训练和调整的。它自然地处理任意长度的序列,不涉及字符分割或水平尺度归一化。它不局限于任何预定义的词典,在无词典和基于词典的场景文本识别任务中都取得了显著的性能。它生成了一个有效但小得多的模型,这对于现实世界的应用场景更实用。三、MindStuido介绍与安装MindStudio的具体安装步骤以及详细功能介绍可参考用户手册。3.1 MindStudio简介可提供再AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务。依靠模型可视化、算力测试、IDE本地仿真调试等功能。MindStudio可以单独安装在Windows上。在安装MindStudio前需要在Linux服务器上安装部署好Ascend-cann-toolkit开发套件包,之后在Windows上安装MindStudio,安装完成后通过配置远程连接的方式建立MindStudio所在的Windows服务器与Ascend-cann-toolkit开发套件包所在的Linux服务器的连接,实现全流程开发功。本文开发采用的就是将MindStudio安装在Windows服务器上时,Windows服务器为本地环境,Linux服务器为远端环境。3.2 MindStudio安装步骤1 : 通过MindStudio下载链接,下载Windows系统的安装包,下载完成后点击下载的安装包安装MindStudio。双击下载好的软件安装包进行安装。步骤2:双击安装包,进入安装界面,单击“Next”。步骤3:在下图安装界面,用户根据需要勾选安装选项后,单击“Next”。其中Create Desktop Shortcut:勾选“MindStudio”,创建桌面快捷方式。Update PATH Variable(restart needed):将MindStudio的启动文件路径加入环境变量PATH中,可从系统命令行直接启动MindStudio。如果勾选此项,MindStudio安装配置完成后会重启操作系统。Update Context Menu:勾选“Add "Open Folder as Project"”后,右键单击文件夹,可以作为MindStudio工程打开。Create Associations:默认不勾选。步骤4:选择MindStudio默认安装路径下的启动菜单文件夹,单击“Install”步骤5:开始安装MindStudio,完成后单击“Next”。步骤6:完成MindStudio安装配置,单击“Finish”。以上安装完成后,启动MindStudio,进入导入设置界面,这里选择的是Do not import settings不导入设置。选择该选项,则创建新的配置文件,默认为该选项。如果没有报错信息且能正常进入欢迎界面,则表示MindStudio安装成功。3.3 MindStudio环境搭建进入欢迎界面后,从欢迎界面打开Remote CANN Setting窗口的图文内容:Customize-》All Settings-》Appearance & Behavior-》System Settings-》CANN点击Remote Connection后面的添加图标点击左上角的“➕”,然后填写服务器连接的相关信息,测试成功后点击OK。点击Remote CANN location后面的文件图标,打开远端服务器目录树,选择CANN安装路径,点击OK,点击Finish开始同步。在欢迎界面点击Plugins,在插件市场搜索并安装如下插件工具。Grep ConsolePylintPython Community Edition在欢迎界面依次点击Customize-》All Settings-》Appearance & Behavior-》System Settings-》MindX SDK打开管理界面。点击“Install SDK”,导入远程MindX SDK。以上步骤全部完成且没有报错信息,表示MindStudio开发环境已成功搭建。3.4 MindStudio新建工程在 Projects 标签下点击“New Project”创建一个新的工程。选择 MindX SDK Project (Python),点击“Finish”。点击File->Project Structure点击“SDKs”,点击加号,点击“Add Python SDK”点击Interpreter后的按钮选择python版本(一般系统会自动检索,如果有多个python版本请手动选择正确的)。填好后点击OK。点击“Project”,选择创建的 SDK。点击 “Modules”->“Dependence”,选择创建的 SDK,点击“OK”。File ->Settings ->Tools ->Deployment,点击Mappings,根据下图操作顺序设置远程映射路径。点击“Tools”-> “Deployment”->“Automatic Upload”。进入远程服务器项目所在目录,两端文件已同步完成开发完成后完整的工程结构如下所示:四、模型转换MindStudio模型转换工具的详细使用和参数说明可参考MindStudio用户手册--模型转换。4.1 Resnet模型转换可以通过在菜单栏选择“Ascend > Model Converter” 进入模型转换界面。​打开模型转换页面,在“Model Information”页签中配置Model File,可以选择远端或本地的模型文件,点击“OK”以后会自动解析模型并自动填充如图相关信息。添加input Node, 参数值为“1,3,224,224”,TYPE选择UINT8。设置模型名称、om 模型生成目录、点击“Next”。进入“Data Preprocessing”数据预处理的配置页,开启Load Aipp Configuration,选择对应的配置文件。配置文件如下所示:最终的数据预处理参数如下,点击“Next”。检查生成的atc命令,确认无误后点击“Finish”。模型转换成功后,如下图所示:4.2 DB模型转换可以通过在菜单栏选择“Ascend > Model Converter” 进入模型转换界面。打开模型转换页面,在“Model Information”页签中配置Model File,可以选择远端或本地的模型文件,点击“OK”以后会自动解析模型并自动填充如图相关信息。添加input Node, --input_shape="x:1,3,-1,-1",TYPE选择FP32。dynamic_image_size="1216,1280;1280,1216;1120,1280;1280,1120;1024,1280;1280,1024;928,1280;1280,928;832,1280;1280,832;736,1280;1280,736;704,1280;1280,704;672,1280;1280,672;640,1280;1280,640;608,1280;1280,608;576,1280;1280,576;544,1280;1280,544;512,1280;1280,512;480,1280;1280,480;448,1280;1280,448"。点击Next。 点击“Next”。进入“Advanced Options Preview”高级选项配置页,在Additional Arguments添加转换参数。Command Preview展示了模型转换使用的atc参数预览数。配置文件如下所示:模型转换成功后,如下图所示:4.3 CRNN模型转换可以通过在菜单栏选择“Ascend > Model Converter” 进入模型转换界面。打开模型转换页面,在“Model Information”页签中配置Model File,可以选择远端或本地的模型文件,点击“OK”以后会自动解析模型并自动填充如图相关信息。input Node参数值为input_shape="x:1,3,48,320",Type选择UINT8。点击“Next”。进入“Data Preprocessing”数据预处理的配置页,开启Load Aipp Configuration,选择对应的配置文件。配置文件如下所示:最终的数据预处理参数如下,点击“Next”。进入“Advanced Options Preview”高级选项配置页, 其中Command Preview展示了模型转换使用的atc参数预览数。确认无误后点击“Finish”。模型转换成功后,如下图所示五、项目开发5.1 pipeline流程编排MindX SDK实现功能的最小粒度是插件,每一个插件实现特定的功能,如图片解码、图片缩放等。将这些插件按照合理的顺序编排,实现相应的功能。这个配置文件叫做pipeline,以JSON格式编写,用户必须指定业务流名称、元件名称和插件名称,并根据需要,补充元件属性和下游元件名称信息。本文实现所使用的插件和工作流程如下:(1)输入类型可以是图片数据(jpg图片序列)(2)调用MindX SDK提供的图像解码接口mxpi_imagedecoder,解码后获取图像数据(3)进行图像尺寸大小变换,调用MindX SDK提供的图像尺寸大小变换接口mxpi_imageresize插件(4)首先进行票据类别识别,调用MindX_SDK的mxpi_tensorinfer接口,将尺寸变换后的图像数据输入Resnet训练模型,完成图片所属票据类别的识别(5)根据所属票据类别,结合DBNet模型方法进行文本框识别,并进行文本框缺失判断(6)检测后处理,调用MindX SDK提供的模型推理插件mxpi_tensorinfer,然后调用MindX SDK提供的插件mxpi_objectpostprocessor,将结果组装成json字符串传给下一个插件(7)抠图,调用MindX_SDK的mxpi_imagecrop插件,将各个文本框分别抠出并标记(8)对框内文本进行识别,然后将结构化信息写入文本文件中。文本文件与图片名保持一致。序号插件功能描述图像解码调用MindX SDK的 mxpi_imagedecoder图像缩放调用MindX SDK的mxpi_imageresize分类识别使用已经训练好的Resnet模型,对图像进行票据分类。插件:mxpi_tensorinfer分类后处理mxpi_classpostprocessor文本框识别使用已经训练好的DBNet模型,对检测出图像中的所有文本框信息。插件:mxpi_tensorinfer检测后处理mxpi_textobjectpostprocessor抠图调用MindX SDK的抠图插件mxpi_imagecrop文字识别使用已经训练好的CRNN模型,对单个文本框进行文字识别。插件:mxpi_tensorinfer文本生成后处理mxpi_textgenerationpostprocessor结构化输出进行后处理插件的开发,将票据类别、文本框分类及文字信息结构化输出到图片同名的文本文件中MindStudio中可以进行可视化流程编排。在顶部菜单栏中选择“Ascend-》MindX SDK Pipeline”,打开空白的pipeline绘制界面,可以在左方插件库中选中所需的插件,并进行插入插件、修改参数等操作。点击Save As进行保存。保存之后可以通过代码进行修改。可在test.pipeline文件中配置所需的模型路径与模型后处理插件路径。next和dataSource制定了各个元件之间的连接关系,om模型地址需要放在推理插件里面,推理插件输出结果不一定可以可视化,所以需要后处理元件对推理插件进行处理输出。最终pipeline可视化如下:5.2 主程序开发由于目前MindStudio连接远程python服务器的功能正在开发中,目前仅支持使用MindStudio实现python项目两端代码同步,项目运行依然需要在服务器上实现。pipeline在脚本main.py内部。获取输入图片文件名与路径将识别的文本内容添加到方框左上方。创建并初始化流管理对象;读取pipeline文件。创建流以及输入对象,输入类型为图片数据(jpg图片序列)。获取输出,并打印结果。判断并标记输入票据的类型保存框出票据的主要文本信息并标记文本内容以及票据类型的jpg图片在./ouput文件夹下。以及最后销毁流。将测试图片放在inputs文件夹中,运行main.py等待运行成功后,MindStudio会自动同步远程项目,但是若是自动同步失败或者没有运行,可以点击菜单栏中的Tools>Deployment>Download,下载服务器里的项目,应当包含模型的输出。待执行完毕可在./outputs目录下查看结果六、模型精度验证测试数据可在此处下载,将下载的数据解压到eval_data目录下。定义获取测试数据的文件名、标签如下:定义计算iou函数以及字符串计数函数如下定义精度函数如下:创建并初始化流管理对象, 读取pipeline。创建流。其中type_acc为分类精度,acc为识别端到端精度。在远程项目目录下执行python3 eval.py可得精度结果如下所示,其中acc为db+crnn端到端精度,type_acc为resnet50精度。七、总结本文主要介绍使用 MindStudio 全流程开发工具链,在昇腾平台上,开发端到端财务票据OCR识别的参考设计,实现对财务票据中的文本信息进行OCR识别的功能,达到功能要求。在开发过程中碰到了很多问题,除了参考 MindStudio用户手册,社区帖子也提供了很多解决问题的思路。建议在开发过程中遇到问题可查看社区相关经验分享。社区地址如下:cid:link_9实现参考链接cid:link_10。参考文档:cid:link_7八、FAQCANN配置失败:Permission denied报错原因与解决方法:原先的CANN安装再root权限的用户下,普通用户没有权限。我们需要重新下载普通用户下,然后导入普通用户的路径。模型转换时,无法导入python module报错原因与解决方法:未配置python的环境变量。打开~/.bashrc文件,添加环境变量。
  • [技术干货] 目标检测算法套件使用Demo
    目标检测算法套件使用指导本Notebook通过引导用户导入数据集、选择模型、训练并可视化推理,快速完成COCO数据集目标检测任务。Step0 安装依赖包!pip install ipywidgets==7.7.1 !pip install pillow==9.1.1 !pip install pandas==1.3.4Step1 加载算法、样例数据集与预训练模型完成模型的微调和探索经典的目标检测方法主要包括单阶段(YOLO、RetinaNet等)和多阶段算法(Faster RCNN、Cascade RCNN等),本案例以fcos算法模型为例,fcos算法属于anchor free的一阶段目标检测算法,具有训练速度快、超参数少等特点。本小节以"mmdetection:fcos/fcos_r50_caffe_fpn_gn-head_1x_coco"模型为例,演示如何下载预训练模型。1. 选择预训练模型#@title Install pretrained model from ma_cau.apis import EnvManager env = EnvManager() env.init_env() # initialize environment algo_name = "mmdetection" #@param {type:"string", dropdown} model_name = "mmdetection:fcos/fcos_r50_caffe_fpn_gn-head_1x_coco" #@param {type:"string", dropdown} dataset_name = "coco2017_sample" #@param {type:"string"}# 安装算法套件,首次安装时可能需要restart kernel用以使用更新后的依赖包 env.install(mode="algorithm", asset_name=algo_name, version="2.17.0")首次安装完套件需要restart kernel,重启后重新执行第一个cell,然后就可以直接执行下面一个cell,不需要再执行安装算法套件步骤def restart_kernel(): import os status = input("Restart Kernel【只需要在第一次安装算法套件时才需要重启kernel,重启后重新执行第一个cell】[y/n(default)]: ") or "n" if status.lower() == "y": os._exit(00) restart_kernel() # 安装样例数据集,数据集会下载到./{project_dir}/data/raw/ env.install(mode="dataset", asset_name=dataset_name) # 从AI Gallery下载 coco2017_sample 数据集 # 安装预训练模型,模型会下载到./{project_dir}/model_zoo/ env.install(mode="model", asset_name=model_name) # 从openmmlab网站下载预训练模型2. 构建数据集DataBlock对象DataBlock支持自动统计数据集信息,比如目标、尺寸等信息,帮助用户更好的理解数据集,同时还可以动态查看每一个batch经过pipeline之后的输入图像,确保数据增强的正确性。detblock.plot_dataset_stats() 可以绘制数据集的统计信息,图像的显示大小可以由figsize参数控制; detblock.print_dataset_stats() 能够打印出具体的统计信息数值; datablock.show_batch() 可以动态展示内存中的经过增强后的图片信息,可以通过rows(显示行数)和figsize(显示大小)来控制输出。DetDataBlock主要接收如下入参:env: EnvManager对象batch_size: 批处理大小 data_type: 数据集类型,目前只支持“coco”,其他数据集格式可以通过CocoConverter进行转换 data_root: 数据集路径 seed:随机数种子,和数据集batch加载顺序相关 num_classes:类别数 categories:类别信息列表,默认为None表示使用所有类别,否则只加载对应类别 train_img_prefix:训练集图片路径,相对于data_root train_ann_file:训练集标注文件路径,相对于data_root val_img_prefix:验证集集图片路径,相对于data_root,可缺省 val_ann_file:验证集标注文件路径,相对于data_root,可缺省 test_img_prefix:测试集图片路径,相对于data_root,可缺省 test_ann_file:测试集标注文件路径,相对于data_root,可缺省 model_name:模型名称#@title Build DataBlock from ma_cau.apis import DetDataBlock num_classes = 80 #@param {type:"integer"} data_root = "./data/raw/coco2017_sample" #@param {type:"string"} train_img_prefix = "val2017" #@param {type:"string"} train_ann_file = "annotations/instances_val2017.json" #@param {type:"string"} val_img_prefix = "val2017" #@param {type:"string"} val_ann_file = "annotations/instances_val2017.json" #@param {type:"string"} batch_size = 4 #@param {type:"slider", min:1, max:10, step:1} db = DetDataBlock(env, batch_size=batch_size, data_root=data_root, seed=0, num_classes=num_classes, train_img_prefix=train_img_prefix, train_ann_file=train_ann_file, val_img_prefix=val_img_prefix, val_ann_file=val_ann_file, model_name=model_name ) 2.1 可视化数据集plotter = db.show_batch(rows=2, figsize=(14, 8))next(plotter)2.2 绘制数据集分布图db.plot_dataset_stats(figsize=(14, 8))2.3 打印数据集分布结果db.print_dataset_stats()3. 构建模型Model对象Model主要接收如下入参:env: EnvManager对象 model_name:模型名称 num_classes:类别数 checkpoint:预训练模型文件路径,默认为None(随机初始化网络权重) load_default_backbone: 是否加载预训练backbone,默认为False。当指定checkpoint参数后,该参数可设置为False请手动选择一个路径,加载预训练模型,如"model_zoo/mmdetection/2.17.0/fcos/fcos_r50_caffe_fpn_gn-head_1x_coco-821213aa.pth"import os from ipyfilechooser import FileChooser from ipywidgets import Layout fc = FileChooser(path=os.getcwd(), layout=Layout(width="1000px")) display(fc)# Build Model from ma_cau.apis import Model ckpt_path = os.path.join(fc.selected_path, fc.selected_filename) fcos_model = Model(env, model_name=model_name, num_classes=num_classes, checkpoint=ckpt_path)4. 构建学习器Learner对象Learner主要接收如下入参model: model对象 datablock: datablock对象 work_dir: 训练输出路径 optimizer: 训练优化器,默认为SGD momentum: 动量 pretrained_model: 预训练模型路径,当构建Model时指定该参数后,此参数可忽略 warmup_policy: warm up策略,如cosine warmup_iters: warm up 步数, 默认为500 epoch_based_eval_interval: 每完成n个epoch训练后进行一次模型评估,用于检测等任务 iter_based_eval_interval: 每完成n个iteration训练后进行一次模型评估,用于分割等任务 save_ckpt_interval: 保存模型的间隔 no_validate: 训练中不进行评估操作,默认为False log_params: 字典类型参数,训练日志类型,默认以表格形式输出训练和评估日志,具体参数如下 log_type: 输出日志类型,默认为table table_highlight_method: 当log_type为table时,对训练结果的高亮方法,默认为best,即高亮最好的训练结果 log_interval: 训练输出间隔,每完成n个训练迭代输出日志 launcher: 分布式作业启动类型,当前暂不支持执行代码如下:from ma_cau.apis import Learner output_path = 'output' log_interval = 11 epoch_based_eval_interval = 1 log_params = { 'log_type': ['graph', 'table'], 'table_highlight_method':'best', 'log_interval':log_interval } learner = Learner(fcos_model, db, output_path, log_params=log_params, epoch_based_eval_interval=epoch_based_eval_interval)learner.fit:model: model对象 datablock: datablock对象 work_dir: 训练输出路径 optimizer: 训练优化器,默认为SGD momentum: 动量 pretrained_model: 预训练模型路径,当构建Model时指定该参数后,此参数可忽略 warmup_policy: warm up策略,如cosine warmup_iters: warm up 步数, 默认为500 epoch_based_eval_interval: 每完成n个epoch训练后进行一次模型评估,用于检测等任务 iter_based_eval_interval: 每完成n个iteration训练后进行一次模型评估,用于分割等任务 save_ckpt_interval: 保存模型的间隔 no_validate: 训练中不进行评估操作,默认为False log_params: 字典类型参数,训练日志类型,默认以表格形式输出训练和评估日志,具体参数如下 log_type: 输出日志类型,默认为table table_highlight_method: 当log_type为table时,对训练结果的高亮方法,默认为best,即高亮最好的训练结果 log_interval: 训练输出间隔,每完成n个训练迭代输出日志 launcher: 分布式作业启动类型,当前暂不支持本步骤主要演示训练过程的loss值可视化功能,1 epoch 训练耗时约12分钟,训练1分钟后即可提前手动停止#@title Fit parameters weight_decay = 0.0005 #@param {type:"number"} max_epochs = 1 #@param {type:"slider", min:0, max:20, step:1} lr = 0.001 #@param {type:"slider", min:0.001, max:0.1, step:0.001} learner.fit(lr=lr, max_epochs=max_epochs, weight_decay=weight_decay, gpu_ids=[0])Step3 模型评估1. 评估验证集learner.validate: 用于模型评估,具体参数如下data: 指定评估的数据集,只接受datablock类型的对象, 默认为None, 如果使用默认值则会使用已经定义好并传入Model中的datablock中的验证数据集进行评估 gpu_collect: 是否使用GPU进行评估,默认为True checkpoint: 评估时使用的模型权重路径, 默认为None。当传入有效路径时,该处优先级最高。没有传入参数时,会按完成训练后的模型权重高于Model中指定的checpoint的优先级加载模型权重。如果均未指定checpoint且没有进行训练,则默认使用随机初始化的权重进行评估# learner.validate() # 这步耗时较长,可跳过2. 图片推理learner.predict: 用于模型推理,具体参数如下img_path: 指定需要推理的图片路径 model: 指定用于推理的模型,默认为None, 不填写该参数则默认使用Learner中的Model进行推理 checkpoint: 推理时使用的模型权重路径, 默认为None。当传入有效路径时,该处优先级最高。没有传入参数时,会按完成训练后的模型权重高于Model中指定的checpoint的优先级加载模型权重。如果均未指定checpoint且没有进行训练,则默认使用随机初始化的权重进行推理 device: 推理时的设备类型,默认为'cpu',即使用cpu进行推理 score_thr: 模型logits判别阈值,默认为0.3 save_dir: 推理后的文件保存路径,默认为None手动选择一张图片进行推理,比如"./data/raw/coco2017_sample/val2017/000000000139.jpg"img_fc = FileChooser(path=os.getcwd(), layout=Layout(width="1000px")) display(img_fc)# 模型推理 result = learner.predict(os.path.join(img_fc.selected_path, img_fc.selected_filename))Step4 交互式推理本算法套件支持动态交互式推理方式,您可以通过鼠标勾选需要推理的图片、视频,并且可以选择不同的iou和score参数进行动态比较。测试图片路径:default_ma_cau_project/data/raw/coco2017_sample/val2017/测试视频路径:default_ma_cau_project/algorithms/mmdetection/algorithm/demo/demo.mp4VisDetPlatform主要接收如下几个参数: learner: Learner对象,主要用于在线实时推理; stage:推理图片所属的数据集类别,"train"、"val"、"test"; ann_json: 标注文件路径,主要用于离线展示 det_file: 验证输出的检测结果文件路径,主要用于离线展示 det_box_color:实际检测框颜色 gt_box_color:GT检测框颜色 without_gt:是否只查看数据集标注 classes:关注的类别列表 mask_palette:mask蒙版颜色列表,如果不设置,则使用随机颜色 infer_param: 推理相关参数,如不指定则使用配置文件默认参数,与推理速度相关,主要包含 1. nms_pre:nms操作前生成的bbox数量 2. max_per_img:每张图片最大目标数 3. img_scale:图像resize尺寸from ma_cau.apis import VisDetPlatform infer_param = {"nms_pre": 200, "max_per_img": 20, "img_scale": (800, 600)} VisDetPlatform(learner, infer_param=infer_param, stage="val", det_box_color=(0, 0, 255))如果您不清楚交互式推理的用法,请查看下方视频
  • 使用MindStudio进行基于双目视觉的目标定位
       对应的视频教程,可参考:【使用MindStudio进行基于双目视觉的目标定位】一、基于双目视觉的目标定位介绍基于计算机视觉的目标定位有单目视觉和双目视觉两种定位方式。单目视觉使用一台相机获取场景图像。由于图像透视投影过程丢失深度信息,因此单目视觉深度恢复得到物体的相对位置。双目视觉感知原理基于哺乳动物视觉机制,获取物体在左右两个相机的图像,并从获取图像恢复物体的三维几何信息。双目视觉从场景获取一组图像,利用这组图像标定相机参数,恢复物体三维几何信息。双目视觉的通用流程是特征点提取、特征点匹配、相机标定、三维重建等处理过程,恢复场景物体的三维几何信息,实现从二维图像重建三维场景。本案例输入的是用自制双目相机同时获取场景物体的图像,案例介绍利用MindX SDK对两幅图像进行相机标定、图像畸变矫正、视差求解、用MindX SDK模型检测目标、计算相物体的三维坐标。项目所用硬件平台:Ascend 310服务器,Atlas 200DK板卡,支持的SDK版本为mxVision 3.0.RC3。双目视觉目标定位流程,如图1-1所示。图1-1 双目视觉目标定位流程双目视觉目标定位流程主要步骤如下:(1)输入一组图像数据标定相机参数,标定的参数包括内参和外参。(2)利用标定的相机参数,用OpenCV函数stereoRectify和remap进行图像校正处理。(3)调用OpenCV函数StereoSGBM_create计算两张图像的视差。(4)通过调用MindX SDK 提供的图像处理插件ImageProcessor的成员函数decode解码并获取校正后图像。(5)对图像进行尺寸变换,调用MindX SDK提供的图像处理插件ImageProcessor的图像尺寸大小改变函数resize改变图像尺寸。(6)调用MindX SDK的Model的infer函数,调用YoloV3模型对尺寸变换后的图像进行推理,定位出目标物体。(7)模型后处理,调用MindX SDK函数post.Yolov3PostProces得到模型推理结果。(8)使用 BTensor函数对后处理结果进行处理,得到标注检测到物体包围盒的左上角和右下角坐标。(9)取右下角坐标,用项目方法把物体检测结果转化为三维坐标。二、MindStudio介绍与安装2.1 MindStudio简介      MindStudio是华为自研昇腾AI处理器开发的AI全栈开发工具平台,该IDE(Integrated Development Environment,集成开发环境)上功能很多,可以进行包括网络模型训练、移植、应用开发、推理运行及自定义算子开发等多类型任务。MindStudio具有工程项目管理、编译、调试、运行等常用功能,还具有性能分析、算子比对等功能,可有效提高开发人员的工作效率。此外,MindStudio具有远程操控功能,可执行远端任务。       MindStudio提供AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程的开发任务。通过模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够在一个IDE中高效便捷地完成AI应用开发。MindStudio采用插件扩展机制,开发者可以通过开发插件来扩展已有功能。2.2 MindStudio安装MindStudio下载地址为MindStudio下载-昇腾社区。点击MindStudio_{version}_win.exe后的“软件包下载”,将其下载到本地指定的目录。双击该软件包,即可开始安装MindStudio。MindStudio安装具体步骤包括 。进入MindStudio Setup安装界面,如图2-1所示,单击“Next”。图2-1 MindStudio 安装开始界面2. 非首次安装MindStudio时,可选择是否卸载已安装MindStudio版本。若不卸载已有版本,直接点击“Next”,进入步骤4;若要卸载则勾选相应版本,点击“Next”,进入步骤3,若同时勾选静默卸载,则会保留之前安装的MindStudio版本的一些配置。图2-2 卸载之前安装的MindStudio版本选取3. 选择需要卸载的项,单击“Uninstall”进行卸载。图2-3 卸载MindStudio4. 输入或选择MindStudio的安装路径,单击“Next”进入下一步骤。图2-4 输入或选取确定MindStudio安装路径5. 根据需要勾选安装选项,选项给出是/否在桌面产生MindStudio快捷启动、是/否把MindStudio可执行文件目录加入到系统路径变量PATH、是/否在右键弹出Context菜单出现“Open Folder as Project”选项、MindStudio缺省关联的文件扩展名,图2-5给出.java、.groovy、.kt及.kts扩展名文件。点击“Next”进入下一步骤。图2-5 选取设定安装配置选项       6. 选择或创建MindStudio安装路径下的启动菜单文件夹,默认即可,单击“Install”。图2-6 Start Menu Folder7. 开始安装MindStudio,完成后单击“Next”。8. 安装完成后,单击“Finish”。9. 双击桌面的MindStudio图标启动MindStudio,或者进入MindStudio安装目录的bin文件夹,双击MindStudio应用程序启动MindStudio。进入设置界面,如图2-7所示。图2-7 首次启动环境设置       默认选择“Do not import settings”,即不导入设置。选择该选项会创建新的配置文件。10. 如果没有报错信息则进入欢迎界面,表示MindStudio安装成功,如图2-8所示。图2-8 MindStudio启动初始界面2.3安装项目运行依赖环境2.3.1安装Python1. 进入Python官网,点击Downloads选项,选择下载Python版本。MindStudio目前支持的Python版本为3.7~3.9。2. 将下载Python压缩包解压、运行,进入图2-9所示的安装选项选取界面。3. 此页面中的选项全部勾选即可,然后点击“Next”。图2-9 安装选项设定4. 在Advanced Options 窗口中,点击“Customize install location”更改安装路径;选取“Create shortcuts for installed applications”在桌面创建Python启动快捷图标;选取“Add Python to environment variables”把Python安装目录加入到系统环境变量。点击“Install”进入安装。图2-10 设定Python安装选项5. 安装完成后,打开Command命令提示符窗口,输入“python”,显示如图2-11所示Python版本信息,表明Python成功安装。图2-11 检查python是否成功安装6. 在MindStudio中配置Python解释器(1) 在菜单栏中选择 File → Project Structure,在 Project Structure窗口中,点击 Platform Settings → SDKs,点击上方的“+”添加 Python SDK,如图2-12。图2-12 添加 Python SDK目录       在弹出窗口中选取“Existing environment”,选择python.exe的安装目录,点击“OK”完成在MindStudio配置Python解释器。若选取“New environment”,则会将“Base interpreter”的python 环境复制到工程目录下,该选项设置表示项目所有类库依赖都脱离系统安装python而运行。图2-13 设置Python解释器目录(2) 在Project Structure窗口中点击 Project Settings → Project,选择添加的 Python SDK,如图2-14所示。图2-14 选择Python SDK(3) 在Project Structure窗口中点击 Project Settings → Modules,右键工程名称,选择“Add”菜单项的“Python”,为 Python Interpreter 添加 Python SDK。点击“Apply”后再点击“OK”,如图2-15所示。图2-15 设定 Python解释器       Python SDK已配置完成。注意:上面各项配置好后,先点击“Apply”后再点击“OK”。2.3.2安装MinGW       MinGW下载地址:cid:link_7       选择下图中红框内的版本进行下载。图2-16 MinGW版本选择       下载后直接将其解压至自定义目录。把MinGW的bin文件路径添加到环境变量中,则安装完成。打开Command命令提示符窗口,输入“g++ --version”,显示如图2-17所示信息,则表示安装成功。图2-17 检查MinGW是否成功安装2.3.3安装CMake       CMake下载地址:https://cmake.org/download/       下载图2-18红框所示版本。图2-18 CMake版本选择       下载完成后,双击安装包进入安装。安装时选择“Add CMake to the system PATH for all users”把CMake路径加入到环境变量。安装完成后打开CMD命令提示符窗口,输入“cmake –version”,若显示如图2-19所示窗口,表明CMake安装成功。图2-19 检查CMake是否成功安装2.3.4安装CANN工具包       从菜单栏中点击File → Settings,并在弹出的窗口中选择Appearance & Behavior → System Settings → CANN进入CANN管理界面,如图2-20所示。图2-20 CANN管理界面       上图所示为CANN工具包安装完成界面。CANN工具包未安装时,蓝框中内容为空,点击图中的Change CANN,进入图2-21所示界面。图2-21 CANN安装       单击“Remote Connection”后的“+”号, 配置MindStudio连接远程开发环境Ascend-cann-toolkit开发套件包;单击“Remote CANN location”后的文件夹图标,在弹出界面中选择Ascend-cann-toolkit开发套件包的安装路径(需要选择到版本号一级)。选择完成后点击Finish开始安装。2.3.5安装MindX SDKMindX SDK提供昇腾AI处理器加速的各类AI软件开发套件(SDK),提供极简易用的API,加速AI应用开发。MindX SDK安装过程如下:1. 从菜单栏中点击File → Settings,并在弹出的窗口中选择Appearance & Behavior → System Settings → MindX SDK进入MindX SDK管理界面,如图2-22所示。图2-22 MindX SDK管理界面2. 界面中“MindX SDK Location”为软件包的默认安装路径,默认安装路径为 “C:\Users\用户名\Ascend\mindx_sdk”。单击Install SDK进入Installation settings界面,如图2-23所示。图2-23 MindX SDK安装3. 上图中前两个参数“Remote Connection”与“Remote CANN location”,跟图2-21中的选择保持一致;第三个参数“Remote SDK location”为远端环境SDK的路径,需配置到版本号一级;第四个参数“Local SDK location”为SDK的本地安装路径,图2-24所示为默认安装路径。选择完成后点击OK开始安装。4. 安装完成后的结果如下,点击OK即可。图2-24 成功安装MindX SDK三、基于双目视觉的目标定位开发3.1创建项目3.1.1创建初始项目1. 首先通过SecoClient连接VPN,以确保MindStudio能够连接远程服务器。启动MindStudio进入图2-8所示窗口,点击New Project,弹出图3-1所示新建项目窗口。2. 命名项目,图文案例把项目命名为BinocularStereoDepthRecovery,选择CANN版本及新建项目位置,点击Next。图3-1 新建昇腾项目3. 在打开的窗口左侧选择Ascend App(如图3-1所示),然后选择MindX SDK Projet(Python)(如图3-2所示),点击Finish。图3-2 选择MindX SDK Projet(Python)类型4. 项目创建完成后的初始界面如图3-3所示。图3-3 新建昇腾项目初始界面3.1.2项目文件介绍为新建昇腾项目创建“基于双目视觉的目标定位”所需文件。创建完毕后,BinocularStereoDepthRecovery项目目录树在MindStudio的显示如图3-4所示。图3-4 所需文件创建完毕的昇腾项目其中,image目录存放测试图片,每两个为一组,是我们用自制双目相机同时获取场景物体的图像。model目录存放模型文件,模型下载地址为:YOLOv3-昇腾社区。本案例所下载模型可直接使用,无需模型转换过程。若需要模型转换,可点击图3-5中任意一个红框位置,进入图3-6所示界面进行设置,具体过程可参考:模型转换-用户指南。图3-5 进入模型转换图3-6 模型转换设置界面camera_configs.py文件主要代码介绍如图3-7所示。执行该函数会从camera.xml文件中有序地导入相机参数,并计算校正变化。该函数在yolo_deep.py文件中被调用。图3-7 相机配置文件代码介绍camera.xml文件中含有相机预标定的数据,包括相机内参、外参和畸变参数,如图3-8与图3-9所示。图3-8 camera.xml文件中的相机参数信息图3-9 camera.xml文件中的相机参数信息yolo_deep.py文件计算物体坐标,主要代码介绍如图3-10与图3-11所示。图3-10 物体坐标计算文件代码介绍图3-11 物体坐标计算文件代码介绍yolov3_infer.py为模型推理文件,主要代码介绍如图3-12与图3-13所示。图3-12 模型推理文件代码介绍图3-13 模型推理文件代码介绍3.1.3接口调用介绍本模型采用API接口实现流程编排,对API的调用可参见第一章中“双目视觉目标定位流程的主要步骤”,代码中调用API的地方如下图所示。图3-14 yolo_deep.py文件中对API的调用图3-15 模型推理文件中对API的调用图3-16 模型推理文件中对API的调用如果需要进行pipeline编排,可在MindStudio顶部菜单栏中选择Ascend下的MindX SDK Pipeline,如图3-17所示,进入pipeline绘制界面,详细的pipeline绘制过程可参考可视化流程编排-用户指南。图3-17 打开pipeline绘制界面3.1.4连接远程终端       1. 选择MindStudio Tools菜单的Start SSH session菜单项,如图3-18所示。图3-18 打开Tools菜单选择“Start SSH session…”       在弹出的对话框中选择要连接的远程终端服务器,如图3-19所示。图3-19 选择远程终端连接的服务器       远程终端开启后,点击MindStudio底部状态栏目的Remote Terminal图标,如图3-20所示。图3-20 打开远程终端2. 激活远程终端mxVision的环境变量在远程终端窗口输入指令“vim ~/.bashrc”,在打开的文件末尾添加图3-21红框中内容(该内容从mxVision目录下的set_env.sh文件中复制得到),添加完成后在末行输入“wq!”保存并退出。最后,输入指令“source ~/.bashrc”使环境变量生效。图3-21 设置远程终端mxVision环境变量3. Deployment配置从顶部菜单栏中选择Tools → Deployment → Configuration,如图3-22所示。图3-22 打开Deployment Configuration新弹出的界面如图3-23所示。图3-23 Deployment Configuration界面点击上图中红框位置处的加号,在弹出的对话框中输入new server name。点击OK后Deployment Configuration界面如图3-24。在Connection模块下,Type项选择SFTP,SSH configuration项选择要连接的远程服务器。图3-24 Deployment界面的Connection模块在Mappings模块下,Local path已给出,保持不变;点击Deployment path后的文件夹图标,会弹出一个指定的目录,选择该默认路径即可。图3-25 Deployment界面的Mappings模块返回Connection模块,点击Test Connection,出现图3-26所示界面则代表连接成功,点击OK。然后依次点击Deployment Configuration界面的Apply与OK,完成配置。图3-26 成功连接服务器4. 如图3-27所示,把鼠标放在项目名上,单击鼠标右键,在弹出的菜单项中选择Deployment下的Upload to,在新弹出的对话框中选择所连接的服务器。执行该操作会把MindStudio本地客户端的项目文件会同步到服务器端。图3-27 同步项目文件到服务器端执行完毕后,会看到MindStudio界面下方的File Transfer窗口中显示如下。图3-28 同步成功提示信息进入服务器端,可以看到新生成了一个MindStudio-WorkSpace目录,如下图所示。图3-29 MindX服务器生成工作目录       进入MindStudio-WorkSpace目录,含有BinocularStereoDepthRecovery项目所在目录,如图3-30中红框所示。图3-30 服务器端创建的项目目录       进入到BinocularStereoDepthRecovery项目目录,可以看到从MindStudio本地客户端同步至服务器端的项目文件,目录信息如图3-31所示。图3-31 服务器端项目目录情况3.2运行项目       选择顶部菜单栏Run下的Edit Configurations菜单项,如图3-32所示。图3-32 打开Edit Configurations弹出的窗口如图3-33所示。在窗口左侧,我们选择Ascend App下的项目名;在窗口右侧,Deployment项是前面已经设置过的,Executable项选择此次要执行函数yolo_deep.py的路径。选择完成后点击OK。图3-33 Run Configurations界面设定完要运行的函数后,点击MindStudio界面的程序运行按钮,即下图中红框内的蓝色三角号,便可执行yolo_deep.py程序。图3-34 程序运行按钮 基于双目视觉的目标定位运行结果如图3-35所示。对于输入的两张(用双目相机拍摄的)图像,输出检测到的物体像素坐标,并且输出物体的世界坐标以及物体与相机的距离。图3-35 深度推理结果图3-36为输入图像中的其中一幅,图3-35中输出的距离便是红色汽车模型与相机之间的距离。此外,我们生成了相对应的深度图,如图3-37所示。深度图中越亮的部分表示与相机的距离越近,越暗的部分与相机的距离越远。图3-36 输入图像图3-37 输入图像对应的深度图四、FAQ1. No Python interpreter configured for the module答:未配置Python解释器,可参考2.3.1节中的步骤6配置Python解释器。2. Get MindX SDK version failed!答:选择远程服务器中SDK路径时,没有选择到版本号一级,选择父路径时会提示SDK版本获取失败。可参考2.3.5节完成MindX SDK的安装。3. CANN 连接错误(连接服务器 SSH 成功,但是连接 CANN 失败)答:有可能是没有选择到版本号一级,选择父路径时会报错,也有可能是因为当前用户非 root 用户,还有可能是服务器端内存不足。查看同步 CANN 运行日志可判断缘由,可在服务器端的log目录下查看日志文件。       开发者在使用 MindStudio 或进行算子开发过程中遇到任何问题,都可以在昇腾社区进行互动,提出问题,获得更多的帮助。 昇腾官网:cid:link_8 昇腾博客:cid:link_5 昇腾论坛:cid:link_6   
  • [经验分享] MindStudio模型推理场景精度比对全流程和结果分析
    视频案例,可以查看Bilibili MindStudio模型推理场景精度比对全流程和结果分析:【经验分享】MindStudio模型推理场景精度比对全流程和结果分析1、MindStudio介绍MindStudio提供在AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务,依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够帮助您在一个工具上就能高效便捷地完成AI应用开发,MindStudio采用了插件化扩展机制,开发者可以通过开发插件来扩展已有功能。本实验使用的MindStudio版本为5.0.RC3,安装请参考MindStudio安装教程。2、交付件介绍(1)精度对比简介​ 在下面两种情况下,自有实现的算子在昇腾AI处理器上的运算结果与业界标准算子(如Caffe、ONNX、TensorFlow、PyTorch)的运算结果可能存在差异。在模型转换过程中对模型进行了优化,包括算子消除、算子融合、算子拆分,这些动作可能会造成自有实现的算子运算结果与业界标准算子(如Caffe、TensorFlow、ONNX)运算结果存在偏差。用户原始网络可以迁移到昇腾910 AI处理器上执行训练,网络迁移可能会造成自有实现的算子运算结果与用业界标准算子(如TensorFlow)运算结果存在偏差。(2)实现流程​ 为了帮助开发人员快速解决算子精度问题,需要提供自有实现的算子运算结果与业界标准算子运算结果之间进行精度差异对比的工具。​ MindStudio精度比对工具提供Tensor比对能力,包含余弦相似度、欧氏相对距离、绝对误差(最大绝对误差、平均绝对误差、均方根误差)、相对误差(最大相对误差、平均相对误差、累积相对误差)、KL散度、标准差算法比对维度。精度比对总体流程如下:(3)代码工程本实验基于MindStudio的代码工程结构如下所示。本实验基于MindStudio的代码工程结构如下所示。 ├── caffeResnet50_49048f18 │ ├── acl_net.py //离线模型推理脚本代码 │ ├── caffe_dump.py //原始模型推理脚本代码 │ ├── caffe_model //原始模型文件存储目录 │ │ ├── resnet50.caffemodel │ │ └── resnet50.prototxt │ ├── caffeResnet50.iml │ ├── constant.py //离线模型推理脚本工具脚本 │ ├── data //数据文件夹 │ │ └── img.png │ ├── dump //离线模型dump数据文件夹 │ ├── model //离线模型文件夹 │ │ └── resnet50.om │ ├── npy_dump //原始模型dump数据文件夹 │ ├── output //精度比对输出文件夹 │ │ └── 20221111205145 │ └── src │ └── acl.json //离线模型dump构造文件 (4)文章介绍​ 文章详细记录了如何使用MindStudio中的精度比对功能去进行推理场景下的模型的精度比对操作,包括原始第三方框架下模型的npy数据准备,离线模型的dump数据准备,精度比对以及分析。第三节介绍了MindStudio的昇腾App工程的创建。第四节介绍了推理场景下的数据准备。第五节介绍了精度比对和分析。第六节介绍了整个流程中遇到的问题和解决方案。第七节介绍MindStudio的更多的内容。3、App工程创建打开MindStudio进入算子工程创建界面首次登录MindStudio:在MindStudio欢迎界面中单击“New Project”,进入创建工程界面。非首次登录MindStudio:在顶部菜单栏中选择“File > New > Project...”,进入创建工程界面。创建App工程左侧导航栏选择“Ascend App”,如图所示,在右侧点击选择ACL Project(Python)工程。单击“Next”,在弹出的页面中,Project name那一行输入项目名称,然后点击Finish,既可完成工程的创建。单击“Finish”,完成应用工程的创建若工作窗口已打开其他工程,会出现如图所示提示。选择“This Window”,则直接在当前工作窗口打开新创建的工程。选择“New Window”,则新建一个工作窗口打开新创建的工程。 4、推理场景数据准备(1)准备Caffe模型npy数据文件MindStudio当前版本不提供Caffe模型numpy数据生成功能,请自行安装Caffe环境并提前准备Caffe原始数据“*.npy”文件。本文仅提供生成符合精度比对要求的numpy格式Caffe原始数据“*.npy”文件的样例参考。下面给出Resnet50原始模型dump数据的推理脚本代码。请参考表1的参数说明进行使用。​ 表1 原始模型推理脚本参数说明-wCaffe 权重文件路径,如'resnet50.caffemodel'-i, --input_bins模型推理输入bin文件或者图片文件路径,多个以;分隔,如'./a.bin;./img.png'-n, --input_names模型推理输入节点名称,多个以;分隔,如'graph_input_0:0; graph_input_1:0'-mCaffe 模型文件路径,如'resnet50.prototxt'-odump输出文件路径,如'./output_dir', 该路径需要用户自己创建脚本代码:# coding=utf-8 import caffe import sys import argparse import os import caffe.proto.caffe_pb2 as caffe_pb2 import google.protobuf.text_format import json import numpy as np import time TIME_LENGTH = 1000 FILE_PERMISSION_FLAG = 0o600 class CaffeProcess: def __init__(self): parse = argparse.ArgumentParser() parse.add_argument("-w", dest="weight_file_path", help="<Required> the caffe weight file path", required=False,default="caffe_model/resnet50.caffemodel") parse.add_argument("-m", dest="model_file_path", help="<Required> the caffe model file path", required=False,default="caffe_model/resnet50.prototxt") parse.add_argument("-o", dest="output_path", help="<Required> the output path", required=False,default="npy_dump") parse.add_argument("-i", "--input_bins", dest="input_bins", help="input_bins bins. e.g. './a.bin;./c.bin'", required=False,default="./data/img.png") parse.add_argument("-n", "--input_names", dest="input_names", help="input nodes name. e.g. 'graph_input_0:0;graph_input_0:1'", required=False,default="data:0") args, _ = parse.parse_known_args(sys.argv[1:]) self.weight_file_path = os.path.realpath(args.weight_file_path) self.model_file_path = os.path.realpath(args.model_file_path) self.input_bins = args.input_bins.split(";") self.input_names = args.input_names.split(";") self.output_path = os.path.realpath(args.output_path) self.net_param = None self.cur_layer_idx = -1 @staticmethod def _check_file_valid(path, is_file): if not os.path.exists(path): print('Error: The path "' + path + '" does not exist.') exit(-1) if is_file: if not os.path.isfile(path): print('Error: The path "' + path + '" is not a file.') exit(-1) else: if not os.path.isdir(path): print('Error: The path "' + path + '" is not a directory.') exit(-1) def _check_arguments_valid(self): self._check_file_valid(self.model_file_path, True) self._check_file_valid(self.weight_file_path, True) self._check_file_valid(self.output_path, False) for input_file in self.input_bins: self._check_file_valid(input_file, True) @staticmethod def calDataSize(shape): dataSize = 1 for dim in shape: dataSize *= dim return dataSize def _load_inputs(self, net): inputs_map = {} for layer_name, blob in net.blobs.items(): if layer_name in self.input_names: input_bin = np.fromfile( self.input_bins[self.input_names.index(layer_name)], np.float32) input_bin_shape = blob.data.shape if self.calDataSize(input_bin_shape) == self.calDataSize(input_bin.shape): input_bin = input_bin.reshape(input_bin_shape) else: print("Error: input node data size %d not match with input bin data size %d.", self.calDataSize( input_bin_shape), self.calDataSize(input_bin.shape)) exit(-1) inputs_map[layer_name] = input_bin return inputs_map def process(self): """ Function Description: process the caffe net, save result as dump data """ # check path valid self._check_arguments_valid() # load model and weight file net = caffe.Net(self.model_file_path, self.weight_file_path, caffe.TEST) inputs_map = self._load_inputs(net) for key, value in inputs_map.items(): net.blobs[key].data[...] = value # process net.forward() # read prototxt file net_param = caffe_pb2.NetParameter() with open(self.model_file_path, 'rb') as model_file: google.protobuf.text_format.Parse(model_file.read(), net_param) for layer in net_param.layer: name = layer.name.replace("/", "_").replace(".", "_") index = 0 for top in layer.top: data = net.blobs[top].data[...] file_name = name + "." + str(index) + "." + str( round(time.time() * 1000000)) + ".npy" output_dump_path = os.path.join(self.output_path, file_name) np.save(output_dump_path, data) os.chmod(output_dump_path, FILE_PERMISSION_FLAG) print('The dump data of "' + layer.name + '" has been saved to "' + output_dump_path + '".') index += 1 if __name__ == "__main__": caffe_process = CaffeProcess() caffe_process.process()说明:运行之前需要提前准备数据文件和模型文件,原始模型下载地址为:cid:link_3​ 数据图片下载地址为:https://gitee.com/link?target=https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/models/aclsample/dog1_1024_683.jpg远程安装好caffe的python3环境,在本地配置好安装的caffe的SDK。将上述代码拷贝到新建的python脚本中,右键点击运行该脚本,即可以在参数-o指定的路径下生成npy数据文件。生成的文件是以{op_name}.{output_index}.{timestamp}.npy形式命名。其中{op_name}为算子名称,{output_index}是算子的编号索引,{timestamp}是时间戳;设置numpy数据文件名包括output_index字段且值为0,确保转换生成的dump数据的output_index为0,否则无比对结果,原因是精度比对时默认从第一个output_index为0的数据开始。(2)准备离线模型dump数据通过MindStudio提供的dump功能,生成离线模型的dump数据,需要提前完成以下操作:完成Caffe、TensorFlow或ONNX模型的ATC模型转换,将原始模型转换为OM离线模型。详细介绍请参见模型转换。完成应用工程的开发、编译和运行,确保具备可执行的应用工程。详细介绍请参见应用开发。操作步骤如下:准备好离线模型,离线模型下载地址为:cid:link_3; 或者参考如下模型转换步骤进行模型转换(1) 在菜单栏选择“Ascend > Model Converter”。出现如下配置界面,参数配置参考MindStudio官网>用户指南>模型转换>操作步骤。(2) 单击“Next”,进入“Data Pre-Processing”配置数据预处理页签,界面参考如图所示。说明:数据预处理是昇腾AI处理器提供的硬件图像预处理模块,包括色域转换,图像归一化(减均值/乘系数)和抠图(指定抠图起始点,抠出神经网络需要大小的图片)等功能。只有当“Model Information”页签,“Input Nodes”参数中,输入节点的“Type”有配置为“Uint8”类型,“Data Pre-Processing”页签才可以配置该节点的数据预处理功能。如果模型有多个输入,每个输入节点都可以获取shape信息中的宽和高,并且“Input Nodes”参数中每个输入节点的“Type”都配置为“Uint8”,则“Data Pre-Processing”页签可以配置多个节点的数据预处理功能。(3) 单击“Next”,进入“Advanced Options Preview”高级选项配置页签,界面参考如图所示。(4) 单击Finish完成模型转换。在MindStudio界面下方,“Output”窗口会显示模型转换过程中的日志信息,如果提示“Model converted successfully”,则表示模型转换成功。准备好离线模型的推理代码。推理代码可以从cid:link_0中获取,或者直接拷贝下面代码。构造dump的.json配置,选择“Ascend > Dump Configuration”菜单,弹出“Select Offline Model”窗口,如图所示。注意:如果不知道自己本地同步到远程哪个路径下,可以点击Tools>Development>Configuration下查看。选择.om模型文件,单击“OK”,展示模型文件结构,设置dump开关。如图所示。它会在src目录下生成acl.json配置文件,通过修改窗口最右侧配置项,设置.om模型文件的dump配置项,会自动更新到acl.json文件中。(1) Dump Option:配置dump范围。ALL:所有算子开启dump。Several:自定义部分算子开启dump。选择该项后,需要右键单击待dump数据的算子并选择“Enable Dump”。None:所有算子不开启dump。(2) Dump Mode:dump数据模式。ALL:同时dump算子的输入、输出数据。Input:dump算子的输入数据。Output:dump算子的输出数据。(3) Dump Path:配置保存dump数据文件的路径,默认为:{project_path}/dump。如果Dump Path设置为其他路径,需要确保MindStudio安装用户对该路径具有读写权限。注意:该选项要选择远程的dump目录,当前版本mindstudio只支持选择本地的dump目录,如果不能选择远程dump目录,请自行在acl.json中配置。(4) AclConfig File:Acl配置文件,在dump操作中该文件保存算子的dump配置信息。一般路径为{project_path}/src/acl.json。请参考表2中的参数说明使用该脚本​ 表2 离线模型推理脚本参数说明--devicenpu设备编号。--model_path离线模型文件路径,到文件名层次。--images_path数据文件路径,到数据文件的文件夹层次。import argparse import numpy as np import acl import os from PIL import Image from constant import ACL_MEM_MALLOC_HUGE_FIRST, \ ACL_MEMCPY_HOST_TO_DEVICE, ACL_MEMCPY_DEVICE_TO_HOST, \ ACL_SUCCESS, IMG_EXT, NPY_FLOAT32 buffer_method = { "in": acl.mdl.get_input_size_by_index, "out": acl.mdl.get_output_size_by_index } def check_ret(message, ret): if ret != ACL_SUCCESS: raise Exception("{} failed ret={}" .format(message, ret)) class Net(object): def __init__(self, device_id, model_path): self.device_id = device_id # int self.model_path = model_path # string self.model_id = None # pointer self.context = None # pointer self.input_data = [] self.output_data = [] self.model_desc = None # pointer when using self.load_input_dataset = None self.load_output_dataset = None self.init_resource() def release_resource(self): print("Releasing resources stage:") ret = acl.mdl.unload(self.model_id) check_ret("acl.mdl.unload", ret) if self.model_desc: acl.mdl.destroy_desc(self.model_desc) self.model_desc = None while self.input_data: item = self.input_data.pop() ret = acl.rt.free(item["buffer"]) check_ret("acl.rt.free", ret) while self.output_data: item = self.output_data.pop() ret = acl.rt.free(item["buffer"]) check_ret("acl.rt.free", ret) if self.context: ret = acl.rt.destroy_context(self.context) check_ret("acl.rt.destroy_context", ret) self.context = None ret = acl.rt.reset_device(self.device_id) check_ret("acl.rt.reset_device", ret) ret = acl.finalize() check_ret("acl.finalize", ret) print('Resources released successfully.') def init_resource(self): print("init resource stage:") current_dir=os.path.dirname(os.path.abspath(__file__)) ret = acl.init(os.path.join(current_dir,"./src/acl.json")) check_ret("acl.init", ret) # ret = acl.mdl.init_dump() # check_ret("acl.init", ret) # ret = acl.mdl.set_dump(os.path.join(current_dir,"./src/acl.json")) # check_ret("acl.init", ret) ret = acl.rt.set_device(self.device_id) check_ret("acl.rt.set_device", ret) self.context, ret = acl.rt.create_context(self.device_id) check_ret("acl.rt.create_context", ret) # load_model self.model_id, ret = acl.mdl.load_from_file(self.model_path) check_ret("acl.mdl.load_from_file", ret) print("model_id:{}".format(self.model_id)) self.model_desc = acl.mdl.create_desc() self._get_model_info() print("init resource success") def _get_model_info(self,): ret = acl.mdl.get_desc(self.model_desc, self.model_id) check_ret("acl.mdl.get_desc", ret) input_size = acl.mdl.get_num_inputs(self.model_desc) output_size = acl.mdl.get_num_outputs(self.model_desc) self._gen_data_buffer(input_size, des="in") self._gen_data_buffer(output_size, des="out") def _gen_data_buffer(self, size, des): func = buffer_method[des] for i in range(size): # check temp_buffer dtype temp_buffer_size = func(self.model_desc, i) temp_buffer, ret = acl.rt.malloc(temp_buffer_size, ACL_MEM_MALLOC_HUGE_FIRST) check_ret("acl.rt.malloc", ret) if des == "in": self.input_data.append({"buffer": temp_buffer, "size": temp_buffer_size}) elif des == "out": self.output_data.append({"buffer": temp_buffer, "size": temp_buffer_size}) def _data_interaction(self, dataset, policy=ACL_MEMCPY_HOST_TO_DEVICE): temp_data_buffer = self.input_data \ if policy == ACL_MEMCPY_HOST_TO_DEVICE \ else self.output_data if len(dataset) == 0 and policy == ACL_MEMCPY_DEVICE_TO_HOST: for item in self.output_data: temp, ret = acl.rt.malloc_host(item["size"]) if ret != 0: raise Exception("can't malloc_host ret={}".format(ret)) dataset.append({"size": item["size"], "buffer": temp}) for i, item in enumerate(temp_data_buffer): if policy == ACL_MEMCPY_HOST_TO_DEVICE: if "bytes_to_ptr" in dir(acl.util): bytes_data = dataset[i].tobytes() ptr = acl.util.bytes_to_ptr(bytes_data) else: ptr = acl.util.numpy_to_ptr(dataset[i]) ret = acl.rt.memcpy(item["buffer"], item["size"], ptr, item["size"], policy) check_ret("acl.rt.memcpy", ret) else: ptr = dataset[i]["buffer"] ret = acl.rt.memcpy(ptr, item["size"], item["buffer"], item["size"], policy) check_ret("acl.rt.memcpy", ret) def _gen_dataset(self, type_str="input"): dataset = acl.mdl.create_dataset() temp_dataset = None if type_str == "in": self.load_input_dataset = dataset temp_dataset = self.input_data else: self.load_output_dataset = dataset temp_dataset = self.output_data for item in temp_dataset: data = acl.create_data_buffer(item["buffer"], item["size"]) _, ret = acl.mdl.add_dataset_buffer(dataset, data) if ret != ACL_SUCCESS: ret = acl.destroy_data_buffer(data) check_ret("acl.destroy_data_buffer", ret) def _data_from_host_to_device(self, images): print("data interaction from host to device") # copy images to device self._data_interaction(images, ACL_MEMCPY_HOST_TO_DEVICE) # load input data into model self._gen_dataset("in") # load output data into model self._gen_dataset("out") print("data interaction from host to device success") def _data_from_device_to_host(self): print("data interaction from device to host") res = [] # copy device to host self._data_interaction(res, ACL_MEMCPY_DEVICE_TO_HOST) print("data interaction from device to host success") result = self.get_result(res) self._print_result(result) # free host memory for item in res: ptr = item['buffer'] ret = acl.rt.free_host(ptr) check_ret('acl.rt.free_host', ret) def run(self, images): self._data_from_host_to_device(images) self.forward() self._data_from_device_to_host() def forward(self): print('execute stage:') ret = acl.mdl.execute(self.model_id, self.load_input_dataset, self.load_output_dataset) check_ret("acl.mdl.execute", ret) self._destroy_databuffer() print('execute stage success') def _print_result(self, result): vals = np.array(result).flatten() top_k = vals.argsort()[-1:-6:-1] print("======== top5 inference results: =============") for j in top_k: print("[%d]: %f" % (j, vals[j])) def _destroy_databuffer(self): for dataset in [self.load_input_dataset, self.load_output_dataset]: if not dataset: continue number = acl.mdl.get_dataset_num_buffers(dataset) for i in range(number): data_buf = acl.mdl.get_dataset_buffer(dataset, i) if data_buf: ret = acl.destroy_data_buffer(data_buf) check_ret("acl.destroy_data_buffer", ret) ret = acl.mdl.destroy_dataset(dataset) check_ret("acl.mdl.destroy_dataset", ret) def get_result(self, output_data): result = [] dims, ret = acl.mdl.get_cur_output_dims(self.model_desc, 0) check_ret("acl.mdl.get_cur_output_dims", ret) out_dim = dims['dims'] for temp in output_data: ptr = temp["buffer"] # 转化为float32类型的数据 if "ptr_to_bytes" in dir(acl.util): bytes_data = acl.util.ptr_to_bytes(ptr, temp["size"]) data = np.frombuffer(bytes_data, dtype=np.float32).reshape(tuple(out_dim)) else: data = acl.util.ptr_to_numpy(ptr, tuple(out_dim), NPY_FLOAT32) result.append(data) return result def transfer_pic(input_path): input_path = os.path.abspath(input_path) with Image.open(input_path) as image_file: image_file = image_file.resize((256, 256)) img = np.array(image_file) height = img.shape[0] width = img.shape[1] # 对图片进行切分,取中间区域 h_off = (height - 224) // 2 w_off = (width - 224) // 2 crop_img = img[h_off:height - h_off, w_off:width - w_off, :] # rgb to bgr,改变通道顺序 img = crop_img[:, :, ::-1] shape = img.shape img = img.astype("float16") img[:, :, 0] -= 104 img[:, :, 1] -= 117 img[:, :, 2] -= 123 img = img.reshape([1] + list(shape)) img = img.transpose([0, 3, 1, 2]) result = np.frombuffer(img.tobytes(), np.float16) return result if __name__ == '__main__': current_dir = os.path.dirname(os.path.abspath(__file__)) parser = argparse.ArgumentParser() parser.add_argument('--device', type=int, default=0) parser.add_argument('--model_path', type=str, default=os.path.join(current_dir, "./model/resnet50.om")) parser.add_argument('--images_path', type=str, default=os.path.join(current_dir, "./data")) args = parser.parse_args() print("Using device id:{}\nmodel path:{}\nimages path:{}" .format(args.device, args.model_path, args.images_path)) images_list = [os.path.join(args.images_path, img) for img in os.listdir(args.images_path) if os.path.splitext(img)[1] in IMG_EXT] net = Net(args.device, args.model_path) for image in images_list: print("images:{}".format(image)) img = transfer_pic(image) net.run([img]) # acl.mdl.finalize_dump() # net.run([img]) print("*****run finish******") net.release_resource() 说明:(1) 数据文件应该是与原始模型生成npy数据文件保持一致。(2) 如果是从gitee上下载的代码,需要修改acl.init()这行代码,在里面传入dump的配置参数.json文件。6.设置dump完成后,单击MindStudio界面“Run”菜单,重新编译和运行应用工程。工程运行完毕后,可以在{project_path}/dump路径下查看到生成的dump数据文件。生成的路径及格式说明:time/device_id/model_name/model_id/data_index/dump文件time:dump数据回传落盘时间。格式为:YYYYMMDDhhmmss。device_id:Device设备ID号。model_name:模型名称。model_id:模型ID号。data_index:针对每个Task ID执行的次数维护一个序号,从0开始计数,该Task每dump一次数据,序号递增1。dump文件:命名规则如{op_type}.{op_name}.{taskid}.{timestamp}。如果model_name、op_type、op_name出现了“.”、“/”、“\”、空格时,转换为下划线表示。5、精度比对及分析(1)全网精度比对操作步骤在MindStudio界面菜单栏选择“Ascend > Model Accuracy Analyzer > New Task”菜单,进入比对界面,如下图所示。参考表3配置好参数后点击Next下一步。进入到数据和模型的配置界面。 ​ 表3 精度比对New Task参数说明参数说明Run ModeRemote Run:远程运行。Local Run:本地运行。Windows使用场景下仅支持Remote Run,该参数不展示。Deployment运行配置,选择Remote Run模式时可见,必选配置。通过Deployment功能,详细请参见Deployment,可以将指定项目中的文件、文件夹同步到远程指定机器的指定目录。Remote Toolkit Path远端运行环境toolkit软件包安装路径,选择Remote Run模式时可见,必选配置。例如配置为${HOME}/Ascend/ascend-toolkit/xxx/toolkit。与Deployment参数为绑定关系,单击“Start”后参数值将被保存。再次配置时,如连接已配置过的Deployment,则参数自动填充,可手动修改。Environment Variables环境变量配置,选择Remote Run模式时可见,可以直接在框中输入,也可以单击后在弹窗内单击填写。可选配置,当Model File指定文件为离线模型文件(*.om)时,需要配置环境变量,否则工具将无法为离线模型文件(*.om)进行ATC转换导致比对失败。与Deployment参数为绑定关系,单击“Start”后参数值将被保存。再次配置时,如连接已配置过的Deployment,则参数自动填充,可手动修改。Output Path比对数据结果存放路径,必选配置。无论选择Remote Run模式还是Local Run模式,均需要指定为本端路径。默认路径为当前系统的用户目录。Analysis Mode精度比对分析模式,必选配置。可选择模式为:NPU vs NPU:表示两个比对文件均为昇腾AI处理器上运行生成的dump数据文件。此时Model File参数可选。一般用于分析开启和关闭融合规则时进行模型转换后的dump数据文件之间的精度差。模型转换开启和关闭融合规则的详细介绍请参见模型转换。NPU vs GPU/CPU:表示昇腾AI处理器上运行生成的dump数据文件与原始模型的npy文件进行比对。此时展示Framework必选参数。Framework比对数据所属的框架类型,必选配置。Analysis Mode为NPU vs GPU/CPU时可见。可选类型为:- TensorFlow:TensorFlow框架模型dump数据的精度比对,支持推理、训练场景,Model File参数必选。- ONNX:ONNX框架模型dump数据的精度比对,支持推理场景,Model File参数必选。- Caffe:Caffe框架模型dump数据的精度比对,支持推理场景,Model File参数必选。NPU Dump昇腾AI处理器上运行生成的dump数据文件目录,必选配置。在远端执行比对时(Remote Run),须指定远端设备上的dump数据文件目录。Model File模型文件或融合规则文件。Analysis Mode为NPU vs NPU时,进行离线模型转换开启算子融合功能前后的dump数据精度比对,需要指定开融合的算子映射文件(.json)或离线模型文件(*.om)和关融合的算子映射文件(.json)或离线模型文件(*.om)。Analysis Mode为NPU vs GPU/CPU时,根据Framework选择的框架类型选择不同的文件:l TensorFlow:推理场景选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om);训练场景选择计算图文件(*.txt)。l ONNX:选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om)。l Caffe:选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om)。l 具体选择文件请参见比对场景。Quantization Rule File(.json)量化算子映射关系文件(昇腾模型压缩输出的json文件),可选配置。仅Framework为Caffe时展示。Ground Truth原始模型的npy文件目录,必选配置。在远端执行比对时(Remote Run),须指定远端设备上的原始模型的npy文件目录。Algorithm比对算法维度。取值为:l Cosine Similarity:余弦相似度算法,默认勾选。l Relative Euclidean Distance:欧氏相对距离算法,默认勾选。l Absolute Error,绝对误差,默认勾选,此项执行的比对算法为:l Max Absolute Error:最大绝对误差。l Mean Absolute Error:平均绝对误差。l Root Mean Square Error:均方根误差。l Relative Error,相对误差,默认勾选,此项执行的比对算法为:l Max Relative Error:最大相对误差。l Mean Relative Error:平均相对误差。l Accumulated Relative Error:累积相对误差。l Kullback Leibler Divergence:KL散度算法,默认不勾选。l Standard Deviation:标准差算法,默认不勾选。l 与Customized Algorithm自定义算法之间至少勾选一种算法。Advance Options扩展选项。包括Customized Algorithm、Advisor和Operator Range。Customized Algorithm自定义算法文件路径。与Algorithm内置算法之间至少勾选一种算法。需用户自行准备自定义算法.py文件,所在目录格式为“algorithm”,指定该目录下的自定义算法.py文件,生成自定义算法。自定义算法.py文件相关要求参见《精度比对工具使用指南》附录中的“准备自定义算法.py文件”章节。Advisor专家系统分析开关,默认关闭。开启后会在完成整网比对后对比对结果进行专家系统分析并输出问题节点、问题类型和优化建议。详细介绍请参见比对结果专家建议。使用本功能前需要先执行*pip3* *install* ****pandas****命令安装pandas 1.3或更高版本依赖。与Operator Range无法同时开启。Operator Range设定算子比对范围。有两种设置方式:方式一:单击“Select”按钮,在弹出框内勾选需要比对的算子。方式二:根据Start、End、Step参数配置比对算子的范围。l start:第一个比对的算子,取值范围为[1, 参与计算的算子个数],默认值为1。l end:最后一个比对的算子,取值范围为-1或[start, 参与计算的算子个数],默认值为-1(动态获取网络模型中最后一个参与计算的算子)。l step:第start+stepn个比对的算子,step取值范围为[1, 参与计算的算子个数),默认值为1,n为从1开始的正整数。配置格式为:“start,end,step”。比如:-r 1,101,20,表示算子1,21,41,61,81,101的Tensor参与比对。不配置本参数时,比对网络模型中的所有参与计算的算子。配置本参数且Analysis Mode参数配置为NPU vs NPU时,需同时指定NPU Dump和Ground Truth的Model File分别指定开融合的算子映射文件(.json)或离线模型文件(.om)和关融合的算子映射文件(.json)或离线模型文件(*.om)。与Advisor无法同时开启。(2)全网比对结果分析上面步骤配置好参数后点击start即可以出现对比的结果界面。如下所示。图一 图二 图三 所示将Tensor比对结果界面分为四个区域分别进行介绍。其中1~4区域为整网比对结果。表4 整网比对结果说明区域区域名称说明1菜单栏从左到右分别为Open…、New Task、Refresh、Help四项功能。Open…为打开并展示比对结果csv文件;New Task为创建新的比对任务;Refresh用于读取并刷新File Manager中管理的文件;单击Help弹出小窗,可展示精度比对工具的使用限制(Restrictions)、使用建议、在线教程链接等。2File Manager,历史数据管理显示用户指定文件夹以及文件夹下生成的整网比对的csv文件以及显示通过Open…单独打开的csv文件;对文件夹和csv,提供历史数据管理功能,包括打开、删除、另存为;在文件夹处右键删除;在空白处右键创建新比对任务(New Task)、刷新(Refresh)和Open…(打开并展示比对结果csv文件)。3Model Accuracy Analysis,精度比对分析界面默认仅显示有结果的算子。可单击列名,进行排序;单击Show Invalid Data,可展示无法比对的数据,各列字段含义请参见表2。4Scatter Diagram,各项算法指标的散点分布图Show Model,比对模型可视化展示Scatter Diagram:横坐标表示算子的执行顺序,纵坐标为算法指标在对应Tensor上的实际取值。各字段含义请参见表3。Show Model:分别展示NPU和Ground Truth的模型图。详细介绍请参见表4。表5 比对结果字段说明字段说明Index网络模型中算子的ID。OpSequence算子运行的序列。全网层信息文件中算子的ID。仅配置“Operator Range”时展示。OpType算子类型。NPUDump表示NPU Dump模型的算子名。光标悬浮时,可显示具体算子所在的文件路径。DataType表示NPU Dump侧数据算子的数据类型。Addressdump tensor的虚拟内存地址。用于判断算子的内存问题。仅基于昇腾AI处理器运行生成的dump数据文件在整网比对时可提取该数据。GroundTruth表示Ground Truth模型的算子名。光标悬浮时,可显示具体算子所在的文件路径。DataType表示Ground Truth侧数据算子的数据类型。TensorIndex表示NPU Dump模型算子的input ID和output ID。Shape比对的Tensor的Shape。OverFlow溢出算子。显示YES表示该算子存在溢出;显示NO表示算子无溢出;显示NaN表示不做溢出检测。开启Advisor功能时展示,为比对结果专家建议的FP16溢出检测专家建议提供数据。CosineSimilarity进行余弦相似度算法比对出来的结果。取值范围为[-1,1],比对的结果如果越接近1,表示两者的值越相近,越接近-1意味着两者的值越相反。MaxAbsoluteError进行最大绝对误差算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。KullbackLeiblerDivergence进行KL散度算法比对出来的结果。取值范围为0到无穷大。KL散度越小,真实分布与近似分布之间的匹配越好。RootMeanSquareError表示均方根误差。取值范围为0到无穷大,MeanAbsoluteError趋于0,RootMeanSquareError趋于0,说明测量值与真实值越近似;MeanAbsoluteError趋于0,RootMeanSquareError越大,说明存在局部过大的异常值;MeanAbsoluteError越大,RootMeanSquareError等于或近似MeanAbsoluteError,说明整体偏差越集中;MeanAbsoluteError越大,RootMeanSquareError越大于MeanAbsoluteError,说明存在整体偏差,且整体偏差分布分散;不存在以上情况的例外情况,因为RMSE ≥ MAE恒成立。MaxRelativeError表示最大相对误差。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。RelativeEuclideanDistance进行欧氏相对距离算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。StandardDeviation进行标准差算法比对出来的结果。取值范围为0到无穷大。标准差越小,离散度越小,表明越接近平均值。该列显示NPU Dump和Ground Truth两组数据的均值和标准差,第一组展示NPU Dump模型dump数据的数值(均值;标准差),第二组展示Ground Truth模型dump数据的数值(均值;标准差)。AccumulatedRelativeError进行累积相对误差算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。MeanAbsoluteError表示平均绝对误差。取值范围为0到无穷大,MeanAbsoluteError趋于0,RootMeanSquareError趋于0,说明测量值与真实值越近似;MeanAbsoluteError趋于0,RootMeanSquareError越大,说明存在局部过大的异常值;MeanAbsoluteError越大,RootMeanSquareError等于或近似MeanAbsoluteError,说明整体偏差越集中;MeanAbsoluteError越大,RootMeanSquareError越大于MeanAbsoluteError,说明存在整体偏差,且整体偏差分布分散;不存在以上情况的例外情况,因为RMSE ≥ MAE恒成立。MeanRelativeError表示平均相对误差。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。CompareFailReason算子无法比对的原因。若余弦相似度为1,则查看该算子的输入或输出shape是否为空或全部为1,若为空或全部为1则算子的输入或输出为标量,提示:this tensor is scalar。注1:余弦相似度和KL散度比较结果为NaN,其他算法有比较数据,则表明左侧或右侧数据为0;KL散度比较结果为inf,表明右侧数据有一个为0;比对结果为nan,表示dump数据有nan。 注2:光标悬浮在表头可以看到对应的参数详细解释。 注3:若配置了自定义算法比对,则在比对结果的内置算法后增加对应自定义算法列。表6 散点分布图字段说明字段说明Algorithm选择展示对应比对算法结果的散点分布图,不支持展示StandardDeviation、KullbackLeiblerDivergence和AccumulatedRelativeError。Tensor过滤显示Input、Output结果散点分布图。Highlight对算子Tensor散点进行高亮。通过拖拉游标在对应算法指标的[min,max]间滑动来设置算法指标(纵坐标)的阈值,高于或等于阈值的点显示为蓝色,低于阈值的点显示为红色。如针对余弦相似度,图中设置阈值为0.98,小于0.98的算子Tensor被标记为红色。注1:光标移动到对应Tensor点上时,浮窗显示Tensor信息。信息包括:Index(Tensor对应算子的Index)、Op Name(算子名称)、Tensor Index(Tensor类型(input/output))以及Value(在当前算法维度下的Tensor数值)。注2:支持对散点图进行缩放。注3:指定区域3中的Tensor时,高亮对应Tensor点。表7 比对模型可视化展示字段说明字段说明NPU Model离线模型可视化。指定算子映射文件(.json)或离线模型文件(*.om)展示。训练场景下,若整网比对使用的Model File为计算图文件(*.txt),此处不支持展示模型图。Ground Truth Model原始模型可视化。指定原始模型文件展示。Input Model指定算子映射文件(.json)、离线模型文件(*.om)或原始模型文件。注:指定区域3中的Tensor时,高亮对应模型网络中的节点。在第一部分我们可以选择菜单,精度对比、历史等选项。我们可以从第二部分选择我们经过精度对比操作之后得到的不同的答案,并选择我们想要的内容来进行第三部分和第四部分的展示,在本次的实例当中我们只生成了一个模型的整网对比,所以只有一个对应的结果的文件,打开相应的文件夹,双击里面的csv文件,就可以呈现出我们本次模型的精度对比。精度对比页面第三部分看出我们的原模型和转换模型之间每个算子之间的结果的差距,并且也可以得到输入和输出的shape。在后面几栏的算子的精度的对比,我们可以根据不同的评判方法得出原算子和转化的算子之间经过运算之后得出的结果的相似程度来判断算子转化的优劣,我们根据后面几项的精度对比,从数据上可以看出精度正在下降,也意味着误差正在增加。随后也可观察4部分的散点图来观察从最开始的输入到最后的输出,经过每一个算子的计算,两模型之间的精度差距,我们可以看到余弦相似度的值有下降的趋势,且最后的结果接近于零,所以说两模型之间的误差在慢慢的增大。并且在第四部分还可以根据Algorithm选项选择不同的精度比较方法,比如说图1和图3选择的是余弦相似度和均方根误差来来展示精度的对比。在Tensor选项当中,我们可以选择input或者output选项来展示输入或者输出之间的精度对比。我们还可以选择第四部分的show model选项,即可以展示网络模型结构中算子之间的关系,也可以配合精度比对结果来定位具体算子的精度问题。(3)单算子精度比对操作步骤在刚刚的整网络分析界面下,点击下面的Operator Detail,出现如下界面。 对比操作。 (1)基于已经读取到的Tensor信息,通过Operator下拉框选择要比对的算子和对应Tensor(output/input)。 (2)通过Metric选择比对算子的Absolute Error(绝对误差)或Relative Error(相对误差)。 (3)配置输出该指标的TopN个Tensor元素(取值范围为[1,10000])。 (4)单击“Compare”按钮进行单算子比对。 (5)TopN结果显示请参见比对结果。 单算子比对界面说明。算子比对功能是在比对结果的基础上选择具体算子并根据需要指定参数进行比对的。界面展示为图5的6区域、7区域和8区域,如图5。详细介绍请参见表7表7 单算子比对结果说明区域说明5Operator Detail,单算子比对功能。下发单算子比对命令。具体操作请参见比对操作。6单算子比对TopN结果。各列字段解释请参见表8。7Cumulative Error,对于TopN Tensor元素,绘制的误差累积分布折线图。详细介绍请参见表8。比对结果。单算子比对结果界面展示为图5的7区域和8区域。详细介绍请参见表8。表8 比对结果字段说明字段说明6区域Index算子比对的条数。N C H W数据格式。NPUDumpNPU Dump侧算子的dump值。GroundTruthGround Truth侧算子的dump值。Absolute Error绝对误差,NPU Dump侧算子的dump值减Ground Truth侧算子的dump值取绝对值比对出来的结果。小数点后最多6位。Relative Error相对误差,Absolute Error值除以Ground Truth侧算子的dump值比对出来的结果。当Ground Truth侧算子的dump值为0时,该处显示为“-”。小数点后最多6位。7区域A % of tensor elements (B elements) have an absolute error greater than C.当前算子比对的所有tensor元素的绝对误差结果中有A %的tensor也就是B个元素的绝对误差超过了C。其中absolute error根据5区域配置的Metric取值变化可以为relative error;右侧滑块控制C的取值,范围由6区域AbsoluteError或RelativeError的最大最小值决定。误差累积分布折线图横坐标为6区域的AbsoluteError或RelativeError,取值范围由AbsoluteError或RelativeError的最大最小值决定;纵坐标为累积百分占比,含义为AbsoluteError或RelativeError到达某个阈值时,小于等于该阈值的所有tensor元素在整体tensor元素中的占比。注:光标移动到对应Tensor点上时,浮窗显示Tensor信息。信息包括:Index(算子比对的条数)、Absolute Error/Relative Error(绝对/相对误差)、Cumulative Percentage(累积百分占比)(4)对比结果专家建议FP16溢出检测 针对比对数据中数据类型为FP16的数据,进行溢出检测。如果存在溢出数据,输出专家建议。专家系统分析结果:Detection Type: FP16 overflowOperator Index: 228Expert Advice: Float16 data overflow occurs. Rectify the fault and perform comparison again.检测类型:FP16溢出检测Operator Index:228 专家建议:存在Float16数据溢出,请修正溢出问题,再进行比对。输入不一致检测 针对整网的输入数据进行检测,主要判断整网两批待比对数据的输入data是否一致。如果存在不一致问题(余弦相似度<0.99),输出专家建议。专家系统分析结果:Detection Type: Input inconsistentOperator Index: 0Expert Advice: The input data of NPUDump is inconsistent with that of GroundTruth. Use the same data or check the data preprocessing process.检测类型:输入不一致检测Operator Index:0 专家建议:NPUDump和GroundTruth间的输入数据不一致,请使用相同数据或者检查数据预处理流程。整网一致性检测(问题节点检测) 判断整网比对结果中,是否某层小于阈值,该层后续数据均小于阈值或最后一层小于阈值(余弦相似度<0.99),输出量化误差修正建议。专家系统分析结果:Detection Type: global consistencyOperator Index: 1174Expert Advice: The accuracy of some tensors is low, resulting in an unqualified final accuracy. This may be caused by quantization. Calibrate the data or contact Huawei for further diagnosis.检测类型:整网一致性检测Operator Index:1174专家建议:部分张量精度较低,且导致最终结果精度不达标;很可能由量化造成,请进行数据校准或者反馈给华为做进一步定位。整网一致性检测(单点误差检测) 判断整网比对结果中,是否某层小于阈值(余弦相似度<0.99),但最终结果符合精度要求,输出专家建议。专家系统分析结果:Detection Type: global consistencyOperator Index: 195Expert Advice: The accuracy of some tensors is low, while the final accuracy is qualified. This may be caused by Ascend internal optimization. Ignore or contact Huawei for further diagnosis.检测类型:整网一致性检测Operator Index:195专家建议:部分张量精度较低,但最终结果精度达标,可能由内部优化导致,请忽略或反馈给华为做进一步定位。整网一致性检测(一致性检测) 比对结果中的所有数据均符合精度要求,输出专家建议。专家系统分析结果:Detection Type: global consistencyOperator Index: NAExpert Advice: All data in the comparison result meets the accuracy requirements.If data accuracy of the model is still not up to standard in practical application, please check the post-processing process of model outputs.检测类型:整网一致性检测Operator Index:NA专家建议:比对结果中的所有数据均符合精度要求。如果模型实际应用中,精度依旧不达标,请排查输出数据的后处理流程。6、经验总结运行代码的时候,显示同步文件出现问题,如下。解决方法:远程python3运行环境中缺少google模块和protobuf==3.19.0模块,使用pip安装后再运行即可。 2. 单算子分析的时候,点击下面栏框显示不出来单算子分析的窗口。解决方法:确认没有报错信息的情况下,点击自己电脑的设置,调整显示屏分辨率或者缩放比例即可。Windows端的MindStudio中使用离线模型dump数据时,路径配置只能选择本地的路径,没有可选的远程路径。 解决方法:找到自己项目目录下的src/acl.json文件,手动修改JSON文件导出路径配置为远程目录的路径。配置好路径,但是运行的时候有时候会报错路径不存在。 解决方法:所有文件路径,请先确保本地存在相应路径,再同步到远程服务器中,有时候MindStudio不会自动生成路径,导致报错。7、关于MindStudio更多的内容 如果需要了解关于MindStudio更多的信息,请查阅昇腾社区中MindStudio的用户手册cid:link_4,里面有算子开发、模型开发等各种使用操作的详细介绍。 如果在使用MindStudio过程中遇到任何问题,也可以在昇腾社区中的昇腾论坛cid:link_12里进行提问,会有华为内部技术人员对其进行解答,如下图。
  • [经验分享] MindStudio模型推理场景精度比对全流程和结果分析
    视频案例,可以查看Bilibili MindStudio模型推理场景精度比对全流程和结果分析:【经验分享】MindStudio模型推理场景精度比对全流程和结果分析1、MindStudio介绍MindStudio提供在AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务,依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够帮助您在一个工具上就能高效便捷地完成AI应用开发,MindStudio采用了插件化扩展机制,开发者可以通过开发插件来扩展已有功能。本实验使用的MindStudio版本为5.0.RC3,安装请参考MindStudio安装教程。2、交付件介绍(1)精度对比简介​ 在下面两种情况下,自有实现的算子在昇腾AI处理器上的运算结果与业界标准算子(如Caffe、ONNX、TensorFlow、PyTorch)的运算结果可能存在差异。在模型转换过程中对模型进行了优化,包括算子消除、算子融合、算子拆分,这些动作可能会造成自有实现的算子运算结果与业界标准算子(如Caffe、TensorFlow、ONNX)运算结果存在偏差。用户原始网络可以迁移到昇腾910 AI处理器上执行训练,网络迁移可能会造成自有实现的算子运算结果与用业界标准算子(如TensorFlow)运算结果存在偏差。(2)实现流程​ 为了帮助开发人员快速解决算子精度问题,需要提供自有实现的算子运算结果与业界标准算子运算结果之间进行精度差异对比的工具。​ MindStudio精度比对工具提供Tensor比对能力,包含余弦相似度、欧氏相对距离、绝对误差(最大绝对误差、平均绝对误差、均方根误差)、相对误差(最大相对误差、平均相对误差、累积相对误差)、KL散度、标准差算法比对维度。精度比对总体流程如下:(3)代码工程本实验基于MindStudio的代码工程结构如下所示。本实验基于MindStudio的代码工程结构如下所示。 ├── caffeResnet50_49048f18 │ ├── acl_net.py //离线模型推理脚本代码 │ ├── caffe_dump.py //原始模型推理脚本代码 │ ├── caffe_model //原始模型文件存储目录 │ │ ├── resnet50.caffemodel │ │ └── resnet50.prototxt │ ├── caffeResnet50.iml │ ├── constant.py //离线模型推理脚本工具脚本 │ ├── data //数据文件夹 │ │ └── img.png │ ├── dump //离线模型dump数据文件夹 │ ├── model //离线模型文件夹 │ │ └── resnet50.om │ ├── npy_dump //原始模型dump数据文件夹 │ ├── output //精度比对输出文件夹 │ │ └── 20221111205145 │ └── src │ └── acl.json //离线模型dump构造文件 (4)文章介绍​ 文章详细记录了如何使用MindStudio中的精度比对功能去进行推理场景下的模型的精度比对操作,包括原始第三方框架下模型的npy数据准备,离线模型的dump数据准备,精度比对以及分析。第三节介绍了MindStudio的昇腾App工程的创建。第四节介绍了推理场景下的数据准备。第五节介绍了精度比对和分析。第六节介绍了整个流程中遇到的问题和解决方案。第七节介绍MindStudio的更多的内容。3、App工程创建打开MindStudio进入算子工程创建界面首次登录MindStudio:在MindStudio欢迎界面中单击“New Project”,进入创建工程界面。非首次登录MindStudio:在顶部菜单栏中选择“File > New > Project...”,进入创建工程界面。创建App工程左侧导航栏选择“Ascend App”,如图所示,在右侧点击选择ACL Project(Python)工程。单击“Next”,在弹出的页面中,Project name那一行输入项目名称,然后点击Finish,既可完成工程的创建。单击“Finish”,完成应用工程的创建若工作窗口已打开其他工程,会出现如图所示提示。选择“This Window”,则直接在当前工作窗口打开新创建的工程。选择“New Window”,则新建一个工作窗口打开新创建的工程。4、推理场景数据准备(1)准备Caffe模型npy数据文件MindStudio当前版本不提供Caffe模型numpy数据生成功能,请自行安装Caffe环境并提前准备Caffe原始数据“*.npy”文件。本文仅提供生成符合精度比对要求的numpy格式Caffe原始数据“*.npy”文件的样例参考。下面给出Resnet50原始模型dump数据的推理脚本代码。请参考表1的参数说明进行使用。​ 表1 原始模型推理脚本参数说明-wCaffe 权重文件路径,如'resnet50.caffemodel'-i, --input_bins模型推理输入bin文件或者图片文件路径,多个以;分隔,如'./a.bin;./img.png'-n, --input_names模型推理输入节点名称,多个以;分隔,如'graph_input_0:0; graph_input_1:0'-mCaffe 模型文件路径,如'resnet50.prototxt'-odump输出文件路径,如'./output_dir', 该路径需要用户自己创建脚本代码:# coding=utf-8 import caffe import sys import argparse import os import caffe.proto.caffe_pb2 as caffe_pb2 import google.protobuf.text_format import json import numpy as np import time TIME_LENGTH = 1000 FILE_PERMISSION_FLAG = 0o600 class CaffeProcess: def __init__(self): parse = argparse.ArgumentParser() parse.add_argument("-w", dest="weight_file_path", help="<Required> the caffe weight file path", required=False,default="caffe_model/resnet50.caffemodel") parse.add_argument("-m", dest="model_file_path", help="<Required> the caffe model file path", required=False,default="caffe_model/resnet50.prototxt") parse.add_argument("-o", dest="output_path", help="<Required> the output path", required=False,default="npy_dump") parse.add_argument("-i", "--input_bins", dest="input_bins", help="input_bins bins. e.g. './a.bin;./c.bin'", required=False,default="./data/img.png") parse.add_argument("-n", "--input_names", dest="input_names", help="input nodes name. e.g. 'graph_input_0:0;graph_input_0:1'", required=False,default="data:0") args, _ = parse.parse_known_args(sys.argv[1:]) self.weight_file_path = os.path.realpath(args.weight_file_path) self.model_file_path = os.path.realpath(args.model_file_path) self.input_bins = args.input_bins.split(";") self.input_names = args.input_names.split(";") self.output_path = os.path.realpath(args.output_path) self.net_param = None self.cur_layer_idx = -1 @staticmethod def _check_file_valid(path, is_file): if not os.path.exists(path): print('Error: The path "' + path + '" does not exist.') exit(-1) if is_file: if not os.path.isfile(path): print('Error: The path "' + path + '" is not a file.') exit(-1) else: if not os.path.isdir(path): print('Error: The path "' + path + '" is not a directory.') exit(-1) def _check_arguments_valid(self): self._check_file_valid(self.model_file_path, True) self._check_file_valid(self.weight_file_path, True) self._check_file_valid(self.output_path, False) for input_file in self.input_bins: self._check_file_valid(input_file, True) @staticmethod def calDataSize(shape): dataSize = 1 for dim in shape: dataSize *= dim return dataSize def _load_inputs(self, net): inputs_map = {} for layer_name, blob in net.blobs.items(): if layer_name in self.input_names: input_bin = np.fromfile( self.input_bins[self.input_names.index(layer_name)], np.float32) input_bin_shape = blob.data.shape if self.calDataSize(input_bin_shape) == self.calDataSize(input_bin.shape): input_bin = input_bin.reshape(input_bin_shape) else: print("Error: input node data size %d not match with input bin data size %d.", self.calDataSize( input_bin_shape), self.calDataSize(input_bin.shape)) exit(-1) inputs_map[layer_name] = input_bin return inputs_map def process(self): """ Function Description: process the caffe net, save result as dump data """ # check path valid self._check_arguments_valid() # load model and weight file net = caffe.Net(self.model_file_path, self.weight_file_path, caffe.TEST) inputs_map = self._load_inputs(net) for key, value in inputs_map.items(): net.blobs[key].data[...] = value # process net.forward() # read prototxt file net_param = caffe_pb2.NetParameter() with open(self.model_file_path, 'rb') as model_file: google.protobuf.text_format.Parse(model_file.read(), net_param) for layer in net_param.layer: name = layer.name.replace("/", "_").replace(".", "_") index = 0 for top in layer.top: data = net.blobs[top].data[...] file_name = name + "." + str(index) + "." + str( round(time.time() * 1000000)) + ".npy" output_dump_path = os.path.join(self.output_path, file_name) np.save(output_dump_path, data) os.chmod(output_dump_path, FILE_PERMISSION_FLAG) print('The dump data of "' + layer.name + '" has been saved to "' + output_dump_path + '".') index += 1 if __name__ == "__main__": caffe_process = CaffeProcess() caffe_process.process()说明:运行之前需要提前准备数据文件和模型文件,原始模型下载地址为:cid:link_3​ 数据图片下载地址为:https://gitee.com/link?target=https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/models/aclsample/dog1_1024_683.jpg远程安装好caffe的python3环境,在本地配置好安装的caffe的SDK。将上述代码拷贝到新建的python脚本中,右键点击运行该脚本,即可以在参数-o指定的路径下生成npy数据文件。生成的文件是以{op_name}.{output_index}.{timestamp}.npy形式命名。其中{op_name}为算子名称,{output_index}是算子的编号索引,{timestamp}是时间戳;设置numpy数据文件名包括output_index字段且值为0,确保转换生成的dump数据的output_index为0,否则无比对结果,原因是精度比对时默认从第一个output_index为0的数据开始。(2)准备离线模型dump数据通过MindStudio提供的dump功能,生成离线模型的dump数据,需要提前完成以下操作:完成Caffe、TensorFlow或ONNX模型的ATC模型转换,将原始模型转换为OM离线模型。详细介绍请参见模型转换。完成应用工程的开发、编译和运行,确保具备可执行的应用工程。详细介绍请参见应用开发。操作步骤如下:准备好离线模型,离线模型下载地址为:cid:link_3;或者参考如下模型转换步骤进行模型转换(1) 在菜单栏选择“Ascend > Model Converter”。出现如下配置界面,参数配置参考MindStudio官网>用户指南>模型转换>操作步骤。(2) 单击“Next”,进入“Data Pre-Processing”配置数据预处理页签,界面参考如图所示。说明:数据预处理是昇腾AI处理器提供的硬件图像预处理模块,包括色域转换,图像归一化(减均值/乘系数)和抠图(指定抠图起始点,抠出神经网络需要大小的图片)等功能。只有当“Model Information”页签,“Input Nodes”参数中,输入节点的“Type”有配置为“Uint8”类型,“Data Pre-Processing”页签才可以配置该节点的数据预处理功能。如果模型有多个输入,每个输入节点都可以获取shape信息中的宽和高,并且“Input Nodes”参数中每个输入节点的“Type”都配置为“Uint8”,则“Data Pre-Processing”页签可以配置多个节点的数据预处理功能。(3) 单击“Next”,进入“Advanced Options Preview”高级选项配置页签,界面参考如图所示。(4) 单击Finish完成模型转换。在MindStudio界面下方,“Output”窗口会显示模型转换过程中的日志信息,如果提示“Model converted successfully”,则表示模型转换成功。准备好离线模型的推理代码。推理代码可以从cid:link_0中获取,或者直接拷贝下面代码。构造dump的.json配置,选择“Ascend > Dump Configuration”菜单,弹出“Select Offline Model”窗口,如图所示。注意:如果不知道自己本地同步到远程哪个路径下,可以点击Tools>Development>Configuration下查看。选择.om模型文件,单击“OK”,展示模型文件结构,设置dump开关。如图所示。它会在src目录下生成acl.json配置文件,通过修改窗口最右侧配置项,设置.om模型文件的dump配置项,会自动更新到acl.json文件中。(1) Dump Option:配置dump范围。ALL:所有算子开启dump。Several:自定义部分算子开启dump。选择该项后,需要右键单击待dump数据的算子并选择“Enable Dump”。None:所有算子不开启dump。(2) Dump Mode:dump数据模式。ALL:同时dump算子的输入、输出数据。Input:dump算子的输入数据。Output:dump算子的输出数据。(3) Dump Path:配置保存dump数据文件的路径,默认为:{project_path}/dump。如果Dump Path设置为其他路径,需要确保MindStudio安装用户对该路径具有读写权限。注意:该选项要选择远程的dump目录,当前版本mindstudio只支持选择本地的dump目录,如果不能选择远程dump目录,请自行在acl.json中配置。(4) AclConfig File:Acl配置文件,在dump操作中该文件保存算子的dump配置信息。一般路径为{project_path}/src/acl.json。请参考表2中的参数说明使用该脚本​ 表2 离线模型推理脚本参数说明--devicenpu设备编号。--model_path离线模型文件路径,到文件名层次。--images_path数据文件路径,到数据文件的文件夹层次。import argparse import numpy as np import acl import os from PIL import Image from constant import ACL_MEM_MALLOC_HUGE_FIRST, \ ACL_MEMCPY_HOST_TO_DEVICE, ACL_MEMCPY_DEVICE_TO_HOST, \ ACL_SUCCESS, IMG_EXT, NPY_FLOAT32 buffer_method = { "in": acl.mdl.get_input_size_by_index, "out": acl.mdl.get_output_size_by_index } def check_ret(message, ret): if ret != ACL_SUCCESS: raise Exception("{} failed ret={}" .format(message, ret)) class Net(object): def __init__(self, device_id, model_path): self.device_id = device_id # int self.model_path = model_path # string self.model_id = None # pointer self.context = None # pointer self.input_data = [] self.output_data = [] self.model_desc = None # pointer when using self.load_input_dataset = None self.load_output_dataset = None self.init_resource() def release_resource(self): print("Releasing resources stage:") ret = acl.mdl.unload(self.model_id) check_ret("acl.mdl.unload", ret) if self.model_desc: acl.mdl.destroy_desc(self.model_desc) self.model_desc = None while self.input_data: item = self.input_data.pop() ret = acl.rt.free(item["buffer"]) check_ret("acl.rt.free", ret) while self.output_data: item = self.output_data.pop() ret = acl.rt.free(item["buffer"]) check_ret("acl.rt.free", ret) if self.context: ret = acl.rt.destroy_context(self.context) check_ret("acl.rt.destroy_context", ret) self.context = None ret = acl.rt.reset_device(self.device_id) check_ret("acl.rt.reset_device", ret) ret = acl.finalize() check_ret("acl.finalize", ret) print('Resources released successfully.') def init_resource(self): print("init resource stage:") current_dir=os.path.dirname(os.path.abspath(__file__)) ret = acl.init(os.path.join(current_dir,"./src/acl.json")) check_ret("acl.init", ret) # ret = acl.mdl.init_dump() # check_ret("acl.init", ret) # ret = acl.mdl.set_dump(os.path.join(current_dir,"./src/acl.json")) # check_ret("acl.init", ret) ret = acl.rt.set_device(self.device_id) check_ret("acl.rt.set_device", ret) self.context, ret = acl.rt.create_context(self.device_id) check_ret("acl.rt.create_context", ret) # load_model self.model_id, ret = acl.mdl.load_from_file(self.model_path) check_ret("acl.mdl.load_from_file", ret) print("model_id:{}".format(self.model_id)) self.model_desc = acl.mdl.create_desc() self._get_model_info() print("init resource success") def _get_model_info(self,): ret = acl.mdl.get_desc(self.model_desc, self.model_id) check_ret("acl.mdl.get_desc", ret) input_size = acl.mdl.get_num_inputs(self.model_desc) output_size = acl.mdl.get_num_outputs(self.model_desc) self._gen_data_buffer(input_size, des="in") self._gen_data_buffer(output_size, des="out") def _gen_data_buffer(self, size, des): func = buffer_method[des] for i in range(size): # check temp_buffer dtype temp_buffer_size = func(self.model_desc, i) temp_buffer, ret = acl.rt.malloc(temp_buffer_size, ACL_MEM_MALLOC_HUGE_FIRST) check_ret("acl.rt.malloc", ret) if des == "in": self.input_data.append({"buffer": temp_buffer, "size": temp_buffer_size}) elif des == "out": self.output_data.append({"buffer": temp_buffer, "size": temp_buffer_size}) def _data_interaction(self, dataset, policy=ACL_MEMCPY_HOST_TO_DEVICE): temp_data_buffer = self.input_data \ if policy == ACL_MEMCPY_HOST_TO_DEVICE \ else self.output_data if len(dataset) == 0 and policy == ACL_MEMCPY_DEVICE_TO_HOST: for item in self.output_data: temp, ret = acl.rt.malloc_host(item["size"]) if ret != 0: raise Exception("can't malloc_host ret={}".format(ret)) dataset.append({"size": item["size"], "buffer": temp}) for i, item in enumerate(temp_data_buffer): if policy == ACL_MEMCPY_HOST_TO_DEVICE: if "bytes_to_ptr" in dir(acl.util): bytes_data = dataset[i].tobytes() ptr = acl.util.bytes_to_ptr(bytes_data) else: ptr = acl.util.numpy_to_ptr(dataset[i]) ret = acl.rt.memcpy(item["buffer"], item["size"], ptr, item["size"], policy) check_ret("acl.rt.memcpy", ret) else: ptr = dataset[i]["buffer"] ret = acl.rt.memcpy(ptr, item["size"], item["buffer"], item["size"], policy) check_ret("acl.rt.memcpy", ret) def _gen_dataset(self, type_str="input"): dataset = acl.mdl.create_dataset() temp_dataset = None if type_str == "in": self.load_input_dataset = dataset temp_dataset = self.input_data else: self.load_output_dataset = dataset temp_dataset = self.output_data for item in temp_dataset: data = acl.create_data_buffer(item["buffer"], item["size"]) _, ret = acl.mdl.add_dataset_buffer(dataset, data) if ret != ACL_SUCCESS: ret = acl.destroy_data_buffer(data) check_ret("acl.destroy_data_buffer", ret) def _data_from_host_to_device(self, images): print("data interaction from host to device") # copy images to device self._data_interaction(images, ACL_MEMCPY_HOST_TO_DEVICE) # load input data into model self._gen_dataset("in") # load output data into model self._gen_dataset("out") print("data interaction from host to device success") def _data_from_device_to_host(self): print("data interaction from device to host") res = [] # copy device to host self._data_interaction(res, ACL_MEMCPY_DEVICE_TO_HOST) print("data interaction from device to host success") result = self.get_result(res) self._print_result(result) # free host memory for item in res: ptr = item['buffer'] ret = acl.rt.free_host(ptr) check_ret('acl.rt.free_host', ret) def run(self, images): self._data_from_host_to_device(images) self.forward() self._data_from_device_to_host() def forward(self): print('execute stage:') ret = acl.mdl.execute(self.model_id, self.load_input_dataset, self.load_output_dataset) check_ret("acl.mdl.execute", ret) self._destroy_databuffer() print('execute stage success') def _print_result(self, result): vals = np.array(result).flatten() top_k = vals.argsort()[-1:-6:-1] print("======== top5 inference results: =============") for j in top_k: print("[%d]: %f" % (j, vals[j])) def _destroy_databuffer(self): for dataset in [self.load_input_dataset, self.load_output_dataset]: if not dataset: continue number = acl.mdl.get_dataset_num_buffers(dataset) for i in range(number): data_buf = acl.mdl.get_dataset_buffer(dataset, i) if data_buf: ret = acl.destroy_data_buffer(data_buf) check_ret("acl.destroy_data_buffer", ret) ret = acl.mdl.destroy_dataset(dataset) check_ret("acl.mdl.destroy_dataset", ret) def get_result(self, output_data): result = [] dims, ret = acl.mdl.get_cur_output_dims(self.model_desc, 0) check_ret("acl.mdl.get_cur_output_dims", ret) out_dim = dims['dims'] for temp in output_data: ptr = temp["buffer"] # 转化为float32类型的数据 if "ptr_to_bytes" in dir(acl.util): bytes_data = acl.util.ptr_to_bytes(ptr, temp["size"]) data = np.frombuffer(bytes_data, dtype=np.float32).reshape(tuple(out_dim)) else: data = acl.util.ptr_to_numpy(ptr, tuple(out_dim), NPY_FLOAT32) result.append(data) return result def transfer_pic(input_path): input_path = os.path.abspath(input_path) with Image.open(input_path) as image_file: image_file = image_file.resize((256, 256)) img = np.array(image_file) height = img.shape[0] width = img.shape[1] # 对图片进行切分,取中间区域 h_off = (height - 224) // 2 w_off = (width - 224) // 2 crop_img = img[h_off:height - h_off, w_off:width - w_off, :] # rgb to bgr,改变通道顺序 img = crop_img[:, :, ::-1] shape = img.shape img = img.astype("float16") img[:, :, 0] -= 104 img[:, :, 1] -= 117 img[:, :, 2] -= 123 img = img.reshape([1] + list(shape)) img = img.transpose([0, 3, 1, 2]) result = np.frombuffer(img.tobytes(), np.float16) return result if __name__ == '__main__': current_dir = os.path.dirname(os.path.abspath(__file__)) parser = argparse.ArgumentParser() parser.add_argument('--device', type=int, default=0) parser.add_argument('--model_path', type=str, default=os.path.join(current_dir, "./model/resnet50.om")) parser.add_argument('--images_path', type=str, default=os.path.join(current_dir, "./data")) args = parser.parse_args() print("Using device id:{}\nmodel path:{}\nimages path:{}" .format(args.device, args.model_path, args.images_path)) images_list = [os.path.join(args.images_path, img) for img in os.listdir(args.images_path) if os.path.splitext(img)[1] in IMG_EXT] net = Net(args.device, args.model_path) for image in images_list: print("images:{}".format(image)) img = transfer_pic(image) net.run([img]) # acl.mdl.finalize_dump() # net.run([img]) print("*****run finish******") net.release_resource() 说明:(1) 数据文件应该是与原始模型生成npy数据文件保持一致。(2) 如果是从gitee上下载的代码,需要修改acl.init()这行代码,在里面传入dump的配置参数.json文件。6.设置dump完成后,单击MindStudio界面“Run”菜单,重新编译和运行应用工程。工程运行完毕后,可以在{project_path}/dump路径下查看到生成的dump数据文件。生成的路径及格式说明:time/device_id/model_name/model_id/data_index/dump文件time:dump数据回传落盘时间。格式为:YYYYMMDDhhmmss。device_id:Device设备ID号。model_name:模型名称。model_id:模型ID号。data_index:针对每个Task ID执行的次数维护一个序号,从0开始计数,该Task每dump一次数据,序号递增1。dump文件:命名规则如{op_type}.{op_name}.{taskid}.{timestamp}。如果model_name、op_type、op_name出现了“.”、“/”、“\”、空格时,转换为下划线表示。5、精度比对及分析(1)全网精度比对操作步骤在MindStudio界面菜单栏选择“Ascend > Model Accuracy Analyzer > New Task”菜单,进入比对界面,如下图所示。参考表3配置好参数后点击Next下一步。进入到数据和模型的配置界面。​ 表3 精度比对New Task参数说明参数说明Run ModeRemote Run:远程运行。Local Run:本地运行。Windows使用场景下仅支持Remote Run,该参数不展示。Deployment运行配置,选择Remote Run模式时可见,必选配置。通过Deployment功能,详细请参见Deployment,可以将指定项目中的文件、文件夹同步到远程指定机器的指定目录。Remote Toolkit Path远端运行环境toolkit软件包安装路径,选择Remote Run模式时可见,必选配置。例如配置为${HOME}/Ascend/ascend-toolkit/xxx/toolkit。与Deployment参数为绑定关系,单击“Start”后参数值将被保存。再次配置时,如连接已配置过的Deployment,则参数自动填充,可手动修改。Environment Variables环境变量配置,选择Remote Run模式时可见,可以直接在框中输入,也可以单击后在弹窗内单击填写。可选配置,当Model File指定文件为离线模型文件(*.om)时,需要配置环境变量,否则工具将无法为离线模型文件(*.om)进行ATC转换导致比对失败。与Deployment参数为绑定关系,单击“Start”后参数值将被保存。再次配置时,如连接已配置过的Deployment,则参数自动填充,可手动修改。Output Path比对数据结果存放路径,必选配置。无论选择Remote Run模式还是Local Run模式,均需要指定为本端路径。默认路径为当前系统的用户目录。Analysis Mode精度比对分析模式,必选配置。可选择模式为:NPU vs NPU:表示两个比对文件均为昇腾AI处理器上运行生成的dump数据文件。此时Model File参数可选。一般用于分析开启和关闭融合规则时进行模型转换后的dump数据文件之间的精度差。模型转换开启和关闭融合规则的详细介绍请参见模型转换。NPU vs GPU/CPU:表示昇腾AI处理器上运行生成的dump数据文件与原始模型的npy文件进行比对。此时展示Framework必选参数。Framework比对数据所属的框架类型,必选配置。Analysis Mode为NPU vs GPU/CPU时可见。可选类型为:- TensorFlow:TensorFlow框架模型dump数据的精度比对,支持推理、训练场景,Model File参数必选。- ONNX:ONNX框架模型dump数据的精度比对,支持推理场景,Model File参数必选。- Caffe:Caffe框架模型dump数据的精度比对,支持推理场景,Model File参数必选。NPU Dump昇腾AI处理器上运行生成的dump数据文件目录,必选配置。在远端执行比对时(Remote Run),须指定远端设备上的dump数据文件目录。Model File模型文件或融合规则文件。Analysis Mode为NPU vs NPU时,进行离线模型转换开启算子融合功能前后的dump数据精度比对,需要指定开融合的算子映射文件(.json)或离线模型文件(*.om)和关融合的算子映射文件(.json)或离线模型文件(*.om)。Analysis Mode为NPU vs GPU/CPU时,根据Framework选择的框架类型选择不同的文件:l TensorFlow:推理场景选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om);训练场景选择计算图文件(*.txt)。l ONNX:选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om)。l Caffe:选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om)。l 具体选择文件请参见比对场景。Quantization Rule File(.json)量化算子映射关系文件(昇腾模型压缩输出的json文件),可选配置。仅Framework为Caffe时展示。Ground Truth原始模型的npy文件目录,必选配置。在远端执行比对时(Remote Run),须指定远端设备上的原始模型的npy文件目录。Algorithm比对算法维度。取值为:l Cosine Similarity:余弦相似度算法,默认勾选。l Relative Euclidean Distance:欧氏相对距离算法,默认勾选。l Absolute Error,绝对误差,默认勾选,此项执行的比对算法为:l Max Absolute Error:最大绝对误差。l Mean Absolute Error:平均绝对误差。l Root Mean Square Error:均方根误差。l Relative Error,相对误差,默认勾选,此项执行的比对算法为:l Max Relative Error:最大相对误差。l Mean Relative Error:平均相对误差。l Accumulated Relative Error:累积相对误差。l Kullback Leibler Divergence:KL散度算法,默认不勾选。l Standard Deviation:标准差算法,默认不勾选。l 与Customized Algorithm自定义算法之间至少勾选一种算法。Advance Options扩展选项。包括Customized Algorithm、Advisor和Operator Range。Customized Algorithm自定义算法文件路径。与Algorithm内置算法之间至少勾选一种算法。需用户自行准备自定义算法.py文件,所在目录格式为“algorithm”,指定该目录下的自定义算法.py文件,生成自定义算法。自定义算法.py文件相关要求参见《精度比对工具使用指南》附录中的“准备自定义算法.py文件”章节。Advisor专家系统分析开关,默认关闭。开启后会在完成整网比对后对比对结果进行专家系统分析并输出问题节点、问题类型和优化建议。详细介绍请参见比对结果专家建议。使用本功能前需要先执行*pip3* *install* ****pandas****命令安装pandas 1.3或更高版本依赖。与Operator Range无法同时开启。Operator Range设定算子比对范围。有两种设置方式:方式一:单击“Select”按钮,在弹出框内勾选需要比对的算子。方式二:根据Start、End、Step参数配置比对算子的范围。l start:第一个比对的算子,取值范围为[1, 参与计算的算子个数],默认值为1。l end:最后一个比对的算子,取值范围为-1或[start, 参与计算的算子个数],默认值为-1(动态获取网络模型中最后一个参与计算的算子)。l step:第start+stepn个比对的算子,step取值范围为[1, 参与计算的算子个数),默认值为1,n为从1开始的正整数。配置格式为:“start,end,step”。比如:-r 1,101,20,表示算子1,21,41,61,81,101的Tensor参与比对。不配置本参数时,比对网络模型中的所有参与计算的算子。配置本参数且Analysis Mode参数配置为NPU vs NPU时,需同时指定NPU Dump和Ground Truth的Model File分别指定开融合的算子映射文件(.json)或离线模型文件(.om)和关融合的算子映射文件(.json)或离线模型文件(*.om)。与Advisor无法同时开启。(2)全网比对结果分析上面步骤配置好参数后点击start即可以出现对比的结果界面。如下所示。图一图二图三所示将Tensor比对结果界面分为四个区域分别进行介绍。其中1~4区域为整网比对结果。表4 整网比对结果说明区域区域名称说明1菜单栏从左到右分别为Open…、New Task、Refresh、Help四项功能。Open…为打开并展示比对结果csv文件;New Task为创建新的比对任务;Refresh用于读取并刷新File Manager中管理的文件;单击Help弹出小窗,可展示精度比对工具的使用限制(Restrictions)、使用建议、在线教程链接等。2File Manager,历史数据管理显示用户指定文件夹以及文件夹下生成的整网比对的csv文件以及显示通过Open…单独打开的csv文件;对文件夹和csv,提供历史数据管理功能,包括打开、删除、另存为;在文件夹处右键删除;在空白处右键创建新比对任务(New Task)、刷新(Refresh)和Open…(打开并展示比对结果csv文件)。3Model Accuracy Analysis,精度比对分析界面默认仅显示有结果的算子。可单击列名,进行排序;单击Show Invalid Data,可展示无法比对的数据,各列字段含义请参见表2。4Scatter Diagram,各项算法指标的散点分布图Show Model,比对模型可视化展示Scatter Diagram:横坐标表示算子的执行顺序,纵坐标为算法指标在对应Tensor上的实际取值。各字段含义请参见表3。Show Model:分别展示NPU和Ground Truth的模型图。详细介绍请参见表4。表5 比对结果字段说明字段说明Index网络模型中算子的ID。OpSequence算子运行的序列。全网层信息文件中算子的ID。仅配置“Operator Range”时展示。OpType算子类型。NPUDump表示NPU Dump模型的算子名。光标悬浮时,可显示具体算子所在的文件路径。DataType表示NPU Dump侧数据算子的数据类型。Addressdump tensor的虚拟内存地址。用于判断算子的内存问题。仅基于昇腾AI处理器运行生成的dump数据文件在整网比对时可提取该数据。GroundTruth表示Ground Truth模型的算子名。光标悬浮时,可显示具体算子所在的文件路径。DataType表示Ground Truth侧数据算子的数据类型。TensorIndex表示NPU Dump模型算子的input ID和output ID。Shape比对的Tensor的Shape。OverFlow溢出算子。显示YES表示该算子存在溢出;显示NO表示算子无溢出;显示NaN表示不做溢出检测。开启Advisor功能时展示,为比对结果专家建议的FP16溢出检测专家建议提供数据。CosineSimilarity进行余弦相似度算法比对出来的结果。取值范围为[-1,1],比对的结果如果越接近1,表示两者的值越相近,越接近-1意味着两者的值越相反。MaxAbsoluteError进行最大绝对误差算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。KullbackLeiblerDivergence进行KL散度算法比对出来的结果。取值范围为0到无穷大。KL散度越小,真实分布与近似分布之间的匹配越好。RootMeanSquareError表示均方根误差。取值范围为0到无穷大,MeanAbsoluteError趋于0,RootMeanSquareError趋于0,说明测量值与真实值越近似;MeanAbsoluteError趋于0,RootMeanSquareError越大,说明存在局部过大的异常值;MeanAbsoluteError越大,RootMeanSquareError等于或近似MeanAbsoluteError,说明整体偏差越集中;MeanAbsoluteError越大,RootMeanSquareError越大于MeanAbsoluteError,说明存在整体偏差,且整体偏差分布分散;不存在以上情况的例外情况,因为RMSE ≥ MAE恒成立。MaxRelativeError表示最大相对误差。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。RelativeEuclideanDistance进行欧氏相对距离算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。StandardDeviation进行标准差算法比对出来的结果。取值范围为0到无穷大。标准差越小,离散度越小,表明越接近平均值。该列显示NPU Dump和Ground Truth两组数据的均值和标准差,第一组展示NPU Dump模型dump数据的数值(均值;标准差),第二组展示Ground Truth模型dump数据的数值(均值;标准差)。AccumulatedRelativeError进行累积相对误差算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。MeanAbsoluteError表示平均绝对误差。取值范围为0到无穷大,MeanAbsoluteError趋于0,RootMeanSquareError趋于0,说明测量值与真实值越近似;MeanAbsoluteError趋于0,RootMeanSquareError越大,说明存在局部过大的异常值;MeanAbsoluteError越大,RootMeanSquareError等于或近似MeanAbsoluteError,说明整体偏差越集中;MeanAbsoluteError越大,RootMeanSquareError越大于MeanAbsoluteError,说明存在整体偏差,且整体偏差分布分散;不存在以上情况的例外情况,因为RMSE ≥ MAE恒成立。MeanRelativeError表示平均相对误差。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。CompareFailReason算子无法比对的原因。若余弦相似度为1,则查看该算子的输入或输出shape是否为空或全部为1,若为空或全部为1则算子的输入或输出为标量,提示:this tensor is scalar。注1:余弦相似度和KL散度比较结果为NaN,其他算法有比较数据,则表明左侧或右侧数据为0;KL散度比较结果为inf,表明右侧数据有一个为0;比对结果为nan,表示dump数据有nan。 注2:光标悬浮在表头可以看到对应的参数详细解释。 注3:若配置了自定义算法比对,则在比对结果的内置算法后增加对应自定义算法列。表6 散点分布图字段说明字段说明Algorithm选择展示对应比对算法结果的散点分布图,不支持展示StandardDeviation、KullbackLeiblerDivergence和AccumulatedRelativeError。Tensor过滤显示Input、Output结果散点分布图。Highlight对算子Tensor散点进行高亮。通过拖拉游标在对应算法指标的[min,max]间滑动来设置算法指标(纵坐标)的阈值,高于或等于阈值的点显示为蓝色,低于阈值的点显示为红色。如针对余弦相似度,图中设置阈值为0.98,小于0.98的算子Tensor被标记为红色。注1:光标移动到对应Tensor点上时,浮窗显示Tensor信息。信息包括:Index(Tensor对应算子的Index)、Op Name(算子名称)、Tensor Index(Tensor类型(input/output))以及Value(在当前算法维度下的Tensor数值)。注2:支持对散点图进行缩放。注3:指定区域3中的Tensor时,高亮对应Tensor点。表7 比对模型可视化展示字段说明字段说明NPU Model离线模型可视化。指定算子映射文件(.json)或离线模型文件(*.om)展示。训练场景下,若整网比对使用的Model File为计算图文件(*.txt),此处不支持展示模型图。Ground Truth Model原始模型可视化。指定原始模型文件展示。Input Model指定算子映射文件(.json)、离线模型文件(*.om)或原始模型文件。注:指定区域3中的Tensor时,高亮对应模型网络中的节点。在第一部分我们可以选择菜单,精度对比、历史等选项。我们可以从第二部分选择我们经过精度对比操作之后得到的不同的答案,并选择我们想要的内容来进行第三部分和第四部分的展示,在本次的实例当中我们只生成了一个模型的整网对比,所以只有一个对应的结果的文件,打开相应的文件夹,双击里面的csv文件,就可以呈现出我们本次模型的精度对比。精度对比页面第三部分看出我们的原模型和转换模型之间每个算子之间的结果的差距,并且也可以得到输入和输出的shape。在后面几栏的算子的精度的对比,我们可以根据不同的评判方法得出原算子和转化的算子之间经过运算之后得出的结果的相似程度来判断算子转化的优劣,我们根据后面几项的精度对比,从数据上可以看出精度正在下降,也意味着误差正在增加。随后也可观察4部分的散点图来观察从最开始的输入到最后的输出,经过每一个算子的计算,两模型之间的精度差距,我们可以看到余弦相似度的值有下降的趋势,且最后的结果接近于零,所以说两模型之间的误差在慢慢的增大。并且在第四部分还可以根据Algorithm选项选择不同的精度比较方法,比如说图1和图3选择的是余弦相似度和均方根误差来来展示精度的对比。在Tensor选项当中,我们可以选择input或者output选项来展示输入或者输出之间的精度对比。我们还可以选择第四部分的show model选项,即可以展示网络模型结构中算子之间的关系,也可以配合精度比对结果来定位具体算子的精度问题。(3)单算子精度比对操作步骤在刚刚的整网络分析界面下,点击下面的Operator Detail,出现如下界面。对比操作。 (1)基于已经读取到的Tensor信息,通过Operator下拉框选择要比对的算子和对应Tensor(output/input)。 (2)通过Metric选择比对算子的Absolute Error(绝对误差)或Relative Error(相对误差)。 (3)配置输出该指标的TopN个Tensor元素(取值范围为[1,10000])。 (4)单击“Compare”按钮进行单算子比对。 TopN结果显示请参见比对结果。单算子比对界面说明。算子比对功能是在比对结果的基础上选择具体算子并根据需要指定参数进行比对的。界面展示为图5的6区域、7区域和8区域,如图5。详细介绍请参见表7表7 单算子比对结果说明区域说明5Operator Detail,单算子比对功能。下发单算子比对命令。具体操作请参见比对操作。6单算子比对TopN结果。各列字段解释请参见表8。7Cumulative Error,对于TopN Tensor元素,绘制的误差累积分布折线图。详细介绍请参见表8。比对结果。单算子比对结果界面展示为图5的7区域和8区域。详细介绍请参见表8。表8 比对结果字段说明字段说明6区域Index算子比对的条数。N C H W数据格式。NPUDumpNPU Dump侧算子的dump值。GroundTruthGround Truth侧算子的dump值。Absolute Error绝对误差,NPU Dump侧算子的dump值减Ground Truth侧算子的dump值取绝对值比对出来的结果。小数点后最多6位。Relative Error相对误差,Absolute Error值除以Ground Truth侧算子的dump值比对出来的结果。当Ground Truth侧算子的dump值为0时,该处显示为“-”。小数点后最多6位。7区域A % of tensor elements (B elements) have an absolute error greater than C.当前算子比对的所有tensor元素的绝对误差结果中有A %的tensor也就是B个元素的绝对误差超过了C。其中absolute error根据5区域配置的Metric取值变化可以为relative error;右侧滑块控制C的取值,范围由6区域AbsoluteError或RelativeError的最大最小值决定。误差累积分布折线图横坐标为6区域的AbsoluteError或RelativeError,取值范围由AbsoluteError或RelativeError的最大最小值决定;纵坐标为累积百分占比,含义为AbsoluteError或RelativeError到达某个阈值时,小于等于该阈值的所有tensor元素在整体tensor元素中的占比。注:光标移动到对应Tensor点上时,浮窗显示Tensor信息。信息包括:Index(算子比对的条数)、Absolute Error/Relative Error(绝对/相对误差)、Cumulative Percentage(累积百分占比)(4)对比结果专家建议FP16溢出检测 针对比对数据中数据类型为FP16的数据,进行溢出检测。如果存在溢出数据,输出专家建议。专家系统分析结果:Detection Type: FP16 overflowOperator Index: 228Expert Advice: Float16 data overflow occurs. Rectify the fault and perform comparison again.检测类型:FP16溢出检测Operator Index:228 专家建议:存在Float16数据溢出,请修正溢出问题,再进行比对。输入不一致检测 针对整网的输入数据进行检测,主要判断整网两批待比对数据的输入data是否一致。如果存在不一致问题(余弦相似度<0.99),输出专家建议。专家系统分析结果:Detection Type: Input inconsistentOperator Index: 0Expert Advice: The input data of NPUDump is inconsistent with that of GroundTruth. Use the same data or check the data preprocessing process.检测类型:输入不一致检测Operator Index:0 专家建议:NPUDump和GroundTruth间的输入数据不一致,请使用相同数据或者检查数据预处理流程。整网一致性检测(问题节点检测) 判断整网比对结果中,是否某层小于阈值,该层后续数据均小于阈值或最后一层小于阈值(余弦相似度<0.99),输出量化误差修正建议。专家系统分析结果:Detection Type: global consistencyOperator Index: 1174Expert Advice: The accuracy of some tensors is low, resulting in an unqualified final accuracy. This may be caused by quantization. Calibrate the data or contact Huawei for further diagnosis.检测类型:整网一致性检测Operator Index:1174专家建议:部分张量精度较低,且导致最终结果精度不达标;很可能由量化造成,请进行数据校准或者反馈给华为做进一步定位。整网一致性检测(单点误差检测) 判断整网比对结果中,是否某层小于阈值(余弦相似度<0.99),但最终结果符合精度要求,输出专家建议。专家系统分析结果:Detection Type: global consistencyOperator Index: 195Expert Advice: The accuracy of some tensors is low, while the final accuracy is qualified. This may be caused by Ascend internal optimization. Ignore or contact Huawei for further diagnosis.检测类型:整网一致性检测Operator Index:195专家建议:部分张量精度较低,但最终结果精度达标,可能由内部优化导致,请忽略或反馈给华为做进一步定位。整网一致性检测(一致性检测) 比对结果中的所有数据均符合精度要求,输出专家建议。专家系统分析结果:Detection Type: global consistencyOperator Index: NAExpert Advice: All data in the comparison result meets the accuracy requirements.If data accuracy of the model is still not up to standard in practical application, please check the post-processing process of model outputs.检测类型:整网一致性检测Operator Index:NA专家建议:比对结果中的所有数据均符合精度要求。如果模型实际应用中,精度依旧不达标,请排查输出数据的后处理流程。6、经验总结运行代码的时候,显示同步文件出现问题,如下。解决方法:远程python3运行环境中缺少google模块和protobuf==3.19.0模块,使用pip安装后再运行即可。 2. 单算子分析的时候,点击下面栏框显示不出来单算子分析的窗口。解决方法:确认没有报错信息的情况下,点击自己电脑的设置,调整显示屏分辨率或者缩放比例即可。Windows端的MindStudio中使用离线模型dump数据时,路径配置只能选择本地的路径,没有可选的远程路径。 解决方法:找到自己项目目录下的src/acl.json文件,手动修改JSON文件导出路径配置为远程目录的路径。配置好路径,但是运行的时候有时候会报错路径不存在。 解决方法:所有文件路径,请先确保本地存在相应路径,再同步到远程服务器中,有时候MindStudio不会自动生成路径,导致报错。7、关于MindStudio更多的内容 如果需要了解关于MindStudio更多的信息,请查阅昇腾社区中MindStudio的用户手册cid:link_4,里面有算子开发、模型开发等各种使用操作的详细介绍。 如果在使用MindStudio过程中遇到任何问题,也可以在昇腾社区中的昇腾论坛cid:link_12里进行提问,会有华为内部技术人员对其进行解答,如下图。
  • [经验分享] 用MindStudio完成基于CTC算法的语音热词唤醒
    Bilibili视频链接:https://www.bilibili.com/video/BV1zD4y187Pg/?vd_source=3c13d92bfc824135ee1784f59673e7d4一、 MindStudio 介绍与安装相关课程:昇腾全流程开发工具链(MindStudio)在线课程,提供了系统的、全面的MindStudio使用,可为初学者、一线工程师、经验丰富的开发者提供参考和帮助。本课程主要介绍MindStudio在昇腾AI开发中的使用,作为昇腾AI全栈中的全流程开发工具链,提供覆盖训练模型、推理应用和自定义算子开发三个场景下端到端工具,极大地提高开发效率。1、 MindStudio介绍MindStudio 提供您在AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务。依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够帮助您在一个工具上就能高效便捷地完成AI应用开发。MindStudio采用了插件化扩展机制,开发者可以通过开发插件来扩展已有功能。1.功能介绍●针对安装与部署,MindStudio提供多种部署方式,支持多种主流操作系统,为开发者提供最大便利。 ●针对网络模型的开发,MindStudio支持TensorFlow、PyTorch、MindSpore框架的模型训练,支持多种主流框架的模型转换。集成了训练可视化、脚本转换、模型转换、精度比对等工具,提升了网络模型移植、分析和优化的效率。 ●针对算子开发,MindStudio提供包含UT测试、ST测试、TIK 算子调试等的全套算子开发流程。支持 TensorFlow、PyTorch、MindSpore 等多种主流框架的TBE和AICPU自定义算子开发。 ●针对应用开发,MindStudio 集成了Profiling性能调优、编译器、MindX SDK的应用开发、可视化pipeline业务流编排等工具,为开发者提供了图形化的集成开发环境,通过 MindStudio能够进行工程管理、编译、调试、性能分析等全流程开发,能够很大程度提高开发效率。2.功能框架MindStudio功能框架如图1所示,目前含有的工具链包括:模型转换工具、模型训练工具、自定义算子开发工具、应用开发工具、工程管理工具、编译工具、流程编排工具、精度比对工具、日志管理工具、性能分析工具、设备管理工具等多种工具。图1工具链功能架构3.工具功能MindStudio工具中的主要几个功能特性如下:工程管理:为开发人员提供创建工程、打开工程、关闭工程、删除工程、新增工程文件目录和属性设置等功能。SSH管理:为开发人员提供新增SSH连接、删除SSH连接、修改SSH连接、加密SSH密码和修改SSH密码保存方式等功能。应用开发:针对业务流程开发人员,MindStudio工具提供基于AscendCL(Ascend Computing Language)和集成 MindX SDK 的应用开发编程方式,编程后的编译、运行、结果显示等一站式服务让流程开发更加智能化,可以让开发者快速上手。 自定义算子开发:提供了基于TBE和AICPU的算子编程开发的集成开发环境,让不同平台下的算子移植更加便捷,适配昇腾AI处理器的速度更快。 离线模型转换:训练好的第三方网络模型可以直接通过离线模型工具导入并转换成离线模型,并可一键式自动生成模型接口,方便开发者基于模型接口进行编程,同时也提供了离线模型的可视化功能。 日志管理:MindStudio为昇腾AI处理器提供了覆盖全系统的日志收集与日志分析解决方案,提升运行时算法问题的定位效率。提供了统一形式的跨平台日志可视化分析能力及运行时诊断能力,提升日志分析系统的易用性。 性能分析:MindStudio以图形界面呈现方式,实现针对主机和设备上多节点、多模块异构体系的高效、易用、可灵活扩展的系统化性能分析,以及针对昇腾AI处理器的性能和功耗的同步分析,满足算法优化对系统性能分析的需求。 设备管理:MindStudio提供设备管理工具,实现对连接到主机上的设备的管理功能。 精度比对:可以用来比对自有模型算子的运算结果与Caffe、TensorFlow、ONNX标准算子的运 算结果,以便用来确认神经网络运算误差发生的原因。 开发工具包的安装与管理:为开发者提供基于昇腾 AI处理器的相关算法开发套件包 Ascend-canntoolkit,旨在帮助开发者进行快速、高效的人工智能算法开发。开发者可以将开发套件包安装到MindStudio上,使用MindStudio进行快速开发。Ascend-cann-toolkit包含了基于昇腾AI处理器开发依赖的头文件和库文件、编译工具链、调优工具等。2、 MindStudio安装MindStudio安装:安装指南-5.0.RC1-MindStudio,昇腾社区 (hiascend.com)提供MindStudio环境搭建指导视频全流程讲解、实操演示助您轻松完成环境搭建。1. 场景介绍●纯开发场景(分部署形态):在非昇腾AI设备上安装MindStudio和Ascend-cann-toolkit开发套件包。可作为开发环境仅能用于代码开发、编译等不依赖于昇腾设备的开发活动(例如ATC模型转换、算子和推理应用程序的纯代码开发)。如果想运行应用程序或进行模型训练等,需要通过MindStudio远程连接功能连接已部署好运行环境所需软件包的昇腾AI设备。 ●开发运行场景(共部署形态):在昇腾AI设备上安装MindStudio、Ascend-cann-toolkit 开发套件包、npu-firmware安装包、npu-driver安装包和AI框架(进行模型训练时需要安装)。作为开发环境,开发人员可以进行普通的工程管理、代码编写、编译、模型转换等功能。同时可以作为运行环境,运行应用程序或进行模型训练。2. 软件包介绍˜MindStudio:提供图形化开发界面,支持应用开发、调试和模型转换功能,同时还支持网络移植、优化和分析等功能。 ˜Ascend-cann-toolkit:开发套件包。为开发者提供基于昇腾AI处理器的相关算法开发工具包,旨在帮助开发者进行快速、高效的模型、算子和应用的开发。开发套件包只能安装在Linux服务器上,开发者可以在安装开发套件包后,使用MindStudio开发工具进行快速开发。二、MindX SDK介绍与安装1、MindX SDK介绍MindX SDK提供昇腾AI处理器加速的各类AI软件开发套件(SDK),提供极简易用的 API,加速AI应用的开发。 应用开发旨在使用华为提供的SDK和应用案例快速开发并部署人工智能应用,是基于现有模型、使用pyACL提供的Python语言API库开发深度神经网络应用,用于实现目标识别、图像分类等功能。通过MindStudio实现SDK应用开发分为基础开发与深入开发,通常情况下用户关注基础开发即可,基础开发主要包含如何通过现有的插件构建业务流并实现业务数据对接,采用模块化的设计理念,将业务流程中的各个功能单元封装成独立的插件,通过插件的串接快速构建推理业务。mxManufacture & mxVision关键特性:●配置文件快速构建AI推理业务。 ●插件化开发模式,将整个推理流程“插件化”,每个插件提供一种功能,通过组装不同的插件,灵活适配推理业务流程。 ●提供丰富的插件库,用户可根据业务需求组合JPEG解码、抠图、缩放、模型推理、数据序列化等插件。 ●基于Ascend Computing Language(ACL),提供常用功能的高级API,如模型推理、解码、预处理等,简化Ascend芯片应用开发。 ●支持自定义插件开发,用户可快速地将自己的业务逻辑封装成插件,打造自己的应用插件。2、MindX SDK 安装步骤1 Windows场景下基于MindStudio的SDK应用开发,请先确保远端环境上 MindX SDK软件包已安装完成,安装方式参见MindX SDK 2.0.4 mxManufacture用户指南和MindX SDK 2.0.4 mxVision用户指南的“使用命令行方式开发”>“安装 MindX SDK 开发套件”章节。步骤2 在Windows本地进入工程创建页面,工具栏点击 File > Settings > Appearance & Behavior > System Settings > MindX SDK 进入MindX SDK管理界面。界面中MindX SDK Location为软件包的默认安装路径,默认安装路径为 “C:\Users\用户名\Ascend\mindx_sdk”。 单击 Install SDK 进入 Installation settings 界面,如图2。图2 Installation settings 界面如图3所示,为MindX SDK的安装界面,各参数选择如下:Remote Connection:远程连接的用户及IP。 Remote CANN location:远端环境上CANN开发套件包的路径,需配置到版本号一级。Remote SDK location:远端环境上SDK的路径,请配置到版本号一级。IDE将同步该层级下的include、opensource、python、samples文件夹到本地Windows环境,层级选择错误将导致安装失败。 Local SDK location:同步远端环境上SDK文件夹到本地的路径。默认安装路径为“C:\Users\用户名\Ascend\mindx_sdk”。图3 MindX SDK 的安装界面步骤3 单击OK结束,返回SDK管理界面,可查看安装后的SDK的信息,可单击OK结束安装流程。三、基于CTC算法的语音热词唤醒模型介绍随着嵌入式设备、移动设备的快速发展,部署在嵌入式、移动设备的程序越来越多。语音处理应用已在机器人、汽车电子、ATM机等嵌入式、移动设备得到广泛应用。程序、系统在移动设备上运行,必须具有较小的内存占用和较低的计算能力。关键字检测KWS( Keyword Spotting ) 使用深度神经网络DNN训练音频,基于训练的模型对关键字唤醒、推理。基于CTC算法的语音热词唤醒模型基于TensorFlow框架。KWS模型每25ms计算40维log-mel特征,帧移位为10ms。每一帧左重复23帧,向右重复8帧,并将其输入DNN。四、运行基于CTC算法的语音热词唤醒模型步骤1、打开基于CTC算法的语音热词唤醒模型●基于CTC算法的语音热词唤醒模型代码连接:cid:link_5 ●通过SecoClient连接VPN,以确保MindStudio能够连接远程服务器。●双击MindStudio点击右上角Open按钮,选择事先准备好的KWS模型,点击Ok即可进入工程。如图4所示。图4 导入KeywordCTC项目●进入工程后显示如图5界面图5 项目打开界面●单击菜单栏 Ascend > Convert To Ascend Project,如图6所示。图6 工程转换界面●弹出如图7窗口。图7 转换晟腾功能配置对窗口参数介绍如下,用户请根据实际场景选择。Project Type:可选择三种工程类型,分别为Ascend Operator、Ascend Training和Ascend App。确定了Project Type后,再选择项目类型对应的Framework,Framework可选择框架如表1所示。Project TypeFrameworkAscend OperatorMindSporePyTorchTensorFlowONNXAscend TrainingMindSporePyTorchTensorFlowAscend AppAscend ACL AppAscend Python ACL AppAscend MindX SDK App表1 FrameWork可选框架Project Desc:项目描述。单击OK,工程目录以树状呈现。此时成功创建带有.project文件的昇腾工程如图8,请以实际创建结果为准。图8 转换晟腾功能成功界面2、 基于CTC算法的语音热词唤醒模型训练●在项目Project区的KeywordCTC项目目录树找到kws_train_2.py文件,双击打开,如图9所示。kws_train_2.py文件是基于CTC算法的语音热词唤醒模型的训练文件。图9打开kws_train2.py界面●Kws_train2中主要代码介绍:图10 主要代码介绍1图11 主要代码介绍2●在工具栏选择Run>Edit Configurations...进入运行配置界面。配置Deployment,点击Run,将代码同步到远程服务器如图12。图12 Deployment配置●在工具栏选择Tools>Start SSH session…如图13。图13 选择Strat SHH session●选择终端连接的服务器图14 选择服务器连接●远程终端开启后,在MindStudio底部状态栏目的Remote Terminal图标由之前的灰色变为蓝色,并展示欢迎界面如图15。图15 连接成功界面●输入 cd MindStudio-WorkSpace/KeywordCTC进入同步到服务器的代码,输入ll命令展示内容如图16。图16 服务器上的代码目录展示●输入python kws_train_2.py 命令进行模型训练如图17、图18。图17 开始训练图18 训练过程●kws_train_2.py文件开启模型训练结束如图19。图19 训练结束●训练结束后在在result_CTC_2下生成model_weights.h5文件如图20。图20 生成model_weights.h53、 基于CTC算法的语音热词唤醒模型转换●通过pip install 命令安装onnx和tf2onnx如图21、图22。图21 安装onnx图22 安装tf2onnx●输入python keras2onnx.py命令将model_weights.h5模型转换成pb模型如图23。图23 keras2onnx.py开始执行●模型转换成功在tmp_model下可以看到saved_model.pb模型如图24。图24 pb模型生成成功●输入python -m tf2onnx.convert --saved-model tmp_model --output model1.onnx --opset 11命令将pb模型转换为onnx模型如图25、图26。图25 pb模型开始转onnx模型图26 pb模型转onnx模型过程●模型转换成功输入ll命令查看,可以看到model.onnx模型如图27。图27 生成model1.onnx输入命令:Exportinstall_path=/usr/local/Ascend/ascend toolkit/latestexportPATH=/usr/local/python3.7.5/bin:${install_path}/atc/ccec_compiler/bin:${install_path}/atc/bin:$PATHexportPYTHONPATH=${install_path}/atc/python/site-packages:$PYTHONPATHexportLD_LIBRARY_PATH=${install_path}/atc/lib64:${install_path}/acllib/lib64:$LD_LIBRARY_PATHexportASCEND_OPP_PATH=${install_path}/oppexportASCEND_AICPU_PATH=/usr/local/Ascend/ascend-toolkit/latest/设置模型转换环境。●借助ACT工具将onnx模型转换为om模型。atc --framework=5 --model=model1.onnx --output=modelctc1 --input_format=ND --input_shape="input:1,958,13" --log=debug --soc_version=Ascend310输入这行命令,模型转换如图28。图28 onnx模型开始转换om模型图29 om模型转换成功生成modelctc1.om文件4、基于CTC算法的语音热词唤醒模型评估模型训练完成后,运行性能评估文件评估模型性能,判断模型是否正常以及达到训练精度。kws_evaluate.py文件是基于CTC算法的语音热词唤醒模型的模型性能评估文件。●kws_evaluate.py主要代码介绍如下图30、图31。图30 kws_evaluate.py代码介绍1图31 kws_evaluate.py代码介绍2●输入python kws_evaluate.py命令进行模型性能评估如图32、图33。图32 kws_evaluate.py开始运行图33 kws_evaluate.py运行过程●运行结束后在result_CTC_2下面生成performance.txt文件,输入more performance.txt命令查看结果如图34。图34 performance.txt内容●performanc.txt文件里给出性能评价数据,包括keywords、TP、FN、FP 等其中TP,TN,FP,FN的理解定义为:第一个字母T/F代表预测的结果是否和实际情况相符,即如果真实情况为正样本(P),预测为正样本(P),则为T;如果真实情况为负样本(N),预测为负样本(N),则为T;如果真实情况为P,预测为N,则为F;如果真实情况为N预测为P,则为F。第二个字母P/N代表预测结果的正负:如果预测为正样本,则为P;如果预测为负样本,则为N。TP:true positive,被判定为正样本,事实上也是正样本;TN:true negative,被判定为负样本,事实上也是负样本;FP:false positive,被判定为正样本,但事实上是负样本;FN:false negative,被判定为负样本,但事实上是正样本;5、基于CTC算法的语音热词唤醒预测●kws_predict.py主要代码介绍如下图35。图35 kws_predict.py主要代码介绍●kws_predict.py运用训练模型对指定的音频文件进行预测。●输入python kws_predict.py命令运行kws_predict.py文件如图36、图37。图36 kws_predict.py文件开始运行图37 kws_predict.py文件运行过程●基于CTC算法的语音热词唤醒预测结果,如图38、图39所示。图38是从音频文件预测“北京”热词的结果;图39是从含噪音的音频文件预测“北京”热词的结果。图38 推理结果1图39 推理结果2五、推广MindStudio提供图形化开发界面,支持应用开发、调试和模型转换功能,同时还支持网络移植、优化和分析等功能,功能强大。文档以图文说明用MindStudio IDE分析基于CTC算法的语音热词唤醒的训练、精度评估、推理的过程。六、从昇腾社区获取更多帮助开发者在使用 MindStudio 或进行算子开发过程中遇到任何问题,都可以来昇腾社区获得更多的帮助。昇腾官网:昇腾社区-官网丨昇腾万里 让智能无所不及 (hiascend.com)昇腾社区:昇腾众智计划-昇腾社区 (hiascend.com)昇腾论坛:昇腾论坛 (hiascend.com)
  • [经验分享] 行李箱安检边缘套件开发经验分享
    bilibili视频链接:【行李箱安检识别】 https://www.bilibili.com/video/BV12A41197HJ/?share_source=copy_web&vd_source=c70245f8912fa536541e7d4ea81c352f1.MindStudio介绍MindStudio是一套基于华为自研昇腾AI处理器开发的AI全栈开发工具平台,该IDE上功能很多,涵盖面广,可以进行包括网络模型训练、移植、应用开发、推理运行及自定义算子开发等多种任务。MindStudio除了具有工程管理、编译、调试、运行等一般功能外,还能进行性能分析,算子比对,可以有效提高工作人员的开发效率。除此之外,MindStudio具有远端环境,运行任务在远端实现,对于近端的个人设备的要求不高,用户交互体验很好,可以让我们随时随地进行使用。2.案例模型本项目目的是利用MindStudio开发基于Pytorch的训练模型和基于MindX SDK的推理项目。项目对x光安检图象进行推理,利用目标检测框架,对警棍、老虎钳、榔头、充电宝、剪刀、扳手、枪支、子弹、喷罐、手铐、小刀、打火机以上目标进行检测,将检测得到的不同类的目标用不同颜色的矩形框标记。支持硬件平台:本项目以昇腾Atlas310卡、Atlas 200DK为主要的硬件推理平台。3.环境搭建3.1远端环境搭建在服务器Linux端(aarch64架构):1)下载好 MindX SDK mxvision 2.0.4 下载参考链接。在远端任意用户文件夹下,将Ascend-mindxsdk-mxvision_2.0.4_linux-aarch64.run文件上传chmod +x Ascend-mindxsdk-mxvision_2.0.4_linux-aarch64.run ./Ascend-mindxsdk-mxvision_3.0.RC2_linux-x86_64.run --install安装完成后,使环境变量生效:export DDK_PATH=$HOME/Ascend/ascend-toolkit/latestexport NPU_HOST_LIB=$DDK_PATH/acllib/lib64/stubsource ~/Ascend/ascend-toolkit/set_env.shcd ~/software/mxVision/./set_env.sh下载好CANN 5.0.4,下载参考链接。同样在任意用户文件夹下,上传Ascend-cann-toolkit_5.1.RC2.2_linux-aarch64.runchmod +x Ascend-cann-toolkit_5.1.RC2.2_linux-aarch64.run./Ascend-cann-toolkit_5.1.RC2.2_linux-aarch64.run --install显示如下则CANN 5.0.4安装完成。安装完成后,可以创建一个env.txt 文件将文档中红框路径保存以下。3.2 本地(windows端)环境搭建1)windows版本MindStudio。按照官方步骤进安装,同时安装相应依赖。2)安装任意版本的Anoconda。3)按照官方教程进行vpn连接。进入众智实验室容器IP。4)同步CANN。打开MindStudio,在File中选择File > Settings > Appearance & Behavior > System Settings > CANN点击change CANN进入下图界面,选择远端CANN安装的位置配置好后返回上一界面显示如图。5)在File > Settings > Appearance & Behavior > System Settings > MindX SDK,进入MindX SDK管理页面,点击Install进入远程配置界面。在Remote Connection一栏点击加号,配置远程连接,输入申请的账号密码等相关信息。在Remote CANN Location 一栏选择远端安装CANN Toolkits的路径,具体到版本,这里选择的是5.0.4版本。在Remote SDK Location 一栏选择远端安装MindX SDK的路径,这里选择的是Mxvision 2.0.4 版本。Local SDK location为本地默认的SDK安装位置,会将远端的SDK同步过来。点击ok后开始同步。配置完成后,界面如下图所示。4.Pytorch yolox模型训练流程点击File >New >Project 创建一个空训练工程。选择Pytorch项目。创建好工程后将YOLOX训练代码git 到本地。git clone cid:link_5注:由于网络问题,github上的代码经常可能克隆失败,可以直接去原网页下载好代码解压到目录中。下载好的文件目录如图所示。接下来在终端使用conda命令为此工程配置一个虚拟环境。需要的版本python=3.9conda create -n YOLOX_pt python=3.9执行后命令行如图:按y生成环境。之后安装工程所要求的包。pip install -r requirements.txt显示安装成功,这里如果显示安装onnx失败,将requirements中的onnx版本删除,再次运行安装命令即可。此处onnx版本不影响训练。我们还需要安装gpu版本的pytorch才能进行训练,执行下面命令conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch安装完毕后conda list #查看当前已安装包将数据集下载后解压到本地。开始配置exp文件。使用yolox-m模型标准进行训练。在项目的exps> default中找到yolox-m默认配置文件,对文件中路径、参数进行修改。 配置好之后将tools > train.py文件拷贝到文件根目录下,运行python train.py -f ./exps/default/yolox_m.py -d 0 -b 2 --fp16 -o其中标蓝为你的exp文件位置如下界面表示开始训练。最终训练文件会保存在YOLOX_outputs >yolo-m中Train_log会记录训练时的全部信息。我们可以得到best_cpkt.pth权重文件。再将pth文件转换成为onnx权重文件,便于后续离线模型转换。python export_onnx.py --output-name yoloxray1.onnx -n yolox-m -c D:/project/YOLOX2/YOLOX_outputs/yolox_m/best_ckpt.pth5.模型推理App开发流程1)创建工程接下来进行app边缘开发任务,需先创建一个推理工程,点击File >New >Project,选择Ascend APP工程之后建立一个MindX SDK for Python空工程。2)选择编译器点击File >Project structure为项目配置远端python编译器。在SDK一栏点击下拉菜单,点击Add Python SDK进入选择编译器页面,选择SSH,在Interpreter一栏选择一个远端python路径。选择好后分别点击左边Project、Modules、SDKs,可以看到刚才添加的编译器。点击Apply应用配置。环境配置完成,接下来就可以在本地进行开发工作了。3)创建项目目录本次工程目录结构如下图所示在python目录下Main目录放置程序的主要函数test目录,放置测试数据相关内容(测试数据的名称label文件)test_img目录,放置测试图片pipeline目录,放置pipeline文件在config目录下放置各种参数设置文件,包括流的推理日志参数文件sdk.conf、logging.conf。在postprocess目录下放置现成的yolox后处理插件的代码接下来将目录先上传到远端。进入Files >settings界面,选择左方的tools下的Deployment界面在Mappings下选择项目的远端同步路径在Excluded Paths下,点击左下角加号减号,还可以删改不进行同步的文件,我们可以排除掉模型文件等较大文件,这样可以加快流程开发速度。我们排除掉除了项目中Python/Main路径下的主函数文件外,其余所有的文件路径,可以减少文件上传和下载的时间。之后右键文件根目录,点击Deployment >Upload to将项目整体同步一次到远端。4)onnx 模型转换成 om离线模型1. 预处理参数设置利用官方提供的aipp转换方式对模型转换参数进行设置。这里介绍一下aipp预处理方法,AIPP(Artificial Intelligence Pre-Processing)人工智能预处理,用于在AI Core上完成图像预处理,包括改变图像尺寸、色域转换(转换图像格式)、减均值/乘系数(改变图像像素),数据处理之后再进行真正的模型推理。该模块功能与DVPP相似,都是用于图像数据预处理,但与DVPP相比,由于DVPP各组件基于处理速度和处理占有量的考虑,对输入、输出有特殊的限制,如对输出图片的宽高有对齐要求,且其输出格式通常为YUV420SP等格式。这样的设定虽在视频分析的场景下有非常广阔的输入,但深度学习模型的输入通常为RGB或BGR,且输入图片尺寸各异,因此ATC工具流程中提供了AIPP功能模块。创建一个空cfg文件。根据官方的文档说明设置参数。原模型图片格式为YUV420SP_U8,转换成BGR格式模型,详细参数需按照以下设置。选择静态aipp。所有参数如图编写成的yolox_bgr.cfg,放于根目录的config文件夹下。可视化模型转换将第四节训练好的onnx模型上传到远端服务器上,点击Ascend >Model convert进入模型转换界面,选择服务器上的onnx模型。Output Path选择本地任意位置。Type为UINT8。之后点击next附:点击模型右边的眼睛按钮还可以可视化的查看模型选择aipp参数文件选择图片格式为BGR之后点击next。环境变量在之前已经设置好了,所以这里不配置也可以转换成功。点击finish,等待模型开始转换,最终结果如下,表示模型转换成功。如果转换失败,则需要手动添加以下环境变量 insall_path=/usr/local/Ascend/ascend-toolkit/latestLD_LIBRARY_PATH=${install_path}/atc/lib64:${install_path}/acllib/lib64:$LD_LIBRARY_PATHASCEND_OPP_PATH=${install_path}/oppASCEND_AICPU_PATH=/usr/local/Ascend/ascend-toolkit/latest/然后再次进行转换最后,将生成好的om模型文件上传到远端Python/models路径下。5)后处理的标签文件、后处理插件配置。标签文件coco.names 生成创建一个coco.names文件,将标签内容填入保存。放在Python/models路径下,上传至远端。配置后处理参数文件yolox_eval.cfg。以下为各参数介绍,可以根据模型需要来选择。CLASS_NUM类别数量。80OBJECTNESS_THRESH是否为目标的阈值,大于阈值即认为是目标。0.3IOU_THRESH两个框的IOU阈值,超过阈值即认为同一个框。0.45以yolox_eval.cfg保存,放在configs路径下,上传至远端。3.后处理插件(.so文件)生成点击Tools >Start SSH,进入远端的终端cd 到postprocess目录下,执行bash build.sh会在远端当前路径下,生成yolox后处理插件。注:在这里注意如果编译失败,需要在终端通过export重新配置编译环境,包括MindX SDK路径和CANN路径。6)pipeline编排此次插件处理流程如下点击Ascend > MindX SDK pipeline进入可视化设计界面。根据流程编排插件在左边search界面搜索需要的插件拖动插件名称到右方,生成一个插件。按照此方法依次将需要的插件拖动至右方。点击每个插件右边的小点,将插件顺次连接。如果觉得排列不整齐,可以点击Format按钮让他们变整齐>> 最终所有插件依次连接效果如下。点击每个插件,可以在右方设置好每个插件的的参数。具体每个插件的功能和参数说明在官方文档中。decoder的参数。resizer的参数。在tensorinfer中选择刚才转换好的推理模型路径。在postprocessor插件中配置好远端cfg、names、so文件路径参数点击save之后会生成一个new.pipeline文件,我们将文件放于Python/pipeline中。将pipeline文件命名为pre_post.pipeline,上传至远端。7)main函数编写首先创建流:若创建失败则退出。运用StreamManagerApi 读取pipeline。载入图片,进行推理,获得带有框的图片输出。获得框向量和物体名称以及置信度,进行画框,并将结果写入test_img文件,保存名称为pre_post_bgr.jpg最后不要忘了销毁流至此主函数编写完毕,命名为pre_post.py,放到python/Main目录下。6.编译执行在主界面点击图示Edit configurations配置运行参数。Executable :选择需要执行的Main函数文件Command Arguments:如果在运行时有arg参数可以进行配置,本项目主函数中参数已经设置好了所以不用配置。Environment variables:一栏配置远端的环境变量,请确保配置好以下路径:SDK-path: mxVision SDK 安装路径ascend-toolkit-path: CANN 安装路径点击apply然后关闭界面。配置好后点击旁边的三角键,我们的主函数就可以传输到远端进行编译了。编译成功,等待远端output文件夹传输至本地后,在目录下查看结果。7.性能验证1.下载验证数据集将数据集上传到远端,进行性能验证。小提示:建议将工程文件的数据集和模型文件之类大型文件都排除在同步列表之外。2.运行路径``python/test``下的文件 parse_coco.py 参数:--json_file=data/annotations/instances_test2017.json--img_path=data/test2017注:这里路径最好换成你上传的数据集所在的绝对路径 若运行成功,会在该目录下生成文件夹ground_truth,其中包含每张图像上提取的目标框真实位置与类别的txt文件。3.接下来将每张图的预测结果转为txt文件,并保存在同一文件夹下,其步骤如下:打开MindX SDK安装路径下的日志配置文件vim ${MX_SDK_HOME}/config/sdk.conf之后修改参数 enable_ps=true,开启日志记录,之后pipeline运行时会在指定文件夹生成运行日志。修改完毕后,运行该路径下文件python/Main/python3 eval_nopre_post.py 若运行成功,会在``python/test`` 路径下生成 test_nopre_post 文件夹,该目录下包含有每张图像上的检测结果的 txt 文件。同时会得到fps为32 > 20,满足性能要求运行命令: python/test/python3 map_calculate.py 参数:--npu_txt_path="./test_nopre_post" 得到以上结果,使用MindX SDK环境推理精度为47.43%,与原模型精度一致。8.FAQ1)ModuleNotFoundError:No module named XXX大多是因为在运行程序前未配置好路径,请检查CANNToolKits和MindX SDK路径配置问题。配置远端CANNToolsKits包时提示permission denied建议非root权限用户选择非usr/local路径下的CannTooKits包进行配置,否则会出现权限不够的问题。模型转换时无法使用前处理问题按照提示,模型的输入必须满足type为utf8的格式,之后才可以进行模型转换。详情可以参照官方模型参数说明。色域转换配置说明 - CANN 5.0.4 ATC工具使用指南 01 - 华为 (huawei.com)9.从昇腾论坛获得更多支持如上述步骤中在在实践中仍然遇到其他问题,包括om模型参数设置问题,调用streamMannagerApi时的问题,都可以在论坛中提出自己的问题或者查找相关问题,我的很多问题都是在这里解决的。也非常推荐大家一期建设这个论坛。昇腾社区-官网丨昇腾万里 让智能无所不及 (hiascend.com)
  • [经验分享] Yolact边缘套件开发经验分享
    bilibili视频链接:【YOLACT边缘套件开发经验分享】 https://www.bilibili.com/video/BV18R4y1k7kY/?share_source=copy_web&vd_source=c70245f8912fa536541e7d4ea81c352f1.MindStudio介绍MindStudio是一套基于华为自研昇腾AI处理器开发的AI全栈开发工具平台,该IDE上功能很多,涵盖面广,可以进行包括网络模型训练、移植、应用开发、推理运行及自定义算子开发等多种任务。MindStudio除了具有工程管理、编译、调试、运行等一般普通功能外,还能进行性能分析,算子比对,可以有效提高工作人员的开发效率。除此之外,MindStudio具有远端环境,运行任务在远端实现,对于近端的个人设备的要求不高,用户交互体验很好,可以让我们随时随地进行使用。2.模型介绍YOLACT是2019年发表在ICCV上面的一个实时实例分割的模型,它主要是通过两个并行的子网络来实现实例分割的。(1)Prediction Head分支生成各个anchor的类别置信度、位置回归参数以及mask的掩码系数;(2)Protonet分支生成一组原型mask。然后将原型mask和mask的掩码系数相乘,从而得到图片中每一个目标物体的mask。论文中还提出了一个新的NMS算法叫Fast-NMS,和传统的NMS算法相比只有轻微的精度损失,但是却大大提升了分割的速度。3.环境搭建3.1开发环境安装 Windows版本MindStudio。按照官方安装步骤进行Windows平台MindStudio环境配置。[参考链接](cid:link_4)在下载界面中选择软件包下载,根据系统和习惯选择相应包进行下载。如果下载的.exe文件,下载后进行安装。3.2远端环境配置3.2.1 安装CANNCANN(Compute Architecture for Neural Networks)是华为公司针对AI场景推出的异构计算架构,通过提供多层次的编程接口,支持用户快速构建基于昇腾平台的AI应用和业务。首先下载CANN安装包,选择并下载平台开发套件软件包。[参考链接](cid:link_6)下载完成后按照如下步骤进行安装,详细说明参考昇腾社区。[参考链接](cid:link_2)以软件包的安装用户登录安装环境。若安装依赖中安装依赖的用户为root用户,则软件包的安装用户可自行指定;若安装依赖中安装依赖的用户为非root用户,请确保软件包的安装用户与该用户保持一致。将获取到的开发套件包上传到安装环境任意路径(如“/home/package”)。进入软件包所在路径。增加对软件包的可执行权限。chmod +x 软件包名.run软件包名.run表示开发套件包Ascend-cann-toolkit_{version}_linux-{arch}.run,请根据实际包名进行替换。执行如下命令校验软件包安装文件的一致性和完整性。./软件包名.run --check执行以下命令安装软件(以下命令支持--install-path=等参数,具体参数说明请参见参数说明)。./软件包名.run –installCANN软件提供进程级环境变量设置脚本,供用户在进程中引用,以自动完成环境变量设置。用户进程结束后自动失效。示例如下(以root用户默认安装路径为例):. /usr/local/Ascend/ascend-toolkit/set_env.sh 用户也可以通过修改~/.bashrc文件方式设置永久环境变量,操作如下:以运行用户在任意目录下执行vi ~/.bashrc命令,打开.bashrc文件,在文件最后一行后面添加上述内容。执行:wq!命令保存文件并退出。执行source ~/.bashrc命令使其立即生效。3.3创建项目3.3.1新建项目点击New Project。选择Ascend App,配置好项目名称,如果没有同步CANN,请点击Change按钮。第一次使用需要配置远端服务器,点击+号进行配置。输入远程服务器信息,测试连接成功后点击OK。回到Remote CANN Setting界面,在Remote CANN location行右边选择CANN位置。选择CANN所在位置选择后点击finish等待同步文件同步完成后点击Next,继续创建工程选择MindX SDK project(Python),然后点击finish。3.3.2配置Deployment点击Tools->Deployment,选择Configuration。可以在Deployment中点击+号,输入名字添加。然后再Connection中点击SSH configuration右边的…,添加服务器。完成后可以在Connection中看到已经成功添加服务器,并可以通过Test Connection测试连接是否成功。点击Mappings,在Deployment Path下方的路径选择,选择远程代码路径。右侧Excluded Path可以选择不拉取的文件,比如不需要把数据集拉取到本地,就选择Mappings路径中的无需拉取的文件。右击Project,选择Deployment,选择Download from,选择刚才所设置的源,等待代码拉取。3.3.3配置远端解释器点击File->Project Structrue ->SDK 配置python SDK。点击加号添加Python SDK。选择SSH Interpreter,选择deployment,Interpreter和Name会自动填充,如果需要自定远端Python版本,则点击Interpreter后面的按钮(如下图所示),打开远端目录,选择需要的Python点击Project,如图所示,选择刚刚配置好的远端SDK,点击OK使配置生效。3.3.4配置MindX SDK打开MindStudio,在File中选择File > Settings > Appearance & Behavior > System Settings > MindX SDK,进入MindX SDK管理页面,点击Install进入远程配置界面。在配置前,请确保远端环境已经配置好MindX SDK和CANN Toolkits。在Remote Connection一栏配置远程连接,输入申请的账号密码等相关信息。在Remote CANN Location 一栏选择远端安装CANN Toolkits的路径,具体到版本,这里选择的是5.0.4版本。在Remote SDK Location 一栏选择远端安装MindSDK的路径,这里选择的时Mxvision 2.0.4 版本。Local SDK location为本地默认的xSDK安装位置,会将远端的SDK同步过来。点击ok后开始同步,配置完成后,如果界面如下图所示,则表示成功。4. 本地Git clone代码点击最下方的Terminal,打开本地终端。可以看到左下角已经打开本地终端。复制Github代码链接:cid:link_5, 在本地终端输入git clone cid:link_5并运行。5. 项目开发5.1onnx转om离线模型转换我使用的是Pytorch模型,他的权重是一个pth文件,而Mind SDK里面支持的是om模型,所以我们需要进行一个转换。首先我们要把我们的pth文件转换成onnx文件,然后再转换成om模型。5.2.1 pth转换成onnxpth转换成onnx模型首先就是要加载权重,然后用权重来初始化自己的模型,随后调用torch自带的转onnx函数就可以完成模型的转换。代码仓库链接如下:cid:link_5pth模型我们直接下载,链接如下:cid:link_3在om转onnx时,需要将predict.py中21行代码改为mode = "export_onnx",然后运行python3 predict.py就可以得到onnx模型。5.2.2 onnx转om模型选择Ascend->Model Converter在Model File中选择需要转换的onnx模型路径,选择后会自动分析模型,分析后得到如下。这里软件自动解析模型,将模型的输入形状填写到了Shape下,在Type下也自动填写了精度类型。具体ACT模型转换时所有可以用到的参数,可以在此链接中详细查询https://www.hiascend.com/document/detail/zh/mindstudio/50RC3/msug/msug_000394.html。点击Select选择输出结点。找到模型的所有输出节点,右击后选择select选择所有输出结点后点击OK,返回界面后点击Next由于本模型中未使用AIPP,继续点击Next。这一步无需修改,点击Finish。可以看到ATC工具开始运行转换模型。模型转换成功后得到如下输出5.2pipeline编写 绘制整个流程的流程图,画出流程图如下。图像读取步骤中我选择使用cv2完成。据流程图编写完整的pipeline,创建yolact.pipline文件,打开后进行插件编排。首先选择输入插件,我选择使用appsrc插件,将其拖出来。之后使用推理插件mxpi_tensorinfer0,两者之间拖动连线连接起来。点击mxpi_tensorinfer0插件,在modelPath中选择推理使用的om模型路径,如何转换得到om模型会在下文讲到。以此类推,完成所有插件编排后结果如下。点击Text,可以看到想要插件流程的代码。5.3main函数编写创建流:若创建失败则退出。运用StreamManagerApi 读取pipeline。载入图片,进行推理。对推理结果进行后处理。推理结果保存并计算精度至此主函数编写完毕,命名为main.py,放到主目录下。 6. 运行推理放入一张生活场景的图片,点击Run下的Edit ConfigurationDeployment选择我们所在服务器,Executable选择执行文件,即main.py,Command Arguments中可以输入我们想要输入的参数。比如我们在执行图像可视化时,就输入—image=”street.jpg”。点击OK完成设置,然后点击工具类的三角形图标,开始运行。可以看到文件夹中已经生成了img.jpg输出结果。可视化结果图像如下。7. 精度测评基于coco数据集进行精度测评,coco数据集放置目录结构如下。├── data│ ├── coco_test│ │ ├── annotations │ │ ├── images ├── convert│ └── -----├── model_data │ └── -----├── utils │ └── -----├── images │ └── -----├── main.py ├── README.md 执行精度评估,同理在Run下的Edit Configuration中配置运行设置。配置如下,设置main.py为执行文件,不需要添加任何参数。点击OK完成配置并点击运行。运行精度结果如下得到精度结果如下:精度指标精度bbox mAP 0.5:0.9530.4%bbox mAP 0.552.0%segm mAP 0.5:0.9527.3%segm mAP 0.547.7%对比原代码仓库的精度如下:可见精度结果对比完全一致。
  • [MindX SDK] 波比跳运动小程序
    波比跳运动小程序1 介绍波比跳运动小程序基于 MindX SDK 开发,在 Ascend 310 芯片上进行目标检测,将检测结果保存成视频。项目主要流程:1)视频流程:通过 live555 服务器进行拉流输入视频,然后进行视频解码将 H.264 格式的视频解码为图片,图片缩放后经过模型推理进行波比跳检测,识别结果经过后处理后利用 cv 可视化识别框,以视频的形式输出,同时生成文本文件记录视频中完成的波比跳个数。2)小程序流程:通过微信小程序开发者将摄像头截取的图片数据上传至腾讯云桶中,然后后端将桶中数据下载至本地并将数据输入至流水线内,接着进行图片解码和缩放,最后经过模型推理进行波比跳检测,识别结果经过后处理后上传至腾讯云桶中,为前端小程序使用。1.1 支持的产品昇腾 310(推理)1.2 支持的版本本样例配套的 CANN 版本为 5.1.RC1,MindX SDK 版本为 3.0.RC3。MindX SDK 安装前准备可参考《用户指南》,安装教程1.3 软件方案介绍基于 MindX SDK 的波比跳运动小程序业务流程为:通过微信小程序开发者将摄像头截取的图片数据上传至腾讯云桶中,然后后端将桶中数据下载至本地并经mxpi_appsrc拉流插件输入,然后使用图片解码插件mxpi_imagedecoder将图片解码,再通过图像缩放插件mxpi_imageresize将图像缩放至满足检测模型要求的输入图像大小要求,缩放后的图像输入模型推理插件mxpi_modelinfer得到检测结果,根据检测结果改变波比跳识别的状态机状态,并更新波比跳识别个数,最后上传记录波比跳识别个数的txt文件到腾讯云桶中,以供小程序使用。1.4 代码目录结构与说明本 Sample 工程名称为 Burpee_Detection,工程目录如下图所示:├── envs │   └── env.sh     //基础环境变量与atc转换需要的环境变量 ├── readme_img         //ReadMe图片资源 │   ├── app_1.jpg   │   ├── app_2.jpg   │   ├── app_3.jpg   │   ├── app_4.jpg   │   ├── app_5.jpg   │   ├── dataset.jpg   │   ├── video.jpg   │   ├── app_flow.jpg   │   ├── video_flow.jpg │   ├── dark.jpg ├── model │   ├── atc.sh                   //atc运行脚本 ├── pipeline │   ├── burpee_detection_p.pipeline//图片识别使用的pipeline文件 │   └── burpee_detection_v.pipeline//视频识别使用的pipeline文件 ├── App_burpee_detection │   ├── app_main.py           //识别,保存结果,并进行性能测试 │   └── run.sh                 //运行脚本 ├── Pic_burpee_detection │   ├── map_calculate.py     //mAP计算(精度计算) │   ├── pic_main.py           //识别,保存结果,并进行性能测试 │   └── run.sh                 //运行脚本 ├── Video_burpee_detection │   ├── video_main.py         //识别,保存结果,并进行性能测试 │   └── run.sh                 //运行脚本 └── README.md本项目的代码地址为:cid:link_61.5 技术实现流程图视频流程:小程序应用后端流程:1.6 特性及使用场景举例该应用特色在于mindsdk与小程序的结合,其并不局限于波比跳的计数,该应用模式仍适用于其他实时图像识别类小程序功能的开发。 对于画面内单人,且光线正常的情况下小程序都能正常且精准的计数。在精度和性能上,该应用实现流程都超过了要求水平,但仍有一些场景,情况不适用:· 光线极暗的情况下,由于前端获取的数据的清晰度较低且mindsdk中图片解码插件只适用jpg,精度会大幅下降 · mindsdk只存在rtsp拉流的插件,如若推流以视频形式在小程序与后端之间传输,需自行编写新的推流插件 · 当画面人物为正对摄像头做波比跳时,会出现检测不到动作的情况,用户应侧对摄像头。正对很难判断动作是否标准。2 环境依赖软件名称版本说明获取方式MindX SDK3.0.RC3mxVision软件包链接ubuntu18.04.1 LTS操作系统Ubuntu官网获取Ascend-CANN-toolkit5.1.RC1Ascend-cann-toolkit开发套件包链接live5551.09实现视频转 rtsp 进行推流链接ffmpeg2021-10-14实现 mp4 格式视频转为 H.264 格式视频链接微信开发者工具1.06.2207210实现小程序的使用链接小程序导入代码-微信小程序代码链接腾讯桶内文件夹格式-压缩包解压后文件夹内文件形式即为桶内文件形式链接对象储存 python sdk-小程序相关python sdk快速入门链接模型文件-pt 模型文件,onnx 模型文件,om 模型文件,names文件,模型配置文件链接在运行项目需要的环境变量如下,运行前不需要特别设置,环境依赖已经写入脚本中,脚本在Burpee_Detection/envs目录下:export MX_SDK_path=""# mxVision 安装路径 export Ascend_toolkit_path=""#CANN 安装路径 ​ # MindXSDK 环境变量: . /${MX_SDK_path}/set_env.sh ​ # CANN 环境变量: . /${Ascend_toolkit_path}/set_env.sh注:其中${MX_SDK_path}替换为用户的SDK安装路径;Ascend_toolkit_path替换为ascend-toolkit开发套件包所在路径。3 模型转换以及依赖安装本项目使用的模型是波比跳识别的模型。模型文件可以直接下载。(下载链接在第二小节)3.1 模型转换使用模型转换工具 ATC 将 onnx 模型转换为 om 模型,模型转换工具相关介绍参考链接:CANN 社区版 。步骤如下:步骤1 下载onnx模型,请移动至Burpee_Detection/model目录下;若下载om模型文件,请跳过模型转换步骤。(下载链接在第二小节)步骤2 将best.onnx文件移动至Burpee_Detection/model目录下,然后运行model目录下的atc.shbash /model/atc.sh执行该命令后会在当前文件夹下生成项目需要的模型文件ATC start working now, please wait for a moment. ATC run success, welcome to the next use.表示命令执行成功。3.2 准备按照第3小节软件依赖安装 live555 和 ffmpeg,按照 Live555离线视频转RTSP说明文档将 mp4 视频转换为 H.264 格式。并将生成的 H.264 格式的视频上传到live/mediaServer目录下,然后修改pipeline目录下的burpee_detection_v.pipeline文件中mxpi_rtspsrc0的内容。"mxpi_rtspsrc0":{ "props": { "rtspUrl":"rtsp://xxx.xxx.xxx.xxx:xxxx/xxx.264",  // 修改为自己所使用的的服务器和文件名 },    "factory": "mxpi_rtspsrc", "next": "mxpi_videodecoder0" }4 运行与测试4.1 运行4.1.1 视频步骤1 按照第 2 小节 环境依赖 中的步骤设置环境变量。步骤2 按照第 3 小节 模型转换 中的步骤获得 om 模型文件,放置在 Burpee_Detection/models 目录下。步骤3 修改burpee_detection_v.pipeline中mxpi_modelinfer0中postProcessLibPath的值${MX_SDK_path}为 MindX SDK 的安装路径步骤4 按照 3 小节 准备 中的步骤创建rtsp流以实现本地视频的rtsp拉流操作。步骤5 运行。在 Burpee_Detection/Video_burpee_detection 目录下执行命令:bash run.sh运行可视化结果会以video_result.mp4视频形式保存在Burpee_Detection/Video_burpee_detection目录下 波比跳识别个数会以result.txt文件形式保存在Burpee_Detection/Video_burpee_detection目录下4.1.2 小程序步骤1 按照第 4 小节 视频 中的步骤1到步骤3搭建小程序后端环境。步骤2 运行。在 Burpee_Detection/App_burpee_detection 目录下执行命令:bash run.sh步骤3 创建obs桶内文件夹和文件,如下所示├── input   //存放小程序获取数据 ├── result //存放后端处理的数据输出结果 ├── state   //用于判断小程序状态(前端改写,后端查看) ├── state.txt //前端放入state文件夹的文件 ├── result.txt//存放后端处理的计数值步骤4 下载微信开发者工具并登录,在微信公众平台注册小程序并获取AppID步骤5 点击导入,选择小程序代码文件夹并打开(代码可下载,下载链接在第二小节),点击编译模式选中pages目录下的子目录bind并选择bind,点击详情-本地设置,选中不效验合法域名后(可在小程序公众平台开发管理-开发设置中,配置合法域名),点击真机调试,然后用手机扫描二维码步骤6 进入微信小程序页面,点击开始计数,小程序将摄像头以40ms(fps=25)的速率拍摄照片,并上传至腾讯云桶内,后台接收图片并处理步骤7 人物在摄像头前进行波比跳,后台实时更新波比跳个数并将结果发送至桶内,小程序端以0.1s的速率刷新页面展示的个数步骤8 点击结束,小程序停止发送图像并清理上传至桶内的图片释放内存,后端等待小程序下次开始计数4.2 性能与精度测试步骤1 准备测试数据集(数据集内应有数据以及对应的标签,格式为yolo),并将data文件夹放在Burpee_Detection目录下步骤2 打开Burpee_Detection/Pic_burpee_detection目录下pic_burpee_detection.py文件,将变量 INPUT_PATH ,OUTPUT_PATH ,OUTPUT_PIC_PATH分别初始化为 ["../data/images/test/"],[".././Pic_burpee_detection/result_test/"],[".././Pic_burpee_detection/result_test_pic/"]步骤3 在Burpee_Detection/Pic_burpee_detection目录下运行run.sh脚本,对data/images/test目录下的图片进行识别并输出结果bash run.sh运行脚本后会生成经过 SDK 后的推理结果结果保留在result_test目录下以.txt格式保存。 结果可视化效果保留在result_test_pic目录下以.jpg格式保存运行结果中会有Spend time:是识别所有图片所用的时间,fps:计算得到的帧数Image count:237 Spend time:5.785876989364624 fps:40.961811050536376步骤4 在Burpee_Detection/Pic_burpee_detection目录下运行map_calculate.py脚本,计算精度。python3.9.2 map_calculate.py测试结果98.67% = crouch AP 84.93% = jump AP 94.91% = support AP m_ap = 92.83%4.3 特殊情况测试数据为光线较暗时(无光源的情况下)图片测试结果:No objects detected!!!当测试无目标时会有对应报错
  • [经验分享] 使用MindStudio的HPO界面工具进行调优
    一、MindStudio介绍1.1基本介绍MindStudio为用户提供在AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务。通过依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够帮助用户在一个工具上就能高效便捷地完成AI应用开发。另一方面,MindStudio采用插件化扩展机制,以支持开发者通过开发插件来扩展已有功能。在本案例中所使用的MindStudio版本为5.0.RC1,具体安装流程可参考MindStudio安装教程(https://www.hiascend.com/document/detail/zh/mindstudio/50RC3/instg/instg_000002.html)。具体的,MindStudio的功能包括:针对安装与部署,MindStudio提供多种部署方式,支持多种主流操作系统,为开发者提供最大便利。针对网络模型的开发,MindStudio支持TensorFlow、Pytorch、MindSpore框架的模型训练,支持多种主流框架的模型转换。集成了训练可视化、脚本转换、模型转换、精度比对等工具,提升了网络模型移植、分析和优化的效率。针对算子开发,MindStudio提供包含UT测试、ST测试、TIK算子调试等的全套算子开发流程。支持TensorFlow、PyTorch、MindSpore等多种主流框架的TBE和AI CPU自定义算子开发。针对应用开发,MindStudio集成了Profiling性能调优、编译器、MindX SDK的应用开发、可视化pipeline业务流编排等工具,为开发者提供了图形化的集成开发环境,通过MindStudio可以进行工程管理、编译、调试、性能分析等全流程开发,可以很大程度提高开发效率。MindStudio功能框架如图1所示,目前含有的工具链包括:模型转换工具、模型训练工具、自定义算子开发工具、应用开发工具、工程管理工具、编译工具、流程编排工具、精度比对工具、日志管理工具、性能分析工具、设备管理工具等多种工具。图11.2 MindStudio工具中的主要功能特性:工程管理:为开发人员提供创建工程、打开工程、关闭工程、删除工程、新增工程文件目录和属性设置等功能。SSH管理:为开发人员提供新增SSH连接、删除SSH连接、修改SSH连接、加密SSH密码和修改SSH密码保存方式等功能。应用开发:针对业务流程开发人员,MindStudio工具提供基于AscendCL(Ascend Computing Language)和集成MindX SDK的应用开发编程方式,编程后的编译、运行、结果显示等一站式服务让流程开发更加智能化,可以让开发者快速上手。自定义算子开发:提供了基于TBE和AI CPU的算子编程开发的集成开发环境,让不同平台下的算子移植更加便捷,适配昇腾AI处理器的速度更快。离线模型转换:训练好的第三方网络模型可以直接通过离线模型工具导入并转换成离线模型,并可一键式自动生成模型接口,方便开发者基于模型接口进行编程,同时也提供了离线模型的可视化功能。日志管理:MindStudio为昇腾AI处理器提供了覆盖全系统的日志收集与日志分析解决方案,提升运行时算法问题的定位效率。提供了统一形式的跨平台日志可视化分析能力及运行时诊断能力,提升日志分析系统的易用性。性能分析:MindStudio以图形界面呈现方式,实现针对主机和设备上多节点、多模块异构体系的高效、易用、可灵活扩展的系统化性能分析,以及针对昇腾AI处理器的性能和功耗的同步分析,满足算法优化对系统性能分析的需求。设备管理:MindStudio提供设备管理工具,实现对连接到主机上的设备的管理功能。精度比对:可以用来比对自有模型算子的运算结果与Caffe、TensorFlow、ONNX标准算子的运算结果,以便用来确认神经网络运算误差发生的原因。开发工具包的安装与管理:为开发者提供基于昇腾AI处理器的相关算法开发套件包Ascend-cann-toolkit,旨在帮助开发者进行快速、高效的人工智能算法开发。开发者可以将开发套件包安装到MindStudio上,使用MindStudio进行快速开发。Ascend-cann-toolkit包含了基于昇腾AI处理器开发依赖的头文件和库文件、编译工具链、调优工具等。1.3.安装指南:使用MindStudio前,首先应确定其使用场景,包括纯开发场景和开发运行场景两种:纯开发场景(分部署形态):在非昇腾AI设备上安装MindStudio和Ascend-cann-toolkit开发套件包。可作为开发环境仅能用于代码开发、编译等不依赖于昇腾设备的开发活动(例如ATC模型转换、算子和推理应用程序的纯代码开发)。如果想运行应用程序或进行模型训练等,需要通过MindStudio远程连接功能连接已部署好运行环境所需软件包的昇腾AI设备。开发运行场景(共部署形态):在昇腾AI设备上安装MindStudio、Ascend-cann-toolkit开发套件包、npu-firmware安装包、npu-driver安装包和AI框架(进行模型训练时需要安装)。作为开发环境,开发人员可以进行普通的工程管理、代码编写、编译、模型转换等功能。同时可作为运行环境,运行应用程序或进行模型训练。其中,不管哪种场景,都需要安装MindStudio、Ascend-cann-toolkit开发套件包:MindStudio:提供图形化开发界面,支持应用开发、调试和模型转换功能,同时还支持网络移植、优化和分析等功能。Ascend-cann-toolkit:开发套件包。为开发者提供基于昇腾AI处理器的相关算法开发工具包,旨在帮助开发者进行快速、高效的模型、算子和应用的开发。开发套件包只能安装在Linux服务器上,开发者可以在安装开发套件包后,使用MindStudio开发工具进行快速开发部署。1.4安装方案:1.4.1安装方案——LinuxMindStudio和Ascend-cann-toolkit可以使用Linux服务器上原生桌面自带的终端gnome-terminal进行安装,也可以在Windows服务器上通过SSH登录到Linux服务器进行安装。因为MindStudio是一款GUI程序,所以在Windows服务器上通过SSH登录到Linux服务器进行安装时,需要使用集成了X server的SSH终端(比如MobaXterm,该工具版本需要为v20.2及以上)。纯开发场景(分部署形态):该场景下纯开发环境需要安装MindStudio和Ascend-cann-toolkit,如图2所示。昇腾AI设备上运行环境的安装操作请参见《CANN 软件安装指南》。图2开发运行场景(共部署形态):该场景下需要安装如图3所示软件包,其中驱动、固件、Ascend-cann-toolkit和AI框架包的安装操作请参见《CANN 软件安装指南》。图31.4.2安装方案——WindowsMindStudio可以单独安装在Windows上。在安装MindStudio前需要在Linux服务器上安装部署好Ascend-cann-toolkit开发套件包,之后在Windows上安装MindStudio,安装完成后通过配置远程连接的方式建立MindStudio所在的Windows服务器与Ascend-cann-toolkit开发套件包所在的Linux服务器的连接,实现全流程开发功能。纯开发场景(分部署形态):该场景下在Windows服务器上安装MindStudio,昇腾AI设备上的驱动、固件、Ascend-cann-toolkit和AI框架包的安装操作请参见《CANN 软件安装指南》。图4开发运行场景(共部署形态):该场景下在Windows服务器上安装MindStudio,在纯开发环境需要安装Ascend-cann-toolkit,两者建立连接后,形成了集成MindStudio的纯开发环境。昇腾AI设备上运行环境的安装部署操作请参见《CANN 软件安装指南》,此场景运行环境多为端侧、边侧设备如Atlas 500 智能小站和Atlas 200 DK 开发者套件等。图5Windows工控机场景:该场景下在Windows服务器上安装MindStudio、驱动、固件和Windows版nnrt,其中驱动、固件和Windows版nnrt需要参见《CANN Windows版用户指南》进行安装。纯开发环境需要安装Ascend-cann-toolkit,与MindStudio连接后基于两者开发的应用程序可在Windows服务器上运行。图61.5.安装流程:1.5.1安装流程——Linux图7 Linux环境下,MindStudio安装流程如图7所示。环境要求:MindStudio安装的环境要求如表1,可对照着判断是否满足条件。表1 MindStudio环境要求类别限制要求说明硬件内存:最小4GB,推荐8GB磁盘空间:最小6GB若Linux宿主机内存为4G,在MindStudio中进行模型转换时,建议Model文件大小不超过350M,如果超过此规格,操作系统可能会因为超过安全内存阈值而工作不稳定。若Linux宿主机配置升级,比如8G内存,则相应支持的操作对象规格按比例提升。例如,内存由4G升级到8G,则Model文件建议大小不超过700M。系统语言en_US.UTF-8当前仅支持系统语言为英文。请以任意用户使用locale命令在任意路径下查询编码格式,若系统返回“LANG=en_US.UTF-8”,则表示正确;否则,请以root用户使用“vim /etc/default/locale”命令修改“LANG=en_US.UTF-8”,重启(使用reboot命令)使之生效。系统要求操作系统可以通过ssh登录,同时打开ssh的X11Forwarding功能glibc版本应大于或等于2.27ssh服务的开启和X11Forwarding的配置请参见启动MindStudio时无法显示图形化界面。对于Docker环境,启动容器时需要映射ssh端口,如docker run -p {宿主机端口}:{容器内ssh端口} ...若系统glibc版本小于2.27,请参见启动MindStudio时报glibc版本太低问题处理。已验证支持的操作系统Ubuntu 18.04-x86_64Ubuntu 18.04-aarch64Ubuntu 20.04-x86_64Ubuntu 20.04-aarch64EulerOS 2.8-aarch64EulerOS 2.9-aarch64EulerOS 2.9-x86_64EulerOS 2.10-aarch64EulerOS 2.10-x86_64OpenEuler 20.03-x86_64OpenEuler 20.03-aarch64OpenEuler 22.03 LTS-x86_64OpenEuler 22.03 LTS-aarch64CentOS 7.6/8.2-x86_64CentOS 7.6/8.2-aarch64银河麒麟OS V10 SP1-aarch64中标麒麟OS 7.6-aarch64-准备软件包:软件安装前,请参考表2获取所需软件包和对应的数字签名文件。其中在软件数字签名验证方面,为了防止软件包在传递过程或存储期间被恶意篡改,下载软件包时需下载对应的数字签名文件用于完整性验证。在软件包下载之后,可以参考《OpenPGP签名验证指南》,对从网站下载的软件包进行PGP数字签名校验。如果校验失败,则不要直接使用该软件包,应先联系华为技术支持工程师解决。使用软件包安装/升级之前,也需要按上述过程先验证软件包的数字签名,确保软件包未被篡改过。表2 软件包软件包说明MindStudio_{version}_linux.tar.gzMindStudio软件包,含有GUI的集成开发环境。MindStudio安装包解压后包含以下文件:bin:MindStudio的执行目录及依赖的二进制文件build.txt:安装包构建信息classpath.txt:MindStudio运行时ClassPath加载顺序文件icons.db:MindStudio运行时SVG图标预编译数据库缓存文件Install-Linux-tar.txt:MindStudio安装说明jbr:64位系统的依赖库以及文件lib:Java依赖库license:所用的第三方依赖的许可证LICENSE.txt:Apache Licence说明文档NOTICE.txt:注意事项plugins:MindStudio所用到的基本插件及Java库product-info.json:MindStudio版本号以及执行文档路径redist:Java辅助注解tools:工具库Ascend-cann-toolkit_{version}_linux-{arch}.runAscend-cann-toolkit开发套件包,包含开发辅助工具和相关开发接口的开发套件包。如果环境上已安装Ascend-cann-toolkit开发套件包,则无需再次获取。准备安装用户:如果已安装Ascend-cann-toolkit开发套件包,请使用Ascend-cann-toolkit开发套件包的安装用户安装MindStudio。如果未安装Ascend-cann-toolkit开发套件包(可参考《CANN 软件安装指南》的“安装开发环境”章节),请执行如下操作:创建安装用户可使用root或非root用户进行安装。若使用root用户安装,可直接开始安装依赖。若使用已存在的非root用户安装,须保证该用户对$HOME目录具有读写以及可执行权限。若使用新的非root用户安装,则需要先创建该用户,请参见如下方法创建(请以root用户执行以下命令)。创建用户组和安装用户并设置该用户的$HOME目录。其中usergroup为用户组,username为用户名。groupadd usergroup    useradd -g usergroup -d /home/username -m username -s /bin/bash以HwHiAiUser组为例,可执行如下命令创建软件包安装用户并加入到HwHiAiUser组中。groupadd HwHiAiUseruseradd -g HwHiAiUser -d /home/username -m username -s /bin/bash执行以下命令设置非root用户密码。passwd username安装依赖:安装MindStudio和Ascend-cann-toolkit开发套件包前需要安装相关依赖。具体的依赖列表可参考官方文档。安装MindStudio:在完成了软件包至安装依赖,以及Ascend-cann-toolkit开发套件包的安装后,可以进行MindStudio的安装,其具体的安装步骤如下:使用MindStudio的安装用户上传软件包至待安装环境。解压MindStudio软件包:使用MindStudio的安装用户在软件包所在路径执行如下命令,解压MindStudio_{version}_linux.tar.gz软件包,tar -zxvf MindStudio_{version}_linux.tar.gz,解压后包的内容以及说明请参见表3。表3 参数说明参数说明Projects页签(工程管理)New Project创建新工程,创建后工程保存在“$HOME/AscendProjects”目录。Open打开已有工程。System Profiler进入System Profiling界面。Get from Version Control…用版本控制工具下载代码仓并打开。Customize页签(定制化个性设置)Color theme设置颜色主题。Accessibility设置辅助功能,包括设置IDE字体大小和针对红绿色视觉缺陷调整颜色。Keymap设置键盘映射,MindStudio会根据您的环境自动建议预定义的键盘映射,请确保它与您正在使用的操作系统匹配,或者手动选择与您习惯使用的另一个IDE或编辑器中的快捷方式匹配的操作系统。Import Settings…从自定义配置目录导入MindStudio个性化设置。All Settings…进入设置界面。Plugins页签(插件管理)Marketplace插件市场,可搜索并下载需要的插件。Installed查看已安装的插件。Learn MindStudio页签(MindStudio实用帮助)使用MindStudio的安装用户进入软件包解压后的MindStudio/bin目录并启动MindStudio。进入导入设置界面,如图8所示界面。图8如果没有报错信息且能正常进入欢迎界面,则表示MindStudio安装成功。图91.5.2安装流程——Windows将MindStudio安装在Windows服务器上时,Windows服务器为本地环境,Linux服务器为远端环境。MindStudio安装流程如图10所示。图10环境要求:本地环境要求:Windows 10 x86_64操作系统本地安装依赖:Python(版本要求:3.7~3.9),MinGW,Cmake,ACLlib(可选,Windows工控机场景开发Windows应用)配置远端环境:共部署形态远端昇腾AI设备:可参考《CANN 软件安装指南》部署好昇腾AI设备。分部署形态远端纯开发环境:可根据远端Linux服务器的具体系统版本,参见准备安装用户、安装依赖和配置编译环境章节配置MindStudio使用环境。请参考《CANN 软件安装指南》安装Ascend-cann-toolkit开发套件包。准备软件包:软件安装前,请参考表4获取所需软件包和对应的数字签名文件。表4 软件包软件包说明MindStudio_{version}_win.zipMindStudio免安装压缩包,含有GUI的集成开发环境。MindStudio_{version}_win.exeMindStudio安装包,含有GUI的集成开发环境。安装依赖:根据官方流程安装Python依赖,安装MinGW依赖,安装ACLlib包,安装Cmake。安装MindStudio:在完成上述步骤,即可进行MindStudio的安装。双击MindStudio_{version}_win.exe安装包,开始安装MindStudio。进入MindStudio Setup界面,单击“Next”,如图11所示。图11选择MindStudio的安装路径后,单击“Next”,如图12所示。图12用户根据需要勾选安装选项后,单击“Next”,如图13所示。图13选择或创建MindStudio安装路径下的启动菜单文件夹,单击“Install”,如图14所示。图14开始安装MindStudio,完成后单击“Next”,如图15所示。图15完成MindStudio安装配置,单击“Finish”,如图16所示。图16进入MindStudio安装目录的bin文件夹,双击MindStudio应用程序启动MindStudio,导入设置界面,如图17所示界面。图17如果没有报错信息且能正常进入欢迎界面,则表示MindStudio安装成功,如图18所示。图18二、超参数优化基本介绍在机器学习、深度学习中,有两类参数,一类需要从数据中学习和估计得到,称为模型参数(Parameter);另一类需要人为设定,称为超参数(Hyperparameter),例如学习率、正则化系数等。超参数优化,是指用自动化的算法来优化超参数,从而提升模型的精度、性能等指标。使用HPO能力,可以快速高效地在超参数空间中测试选择最佳的超参数组合,节省大量人力和时间。当前MindStudio提供的HPO能力支持Random、ASHA、BOHB、BOSS、PBT等HPO算法,适用于常见的深度神经网络的超参数优化,包括单目标优化和随机帕累托的多目标超参选择。三、超参数优化前期准备工作AutoML(Auto Machine Learning)包括模型自动生成和调优和训练工程超参数自动调优。昇腾模型开发用户可以通过模型自动性能调优功能找到性能更好的模型。AI初学者可以通过AutoML工具结合数据集,自动生成满足需求的模型,对训练超参进行自动调优。训练工程超参数优化(Hyperparameter Optimization,简称HPO),支持在昇腾910 AI处理器上训练,覆盖MindSpore,PyTorch,TensorFlow框架,用自动化的算法来优化超参数,从而提升模型的精度、性能等指标。模型自动生成和调优以昇腾910 AI处理器的搜索训练,昇腾310 AI处理器和昇腾310P AI处理器的推理验证为前提,覆盖MindSpore,PyTorch框架,面向分类、检测分割场景实现模型自动生成和调优。这个场景主要功能是基于数据集自动生成模型和基于预训练模型进行微调后自动生成模型。业务流程如图19所示:图 193.1环境准备使用AutoML工具前,可参考《CANN 软件安装指南》手册完成环境搭建,其他环境要求请参见训练服务器和推理服务器。使用非root用户运行任务时,需要以root用户将运行用户加入驱动运行用户组(例如:HwHiAiUser)中,保证普通用户对run包的lib库有读权限。集群配置中的训练和推理服务器需安装Vega,训练服务器安装noah_vega,推理服务器安装evaluate_service,具体可参考Vega官网自行安装。noah_vega提供安全通信特性,相关配置请参照安全配置说明,用户在AutoML安装完成后需要参照该说明正确配置vega之后才能以通信安全的方式运行训练任务。如果使用1.8.0及以上版本的安全特性noah_vega包,启动任务时需要在命令末端增加“-s”参数。用户根据需要自行安装以下AI框架包:MindSpore:请参考MindSpore官网安装MindSpore框架。PyTorch:请参考《CANN软件安装指南》的“安装PyTorch”章节编译安装PyTorch1.5.0框架。安装Torchvision依赖,可参考以下方法进行安装:在x86_64架构下安装Torchvision包:       pip3 install --user torchvision==0.6.0在aarch64架构下先从azureology/torchvision下载源码,执行以下命令安装0.6.0版本的Torchvision包:       python setup.py install若Pytorch下需要统计模型的参数量信息,则需要安装依赖thop:       pip3 install --user thopTensorFlow:参考《CANN 软件安装指南》安装tfplugin框架插件包和TensorFlow。请注意CANN版本与MindSpore、PyTorch和TensorFlow的版本配套关系。3.1.1训练服务器所有训练服务器的Python版本需要保持一致。已安装sshd。在各个训练服务器上的~/.bashrc文件中配置如下环境变量:source $HOME/Ascend/ascend-toolkit/set_env.sh   #请根据实际情况替换CANN软件包安装路径source {$HOME/Ascend/tfplugin/set_env.sh       #安装tfplugin时需要配置,请根据实际情况替换CANN软件包安装路径#以下为单卡训练时的配置,请根据实际环境和需求配置export DEVICE_ID=0  #单卡训练使用的device_id#以下6项为多卡训练时的配置,请根据实际环境和需求改动export RANK_ID=0   #指定调用卡的逻辑IDexport RANK_SIZE=8    #指定调用卡的数量export RANK_TABLE_FILE=多卡环境组网信息json文件所在路径  #从多卡环境组网信息json文件中选择要使用的device_idexport NPU_VISIBLE_DEVICES=0,1,2,3,4,5,6,7   #执行多卡任务时需要使用的device_idexport DEVICE_ID=0    #执行多卡训练任务时单卡阶段指定使用的device_idexport TF_CPP_MIN_LOG_LEVEL=3  #该项可控制TF框架本身日志级别的打印,0-DEBUG,1-INFO,2-WARNING,3-ERROR​​说明如果训练服务器中没有多卡环境组网信息json文件,请参见配置分布式环境变量在训练服务器上生成多卡环境组网信息json文件。当运行任务的用户为普通用户时,需要保证普通用户对该文件有可读权限。3.1.2推理服务器在推理服务器上的~/.bashrc文件中配置如下环境变量:​​source $HOME/Ascend/ascend-toolkit/set_env.sh   #请根据实际情况替换CANN软件包安装路径export install_path=$HOME/Ascend/ascend-toolkit/latest    #请根据实际情况替换CANN软件包安装路径export DDK_PATH=${install_path}  #评估服务编译时使用export NPU_HOST_LIB=${install_path}/{arch-os}/devlib   #评估服务编译时使用参见Link配置推理工具,并启动推理服务。说明推理工具中,-t参数为指定推理服务器的芯片型号,默认值Ascend310。若不使用该参数,默认在昇腾310 AI处理器上启动推理服务,参数取值如下。昇腾310 AI处理器参数值:Ascend310(默认)昇腾310P AI处理器参数值:Ascend310P*,例如Ascend310P1其中,*根据芯片性能提升等级、芯片核数使用等级等因素会有不同的取值。请参考《ToolBox用户指南》的“Ascend-DMI工具使用>设备实时状态查询”章节查询芯片详细信息。3.1.3 Vega的安全配置要求:Python3.9及以上dask和distributed版本为2022.2.0Vega的安全配置,包括如下步骤:安装OpenSSL首先要安装OpenSSL 1.1.1,从源码编译安装,或者直接安装编译后的发行包。然后安装OpenSSL的python接口,如下:pip3 install --user pyOpenSSL==19.0.0生成CA根证书执行如下命令生成CA证书:openssl genrsa -out ca.key 409openssl req -new -x509 -key ca.key -out ca.crt -subj "/C=<country>/ST=<province>/L=<city>/O=<organization>/OU=<group>/CN=<cn>"注意:以上<country>、<province>、<city>、<organization>、<group>、<cn>根据实际情况填写,去掉符号<>,本文后面的配置也是同样的。并且CA的配置需要和其他的不同。RSA密钥长度建议在3072位及以上,如本例中使用4096长度。缺省证书有效期为30天,可使用-days参数调整有效期,如-days 365,设置有效期为365天。生成评估服务用的证书评估服务支持加密证书和普通证书:若使用加密证书,需要安装华为公司的KMC安全组件,参考生成加密证书章节若使用普通证书,参考生成普通证书章节生成加密证书执行以下命令,获得证书配置文件:查询openssl配置文件所在的路径:openssl version -d在输出信息中,找到类似于OPENSSLDIR: "/etc/pki/tls",其中"/etc/pki/tls"即为配置文件所在目录。拷贝配置文件到当前目录:cp /etc/pki/tls/openssl.cnf .在配置文件中openssl.cnf中,增加如下配置项:req_extensions = v3_req # The extensions to add to a certificate request执行如下脚本,生成评估服务器所使用的证书的加密私钥,执行该命令时,会提示输入加密密码,密码的强度要求如下:密码长度大于等于8位必须包含至少1位大写字母必须包含至少1位小写字母必须包含至少1位数字必须包含至少1位特殊字符openssl genrsa -aes-256-ofb -out server.key 4096然后再执行如下命令,生成证书,并删除临时文件:openssl req -new -key server.key -out server.csr -subj "/C=<country>/ST=<province>/L=<city>/O=<organization>/OU=<group>/CN=<cn>" -config ./openssl.cnf -extensions v3_reqopenssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile ./openssl.cnf -extensions v3_reqrm server.csr执行如下脚本生成评估服务客户端所使用的证书的加密私钥,执行该命令时,会提示输入加密密码,密码的强度要求如服务器端私钥,且和服务器端私钥密码不同,请记录好该密码,后继还需使用:openssl genrsa -aes-256-ofb -out client.key 4096然后再执行如下命令,生成证书,并删除临时文件:openssl req -new -key client.key -out client.csr -subj "/C=<country>/ST=<province>/L=<city>/O=<organization>/OU=<group>/CN=<cn>" -config ./openssl.cnf -extensions v3_reqopenssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -extfile ./openssl.cnf -extensions v3_reqrm client.csr生成普通证书执行如下脚本,生成评估服务器端和客户端使用的证书的私钥和证书:openssl genrsa -out server.key 4096openssl req -new -key server.key -out server.csr -subj "/C=<country>/ST=<province>/L=<city>/O=<organization>/OU=<group>/CN=<cn>" -config ./openssl.cnf -extensions v3_reqopenssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile ./openssl.cnf -extensions v3_reqrm server.csropenssl genrsa -out client.key 4096openssl req -new -key client.key -out client.csr -extensions v3_ca  -subj "/C=<country>/ST=<province>/L=<city>/O=<organization>/OU=<group>/CN=<cn>" -config ./openssl.cnf -extensions v3_reqopenssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -extfile ./openssl.cnf -extensions v3_reqrm client.csr生成Dask用的证书执行如下脚本,生成Dask服务器端和客户端使用的证书的私钥和证书:openssl genrsa -out server_dask.key 4096openssl req -new -key server_dask.key -out server_dask.csr -subj "/C=<country>/ST=<province>/L=<city>/O=<organization>/OU=<group>/CN=<cn>" -config ./openssl.cnf -extensions v3_reqopenssl x509 -req -in server_dask.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server_dask.crt -extfile ./openssl.cnf -extensions v3_reqrm server_dask.csropenssl genrsa -out client_dask.key 4096openssl req -new -key client_dask.key -out client_dask.csr -subj "/C=<country>/ST=<province>/L=<city>/O=<organization>/OU=<group>/CN=<cn>" -config ./openssl.cnf -extensions v3_reqopenssl x509 -req -in client_dask.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client_dask.crt -extfile ./openssl.cnf -extensions v3_reqrm client_dask.csr删除CA私钥:rm ca.key加密私钥口令若加密服务器使用加密证书,则需要执行本章节余下步骤,若使用普通证书,则跳过该章节。加密生成评估服务的服务器端和客户端的私钥口令,需要安装华为公司KMC安全组件,并将该安全组件动态链接库所在的目录添加到LD_LIBRARY_PATH中。export LD_LIBRARY_PATH=<Directory where the KMC dynamic link library is located>:$LD_LIBRARY_PATH接下来安装Vega,使用Vega的密码加密工具调用KMC安全组件对密码加密。 在执行如下命令时,请输入在生成私钥时输入的口令,该命令会生成加密后的口令,请注意保存,在配置文件中会使用到这两个加密后的口令:vega-encrypt_key --cert=server.crt --key=server.key --key_component_1=ksmaster_server.dat --key_component_2=ksstandby_server.datvega-encrypt_key --cert=client.crt --key=client.key --key_component_1=ksmaster_client.dat --key_component_2=ksstandby_client.dat配置安全相关的配置文件请在当前用户的主目录下创建.vega目录,并将如上生成的秘钥、证书、加密材料等,拷贝到该目录下,并改变权限:mkdir ~/.vegamv * ~/.vega/chmod 600 ~/.vega/*说明如上的秘钥、证书、加密材料也可以放到其他目录位置,注意访问权限要设置为600,并在后继的配置文件中同步修改该文件的位置,需要使用绝对路径。在训练集群上,需要保留ca.crt、client.key、client.crt、ksmaster_client.dat、ksstandby_client.dat、server_dask.key、server_dask.crt、client_dask.key、client_dask.crt,并删除其他文件。评估服务上,需要保留ca.crt、server.key、server.crt、ksmaster_server.dat、ksstandby_server.dat,并删除其他文件。以下为默认配置的加密套件:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-DSS-AES128-GCM-SHA256:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES128-CCM:DHE-RSA-AES256-CCM如需缩小范围,可在client.ini与vega.ini中加入配置:ciphers=ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES256-CCM在~/.vega目录下创建server.ini和client.ini。在训练集群中,需要配置~/.vega/server.ini和~/.vega/client.ini:server.ini:[security]  # 以下文件路径需要修改为绝对路径    ca_cert=<~/.vega/ca.crt>    server_cert_dask=<~/.vega/server_dask.crt>    server_secret_key_dask=<~/.vega/server_dask.key>    client_cert_dask=<~/.vega/client_dask.crt>    client_secret_key_dask=<~/.vega/client_dask.key>client.ini:[security]  # 以下文件路径需要修改为绝对路径    ca_cert=<~/.vega/ca.crt>    client_cert=<~/.vega/client.crt>    client_secret_key=<~/.vega/client.key>    encrypted_password=<加密后的client端的口令>  # 如果使用普通证书, 此项配置为空    key_component_1=<~/.vega/ksmaster_client.dat>  # 如果使用普通证书, 此项配置为空    key_component_2=<~/.vega/ksstandby_client.dat>  # 如果使用普通证书, 此项配置为空在评估服务器上,需要配置~/.vega/vega.ini:[security]  # 以下文件路径需要修改为绝对路径    ca_cert=<~/.vega/ca.crt>    server_cert=<~/.vega/server.crt>    server_secret_key=<~/.vega/server.key>    encrypted_password=<加密后的server端的口令>  # 如果使用普通证书, 此项配置为空    key_component_1=<~/.vega/ksmaster_server.dat>  # 如果使用普通证书, 此项配置为空    key_component_2=<~/.vega/ksstandby_server.dat>  # 如果使用普通证书, 此项配置为空配置评估服务守护服务使用systemctl管理评估服务器进程,当进程出现异常时自动重启,保证评估服务器连续性。首先创建一个启动评估服务的脚本run_evaluate_service.sh,内容如下,注意替换<ip>、<path>为真实IP和目录:vega-evaluate_service-service -i <ip> -w <path>然后再创建一个守护服务的文件evaluate-service.service,脚本内容如下,注意替换为真实的脚本位置:[Unit]    Description=Vega Evaluate Service Daemon[Service]    Type=forking    ExecStart=/<your_run_script_path>/run.sh    Restart=always    RestartSec=60[Install]    WantedBy=multi-user.target然后将evaluate-service.service拷贝到目录/usr/lib/systemd/system中,并启动该服务:sudo cp evaluate-service.service /usr/lib/systemd/system/sudo systemctl daemon-reloadsudo systemctl start evaluate-service配置HCCL白名单请参考Ascend提供的配置指导。注意事项模型风险对于AI框架来说,模型就是程序,模型可能会读写文件、发送网络数据。例如Tensorflow提供了本地操作API tf.read_file, tf.write_file,返回值是一个operation,可以被Tensorflow直接执行。 因此对于未知来源的模型,请谨慎使用,使用前应该排查该模型是否存在恶意操作,消除安全隐患。运行脚本风险Vega提供的script_runner功能可以调用外部脚本进行超参优化,请确认脚本来源,确保不存在恶意操作,谨慎运行未知来源脚本。KMC组件不支持多个用户同时使用若使用KMC组件对私钥密码加密,需要注意KMC组件不支持不同的用户同时使用KMC组件。若需要切换用户,需要在root用户下,使用如下命令查询当前信号量:ipcs然后删除查询到的当前所有的信号量:ipcrm -S '<信号量>'删除开源软件中不适用的私钥文件Vega安装时,会自动安装Vega所依赖的开源软件,请参考列表。部分开源软件的安装包中可能会带有测试用的私钥文件,Vega不会使用这些私钥文件,删除这些私钥文件不会影响Vega的正常运行。可执行如下命令所有的私钥文件:find ~/.local/ -name *.pem在以上命令列出的所有文件中,找到Vega所依赖的开源软件的私钥文件。一般私钥文件的名称中会带有单词key,打开这些文件,可以看到以-----BEGIN PRIVATE KEY-----开头,以-----END PRIVATE KEY-----结尾,这些文件都可以删除。Horovod和TensorFlow在安全模式下,Vega不支持Horovod数据并行,也不支持TensorFlow框架,Vega在运行前检查若是Horovod数据并行程序,或者TensorFlow框架,会自动退出。限定Distributed仅使用tls1.3协议进行通信若需要限定开源软件Distributed的组件间的通信仅使用tls1.3协议,需要配置~/.config/dask/distributed.yamldistributed.yaml:distributed: comm: tls: min-version: 1.3请参考Dask的配置指导。3.2集群管理创建新集群在菜单栏选择“Ascend > AutoML > Cluster Manager”。进入“Cluster Manager”界面。单击“+New Cluster”。进入“Add Cluster”界面,如图20所示。界面参数说明如表5所示。单击“OK”,完成新集群创建。图 20表5参数说明Cluster Name集群名称,在所有集群里具有唯一性。只支持英文字母、数字或者下划线,以英文字母开头,且长度不超过32个字符。例如:Cluster_01。Evaluation Service评估服务,通过下拉框选择已通过SSH配置好的远端环境。Evaluation Service Port评估服务器端口,仅支持输入1~65535之间的数字,默认值为8888。Training Service训练服务器,通过下拉框选择已通过SSH配置好的远端训练环境。Primary训练服务集群主节点,通过下拉框选择已通过SSH配置好的远端训练环境。Add添加训练服务。单击选择此项后,“Secondary”、“Data Sharing Service”和“NFS Server Path”参数才会在界面体现。Secondary训练服务集群从节点,通过下拉框选择已通过SSH配置好的远端训练环境。单击删除按钮可以删除从节点。Data Sharing Service数据共享服务器,通过下拉框选择已通过SSH配置好的远端环境。NFS Server PathNFS服务器路径。例如:/home/test/nfs_cache。Workspace所有训练服务器的工作路径。例如:/home/test/nfs_folder。删除集群在菜单栏选择“Ascend > AutoML > Cluster Manager”。进入“Cluster Manager”界面。单击需要删除的集群后方的,如图21所示。图 21四、模型开发使用HPO界面工具调优流程4.1 前提条件已安装1.1.3版本的pandas依赖包,执行以下命令以安装:pip install pandas==1.1.3 --user4.2 修改模型训练脚本修改用户模型训练脚本,添加dump_objective函数,并在此脚本中调用此函数,保存待优化指标。代码段截图如图22所示。图22用户可参考{CANN包安装路径}/ascend-toolkit/latest/tools/ascend_automl/algorithms /script_hpo/hpo_ui_sample.py进行操作,此样例使用以下语句保存平均耗时和精度指标。如图23所示。图23其中dump_objective函数的入参objective_key要与步骤4.3中General Config页签中填写的Objectives优化目标一致,objective_value为用户脚本中优化目标值。HPO功能在用户指定的搜索空间内,进行超参数采样,并对每一组超参数调起一个用户模型的训练任务。通过以上修改,用户脚本可在模型训练任务完成后,将超参数对应的精度、性能等信息传递给HPO主进程,以便后续选出最优超参。4.3 配置General Config在菜单栏选择“Ascend > AutoML > HPO”,进入General Config页签,如图24所示。详细参数说明如表5所示。图24表 5 参数说明参数说明Compute Nodes Cluster计算集群选择。Parallel Search多卡或者单卡配置按钮,按钮开状态为多卡,关闭为单卡。Total Epochs搜索epoch配额。在HPO过程中,每个训练任务会消耗一定数量的epochs,所有训练任务的epoch总和小于此Total Epochs项。用户可参考Total Epochs*time_per_epoch / num_of_device来估算时间。Task Work Path当前运行用户目录下的工作路径,HPO过程的输出路径。需用户选定或者输入存在且有读权限路径,且文件路径中不包含非法字符。Search Alogorithom Type搜索算法,目前仅支持AshaHpo算法。Objectives优化目标,单击右侧“+”图标可添加需要优化的目标。在文本框中输入优化目标,例如平均精度、训练迭代耗时等。Max:表示期望优化目标最大化。Min:表示期望优化目标最小化。单击右侧删除图标可以删除对应的优化目标参数项。4.4 配置Train Config单击“Next”,进入Train Config页签,如图25所示。详细参数说明如表6所示。图25表 6 参数说明参数说明Train Script4.2中的用户的模型训练脚本,需为存在的可读Python脚本,不包含非法字符。在HPO调优过程中会调用该脚本。Env Variables环境变量。单击右侧按钮添加环境变量。当General Config页签开启Parallel Search参数时,需配置以下环境变量:NPU_VISIBLE_DEVICES:可用的device。RANK_SIZE:device列表长度。RANK_TABLE_FILE:组网信息文件(若在环境准备已配置该环境变量,则不用在此处进行配置)。用户需要先配置组网信息文件,具体可参考cid:link_4。BATCH_TASK_INDEX:任务编号,一般配置为0。当General Config页签关闭Parallel Search参数时,需配置DEVICE_ID实现在指定卡上运行。Search Space搜索空间,单击右侧的“+”按钮可以添加以下搜索内容。Key:搜索关键字,需要优化的用户脚本输入参数名,这里需要优化的是“lr”和“momentum”参数,因此填“--lr”和“--momentum”,必填项。Type:搜索类型。支持CATEGORY、BOOL、INT、INT_EXP、FLOAT、FLOAT_EXP,必填项。Range:当前Key的搜索范围。需手动输入,内容用英文逗号分隔,必填项。单击删除图标可以删除对应的搜索空间。说明:搜索类型可选以下六种:CATEGORY 分组类型,用户在Range中给出可选的取值,可以为任意的数据类型,如:[18, 34, 50, 101],[0.3, 0.7, 0.9],['Adam', 'SGD'],[[1, 0, 1],[0, 0, 1]]。BOOL 布尔类型,对应Range取值为[True, False]。INT 整数类型,对应Range设置最小值和最大值,均匀采样,如:[10, 100]。INT_EXP 整数类型,对应Range设置最小值和最大值,指数采样,如:[1, 100000]。FLOAT 浮点数类型,对应Range设置最小值和最大值,均匀采样,如:[0.1, 0.9]。FLOAT_EXP 浮点数类型,对应Range设置最小值和最大值,指数采样,如:[0.1, 100000.0]。Other Options其他参数项,单击右侧的“+”按钮可以添加不需要优化的参数。Key:不需要优化的用户脚本入参名,可选项。示例中不需要优化的有“--weight_decay”参数,因此填入“--weight_decay”Value:用户指定的入参值,选填项。单击删除图标可以删除对应的其他参数项。Epoch Name在HPO的不同阶段,对网络训练不同的epoch,这一epoch值由HPO进程给出,不需用户指定。因此,用户需将脚本入参中,代表epoch的参数名称,填入此栏,以便HPO过程中将HPO算法给出的epoch值传入用户脚本。例如:4.2中示例,此项应填“--epochs ”说明:如果待优化的训练脚本不能传入epoch参数,需要用户将训练脚本修改为能传入epoch参数的形式。Device Name在HPO过程中,启动多个训练任务,使用不同的超参数进行网络训练。不同的训练任务使用不同的AI芯片,AI芯片ID由HPO进程给出,不需用户指定。因此,用户需将脚本入参中,代表AI芯片ID的参数名称,填入此栏,以便HPO过程中将这一参数自动传入用户脚本。例如:1中示例,此项应填“--device”说明:如果待优化的训练脚本不能传入该device参数,需要用户将训练脚本修改为能传入device参数的形式。传入的device值的格式为“npu:x”,其中x可能为0,1,2,3,4,5,6,7。4.5 预览配置结果单击“Next”,进入Preview页签,如图26、27所示。图26图27基于前面的两个配置界面,可以生成配置文件config.yml,接口文件train.py,启动文件run.sh,并发送到远端服务器,调起HPO任务。此页面提供命令行命令的预览。单击“Finish”之后运行HPO任务。如图28、29、30所示说明可使用vega-process查询正在运行的任务,使用vega-kill -p PID或vega-kill -t task_id结束正在运行的vega任务。图28图29图304.6 过程和结果获取任务开始后,HPO窗口关闭,Output窗口中将提示可到远端查看HPO任务运行过程和结果,如图31~35所示。图31图32图33图34图35在Output窗口所示路径下会生成tasks文件夹,tasks文件夹下有名为{task_id}的文件夹,此文件下有文件夹logs、output和workers。├── tasks│   ├── {task_id}│   │   ├──logs│   │   │   ├──hpo_worker_{worker_id}。log // 第worker_id个worker上进行hpo的日志文件│   │   │   ├──pipeline.log                // 整个hpo任务日志文件│   │   ├──output│   │   │   ├──config.yml                       // 配置文件│   │   │   ├──report.json                      // hpo任务的报告文件│   │   │   ├──hpo│   │   │   │   ├──hps_{worker_id}.json           //搜索出的最佳超参值│   │   │   │   ├──performance_{worker_id}.json   //搜索出的最佳优化指标值│   │   │   │   ├──output.csv                     //优化指标值汇总文件│   │   ├──workers│   │   │   ├──hpo│   │   │   │   ├──{worker_id}│   │   │   │   │   ├──hps_{worker_id}.json           //超参值│   │   │   │   │   ├──performance_{worker_id}.json   //优化目标值五、经验总结利用HPO界面调优会在所指定的路径下生成相应的执行文件,直接在后台执行run.sh文件会报错。图36解决办法:可更改生成的config.yml文件中的task_id为非纯数字的名称,然后利用vega config.yml -d NPU命令在后台执行HPO调优。图37六、关于MindStudio更多的内容如果需要了解关于MindStudio更多的信息,请查阅昇腾社区中MindStudio的[用户手册](https://www.hiascend.com/document/detail/zh/mindstudio/50RC3/progressiveknowledge/index.html),里面模型训练、脚本转换、模型开发、算子开发、精度对比、AI Core Error分析工具、AutoML工具(Beta)、Benchmark工具、专家系统工具等各种使用安装操作的详细介绍。如果在使用MindStudio过程中遇到任何问题,也可以在昇腾社区中的[昇腾论坛](https://www.huaweicloud.com)进行提问,会有华为内部技术人员对其进行解答,如下图。图38