### 4.2.2.NNIE介绍 #### 4.2.2.1 NNIE概念 NNIE是Neural Network Inference Engine的简称,是上海海思媒体SoC中专门针对神经网络特别是深度学习卷积神经网络进行加速处理的硬件单元,支持现有大部分的公开网络,如Alexnet、VGG16、Googlenet、Resnet18、Resnet50等分类网络,FasterR-CNN、YOLO、SSD、RFCN等检测网络,以及SegNet、FCN等场景分割网络。用户基于NNIE开发智能分析方案,降低CPU占用。 目前NNIE配套软件及工具链仅支持Caffe框架,使用其他框架的网络模型需要转化为Caffe框架下的模型。 #### 4.2.2.2 NNIE API接口 NNIE模块提供了创建任务和查询任务的基本接口。 l HI_MPI_SVP_NNIE_LoadModel:从用户事先加载到buf中的模型中解析出网络模型。 l HI_MPI_SVP_NNIE_GetTskBufSize:获取给定网络任务各段辅助内存大小。 l HI_MPI_SVP_NNIE_Forward:多节点输入输出的CNN类型网络预测。 l HI_MPI_SVP_NNIE_ForwardWithBbox:多个节点feature map输入。 l HI_MPI_SVP_NNIE_UnloadModel:卸载模型。 l HI_MPI_SVP_NNIE_Query:查询任务是否完成。 l HI_MPI_SVP_NNIE_AddTskBuf:记录TskBuf地址信息。 l HI_MPI_SVP_NNIE_RemoveTskBuf:移除TskBuf地址信息。 NNIE API接口中参数的数据类型类型,请查阅**源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中**的《HiSVP API 参考.pdf》中的2.4 数据类型和数据结构内容,如下图所示: ![](./figures/hispark_taurus_nnie_sample/001SVP%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E5%92%8C%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.png) **注:本章节提到的错误码,请查阅源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中的《HiSVP API 参考.pdf》操作手册中对应的错误码内容。** 接下来对NNIE API接口进行详细描述。 ###### HI_MPI_SVP_NNIE_LoadModel 【描述】 * 从用户事先加载到buf中的模型中解析出网络模型。 【语法】 * HI_S32 HI_MPI_SVP_NNIE_LoadModel (const SVP_SRC_MEM_INFO_S *pstModelBuf, SVP_NNIE_MODEL_S *pstModel); 【参数】 ![](./figures/hispark_taurus_nnie_sample/002HI_MPI_SVP_NNIE_LoadModel%E5%8F%82%E6%95%B0.png) 【返回值】 ![](./figures/hispark_taurus_nnie_sample/003HI_MPI_SVP_NNIE_LoadModel%E8%BF%94%E5%9B%9E%E5%80%BC.png) 【需求】 * 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h * 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 【注意】 * 用户需要保证pstModelBuf中的地址所指向的内存中存储的模型数据的完整性和正确性。 * 用户需要保证pstModelBuf中的地址所指向的内存只有当所存储的模型不再使用后才能被释放,并且在释放之前内存中的数据不能被修改。 * 用户需要保证解析获得的pstModel里的内容不能被修改。 ###### HI_MPI_SVP_NNIE_GetTskBufSize 【描述】 * 获取给定网络任务各段辅助内存大小。 【语法】 * HI_S32 HI_MPI_SVP_NNIE_GetTskBufSize(HI_U32 u32MaxBatchNum, HI_U32 u32MaxBboxNum, const SVP_NNIE_MODEL_S *pstModel, HI_U32 au32TskBufSize[], HI_U32 u32NetSegNum); 【参数】 ![](./figures/hispark_taurus_nnie_sample/004HI_MPI_SVP_NNIE_GetTskBufSize%E5%8F%82%E6%95%B0.png) 【返回值】 ![](./figures/hispark_taurus_nnie_sample/005HI_MPI_SVP_NNIE_GetTskBufSize%E8%BF%94%E5%9B%9E%E5%80%BC.png) 【需求】 * 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h * 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 【注意】 * 针对单线程运行一个网络模型,用户开辟tskBuf可以根据网络段的运行关系来选择以下两种方案: * 1)NNIE→非NNIE→NNIE→非NNIE,类似这种NNIE、非NNIE(CPU或者DSP等)间隔的网络,用户可以选择开辟一个分段au32TskBufSize[]中的最大值,每个段可以复用这段内存; * 2)NNIE→NNIE→非NNIE→NNIE→非NNIE,类似这种存在N个NNIE连续顺序执行段的网络,连续的NNIE段不能复用tskBuf,按照最省内存原则可以选择开辟满足这N个连续NNIE段的其中N-1个size和最小的tskBuf以及剩余所有段中最大的一片tskBuf,具体按文中示例,可以选择开辟“NNIE→NNIE”中较小size的tskBuf,后面“非NNIE→NNIE→非NNIE”中可以复用最大size这片taskBuf; * 多线程运行同一个网络模型,每个线程需要各自独立的tskBuf,开辟的方式可以参考“针对单线程运行一个网络模型”的情况。 ###### HI_MPI_SVP_NNIE_Forward 【描述】 * 多节点输入输出的CNN类型网络预测。 【语法】 * HI_S32 HI_MPI_SVP_NNIE_Forward(SVP_NNIE_HANDLE *phSvpNnieHandle, const SVP_SRC_BLOB_S astSrc[], const SVP_NNIE_MODEL_S *pstModel, const SVP_DST_BLOB_S astDst[], const SVP_NNIE_FORWARD_CTRL_S *pstForwardCtrl, HI_BOOL bInstant); 【参数】 ![](./figures/hispark_taurus_nnie_sample/006HI_MPI_SVP_NNIE_Forward%E5%8F%82%E6%95%B0.png) ![](./figures/hispark_taurus_nnie_sample/007HI_MPI_SVP_NNIE_Forward%E5%8F%82%E6%95%B02.png) ![](./figures/hispark_taurus_nnie_sample/008HI_MPI_SVP_NNIE_Forward%E5%8F%82%E6%95%B03.png) 【返回值】 ![](./figures/hispark_taurus_nnie_sample/009HI_MPI_SVP_NNIE_Forward%E8%BF%94%E5%9B%9E%E5%80%BC.png) 【需求】 * 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h * 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 【注意】 * 用户需要保证pstModel->stBase中的地址所指向的内存中数据的完整性和正确性。 * 用户需要保证pstModel结构体中的内容与pstModel->stBase中的地址所指向的内存中的数据是同一个模型文件解析获得的。 * 网络段类型为SVP_NNIE_NET_TYPE_RECURRENT类型时,用户需要保证类型为SVP_BLOB_TYPE_SEQ_S32的输入输出blob中虚拟地址virt_addr_step及其指向内存大小的正确性。 * U8图像输入只支持1通道(灰度图)和3通道(RGB图); * 多个Blob输入输出时,配合编译器输出的dot描述文件生成的dot图示,可以看到Blob跟层的对应关系。 NNIE_Forward支持的多节点输入输出网络示意图如下图所示: ![](./figures/hispark_taurus_nnie_sample/010%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA%E7%BD%91%E7%BB%9C%E7%A4%BA%E6%84%8F%E5%9B%BE.png) ###### HI_MPI_SVP_NNIE_UnloadModel 【描述】 * 卸载模型。 【语法】 * HI_S32 HI_MPI_SVP_NNIE_UnloadModel(SVP_NNIE_MODEL_S *pstModel); 【参数】 ![](./figures/hispark_taurus_nnie_sample/011HI_MPI_SVP_NNIE_UnloadModel%E5%8F%82%E6%95%B0.png) 【返回值】 ![](./figures/hispark_taurus_nnie_sample/012HI_MPI_SVP_NNIE_UnloadModel%E8%BF%94%E5%9B%9E%E5%80%BC.png) 【需求】 * 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h * 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 【注意】 * 无。 ###### HI_MPI_SVP_NNIE_Query 【描述】 * 查询任务是否完成。 【语法】 * HI_S32 HI_MPI_SVP_NNIE_Query(SVP_NNIE_ID_E enNnieId, SVP_NNIE_HANDLE svpNnieHandle, HI_BOOL *pbFinish, HI_BOOL bBlock); 【参数】 ![](./figures/hispark_taurus_nnie_sample/013HI_MPI_SVP_NNIE_Query%E5%8F%82%E6%95%B0.png) 【返回值】 ![](./figures/hispark_taurus_nnie_sample/014HI_MPI_SVP_NNIE_Query%E8%BF%94%E5%9B%9E%E5%80%BC.png) 【需求】 * 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h * 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 【注意】 * 无。 ###### HI_MPI_SVP_NNIE_AddTskBuf 【描述】 * 记录TskBuf地址信息。 【语法】 * HI_S32 HI_MPI_SVP_NNIE_AddTskBuf(const SVP_MEM_INFO_S *pstTskBuf); 【参数】 ![](./figures/hispark_taurus_nnie_sample/015HI_MPI_SVP_NNIE_AddTskBuf%E5%8F%82%E6%95%B0.png) 【返回值】 ![](./figures/hispark_taurus_nnie_sample/016HI_MPI_SVP_NNIE_AddTskBuf%E8%BF%94%E5%9B%9E%E5%80%BC.png) 【需求】 * 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h * 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 【注意】 * 记录TskBuf地址信息,用于减少内核态内存映射次数,提升效率。 * TskBuf地址信息的记录是通过链表进行管理,链表长度默认值为32,链表长度可通过模块参数nnie_max_tskbuf_num进行配置。 * 若没有调用HI_MPI_SVP_NNIE_AddTskBuf预先把TskBuf地址信息记录到系统,那么之后调用Forward/ForwardWithBbox每次都会Map/Unmap操作TskBuf内核态虚拟地址,效率会比较低。 * 必须与HI_MPI_SVP_NNIE_RemoveTskBuf成对匹配使用。 * 建议先把Forward/ForwardWithBbox用到的TskBuf地址信息调用此接口记录到系统。当不再使用时调用HI_MPI_SVP_NNIE_RemoveTskBuf把TskBuf地址信息移除。只需要在初始化时把TskBuf地址信息记录,后续可以直接使用,直到不再使用时才移除。 * pstTskBuf->u64VirAddr不使用,不做参数异常检查。 * pstTskBuf->u32Size不能为0。 * TskBuf内存由用户释放,记录的TskBuf要在移除后才能被释放。 **HI_MPI_SVP_NNIE_RemoveTskBuf** 【描述】 移除TskBuf地址信息。 【语法】 HI_S32 HI_MPI_SVP_NNIE_RemoveTskBuf(const SVP_MEM_INFO_S *pstTskBuf); 【参数】 ![](./figures/hispark_taurus_nnie_sample/017HI_MPI_SVP_NNIE_RemoveTskBuf%E5%8F%82%E6%95%B0.png) 【返回值】 ![](./figures/hispark_taurus_nnie_sample/018HI_MPI_SVP_NNIE_RemoveTskBuf%E8%BF%94%E5%9B%9E%E5%80%BC.png) 【需求】 * 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h * 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 【注意】 * 如果TskBuf不再使用,需要将记录的TskBuf地址信息从链表中移除。 * 必须与HI_MPI_SVP_NNIE_AddTskBuf成对匹配使用。 * pstTskBuf->u64VirAddr不使用,不做参数异常检查。 * pstTskBuf->u32Size不能为0。 * TskBuf内存由用户释放,记录的TskBuf要在移除后才能被释放。 #### 4.2.2.3 NNIE推理逻辑图 开发者将RuyiStudio工具量化后生成的wk模型文件通过插件进行加载,并部署到芯片端的Flash或DDR里面,通过NNIE加速器进行推理,NNIE板测推理逻辑图如下: ![](./figures/hispark_taurus_nnie_sample/019NNIE%20%E6%8E%A8%E7%90%86%E9%80%BB%E8%BE%91%E5%9B%BE.png)