深度学习(Deep Learning)因其计算复杂度或参数冗余,在一些场景和设备上限制了相应的模型部署,需要借助模型压缩、系统优化加速、异构计算等方法突破瓶颈,即分别在算法模型、计算图或算子优化以及硬件加速等层面采取必要的手段:
基于计算平台的峰值算力与最高带宽约束,以及AI模型的理论计算强度(前向推理的计算量与内存交换量的比值),Roofline model为AI模型区分了两个性能评估区间,即Memory-bound区间与Compute-bound区间:
TensorRT是NVIDIA推出的面向GPU应用部署的深度学习优化加速工具,即是推理优化引擎、亦是运行时执行引擎。TensorRT采用的原理如下图所示,可分别在图优化、算子优化、Memory优化与INT8 Calibration等层面提供推理优化支持,具体可参考[3] [4]:
TensorRT能够优化重构由不同深度学习框架训练的深度学习模型:
手工分图:将深度网络手工划分为两个部分,一部分包含的操作都是TensorRT支持的,可以转换为TensorRT计算图。另一部分可采用其他框架实现,如MXnet或PyTorch,并建议使用C++ API实现,以确保更高效的Runtime执行;
Custom Plugin:不支持的Op可通过Plugin API实现自定义,并添加进TensorRT计算图,以支持算子的Auto-tuning,从而丰富TensorRT的Op-set完备性,例如Faster Transformer的自定义扩展 [26];Faster Transformer是较为完善的系统工程,能够实现标准Bert/Transformer的高性能计算;
TFTRT自动分图:TensorFlow模型可通过tf.contrib.tensorrt转换,其中不支持的操作会保留为TensorFlow计算节点;FP32 TF TRT优化流程如下:
from tensorflow.contrib import tensorrt as trt
def transfer_trt_graph(pb_graph_def, outputs, precision_mode, max_batch_size):
trt_graph_def = trt.create_inference_graph(
input_graph_def = pb_graph_def,
outputs = outputs,
max_batch_size = max_batch_size,
max_workspace_size_bytes = 1 << 25,
precision_mode = precision_mode,
minimum_segment_size = 2)
return trt_graph_def
trt_gdef = transfer_trt_graph(graph_def, output_name_list,'FP32', batch_size)
input_node, output_node = tf.import_graph_def(trt_gdef, return_elements=[input_name, output_name])
with tf.Session(config=config) as sess:
out = sess.run(output_node, feed_dict={input_node: batch_data})
复制
PyTorch自动分图:基于Torchscript执行自动分图,避免custom plugin或手工分图的低效率支持,提升模型优化的支持效率;并降低用户使用TensorRT的门槛,自动完成计算图转换与优化tuning;对于不支持的Op或Sub-graph,采用Libtorch作为Runtime兜底(参考NVIDIA官方提供的优化加速工具Torch-TensorRT,可作为PyTorch编程范式的扩展):
在1080ti平台上,基于TensorRT4.0.1,Resnet101-v2的优化加速效果如下:
Network |
Precision |
Framework / GPU: 1080ti (P) |
Avg. Time (Batch=8, unit: ms) |
Top1 Val. Acc. (ImageNet-1k) |
---|---|---|---|---|
Resnet101 |
FP32 |
TensorFlow |
36.7 |
0.7612 |
Resnet101 |
FP32 |
MXnet |
25.8 |
0.7612 |
Resnet101 |
FP32 |
TRT4.0.1 |
19.3 |
0.7612 |
Resnet101 |
INT8 |
TRT4.0.1 |
9 |
0.7574 |
在1080ti/2080ti平台上,基于TensorRT5.1.5,Resnet101-v1d的FP16加速效果如下(由于2080ti包含Tensor Core,因此FP16加速效果较为明显):
网络 |
平台 |
数值精度 |
Batch=8 |
Batch=4 |
Batch=2 |
Batch=1 |
---|---|---|---|---|---|---|
Resnet101-v1d |
1080ti |
FP32 |
19.4ms |
12.4ms |
8.4ms |
7.4ms |
FP16 |
28.2ms |
16.9ms |
10.9ms |
8.1ms |
||
INT8 |
8.1ms |
6.7ms |
4.6ms |
4ms |
||
2080ti |
FP32 |
16.6ms |
10.8ms |
8.0ms |
7.2ms |
|
FP16 |
14.6ms |
9.6ms |
5.5ms |
4.3ms |
||
INT8 |
7.2ms |
3.8ms |
3.0ms |
2.6ms |
相比于自动编译优化(以TVM为例):TensorRT的Kernel auto-tuning主要在一些手工优化的Op-set上执行Auto-tuning;而TVM则是基于Relay IR、计算表达与Schedule定义的搜索空间,通过EA、XGBoost或Grid search等搜索策略,执行自动编译优化、生成lower Graph IR(包含计算密集算子的优化op、以及基本的图优化),最终通过后端编译器(LLVM、nvcc等)生成指定硬件平台的优化执行代码。TVM的优化流程如下图所示:
具体而言,TVM提供了AutoTVM与AutoScheduler两种自动优化方式。AutoScheduler又称之为TVM Ansor,能够基于Cost model性能预估和进化算法执行自动寻优,搜索获得最佳的Schedule设置(tiling、op fusion、buffer与inline等)。以Intel CPU应用部署为例,基于TVM Ansor tuning,通过设置SIMD指令(如AVX512、VNNI)和多线程加速,能取得、甚至超过OpenVINO的加速效果。
有关TVM的details具体参考官网:Getting Started With TVM — tvm 0.8.dev0 documentation
有关TVM Ansor的具体介绍,可参考:深度学习编译系列之 ANSOR 技术分享 – 知乎
针对移动端应用部署:TVM自动编译优化也能取得理想的优化加速效果,但是由于移动端需要适配多种OS、与多种设备,因此TVM的tuning成本限制了其在移动端的应用推广。MNN是阿里淘系技术部推出的面向移动端推理部署的轻量型计算引擎,能够为多种深度学习模型的计算实现提供高效率的算子支持(包括FP32、FP16与INT8算子),并通过半自动方式提供优化tuning支持。并且,用户通过自定义的量化表或稀疏表,可以为MNN传递模型量化参数或稀疏率等信息,以支持计算图的量化优化或稀疏化。以量化训练(QAT: Quantization-aware Training)与MNN量化转换为例,可以构建从ASR模型的大规模预训练、到量化训练微调、再到MNN量化优化的工具链路:
深度学习模型因其稀疏性或过拟合倾向,可以被裁剪为结构精简的网络模型,具体包括结构性剪枝与非结构性剪枝:
以Channel Pruning为例,结构剪枝的规整操作如下图所示,可兼容现有的、成熟的深度学习框架和推理优化框架:
模型量化是指权重或激活输出可以被聚类到一些离散、低精度(Reduced precision)的数值点上,通常依赖于特定算法库或硬件平台的支持:
若模型压缩之后,推理精度存在较大损失,可通过Fine-tuning予以恢复,并在训练过程中结合适当的Tricks,例如针对ImageNet分类模型的剪枝后微调,可结合Label Smoothing、Mix-up、Knowledge Distillation、Focal Loss等。 此外,模型压缩、优化加速策略可以联合使用,进而可获得更为极致的压缩比与加速比。例如结合Network Slimming与TensorRT INT8优化,在1080ti Pascal平台上,Resnet101-v1d在压缩比为1.4倍时(Size=170MB->121MB,FLOPS=16.14G->11.01G),经TensorRT int8量化之后,推理耗时仅为7.4ms(Batch size=8)