1### 4.2.2.NNIE介绍 2 3#### 4.2.2.1 NNIE概念 4 5NNIE是Neural Network Inference Engine的简称,是上海海思媒体SoC中专门针对神经网络特别是深度学习卷积神经网络进行加速处理的硬件单元,支持现有大部分的公开网络,如Alexnet、VGG16、Googlenet、Resnet18、Resnet50等分类网络,FasterR-CNN、YOLO、SSD、RFCN等检测网络,以及SegNet、FCN等场景分割网络。用户基于NNIE开发智能分析方案,降低CPU占用。 6 7目前NNIE配套软件及工具链仅支持Caffe框架,使用其他框架的网络模型需要转化为Caffe框架下的模型。 8 9#### 4.2.2.2 NNIE API接口 10 11NNIE模块提供了创建任务和查询任务的基本接口。 12 13l HI_MPI_SVP_NNIE_LoadModel:从用户事先加载到buf中的模型中解析出网络模型。 14 15l HI_MPI_SVP_NNIE_GetTskBufSize:获取给定网络任务各段辅助内存大小。 16 17l HI_MPI_SVP_NNIE_Forward:多节点输入输出的CNN类型网络预测。 18 19l HI_MPI_SVP_NNIE_ForwardWithBbox:多个节点feature map输入。 20 21l HI_MPI_SVP_NNIE_UnloadModel:卸载模型。 22 23l HI_MPI_SVP_NNIE_Query:查询任务是否完成。 24 25l HI_MPI_SVP_NNIE_AddTskBuf:记录TskBuf地址信息。 26 27l HI_MPI_SVP_NNIE_RemoveTskBuf:移除TskBuf地址信息。 28 29NNIE API接口中参数的数据类型类型,请查阅**源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中**的《HiSVP API 参考.pdf》中的2.4 数据类型和数据结构内容,如下图所示: 30 31 32 33**注:本章节提到的错误码,请查阅源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中的《HiSVP API 参考.pdf》操作手册中对应的错误码内容。** 34 35接下来对NNIE API接口进行详细描述。 36 37###### HI_MPI_SVP_NNIE_LoadModel 38 39【描述】 40 41* 从用户事先加载到buf中的模型中解析出网络模型。 42 43【语法】 44 45* HI_S32 HI_MPI_SVP_NNIE_LoadModel (const SVP_SRC_MEM_INFO_S *pstModelBuf, SVP_NNIE_MODEL_S *pstModel); 46 47【参数】 48 49 50 51【返回值】 52 53 54 55【需求】 56 57* 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h 58 59* 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 60 61【注意】 62 63* 用户需要保证pstModelBuf中的地址所指向的内存中存储的模型数据的完整性和正确性。 64 65* 用户需要保证pstModelBuf中的地址所指向的内存只有当所存储的模型不再使用后才能被释放,并且在释放之前内存中的数据不能被修改。 66 67* 用户需要保证解析获得的pstModel里的内容不能被修改。 68 69###### HI_MPI_SVP_NNIE_GetTskBufSize 70 71【描述】 72 73* 获取给定网络任务各段辅助内存大小。 74 75【语法】 76 77* 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); 78 79【参数】 80 81 82 83【返回值】 84 85 86 87【需求】 88 89* 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h 90 91* 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 92 93【注意】 94 95* 针对单线程运行一个网络模型,用户开辟tskBuf可以根据网络段的运行关系来选择以下两种方案: 96 97 * 1)NNIE→非NNIE→NNIE→非NNIE,类似这种NNIE、非NNIE(CPU或者DSP等)间隔的网络,用户可以选择开辟一个分段au32TskBufSize[]中的最大值,每个段可以复用这段内存; 98 99 * 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; 100 101* 多线程运行同一个网络模型,每个线程需要各自独立的tskBuf,开辟的方式可以参考“针对单线程运行一个网络模型”的情况。 102 103###### HI_MPI_SVP_NNIE_Forward 104 105【描述】 106 107* 多节点输入输出的CNN类型网络预测。 108 109【语法】 110 111* 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); 112 113【参数】 114 115 116 117 118 119 120 121【返回值】 122 123 124 125【需求】 126 127* 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h 128 129* 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 130 131【注意】 132 133* 用户需要保证pstModel->stBase中的地址所指向的内存中数据的完整性和正确性。 134 135* 用户需要保证pstModel结构体中的内容与pstModel->stBase中的地址所指向的内存中的数据是同一个模型文件解析获得的。 136 137* 网络段类型为SVP_NNIE_NET_TYPE_RECURRENT类型时,用户需要保证类型为SVP_BLOB_TYPE_SEQ_S32的输入输出blob中虚拟地址virt_addr_step及其指向内存大小的正确性。 138 139* U8图像输入只支持1通道(灰度图)和3通道(RGB图); 140 141* 多个Blob输入输出时,配合编译器输出的dot描述文件生成的dot图示,可以看到Blob跟层的对应关系。 142 143NNIE_Forward支持的多节点输入输出网络示意图如下图所示: 144 145 146 147###### HI_MPI_SVP_NNIE_UnloadModel 148 149【描述】 150 151* 卸载模型。 152 153【语法】 154 155* HI_S32 HI_MPI_SVP_NNIE_UnloadModel(SVP_NNIE_MODEL_S *pstModel); 156 157【参数】 158 159 160 161【返回值】 162 163 164 165【需求】 166 167* 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h 168 169* 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 170 171【注意】 172 173* 无。 174 175###### HI_MPI_SVP_NNIE_Query 176 177【描述】 178 179* 查询任务是否完成。 180 181【语法】 182 183* HI_S32 HI_MPI_SVP_NNIE_Query(SVP_NNIE_ID_E enNnieId, SVP_NNIE_HANDLE svpNnieHandle, HI_BOOL *pbFinish, HI_BOOL bBlock); 184 185【参数】 186 187 188 189【返回值】 190 191 192 193【需求】 194 195* 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h 196 197* 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 198 199【注意】 200 201* 无。 202 203###### HI_MPI_SVP_NNIE_AddTskBuf 204 205【描述】 206 207* 记录TskBuf地址信息。 208 209【语法】 210 211* HI_S32 HI_MPI_SVP_NNIE_AddTskBuf(const SVP_MEM_INFO_S *pstTskBuf); 212 213【参数】 214 215 216 217【返回值】 218 219 220 221【需求】 222 223* 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h 224 225* 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 226 227【注意】 228 229* 记录TskBuf地址信息,用于减少内核态内存映射次数,提升效率。 230 231* TskBuf地址信息的记录是通过链表进行管理,链表长度默认值为32,链表长度可通过模块参数nnie_max_tskbuf_num进行配置。 232 233* 若没有调用HI_MPI_SVP_NNIE_AddTskBuf预先把TskBuf地址信息记录到系统,那么之后调用Forward/ForwardWithBbox每次都会Map/Unmap操作TskBuf内核态虚拟地址,效率会比较低。 234 235* 必须与HI_MPI_SVP_NNIE_RemoveTskBuf成对匹配使用。 236 237* 建议先把Forward/ForwardWithBbox用到的TskBuf地址信息调用此接口记录到系统。当不再使用时调用HI_MPI_SVP_NNIE_RemoveTskBuf把TskBuf地址信息移除。只需要在初始化时把TskBuf地址信息记录,后续可以直接使用,直到不再使用时才移除。 238 239* pstTskBuf->u64VirAddr不使用,不做参数异常检查。 240 241* pstTskBuf->u32Size不能为0。 242 243* TskBuf内存由用户释放,记录的TskBuf要在移除后才能被释放。 244 245**HI_MPI_SVP_NNIE_RemoveTskBuf** 246 247【描述】 248 249移除TskBuf地址信息。 250 251【语法】 252 253HI_S32 HI_MPI_SVP_NNIE_RemoveTskBuf(const SVP_MEM_INFO_S *pstTskBuf); 254 255【参数】 256 257 258 259【返回值】 260 261 262 263【需求】 264 265* 头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h 266 267* 库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib) 268 269【注意】 270 271* 如果TskBuf不再使用,需要将记录的TskBuf地址信息从链表中移除。 272 273* 必须与HI_MPI_SVP_NNIE_AddTskBuf成对匹配使用。 274 275* pstTskBuf->u64VirAddr不使用,不做参数异常检查。 276 277* pstTskBuf->u32Size不能为0。 278 279* TskBuf内存由用户释放,记录的TskBuf要在移除后才能被释放。 280 281#### 4.2.2.3 NNIE推理逻辑图 282 283开发者将RuyiStudio工具量化后生成的wk模型文件通过插件进行加载,并部署到芯片端的Flash或DDR里面,通过NNIE加速器进行推理,NNIE板测推理逻辑图如下: 284 285 286