派大星 · 2021年04月08日

Bolt v1.2加速深度学习推理,发挥x86 CPU极致性能

首发:NeuralTalk
作者:华为诺亚

Bolt是基于华为诺亚方舟实验室研究成果,开源社区孵化的高性能深度学习推理加速库。目前已经更新v1.2版本,主要新增如下特性

  • 1. 新增3D卷积加速,
  • 2. Windows和Mac编译支持,
  • 3. 大幅提升x86推理性能,
  • 4. 提高易用性和稳定性,
  • 5. 开发了图像分类入门教程。

欢迎大家前往下载使用。用户交流QQ群:833345709。

1. Bolt v1.2 x86概况

在ARM CPU的推理加速上Bolt已经处于业界领先地位,见《深度学习加速库Bolt领跑端侧AI,而在x86平台上Bolt也在不断追赶和超越。在新版本中,Bolt开源了一些x86平台的工作,目前Bolt已经能够支持大部分CV/NLP网络x86平台的推理加速,经过大量优化和迭代,Bolt x86性能如今已经能够超越业界标杆Intel Openvino,而与其他开源同类库相比,具有更为明显的优势。

以下为Bolt x86 FP32单线程性能表现:

image.png

图 1 x86单线程实测性能

Bolt目前尚未支持x86上其他数据精度的推理(PS:看来bf16也在未来考虑)。

2. Bolt v1.2 x86优化细节

x86平台优化主要_利用intel SSE/AVX/AVX2进行加速_,采用汇编针对高性能核心算子进行了细致的优化,同时_结合图优化_挖掘网络的性能优化空间。

以卷积为例,Bolt x86的卷积算子采用直接计算方式

// 示例1.Bolt的卷积分块实现部分代码HWout = Hout * Woutfor (int n = 0; n < N; n++)  for (int icb = 0; icb < IC; icb += BLOCK_IC_DIM)    for (int oxyb = 0; oxyb < HWout; oxyb += BLOCK_HW_DIM)      for (int ocb = 0; ocb < OC; oc += BLOCK_OC_DIM)        //unroll        for (int oxy = oxyb; oxy < oxyb + BLOCK_HW_DIM; oxy++)          for (int ic = icb; ic < icb + BLOCK_IC_DIM; ic++) {            for (int ky = 0; ky < KH; ky++)              for (int kx = 0; kx < KW; kx++)                for (int oc = ocb; oc < ocb + BLOCK_OC_DIM; oc++) {                  const int iy = oxy / Wout * SH;                  const int ix = oxy % Wout * SW;                  output[n][oy][ox][oc] +=                     input[n][iy][ix][ic] * filter[oc][ky][kx][ic];                }

在实现过程中,优化策略有:

  1. 首先对循环进行了分块(见上面代码示例1),优化Cache性能并且便于后续的向量化;
  2. SIMD、FMA指令。主要采用AVX2 + FMA对卷积计算进行加速;
  3. 循环展开系数。为了提高计算并行度,对oxy循环进行展开,展开粒度为UNROLL\_HW,此时可以结合向量化方式来确定UNROLL\_HW和BLOCK\_OC\_DIM的值;
  4. 确定使用的寄存器个数。根据AVX2主要有16个256bit的向量寄存器,为了保证数据的重用性同时尽量利用更多的寄存器:
  5. 用12个寄存器来保存输出结果,也就是一次可以得到96个FP32的计算结果,那么可以选择3x32, 4x24, 6x16, 8x12,其中循环展开系数为UNROLL\_HW=3,分块系数BLOCK\_OC\_DIM=32,依此类推。
  6. Bolt在计算过程中会根据卷积计算的规模动态选择向量化的粒度并推断相应的分块参数,进行数据packing,保证在不同的输入和卷积参数下都能取得最优性能。如图2为Bolt和MKL-DNN(现oneDNN)卷积算子的性能对比,处理器频率在3.6GHz,处理器峰值性能115GFlops.
    • *

image.png

图2 Bolt x86 conv3x3实测性能

3. Bolt v1.2 x86上手指南

Bolt目前支持Linux/Winows/Mac直接编译x86,交叉编译Android/iOS。支持常见的caffe/onnx/tflite模,提供了简单易用转模型X2bolt和测试工具benchmark

对C/Java API进行简化,增加检查,日志,将一些常用CV网络纳入测试范畴,提升稳定性。下面以一个常见的resnet50模型测试和算子性能测试为例讲解工具使用。

首先准备编译环境,Linux系统请保证gcc编译器版本在4.9.0及以上,Windows系统请先安装一个shell环境,安装mingw-w64-posix-seh(https://sourceforge.net/proje...)版本。示例指令如下:

mkdir bolt && cd boltgit clone https://github.com/huawei-noah/bolt.git# windows用户编译./install.sh --target=windows-x86_64_avx2 -t 33 --converter=ON –example# linux用户编译./install.sh --target=linux-x86_64_avx2 -t 33 --converter=ON –example# 模型转换,提前准备模型在resnet50目录下,这一步会该目录下生成resnet50_f32.bolt文件./install_linux-x86_64_avx2/tools/X2bolt –d ./resnet50 –m resnet50 –i FP32# benchmark性能测试,loop=100./install_linux-x86_64_avx2/examples/benchmark –m ./resnet50/resnet50_f32.bolt –l 100# 卷积算子性能测试,参数分别为in, ic, ih, iw, fn, fc, fh, fw, group, stride, pad, on, oc, oh, ow./install_linux-x86_64_avx2/tests/test_convolution 1 64 128 128 64 64 3 3 1 1 1 1 64 128 128

_更多详细内容请参考_Bolt 文档:https://github.com/huawei-noa...

具体的应用部署中,Bolt提供C API和Java API可供使用,编译后的API文件生成在./install\_ linux-x86\_64\_avx2/include目录下,对应的库文件生成在./install\_ linux-x86\_64\_avx2/lib目录下,可以参考Bolt提供的图像分类教程:https://github.com/huawei-noa...

以上就是本文的全部内容,相关代码和文档均在Bolt Github(https://github.com/huawei-noa...),欢迎大家使用体验并积极反馈,未来我们会继续利用高性能计算优化技术和编译技术,持续加速深度学习领域,将更多的研究结果带到社区。

往期回顾


本作品采用知识共享署名-相同方式共享 4.0 通用许可协议进行许可。
欢迎关注公众号,关注模型压缩、低比特量化、移动端推理加速优化、部署。
嵌入式AI.jpg
更多嵌入式AI相关技术干货请关注嵌入式AI专栏。
推荐阅读
关注数
16569
内容数
1230
嵌入式端AI,包括AI算法在推理框架Tengine,MNN,NCNN,PaddlePaddle及相关芯片上的实现。欢迎加入微信交流群,微信号:aijishu20(备注:嵌入式)
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息