MXNet 图优化与算子融合

MXNet 图优化与算子融合Graph Optimization and Quantization based on subgraph and MKL-DNN

Purpose

MKL-DNN引入了两个高级特性:融合计算和降精度核。这些特性可以显著地提高各种深度学习拓扑在CPU上的推理性能。

然而,MXNet由于图表示的局限性和以往缺乏图的优化,仍然不能从中受益。幸运的是,MXNet的新子图特性使这些改进现在成为可能。

本文说明基于子图的解决方案,以利用MKL-DNN在MXNet中的功能。一般来说,解决方案将MKL-DNN算子划分为子图,然后在子图中用融合的内核(如果可能)替代这些MKL-DNN算子。可以通过使用MKL-DNN的降精度核(如INT8核)来选择量化流,加速模型的推理过程。

Milestone

本文三个步骤可被视为本项目的里程碑,并用于跟踪过程。

•完成后,将子图分支转换为主分支

•完成,MKL-DNN融合实现到子图分支

•完成后,将量化流实现提交到主分支

Workflow

步骤1. 将MKL-DNN算子划分到子图中

这是子图的主要用途之一。可以列出所有支持的运算符MKL-DNN,并将其传递给DefaultSubgraphProperty。应用图划分后,所有MKL-DNN算子都将分组到子图节点中,子图边界上的数据格式将自动在MKL-DNN内部格式和NDArray默认格式之间转换。根据执行模式,子图边界有点不同。

1.         Symbolic mode

子图将尽量覆盖相邻的MKL-DNN算子。

 

2.         Imperative mode

命令式

每个MKL-DNN操作符将在一个独立的子图中执行,以确保MKL-DNN内部格式不会暴露在子图之外。

 

Step 2. MKL-DNN operator fusion

MKL-DNN算子融合

MKL-DNN库支持在一次执行中,运行多个特定的模式算子。比如卷积+relu。可以定义新的SubgraphSelector子图选择器,捕获这种操作符模式,并生成新的MKL-DNN特定算子来替换原来的算子。

 

新的融合算子是独立算子,表示定义的MKL-DNN库算子。例如,在MKL-DNN库中,卷积可以支持在卷积之后执行relu的post算子。因此,对于卷积+relu融合,将创建一个MKL-DNN卷积(命名为_sg_MKL-DNN_conv),并将relu描述为后算子。

 

NNVM_REGISTER_OP(_sg_MKL-DNN_conv)
.set_attr<FStatefulComputeEx>("FStatefulComputeEx<cpu>",  SgMKL-DNNConvOpForward)

 

In general, new fused operators follow the abstraction of MKL-DNN library, and subgraph fusion pass is the lowering process to convert NNVM common graph to MKL-DNN graph. Fusion pass only happens inside the subgraph created by step1, so won’t affect MXNet default operators.

一般来说,新的融合算子遵循MKL-DNN库的抽象,子图融合pass是NNVM common图到MKL-DNN图的降阶过程。融合pass只发生在由step1创建的子图中,不会影响MXNet默认算子。

Step 3. Quantization

MKL-DNN支持卷积神经网络中大多数精度较低的基元,尤其是融合基元。MXNet INT8推理包括两个步骤:

1.  INT8模型,量化参数,收集校准数据准备

只执行此步骤一次。为了在FP32模型的基础上建立INT8模型,在MKL-DNN支持的情况下,在子图内部运行QuantizeGraph pass,用INT8算子代替FP32算子,并在适当的位置插入dequantize解量化算子。

 

2.       Run INT8 inference

当INT8符号和参数准备好进行inference时,用户可以对与以前相同的新输入数据进行推理。

Accuracy Validation

在使用MKL-DNN时,无论量化程度如何,子图解本身都不会引入精度损失,反而会增强框架的稳定性。

NETWORK

FP32

FP32 with Fusion

Top1

Top5

Top1

Top5

Resnet-152 by MKL-DNN

77.16

92.98

77.16

92.98

Inception by MKL-DNN

72.36

90.58

72.36

90.58

