查看原文
其他

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

华为诺亚 NeuralTalk 2022-11-28

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单线程性能表现:

图 1 x86单线程实测性能

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

2. Bolt v1.2 x86优化细节


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

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

// 示例1.Bolt的卷积分块实现部分代码
HWout = Hout * Wout
for (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的向量寄存器,为了保证数据的重用性同时尽量利用更多的寄存器:

    1. 用12个寄存器来保存输出结果,也就是一次可以得到96个FP32的计算结果,那么可以选择3x32, 4x24, 6x16, 8x12,其中循环展开系数为UNROLL_HW=3,分块系数BLOCK_OC_DIM=32,依此类推。

    2. Bolt在计算过程中会根据卷积计算的规模动态选择向量化的粒度并推断相应的分块参数,进行数据packing,保证在不同的输入和卷积参数下都能取得最优性能。如图2为Bolt和MKL-DNN(现oneDNN)卷积算子的性能对比,处理器频率在3.6GHz,处理器峰值性能115GFlops.


图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/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/installer/mingw-w64-install.exe/download)版本。示例指令如下:

mkdir bolt && cd bolt
git 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-noah/bolt/blob/master/docs/INSTALL.md

具体的应用部署中,Bolt提供C API和Java API可供使用,编译后的API文件生成在./install_ linux-x86_64_avx2/include目录下,对应的库文件生成在./install_ linux-x86_64_avx2/lib目录下,可以参考Bolt提供的图像分类教程:https://github.com/huawei-noah/bolt/tree/master#%E6%95%99%E7%A8%8B

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

同时欢迎高性能计算和深度学习算法方向的童鞋加入我们,后台回复【华为诺亚】、【诺亚】获取投递履历邮箱



华为诺亚的更多文章

1. 《深度学习加速库Bolt领跑端侧AI

2. 《华为诺亚Bolt助力HMS机器翻译:从TinyBert到纯A55小核实时ASR》

3. 《华为端引擎Bolt GPU性能优化:让上帝帮忙掷骰子

4. 《深度学习端侧推理框架Bolt v1.0发布,领跑端侧AI性能与应用》

点击【阅读原文】,阅读往期文章。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存