使用OpenVINO™优化和部署DenseNet模型并在DevCloud上完成性能测试
概述
Intel® DevCloud for the Edge支持在英特尔的硬件平台上主动构建原型并试验面向计算机视觉的AI 工作负载。其硬件平台托管在云环境中,专门用于深度学习,用户可以全面访问这些硬件平台。用户可以使用Intel® OpenVINO™工具套件以及CPU、GPU和VPU和FPGA的组合来测试模型的性能。Intel® DevCloud使用Jupyter* Notebook直接在web浏览器中执行代码,并立即看到可视化结果。用户可以在云环境中构建创新的计算机视觉解决方案原型,然后利用可用的硬件资源执行代码。
本文借助DevCloud内包含的Jupyter* Notebook教程和示例,及OpenVINO™工具套件包含的Benchmark_APP等工具,将下载并转换为IR格式文件的FC-DenseNet-103模型到DevCloud,选择不同的边缘节点,以不同的硬件平台测试模型的性能,完成边缘原型的构建,得到高性能的AI部署解决方案。
在本文中所使用的模型为FC-DenseNet-103—百层提拉米苏,全卷积的DenseNet图像分割模型,如图 1所示为其在CamVid测试集的定性结果。模型FC-DenseNet-103的论文原始出处为:https://arxiv.org/pdf/1611.09326.pdf。
图 1 在CamVid测试集的定性结果
本文具体步骤主要分为以下四步:
第一步,安装TensorFlow相关支持并验证安***r/>第二步,下载并运行FC-DenseNet-03预训练模型
第三步,将Keras h5模型转换模型为ONNX格式和IR格式文件
第四步,使用Benchmark_APP在各个目标硬件上进行性能测试
本文需要的软件运行环境及其对应版本如下:
OpenVINO™ 2021.4 LTS
TensorFlow 2.2.0
Python 3.8.10
1. 使用OpenVINO™工具套件转化和部署FC-DenseNet-103模型
1.1 OpenVINO™工具套件简介
OpenVINO™工具套件全称是Open Visual Inference & Neural Network Optimization,是英特尔®于2018年发布的开源工具包,专注于优化神经网络推理。OpenVINO™工具套件主要包括Model Optimizer(模型优化器)和Inference Engine(推理引擎)两个部分。Model Optimizer是用于优化神经网络模型的工具,Inference Engine是用于加速推理计算的软件包。如图1-1所示,即为OpenVINO™工具套件的主要组成部分。图1-1 OpenVINO™工具套件
1.2 安装Keras2ONNX转换ONNX模型
Keras最初是由Google工程师撰写的研究项目,是基于TensorFlow的深度学习库,是由Python语言编写而成的高层神经网络API。如果安装了TensorFlow2.2.0,则已经安装了Keras,ONNX模型(开放神经网络变换)是一种用于表示深度学习模型的开放格式。我们需要将FC-DenseNet-103模型转换为ONNX模型,再使用OpenVINO™工具套件进行优化部署。具体转换的步骤如下:
第一步,在将Keras模型转换为ONNX之前,需要安装Keras2onnx软件包。打开windows命令行终端,进入TensorFlow虚拟环境,输入命令< pip install keras2onnx >安装Keras2ONNX支持,如图1-2所示:
图1-2 安装Keras2ONNX支持
或者从源代码安装Keras2ONNX,使用命令为:< pip install -U git+https://github.com/microsoft/onnxconverter-common;pip install -U git+https://github.com/onnx/keras-onnx > ,Keras2ONNX的安装依赖于onnxconverter-common,此转换器的最新代码需要onnxconverter-common的最新版本,因此,如果从源代码安装此转换器,需要,安装Keras2ONNX之前以源码形式安装onnxconverter-common。
第二步,转换ONNX模型,在打开的“TensorFlow”虚拟环境命令行终端,通过运行命令<python convert_to_onnx.py>来运行转换ONNX模型的Python脚本,其代码具体内容如代码清单1-1所示:
代码清单1-1 转换ONNX模型
from tensorflow.kera***odels import Model
from tensorflow.keras.layers import *
from tiramisu.model import create_tiramisu
import keras2onnx
# Set the weight file name
kera***odel_weight******odel***y_tiramisu.h5"
onnx_model_weights = kera***odel_weights.split('.')[0]+'.onnx'
# Load model and weights
input_shape = (224, 224, 3)
number_classes = 32 # CamVid data consist of 32 classes
# Prepare the model information
img_input = Input(shape=input_shape, batch_size=1)
x = create_tiramisu(number_classes, img_input)
model = Model(img_input, x)
# Load the kera***odel weights
model.load_weights(kera***odel_weights)
print("Line17")
print(model.name)
onnx_model = keras2onnx.convert_kera***odel, model.name)
# Save the onnx model weights
keras2onnx.save_model(onnx_model, onnx_model_weights)
运行成功后会在“models”文件夹中自动生成名为my_tiramisu.onnx的ONNX模型,用以进行OpenVINO™工具套件的优化部署。
1.3 使用Model_Optimizer优化模型
使用OpenVINO™工具套件将ONNX模型转换为IR格式文件,需要以下几步:
第一步,初始化OpenVINO™工具套件,进入Windows命令行终端,输入命令<"C:\Program Files (x86)\Intel\openvino_2021.4.582\bin\setupvar***at">对其进行初始化。
第二步,使用Model_Optimizer将ONNX模型转换为IR格式文件,首先进入<INSTALL_DIR>\deployment_tools\model_optimizer路径下的命令行终端,使用命令 <python mo_onnx.py --input_model <models_dir>\my_tiramisu.onnx --output_dir <ir_dir>> ,即可生成如图1-3所示的IR格式文件。
图1-3 转换成IR格式文件
1.4 Inference Engine 应用程序典型开发流程
Inference Engine典型的开发流程一共有八步,如图1-4所示。每一步使用相应的API函数进行应用程序的开发。本文基于1.3节生成的IR格式文件my_tiramisu.xml和my_tiramisu.bin从零开始,实现完整的OpenVINO™ AI推理Python程序。
图1-4 Inference Engine典型开发流程
本文通过直接调用Inference Engine Python API函数来开发OpenVINO™ AI推理计算Python程序,具体步骤如下:
具体代码如下:inference_run.py
第一步,导入必要的openvino.inference_engine、cv2、numpy、time、os、sys、decode和argparse模块并配置相关变量,如代码清单1-2所示。
代码清单1-2 导入必要模块
from openvino.inference_engine import IECore
import numpy as np
import time
import cv2 as cv
import os,sys
from camvid.mapping import decode
import argparse
第二步,使用ie=IECore()方法,初始化IECore实例,此类表示推理引擎实体,并允许使用统一的接口操纵插件,如代码清单1-3所示。参考Inference_Engine典型推理流程第一步。
代码清单1-3 初始化IECore()实例
#1.初始化IECore()实例
ie = IECore()
for device in ie.available_devices:
print(device)
第三步,读取IR文件,用net=ie.read.network()方法将IR文件读取到对象net中去,如代码清单1-4所示。参考Inference_Engine典型推理流程第二步。
代码清单1-4 读取IR文件
#2.读入IR格式文件
model_xml = "model***y_tiramisu.xml"
model_bin = "model***y_tiramisu.bin"
net = ie.read_network(model=model_xml, weight***odel_bin)
第四步,配置输入输出,通过input_info和output_info的方法来配置网络输入输出,如代码清单1-5所示。参考Inference_Engine典型推理流程第三步。
代码清单1-5 配置输入输出
#3.配置输入和输出
input_blob = next(iter(net.input_info))
out_blob = next(iter(net.outputs))
第五步,载入模型到执行硬件,使用exec_net=ie.load_network(),将从中间表示 (IR) 读取的网络加载到具有指定设备名称的插件中,载入模型到执行硬件,如代码清单1-6所示。参考Inference_Engine典型推理流程第四步。
代码清单1-6 载入模型到执行硬件
#4.载入模型到执行硬件
exec_net = ie.load_network(network=net, device_name=args.d)
第六步,准备输入数据,根据AI模型输入张量的要求,对图像进行缩放处理,创建模型的输入数据,如代码清单1-7所示。参考Inference_Engine典型推理流程第六步。
#5.准备输入数据
n, h, w, c = net.input_info[input_blob].input_data.shape
print(n, h, w, c)
test = 'images/test_image1.png'
frame = cv.imread(test)
print(frame.shape)
image = cv.resize(frame, (w, h))
#image = image.transpose(2, 0, 1)
print(image.shape)
img_input = image[np.newaxis,:]
第七步,创建推理请求并执行推理计算,在创建推理引擎和执行推理计算的步骤中,使用res=exec_net.infer()方法创建推理请求,并执行推理计算,还可以通过time模块来记录推理所用的时间,如代码清单1-8所示。参考Inference_Engine典型推理流程第五步和第七步
代码清单1-8 创建推理请求并执行推理计算
#6.创建推理请求, 7.执行推理计算
infer_time_list = []
inf_start = time.time()
res = exec_net.infer(inputs={input_blob:img_input})
inf_end = time.time() - inf_start
infer_time_list.append(inf_end)
第八步,处理计算结果,根据模型需要的输出格式,从net.infer()方法的返回值中获得推理计算结果,经过处理后将结果显示在图像上,如代码清单1-9所示。参考Inference_Engine典型推理流程第八步。
代码清单1-9 处理计算结果
#8.处理计算结果
res = res[out_blob].reshape((n, h, w, 32))
res = np.squeeze(res, 0)
res = np.argmax(res, axis=-1)
hh, ww = res.shape
print(res.shape)
mask = color_label(res,id2code)
mask = cv.resize(mask, (frame.shape[1], frame.shape[0]))
result = cv.addWeighted(frame, 0.5, mask, 0.5, 0)
cv.putText(result, "infer time(ms): %.3f, FPS: %.2f"%(inf_end*1000, 1/(inf_end+0.0001)), (10, 50),
cv.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 255), 2, 8)
cv.imshow("semantic segmentation benchmark", result)
cv.waitKey(0) # wait for the image show
第九步,打开Windows的命令行终端,进入tensorflow2.2.0版本的虚拟环境中,初始化OpenVINO™工具套件,然后使用命令<python inference_run.py -d CPU>运行程序,推理结果如图1-5所示,至此,整个部署流程就结束了,已经成功把模型落地并部署到了边缘设备的CPU上。
图1-5 推理结果
2.使用Intel® DevCloud 不同边缘节点进行性能测试
面向边缘的Intel® DevCloud是一项云服务,旨在帮助开发人员使用Intel® OpenVINO™工具套件构建原型并试验计算机视觉应用,注册成功后,可以访问一系列的基于Python和C++的Iupyter* Notebook教程和示例解决方案,并通过web浏览器直接执行。本文通过Jupyter* Notebook中给出的基于Python语言的Benchmark_APP示例,访问不同的边缘节点进行性能测试。
使用Intel® DevCloud在不同的边缘节点进行性能测试一共分为四个步骤,
第一步,在Intel® DevCloud的Benchmak_APP目录下创建IR_models文件夹目录结构
第二步,将FC-DenseNet-103 IR模型导入IR_models内对应数据格式子文件夹
第三步,使用Benchmark_APP对不同的边缘节点进行性能测试
第四步,通过测试结果进行性能分析,选出高性能AI部署解决方案
具体步骤如流程图2-1所示:
流程图2-1 使用Intel® DevCloud在不同的边缘节点进行性能测试
2.1 生成IR_models目录结构并导入模型
在Jupyter* Notebooks的Reference-samples/iot-devcloud/openvino-dev-latest/develop-samples/python/benchmarkAPP-python的所在目录中,创建IR_models目录结构,因为Benckmark_APP的路径是固定的,需要配合其固定好的目录结构,让Benchmark_APP能够找到对应的IR_models。首先创建IR_models文件夹,并在文件夹中创建FP16、FP16-INT8、FP32三个不同数据格式的子文件夹,上传自己的模型到对应的子文件夹中。其具体步骤如下:
第一步,首先进入网址https://devcloud.intel.com/edge/,注册并登录,然后进入网址https://software.intel.com/content/www/us/en/develop/tools/devcloud/edge/build.html后,点击页面中显示的“Connect and Create”按键,如图2-1所示。即可转入Jupyter* Notebooks界面,然后即可运行相关测试。
图2-1 转入Jupyter* Notebooks界面
第二步,进入Reference-samples/iot-devcloud/openvino-dev-latest/develop-samples/python/benchmarkAPP-python路径目录下,然后点开右上方的“New”选项,在弹出的选项框中选择“Teminal”进入命令行终端。如图2-2所示。
图2-2 进入命令行终端
第三步,进入命令行终端后即可在命令行终端使用命令创建IR_models文件夹目录结构,进入Teminal后,使用命令< cd ~/Reference-samples/iot-devcloud/openvino-dev-latest/developer-samples/python/benchmarkApp-python >进入benchmarkAPP-python的文件夹目录下,再使用命令<ls>列出其全部子文件夹,然后使用命令<mkdir FC-DenseNet-103>创建FC-DenseNet-103模型所对应的工作文件夹,如图2-3所示。
图2-3 创建FC-DenseNet-103工作文件夹
第四步,使用命令<cd FC-DenseNet-103>进入其FC-DenseNet-103目录下,使用命令<mkdir IR_models>创建IR_models文件夹,继续使用命令<cd IR_models>进入其目录下,分别使用命令<mkdir FP16>、<mkdir FP16-INT8>,<mkdir FP32>创建三种不同数据类型的子文件夹,以配合Benchmark_APP需要的目录结构,三种不同数据格式的子文件夹创建完毕后,如图2-4所示,即可根据模型的数据格式上传到对应文件夹。
图2-4 创建IR_models目录结构
第五步,导入FC-DenseNet-103模型,根据使用模型优化器进行模型转换时的数据格式,对应不同子文件夹上传FC-DenseNet-103 IR模型,本文分别将数据格式为FP16和FP32的IR模型导入其对应的文件夹,如图2-5所示。首先分别进入FP16和FP32子文件夹内,点击右上角“Upload”按键,选择正确本地路径,再点击“确定”即可将FC-DenseNet-103 IR模型上传到对应数据格式的IR_models文件夹中。
图2-5 上传FC-DenseNet-103 IR模型
2.2 访问边缘节点进行性能测试
将“创建IR_models目录结构”和“导入本地FC-DenseNet-03模型”的准备工作做完后,即可访问Intel® DevCloud的边缘节点,对不同的Intel硬件进行性能的测试本文。使用Intel® DevCloud 提供的基于Python语言的Benchmark_APP示例,访问不同的边缘节点进行性能测试。其步骤如下:
第一步,打开Reference-samples/iot-devcloud/openvino-dev-latest/developer-samples/python/benchmarkApp-python路径下的“BenchmarkAPP.ipynb”,点击左边目录“1.9 Creating lists of FP16 and FP32 models”查看其Python脚本,并在脚本中添加语句“models = ["FC-DenseNet-103"]”,将第7行的代码由“elif”改为“if”然后从头运行到1.9节,可以看到以及读入FP16和FP32数据格式的FC-DenseNet-03 IR模型,如图2-6所示。
图2-6 读入IR_model****>
第二步,读入IR模型后,请先运行“BenchmarkAPP.ipynb”里的“Intel® Distribution of OpenVINO™ Toolkit version check:”和“Wait until the benchmarking report files are written”两个部分。然后即可使用深度学习模型对单个系统进行基准测试。在“Benchmark Individual system with the deep learning model”这一部分单元格中,列举五个不同硬件的边缘节点来进行推理工作。首先以“3.0.1 Run the Benchmark tool app with Intel® Core™ CPU”单元格为例,此单元格将作业提交给配备Intel® Core™ i5 6500TE CPU的IEI Tank* 870的边缘节点,推理工作将在CPU上运行。运行完此单元格后,会在“benchmarkAPP-python”路径下生成相关的“benchmark_app_job.sh…”相关运行日志文件。点开日志文件,便可以显示出在此边缘节点推理的吞吐量和延迟,如图2-7所示:
图2-7 在不同边缘节点的性能
第三步,确定Intel® DevCloud所支持的边缘节点群,边缘计算节点是面向物联网边缘机器学习推理构建和配置的工业计算系统,并已经托管在DenCloud中,一边使用预先开发的示例或者试验各种架构和解决方案。首先确定Intel® DevCloud所支持的边缘节点群,以及他们的Group ID。进入网址https://devcloud.intel.com/zh/edge/resource_docs/selecting_targets/-u8fb9-u7f18-u8282-u70b9即可查看Intel® DevCloud所支持的边缘节点群及其相关的配置信息,如图2-8所示:
图2-8 边缘节点群
3. 对不同边缘节点进行性能分析
在边缘节点群中可以根据需求选择不同的边缘节点,对不同的架构或解决方案进行试验,在本步骤以Group ID为idc046,CPU为Intel® Core™ i5 1145G7E,GPU为Intel® Iris® Xe Graphics边缘节点为例,介绍怎样在“BenchmarkAPP.ipynb”中添加新的边缘节点并使用Benchmark_APP对其边缘节点的模型部署进行性能测试和分析。
3.1 使用CPU边缘节点进行性能分析
使用Intel® Core™ i5 1145G7E CPU边缘节点进行性能分析的具体操作步骤如下:
第一步,在“BenchmarkAPP.ipynb”中重新打开一个单元格,并将单元格“3.0.1 Run the Benchmark tool app with Intel® Core™ CPU”里的代码脚本**进新打开的单元格。
第二步,将单元格内脚本代码的第一行<node = ‘idc001skl’>单引号里面的内容改为新的Group ID,即为改成<node = ‘idc046’>。启动运行单元格,同2.2节第二步表述的过程一样,会在“benchmarkAPP-python”路径下生成相关的“benchmark_app_job.sh…”相关运行日志文件。点开日志文件,便可以显示出在CPU为Intel® Core™ i5 1145G7E边缘节点推理的吞吐量和延迟,如图3-1所示:
图3-1 使用CPU边缘节点的性能
3.2 使用GPU边缘节点进行性能分析
使用Intel® Iris® Xe Graphics GPU边缘节点进行性能分析的具体操作步骤如下:
第一步,在“BenchmarkAPP.ipynb”中重新打开一个单元格,并将单元格“3.0.3 Run Benchmark tool application with Intel® HD Graphics 530 GPU”里的代码脚本**进新打开的单元格。
第二步,将单元格内脚本代码的第一行<node = ‘idc001skl’>单引号里面的内容改为新的Group ID,即为改成<node = ‘idc046’>。
第三步,由于本次的GPU边缘节点为Intel® Iris® Xe Graphics,且模型的数据格式为FP32,所以请修改脚本中第十九行<benchmarks["Intel® HD Graphics 530 GPU"] = wait_for_job_to_finish(job_id_gpu,verbose,model)> ,将双引号内的GPU版本更改为本次试验的GPU版本,即为<benchmarks["Intel® Iris® Xe Graphics GPU"] = wait_for_job_to_finish(job_id_gpu,verbose,model)>,如图3-2所示:
图3-2 更改单元格的代码脚本
第四步,代码更改完毕后,即可启动运行单元格,同2.2节第二步表述的过程一样,会在“benchmarkAPP-python”路径下生成相关的“benchmark_app_job.sh…”相关运行日志文件。点开日志文件,便可以显示出在GPU为Intel® Iris® Xe Graphics边缘节点推理的吞吐量和延迟,如图3-3所示:
图3-3 使用GPU边缘节点的性能
3.3 FC-DenseNet-103模型在不边同缘节点性能
将Group ID为idc046,CPU为Intel® Core™ i5 1145G7E,GPU为Intel® Iris® Xe Graphics边缘节点的CPU和GPU吞吐量和延迟测试出来后,即可同样步骤对其他边缘节点进行性能的分析,本文选择了7-11th CPU的边缘节点,进行性能的测试与对比,结果如表3-1所示,在表中的边缘节点群中可以根据需求选择不同的边缘节点,对不同的架构或解决方案进行试验。
表3-1 benchmark of FC-DenseNet-1034.总结
通过使用Intel® DevCloud的Benchmark_APP在各个目标硬件上进行性能测试,其覆盖的边缘计算方案可以应用多个场景,比如在最高吞吐量应用场景可以选择i7-1185G7或i5-1145G7搭配Iris® Xe Graphics,通过Iris® Xe Graphics进行IR模型的推理,最低功耗应用场景可以选择功耗为15W TDP的i7-1185G7或i5-1145G7,通过Iris® Xe Graphics进行IR模型的推理。或者推荐功耗为15W TDP的i7-8865U,由CPU做推理。由此看来DevCloud和OpenVINO™工具套件可以帮助计算机视觉应用程序开发人员充分利用其应用程序,并可以为每个任务和解决方案选择最理想的硬件。在AI应用程序、解决方案等开发过程中,在程序准备好后,我们可以在开发服务器的CPU上运行代码,或者将代码发送至Intel® DevCloud中的一个或者多个边缘计算硬件集群,以加速推理。通过这些试验,开发者可以完全了解了所需的知识,避免潜在的陷阱、优化性能,确认需要采购的硬件,以加速产品上市速度!
本文对应的源代码Github仓:https://github.com/WangAria/OpenVINO_FC,欢迎大家阅读并提出宝贵意见!