在量化允许的情况下,MKL-DNN与采用熵模式校准的FP32相比,可以在不到0.5%的精度损失范围内获得巨大的性能改进。

Accuracy data from the internal branch are shown in below table .

 

FP32

INT8

 

 

No Calibration

Calibration using 5 batches

Calibration Method

NETWORK

Top1

Top5

Top1

Top5

Top1

Top5

Resnet-152 by GPU

77.19

93.01

75.56

92.32

75.58

92.24

Threshold by min/max

75.65

92.35

Threshold by entropy loss

Resnet-152 by MKL-DNN

77.16

92.98

76.59

92.71

76.44

92.69

Threshold by min/max

76.76

92.79

Threshold by entropy loss

Inception-bn by GPU

72.38

90.61

71.98

90.26

71.78

90.26

Threshold by min/max

71.98

90.36

Threshold by entropy loss

Inception-bn by MKL-DNN

72.36

90.58

72.21

90.50

72.16

90.43

Threshold by min/max

72.19

90.45

Threshold by entropy loss

 

Performance

On performance part, both fusion and quantization can provide the huge improvement on various kinds of topologies.

Below is the inference performance data(images/sec) from the internal branch based on SKX-8180 1 socket with batch size 64. 

在性能方面,融合和量化都可以为各种拓扑结构提供巨大的改进。

 

以下是基于批处理大小为64的SKX-8180 套接字的内部分支的推理性能数据(图像/秒)。

Topology

Base

With Fusion

With Fusion + Quantization

resnet50-v1

208.17

348.80

 568.25

resnet50-v2

198.87

256.10

 

vgg-16

92.11

101.00

 150.92

inception-bn

475.74

658.75

 836.94

inception-v3

175.97

227.29

 327.39

inception-v4

88.99

109.15

 

inception-resnet-v2

104.13

124.75

 

mobilenet 1.0

668.71

1380.64

1788.95

squezenet

708.63

849.27

975.90

测试用例量化解决方案仍在开发中。准备好后会分享更多的数据。

测试需要包括两个部分。第一个是图形转换测试。需要确保:

Step

Criterion 

1

所有MKL-DNN算子按执行方式划分为一个或多个子图。

2

可以捕获所需的模式并创建所需的融合算子。

3

量化过程可以将期望的算子转换为具有正确数据连接的量化版本。

另一个是MKL-DNN特定融合算子的单元测试。测试应涵盖所有融合场景,以确保融合算子能够提供准确的结果。

 

Q & A

•用户将如何调用该功能-要使用的工作流、命令和API是什么?

此功能将在其成熟后启用。

 

•计划进行哪些API增强(或更改)?有关于向后兼容性的问题吗?

 

此更改应用了方案提供的API,没有向后兼容性问题。

 

•调度的单元和集成测试是什么?完整模型的E2E测试是好的,需要一些小测试,可以通过PR检查和常规回归来执行。

 

将进行完整的测试,包括单元测试和模型级测试。增加单元测试,检查生成的图形和融合运算器输出的正确性。

 

模型级测试将检查新变化的训练和推理精度。

 

•添加非CV测试用例。

 

测试了RNN,GAN,RL网络。例如,通过sockeye模型(GNMT、transformers)验证性能和功能。

 

•是否正确地假设用户选择完全独立于底层后端的算子?

 

不完全是。在这个阶段,后端流不会随子图而改变。

 

通过在runtime生成变量(USE \u MKLDNN,USE \u CUDNN)和ctx(gpu,cpu)来指定用户的后端。

 

•这是否意味着如果要卷积,例如,mxnet将自动在cpu、GPU和mkldnn之间进行选择?如果是的话,这到底是怎么做到的?

 

不,按照当前的MXNet后端使用情况,用户不能在不同的后端之间切换单个算子。

 

•认为重要的是,必须明确区分算子及其不同的实现。最后,用户应该能够定义一个网络图,有责任找到执行它的最佳方式。

 

同意。最后,应该达到这个状态,但这不是这一步的目标。

posted @ 2021-05-21 06:35  吴建明wujianming  阅读(637)  评论(0编辑  收藏  举报