基于oneDNN的ResNet50推理速度优化

oneDNN是Intel开源的深度学习加速库,其前身为MKLDNN,对于Intel自家硬件(CPU以及GPU),oneDNN对神经网络算子的计算过程进行了针对性的优化处理,从而显著提升了神经网络算子在Intel硬件下的计算速度。在训练侧,oneDNN已作为第三方工具被目前几乎所有的主流训练框架(TensorFlow、PyTorch、MXNet等)集成;在推理侧,其是OpenVINO的后端,并也经常作为第三方推理加速库被其它工程调用。在下文中,我们将会以ResNet50模型为例,通过直接使用oneDNN API搭建该模型,并增加一些推理加速优化策略,最终实现与OpenVINO几乎相同的推理速度。

一、搭建ResNet50模型

在使用oneDNN搭建ResNet50网络模型时,我们需要熟悉oneDNN开发者手册中每一个算子的性能注意事项,并在编写代码时严格遵守,如:

  1. 在搭建卷积以及全连接算子时,需要将其输入、权重以及输出的内存排布格式设置为dnnl::memory::format_tag::any,以使oneDNN根据运行环境CPU所支持的指令集情况决定最佳的内存排布;

  2. 搭建ReLU、Softmax、Sum等in-place算子时,其算子输入输出内存地址应该相同;

  3. 搭建Sum算子时,需要保证算子输入的内存排布格式相同等。

二、推理加速优化策略

1. Conv+BN+ReLU算子融合

在深度学习模型编译器中,将卷积层与BN层进行融合已是固定技巧,其思想也非常简单。在算子未融合时,卷积层与BN层的整体表达式可以表示如下:

将以上表达式进行展开,我们会得到:

即通过计算并修改卷积层的权重和偏置,我们可以在推理阶段完全舍弃掉BN层,这样便会省去推理时在BN层的计算时间以及内存搬运时间。

在去除掉BN层后,卷积层与ReLU层也可以进行融合,这里实现时需要借助oneDNN的post-op特性,将ReLU作为卷积层的post-op,从而减少了推理阶段在ReLU层的内存搬运时间。

2.Conv+ReLU+Sum算子融合

对对于ResNet50的每一个block,我们还可以进行 层的融合优化。通常情况下, 算子在计算时需要首先等待其输入算子全部计算完毕并将结果写入内存后,再进行自我计算流程;通过使用oneDNN的post-op特性,我们可以改变该流程,在 算子的一个分支计算完成后,在计算另一个分支时,直接将Conv+ReLU算子融合后的计算结果与前一分支对应内存地址的结果相加,并将加法的结果直接存储在该地址中,这样便省去了多次内存搬运时间,从而显著提升了推理速度。

3.Stride Optimization

步长优化(Stride Optimization)是只针对ResNet50这一特定模型的优化方式,其实施方法可如下图所示:

步长优化通过在ResNet50 identity block中增加一个MaxPooling层,然后如上图所示改变对应卷积层的步长,在不需要修改对应卷积层权重以及偏置的情况下,达到计算等价,但计算量减少的目的,从而提高了ResNet50的推理速度。

三、实验测试

本实验环境CPU的型号为Intel(R) Xeon(R) Gold 6136 CPU @ 3.00GHz。在进行benchmark测试时,使用了docker,并在启动测试容器时绑定了32核。最终的测试结果如下:

平均推理时间(ms)推理加速技术
13.0原始ResNet50
10.5Conv+BN+ReLU算子融合
8.3Conv+BN+ReLU算子融合,Conv+ReLU+Sum算子融合
7.2Conv+BN+ReLU算子融合,Conv+ReLU+Sum算子融合,步长优化
7.1OpenVINO

作为对比的OpenVINO推理结果是在相同条件下使用OpenVINO自带的benchmark工具进行测试的。可以看到,第二章中介绍的推理加速技术对于ResNet50的推理速度均有很大的提升,并且在以上技术全部实施后,其推理速度与OpenVINO已基本一致。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值