共计 14282 个字符,预计需要花费 36 分钟才能阅读完成。
前情阐明
本作业基于 Windows 版 MindStudio 5.0.RC3,近程连贯 ECS 服务器应用,ECS 是基于官网分享的 CANN6.0.RC1_MindX_Vision3.0.RC3 镜像创立的。
基于 ECS(Ascend310)的 U -Net 网络的图像宰割
1. U-Net 网络介绍:
U-Net 模型基于二维图像宰割。在 2015 年 ISBI 细胞跟踪比赛中,U-Net 取得了许多最佳奖项。论文中提出了一种用于医学图像宰割的网络模型和数据加强办法,无效利用标注数据来解决医学畛域标注数据有余的问题。U 型网络结构也用于提取上下文和地位信息。
2. ECS 运行阐明
咱们的操作根本都在 root 用户下执行。
首先,批改 bash,具体命令和后果如下。
本我的项目反对 MindStudio 运行和终端运行。
(1)下载我的项目代码
下载链接:https://alexed.obs.cn-north-4…
将我的项目文件 unet_sdk.zip 上传至华为云 ECS 弹性云服务器 /root/ 目录下,并解压;或者下载到本地电脑,用 MindStudio 关上。
将之前 unet_hw960_bs1.air 模型放到 /unet_sdk/model/ 目录下。
我的项目文件构造
├── unet_sdk
├── README.md
├── data // 数据集
│ ├── 1
│ │ ├──image.png // 图片
│ │ ├──mask.png // 标签
│ ...
├── model
│ ├──air2om.sh // air 模型转 om 脚本
│ ├──xxx.air //air 模型
│ ├──xxx.om //om 模型
│ ├──aipp_unet_simple_opencv.cfg // aipp 文件
├── pipeline
│ ├──unet_simple_opencv.pipeline // pipeline 文件
├── main.py // 推理文件
├── run.sh // 执行文件
├── requirements.txt // 须要的三方库
(2) 模型转换
将 unet_hw960_bs1.air 模型转为昇腾 AI 处理器反对的.om 格局离线模型,此处模型转换须要用到 ATC 工具。
昇腾张量编译器(Ascend Tensor Compiler,简称 ATC)是昇腾 CANN 架构体系下的模型转换工具,它能够将开源框架的网络模型或 Ascend IR 定义的单算子形容文件(json 格局)转换为昇腾 AI 处理器反对的.om 格局离线模型。模型转换过程中能够实现算子调度的优化、权值数据重排、内存应用优化等,能够脱离设施实现模型的预处理。
ATC 参数概览:
(3) 运行脚本
运行脚本:
cd unet_sdk/model/ # 切换至模型存储目录
atc --framework=1 --model=unet_hw960_bs1.air --output=unet_hw960_bs1 --input_format=NCHW --soc_version=Ascend310 --log=error --insert_op_conf=aipp_unet_simple_opencv.cfg
- 留神 air 模型转 om 只反对动态 batch,这里 batchsize=1。
参数阐明:
framework:原始框架类型。 model:原始模型文件门路与文件名。 output:转换后的离线模型的门路以及文件名。 input_format:输出数据格式。 soc_version:模型转换时指定芯片版本。 log:显示日志的级别。 insert_op_conf:插入算子的配置文件门路与文件名,这里应用 AIPP 预处理配置文件,用于图像数据预处理。
输入后果:
ATC run success,示意模型转换胜利,失去 unet_hw960_bs1.om 模型。
模型转换胜利之后,能够应用 MindX SDK mxVision 运行脚本,在 Ascend 310 上进行推理。
(4) MindX SDK mxVision 执行推理
MindX SDK 文档请参考:https://support.huaweicloud.c…
MindX SDK 执行推理的业务流程:
通过 stream 配置文件,Stream manager 可辨认须要构建的 element 以及 element 之间的连贯关系,并启动业务流程。Stream manager 对外提供接口,用于向 stream 发送数据和获取后果,帮忙用户实现业务对接。
plugin 示意业务流程中的根底模块,通过 element 的串接构建成一个 stream。buffer 用于外部挂载解码前后的视频、图像数据,是 element 之间传递的数据结构,同时也容许用户挂载元数据(Metadata),用于寄存结构化数据(如指标检测后果)或过程数据(如缩放后的图像)。
MindX SDK 根底概念介绍:
MindX SDK 根底插件:
MindX SDK 业务流程编排:
Stream 配置文件以 json 格局编写,用户必须指定业务流名称、元件名称和插件名称,并依据须要,补充元件属性和上游元件名称信息。
以下表格为本试验 pipeline/unet_simple_opencv.pipeline 文件及其对应的名称及形容:
pipeline/unet_simple_opencv.pipeline 文件内容如下,可依据理论开发状况进行批改。
{
"unet_mindspore": {
"stream_config": {"deviceId": "0"},
"appsrc0": {
"props": {"blocksize": "4096000"},
"factory": "appsrc",
"next": "mxpi_imagedecoder0"
},
"mxpi_imagedecoder0": {
"props": {
"cvProcessor": "opencv",
"outputDataFormat": "BGR"
},
"factory": "mxpi_imagedecoder",
"next": "mxpi_imagecrop0"
},
"mxpi_imagecrop0": {
"props": {
"cvProcessor": "opencv",
"dataSource": "ExternalObjects"
},
"factory": "mxpi_imagecrop",
"next": "mxpi_imageresize0"
},
"mxpi_imageresize0": {
"props": {
"handleMethod": "opencv",
"resizeType": "Resizer_Stretch",
"resizeHeight": "960",
"resizeWidth": "960"
},
"factory": "mxpi_imageresize",
"next": "mxpi_tensorinfer0"
},
"mxpi_tensorinfer0": {
"props": {
"dataSource": "mxpi_imageresize0",
"modelPath": "model/unet_hw960_bs1_AIPP.om"
},
"factory": "mxpi_tensorinfer",
"next": "mxpi_dumpdata0"
},
"mxpi_dumpdata0": {
"props": {"requiredMetaDataKeys": "mxpi_tensorinfer0"},
"factory": "mxpi_dumpdata",
"next": "appsink0"
},
"appsink0": {
"props": {"blocksize": "4096000"},
"factory": "appsink"
}
}
}
(5) 批改 modelPath
关上 pipeline/unet_simple_opencv.pipeline 文件,将 ”mxpi_tensorinfer0″ 元件的属性 ”modelPath”(模型导入门路)批改为模型转换后保留的 om 模型 ”model/unet_hw960_bs1.om”。
批改后果:
"modelPath": "model/unet_hw960_bs1.om"
modelPath 批改实现之后,保留 pipeline/unet_simple_opencv.pipeline 文件。
StreamManagerApi:
StreamManagerApi 文档请参考:
https://support.huaweicloud.c…
StreamManagerApi 用于对 Stream 流程的根本治理:加载流程配置、创立流程、向流程发送数据、取得执行后果、销毁流程。
这里用到的 StreamManagerApi 有:
- InitManager:初始化一个 StreamManagerApi。
- CreateMultipleStreams:依据指定的配置创立多个 Stream。
- SendData:向指定 Stream 上的输出元件发送数据(appsrc)。
- GetResult:取得 Stream 上的输入元件的后果(appsink)
- DestroyAllStreams:销毁所有的流数据。
main.py 文件内容如下,可依据理论开发状况进行批改。
import argparse
import base64
import json
import os
import cv2
import numpy as np
from StreamManagerApi import *
import MxpiDataType_pb2 as MxpiDataType
x0 = 2200 # w:2200~4000; h:1000~2800
y0 = 1000
x1 = 4000
y1 = 2800
ori_w = x1 - x0
ori_h = y1 - y0
def _parse_arg():
parser = argparse.ArgumentParser(description="SDK infer")
parser.add_argument("-d", "--dataset", type=str, default="data/",
help="Specify the directory of dataset")
parser.add_argument("-p", "--pipeline", type=str,
default="pipeline/unet_simple_opencv.pipeline",
help="Specify the path of pipeline file")
return parser.parse_args()
def _get_dataset(dataset_dir):
img_ids = sorted(next(os.walk(dataset_dir))[1])
for img_id in img_ids:
img_path = os.path.join(dataset_dir, img_id)
yield img_path
def _process_mask(mask_path):
# 手动裁剪
mask = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)[y0:y1, x0:x1]
return mask
def _get_stream_manager(pipeline_path):
stream_mgr_api = StreamManagerApi()
ret = stream_mgr_api.InitManager() #初始化 stream
if ret != 0:
print(f"Failed to init Stream manager, ret={ret}")
exit(1)
with open(pipeline_path, 'rb') as f:
pipeline_content = f.read()
ret = stream_mgr_api.CreateMultipleStreams(pipeline_content) # 创立 stream
if ret != 0:
print(f"Failed to create stream, ret={ret}")
exit(1)
return stream_mgr_api
def _do_infer_image(stream_mgr_api, image_path):
stream_name = b'unet_mindspore' # 与 pipeline 中 stream name 统一
data_input = MxDataInput()
with open(image_path, 'rb') as f:
data_input.data = f.read()
# 插入抠图的性能,扣 1800*1800 大小
roiVector = RoiBoxVector()
roi = RoiBox()
roi.x0 = x0
roi.y0 = y0
roi.x1 = x1
roi.y1 = y1
roiVector.push_back(roi)
data_input.roiBoxs = roiVector
unique_id = stream_mgr_api.SendData(stream_name, 0, data_input) # 向指定 Stream 上的输出元件发送数据(appsrc)
if unique_id < 0:
print("Failed to send data to stream.")
exit(1)
infer_result = stream_mgr_api.GetResult(stream_name, unique_id) # 取得 Stream 上的输入元件的后果(appsink)if infer_result.errorCode != 0:
print(f"GetResult error. errorCode={infer_result.errorCode},"
f"errorMsg={infer_result.data.decode()}")
exit(1)
# 用 dumpdata 获取数据
infer_result_data = json.loads(infer_result.data.decode())
content = json.loads(infer_result_data['metaData'][0]['content'])
tensor_vec = content['tensorPackageVec'][0]['tensorVec'][1] # 1 是 argmax 后果
data_str = tensor_vec['dataStr']
tensor_shape = tensor_vec['tensorShape']
argmax_res = np.frombuffer(base64.b64decode(data_str), dtype=np.float32).reshape(tensor_shape)
np.save("argmax_result.npy", argmax_res)
tensor_vec = content['tensorPackageVec'][0]['tensorVec'][0] # 0 是 softmax 后果
data_str = tensor_vec['dataStr']
tensor_shape = tensor_vec['tensorShape']
softmax_res = np.frombuffer(base64.b64decode(data_str), dtype=np.float32).reshape(tensor_shape)
np.save("softmax_result.npy", softmax_res)
return softmax_res # ndarray
# 自定义 dice 系数和 iou 函数
def _calculate_accuracy(infer_image, mask_image):
mask_image = cv2.resize(mask_image, infer_image.shape[1:3])
mask_image = mask_image / 255.0
mask_image = (mask_image > 0.5).astype(np.int)
mask_image = (np.arange(2) == mask_image[..., None]).astype(np.int)
infer_image = np.squeeze(infer_image, axis=0)
inter = np.dot(infer_image.flatten(), mask_image.flatten())
union = np.dot(infer_image.flatten(), infer_image.flatten()) + \
np.dot(mask_image.flatten(), mask_image.flatten())
single_dice = 2 * float(inter) / float(union + 1e-6)
single_iou = single_dice / (2 - single_dice)
return single_dice, single_iou
def main(_args):
dice_sum = 0.0
iou_sum = 0.0
cnt = 0
stream_mgr_api = _get_stream_manager(_args.pipeline)
for image_path in _get_dataset(_args.dataset):
infer_image = _do_infer_image(stream_mgr_api, os.path.join(image_path, 'image.png')) # 抠图并且 reshape 后的 shape,1hw
mask_image = _process_mask(os.path.join(image_path, 'mask.png')) # 抠图后的 shape,hw
dice, iou = _calculate_accuracy(infer_image, mask_image)
dice_sum += dice
iou_sum += iou
cnt += 1
print(f"image: {image_path}, dice: {dice}, iou: {iou}")
print(f"========== Cross Valid dice coeff is: {dice_sum / cnt}")
print(f"========== Cross Valid IOU is: {iou_sum / cnt}")
stream_mgr_api.DestroyAllStreams() # 销毁 stream
if __name__ == "__main__":
args = _parse_arg()
main(args)
run.sh 文件内容如下,可依据理论开发状况进行批改。参考 SDK 软件包 sample 脚本,须要依照理论门路批改各个环境变量门路。
set -e
CUR_PATH=$(cd "$(dirname"$0")" || {warn "Failed to check path/to/run.sh" ; exit ;} ; pwd)
# Simple log helper functions
info() { echo -e "\033[1;34m[INFO][MxStream] $1\033[1;37m" ;}
warn() { echo >&2 -e "\033[1;31m[WARN][MxStream] $1\033[1;37m" ;}
#export MX_SDK_HOME=${CUR_PATH}/../../..
export LD_LIBRARY_PATH=${MX_SDK_HOME}/lib:${MX_SDK_HOME}/opensource/lib:${MX_SDK_HOME}/opensource/lib64:/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64:${LD_LIBRARY_PATH}
export GST_PLUGIN_SCANNER=${MX_SDK_HOME}/opensource/libexec/gstreamer-1.0/gst-plugin-scanner
export GST_PLUGIN_PATH=${MX_SDK_HOME}/opensource/lib/gstreamer-1.0:${MX_SDK_HOME}/lib/plugins
#to set PYTHONPATH, import the StreamManagerApi.py
export PYTHONPATH=$PYTHONPATH:${MX_SDK_HOME}/python
python3 main.py
exit 0
(6) 运行脚本
激活 mxVision 环境变量(本作业无需此步骤):
. /root/mxVision/set_env.sh
运行脚本:
cd /root/unet_sdk/ # 切换至推理脚本目录
bash run.sh
运行截图如下:
通过 MindStudio 运行,会主动上传代码到预设门路,并执行,运行后果如下:
MindStudio 专家系统工具
专家系统工具以后反对专家系统自有知识库和生态知识库对模型 / 算子进行性能剖析,反对性能调优一键式闭环实现一键式性能问题优化能力。
专家系统自有知识库以后提供的性能:基于 Roofline 模型的算子瓶颈辨认与优化倡议、基于 Timeline 的 AI CPU 算子优化、算子交融举荐、TransData 算子辨认和算子优化剖析。
生态知识库的专家系统性能调优性能:由生态开发者应用 Python 编程语言进行开发,用户通过调用专家系统提供的接口,对生态开发者提供的模型 / 算子进行性能剖析。
MindStudio IDE 以后版本仅反对的生态知识库创立性能,能够在下面实现生态知识库代码开发,暂不反对对生态知识库的专家系统剖析性能。性能调优一键式闭环提供一键式性能问题剖析和优化能力,无效晋升用户性能剖析和优化效率。
上面介绍如何应用专家系统工具对模型和算子进行性能瓶颈辨认并输入优化倡议。
1. 单击菜单栏“Ascend > Advisor”,弹出专家系统工具界面。如图所示。
2. 单击上图界面左上角红框中的按钮,关上专家系统配置界面,各参数配置示例如图所示。
各参数具体阐明如下:
3. 配置实现后单击“Start”启动剖析。
之后开始运行,如图所示,具体工夫与网络状况无关。
运行实现后,会主动跳转到如下图所示界面。
这里的 Model Performance Report 是模型性能的总结报告。依据该页面,能够晓得模型性能是好是坏,也能够晓得模型的吞吐率和运行工夫,AI Core 的利用率,Tiling 策略是否正当,局部字段阐明如下所示,具体可参见 https://www.hiascend.com/docu…。
从上述截图的剖析后果能够看出咱们所用的 U -Net 模型的芯片利用率是偏低的,甚至能够说是很差,有很大的优化的空间。上面咱们来详细分析。
先来看依据总体性能数据汇总计算得出的 Model Performance,显示为 Bad,状况不乐观啊。接着看看汇总信息。
能够看到 Cube 吞吐量 Cube Throughput 约 393 GOps,Vector 吞吐量 Vector Throughput 约 0.89 GOps,AI Core 执行工夫 88712us,工作执行工夫 177183us,均匀 BlockDim 利用率 Avg BlockDim Usage,算子执行时的均匀外围数,数值为 1,这反映了反映芯片利用状况,思考到咱们 ECS 的 Ascend 310 总计 2 个 AI Core,且由零碎主动调度,这里为 1 还能够接管。但上面的数据可难看了。
如图所示,芯片利用率 Chip Utilization。依照规定,80 为优,显示为绿色;小于 80 则为差,显示为红色。依据 Pipeline Bound 的数值计算得出。而咱们这里间接为 0 了。再看 Cube 利用率 Cube Ratio 约为 0.41,Vector 利用率 Vector Ratio 约为 0.29,Scalar 利用率 Scalar Ratio 约为 0.26,还有优化空间,而 MTE1 瓶颈、MTE2 瓶颈、MTE3 瓶颈都还不小。特地是 MTE2 瓶颈,约为 0.39。上面接着看。
来看内存读入量的数据切片策略 Tiling Strategy 为 5.23,状况蹩脚。依据规定,数值达到 80 为优,显示为绿色;小于 80 则为差,显示为红色。这是依据 Memory Redundant 的数值计算得出。同时,能够看到实在内存读入量 Real Memory Input(GB)约为 1.44GB,实在内存写出量 Real Memory Output(GB)约为 0.60GB,都在可用范畴内。
接下来进入 Computational Graph Optimization 界面,如图红框所示两处都能够,二者就是简版和精装版的区别了。在这里,咱们能够看到计算图优化,算子交融举荐性能专家系统剖析倡议,会分行展现可交融的算子。
先来看看须要进行 UB 交融的算子,点击算子,会主动跳转相应的计算图,既直观又不便啊。同时咱们看到可交融算子的执行工夫 Fusion Operator Duration 达到了约 9585us,靠近 10ms 了,算是比拟大了。本模型没有 AIPP 交融举荐和 L2Cache 交融举荐。
咱们间接看 TransData 算子交融举荐,如图所示。该算子执行持续时间在 2.5ms 左右,也不算小了,也是一个值得优化的中央啊。
但遗憾的是本次 Roofline 页面(基于 Roofline 模型的算子瓶颈辨认与优化倡议性能输入后果)和 Model Graph Optimization 页面(基于 Timeline 的 AICPU 算子优化性能输入后果)都没什么后果展现,具体别离如下图所示。
这里提个倡议,看了下运行日志(显示了这一句[ERROR] Analyze model(RooflineModel) failed, please check dfx log.),Roofline 之所以没有结果显示,可能是 Roofline 运行失败,不过这个日志有点太简洁了,不太敌对,也没有给出 dfx log 的具体门路或地位,哪怕弹出一个链接给用户,让用户去自行查找呢,这都没有,感觉界面不太敌对啊。
专家系统提供对推理模型和算子的性能瓶颈剖析能力并输入专家建议,但理论性能调优还需用户自行批改,不能做到性能调优一键式闭环。而性能调优一键式闭环提供一键式性能问题剖析和优化能力,无效晋升用户性能剖析和优化效率。同时,性能调优一键式闭环以后实现生态知识库 ONNX 模型的局部推理场景瓶颈辨认和自动化调优能力。
但这须要筹备待优化的 ONNX 模型文件(.onnx)以及 ONNX 模型通过 ATC 转换后的 OM 模型文件(.om),而咱们这次是.air 模型转 om 模型,尽管能够取得 onnx 模型,但太麻烦了,咱们这次就不尝试了。
这里再提个倡议,性能调优一键式闭环还须要下载 ONNX 模型调优知识库,我依照文档(文档链接:https://www.hiascend.com/docu…)中提供 Link 跳转下载(如下图所示),未能找到文档后续所说的 KnowledgeBase Configuration 知识库配置文件 echosystem.json。不晓得是不是我的问题,倡议工程师看看,验证一下。
MindStudio Profiling 工具
Profiling 作为业余的昇腾 AI 工作性能剖析工具,其性能涵盖 AI 工作运行时要害数据采集和性能指标剖析。纯熟应用 Profiling,能够疾速定位性能瓶颈,显著晋升 AI 工作性能剖析的效率。
上面介绍应用 Profiling 工具采集性能数据并作简略的性能数据分析。
1. 更换 python 链接(可选)
这里先给大家排下雷,如果大家遇到如下报错,那么依照上面的操作修复下就行了,报错信息如下图所示:
集体认为,这应该是本地电脑没装置 Python 或者装置了,然而没有增加到零碎 Path,以至无奈调用,这应该 Profiling 须要在 Windows 上调用 Python 做一些操作,但无奈调用 Python 导致的。那么咱们只有装置 Python 的时候,抉择增加到 Path,或者曾经装置 Python 的同学,将 Python 增加到 Path,最终使得可能在 Windows 终端下间接调用 Python 即可。最终成果示例如下:
此外,因为 ECS 终端默认启动的 Python 是 /usr/bin/python,而在 ECS 默认是 Python2 间接运行程序会报错,而咱们须要用 Python3,所以须要从新链接符号,具体流程为:删除 python 链接文件 –>> 新建链接文件到 python3,上面是操作步骤:
那么有人可能就要问了,为什么是 /usr/local/python3.9.5/bin/python3 呢?因为咱们在通过 MindStudio 间接在近程 ECS 上运行的时候,就是用的这个啊,来张图看看:
这里提个倡议,我之前运行会报错,详情见 https://www.hiascend.com/foru…,连着两天重启,试了好几次,就是不行,起初又试了一次,忽然就能够了,感觉很奇怪,莫名其妙地报错,莫名其秒地好了,这给我一种 IDE 很不稳固的感觉。倡议优化一下,晋升下稳定性。
2. 执行 Profiling 采集
(1)单击菜单栏“Ascend > System Profiler > New Project”,弹出 Profiling 配置窗口。
配置“Project Properties”,配置工程名称“Project Name”和抉择工程门路“Project Location”。单击“Next”进入下一步。
(2)进入“Executable Properties”配置界面。
(3)进入“Profiling Options”配置界面,配置项按默认配置
实现上述配置后单击窗口右下角的“Start”按钮,启动 Profiling。工程执行实现后,MindStudio 自动弹出 Profiling 后果视图。
先来看下全量迭代耗时数据,在 Timeline 视图下查看 Step Trace 数据迭代耗时状况,辨认耗时较长迭代进行剖析。留神,可抉择导出对应迭代 Timeline 数据,单击耗时较长迭代按钮
弹出对话框,单击“Yes”导出对应迭代 Timeline 数据。如图所示,如果最后看不见,倡议将鼠标放到图上,之后滑动放大,就能看见了。
还能够查看迭代内耗时状况:存在较长耗时算子时,能够进一步找算子详细信息辅助定位;存在通信耗时或调度间隙较长时,剖析调用过程中接口耗时。如图所示。
在界面下方还能查看对应的算子统计表:查看迭代内每个 AICORE 和 AICPU 算子的耗时及详细信息,进一步定位剖析算子的 Metrics 指标数据,剖析算子数据搬运、执行流水的占比状况,辨认算子瓶颈点。
此外,这里还能查看组件接口耗时统计表:查看迭代内 AscendCL API 和 Runtime API 的接口耗时状况,辅助剖析接口调用对性能的影响。
这个要说一下,限于屏幕大小,上述这次数据的残缺展现,可能须要放大或放大,或者调整某些局部大小,这些操作很卡顿,操作起来没什么反馈,好像这个界面卡死了,可用性差,用户体验不好,倡议优化一下。
咱们能够看到下图中这个 Op 的 Task Wait Time 要 9.895us,而其余 Op 根本为 0,所以能够思考试试能不能缩小这个 Wait Time,从而晋升性能。
这里说一下,上图中这个 Op Name 很长,我须要将这栏横向拉伸很长能力残缺显示,这有点麻烦,我原本想将鼠标悬停此处,让其主动显示残缺名称,但如同不行,是否思考加一下这个悬停显示全部内容的操作,否则我要先拉伸看,之后再拉回去看其余,比拟麻烦。
还记得之前咱们在专家系统工具那时提到的 MTE2 瓶颈相比之下有些大(约 0.39)嘛?这里从下图看到 Mte2 工夫较长,约 3.7ms,说一下,mte2 类型指令应该是 DDR->AI Core 搬运类指令,这里咱们量化一下看看,如下图所示,AI Core 工夫约为 6.8ms,但 Task Duration 约 12.5ms,简直翻倍了,阐明咱们 Task 只有约一半工夫是真正用于 AI Core 计算,很显著很多工夫被节约了。
阐明这一点还是比拟值得优化的。而各个工具之间也是能够互相辅助,互相验证更好地帮忙咱们定位问题。上面咱们再看看,先确认下 Timeline 色彩配置调色板,如下图所示。而咱们之前看到的 Timeline 根本是绿色,未见黄色或红色,预计没什么优化空间了。还是优先做显著地值得优化地点吧,这也算抓大放小吧。
好了,咱们再看点其余的,比方 Analysis Summary,这里展现了比拟具体的软硬件信息,比方 Host Computer Name、Host Operating System 等,还有咱们 ECS 上用的 CPU 的详细信息,包含型号、逻辑外围数量等,令我感兴趣的是,还有 Ascend 310 的信息,包含 AI Core 数量 2,AI CPU 数量 4,Control CPU 数量 4,Control CPU Type 为 ARMv8_Cortex_A55,以及一个 TS CPU,很具体了,很好地展现了 Ascend 310 的外部硬件信息,更有助于咱们理解这款处理器。
同时,再来看看 Baseline Comparison 吧。
总的来说,MindStudio 提供了 Host+Device 侧丰盛的性能数据采集能力和全景 Timeline 交互剖析能力,展现了 Host+Device 侧各项性能指标,帮忙用户疾速发现和定位 AI 利用、芯片及算子的性能瓶颈,包含资源瓶颈导致的 AI 算法短板,领导算法性能晋升和系统资源利用率的优化。MindStudio 反对 Host+Device 侧的资源利用可视化统计分析,具体包含 Host 侧 CPU、Memory、Disk、Network 利用率和 Device 侧 APP 工程的硬件和软件性能数据。
通过 Profiling 性能剖析工具前后两次对网络应用推理的运行工夫进行剖析,并比照两次执行工夫能够得出结论,能够帮忙咱们去验证替换函数或算子后,是否又性能晋升,是否晋升了推理效率。此外,还能够帮忙咱们筛选应该优先选择的网络模型,或者测试自定义算子是否达到最优性能,是否还存在优化空间等等,还是挺有用的。
MindStudio 精度比对工具
1. 定义
为了帮忙开发人员疾速解决算子精度问题,须要提供自有实现的算子运算后果与业界规范算子运算后果之间进行精度差别比照的工具。
2. 性能
提供 Tensor 比对能力,蕴含余弦类似度、欧氏绝对间隔、绝对误差(最大绝对误差、均匀绝对误差、均方根误差)、相对误差(最大相对误差、均匀相对误差、累积相对误差)、KL 散度、标准差算法比对维度。
总结
- MindStudio 的装置过于繁琐
暂不谈 Linux 下的装置和配置,以本次的 Windows 下 MindSutido 搭配近程 ECS 应用来说,Windows 下除了要装置 MindStudio 安装包,还要装置 Python 依赖,装置 MinGW 依赖,以及装置 CMake 等,太麻烦了。是否做成一键装置,毕竟这是个 IDE,感觉应用其余 IDE 都是一键装置,就算有其余依赖,个别也是在 IDE 外部依据须要,自行抉择装置即可,这个 MindStudio 可麻烦了,装置的依赖还很扩散。
- 还是性能问题,性能优化不好
Windows 下 MindStudio 的 CPU、内存等资源占用很大,远大于其余类型 IDE(比方 PyCharm、IntelliJ IEDA 等),而且还卡顿,这还是近程连贯 ECS 应用,可就是这样,感觉本地电脑也快腾飞了,远不如 PyCharm、IntelliJ IEDA 等应用起来顺畅,感觉是软件优化不行,如果是全副在物理机上运行,可能资源开销就更大了,这也太减少负载了,如果是这样,IDE 的可视化操作意义就不大了,很多操作不如在终端执行,将更多资源留给更有用的中央。