在现实场景中,我们经常会遇到这样一个问题,即某篇论文的结果很棒,但是作者提供的训练模型是使用pytorch训练的,而我自己却比较擅长用tensorflow,我想要使用该模型做一些其它的项目。那么很多人就会采取一种方式,去阅读别人的论文、理解别人的代码,然后使用自己熟悉的工具进行代码重现、重新训练一个模型。这个阶段会耗用大量的人力和物力,最终还不能保证一定能得到论文的效果。本文即将介绍的几个模型转换的工具就可以很好的帮你解决你的这个问题,比较有名的包括mmdnn、onnx等。
除此之外,我们的目的是将深度学习模型应用到现实场景中的任务中,但是现实场景中的硬件五花八门,包含着大多数的算力不足的设备,以ARM处理处居多。那么这里面就涉及到了一个问题,即使你说你的模型有多牛逼,但是如果你的模型比较大,需要大量的算力才能跑起来,那么对于应用场景而言,你这个算法其实没有多少利用价值的。为了将使用N卡的GPU训练出来的模型成功的部署在这些低功耗的设备上面,我们通常需要对这些模型进行模型压缩和模型加速操作,比较有名的几个工具包括TensorRT、PocketFlow、TVM等。
简而言之,模型转换工具的作用是:将使用不同训练框架训练出来的模型相互联系起来,用户可以进行快速的转换,节省了大量的人力和物力花销。
1、MMdnn -官网链接
上图展示了MMdnn的主要功能。MMDNN是一套帮助用户在不同的深度学习框架之间进行交互操作的工具。例如,模型转换和可视化。转换caffe、keras、mxnet、tensorflow、cntk、pytorch onnx和coreml之间的模型。 简而言之,通过这个工具,我们可以方便的将某一个框架训练出来的模型转换成另外一个框架所支持的模型,图中基本上包含了当前所有主流的深度学习训练框架,包括Tensorflow、Pytorch、Caffe、MxNet等。除此之外,图中包含了一个关键的概念,那就是Intermediate Representation-中间表示,即这个工具首先将输入框架的模型转换为IR,然后通过IR转换成另外一个框架所支持的模型。
上图展示了MMdnn工具当前所支持的模型。上面的对号表示的是你可以随意的在不同框架之间进行该模型的转换。
# 将Tensorflow的resnet_v2_152模型转换为Pytorch支持的模型
mmdownload -f tensorflow -n resnet_v2_152 -o ./
mmconvert -sf tensorflow -in imagenet_resnet_v2_152.ckpt.meta -iw imagenet_resnet_v2_152.ckpt --dstNodeName MMdnn_Output -df pytorch -om tf_resnet_to_pth.pth
上面展示了一个简单的使用案例,通过简单的两行指令就可以将Tensorlfow的模型转换为pytorch所支持的模型,是不是很方便呢!
2、 ONNX-官网链接
ONNX是一个开放的生态系统,它使人工智能开发者能够随着项目的发展选择正确的工具。ONNX为人工智能模型提供了一种开源格式,包括深度学习和传统的ML。它定义了一个可扩展的计算图模型,以及内置运算符和标准数据类型的定义。目前,我们关注的是推断(评分)所需的能力。
ONNX得到了广泛的支持,它可以应用到很多框架、工具和硬件中。它可以实现不同框架之间的相互转换,并加速研究到产品的速度。
上图展示了ONNX所支持的一些深度学习框架,图中包括了一些主流的框架,但是并不完善,tensorflow的身影竟然没有出现。
上图展示了该工具所支持的一些Converters,不仅包括深度学习框架Tensorflow、Keras等,而且包括ML工具Scikit-learn、Xgboost、LibSVM等。
上图展示了该工具所支持的一些Runtimes(运行时),它更偏向模型的部署端,图中包含了多个大厂,包括NVIDIA、Qualcomm、Tencent、synppsys等。
上图展示了该工具所支持的底层编译器,包括了大名鼎鼎的TVM,下面会对该工具进行详细的介绍。除此之外,包含了一些可视化网络模型的工具,NETRON工具相当好用,具体的细节请看这里。
3、 X2Paddle-官网链接
X2Paddle支持将其余深度学习框架训练得到的模型,转换至PaddlePaddle模型。一个比较小众的工具,感兴趣的请在官网查看具体的细节,这里不再祥述。
简而言之,模型压缩加速工具的作用是:将训练好的模型进行压缩和加速,然后将其部署到一些特定的设备上去,从而满足现实场景的需求。
1、PocketFlow-官网链接
PocketFlow是一个开源框架,可以使用最少的人力压缩和加速深度学习模型。深度学习广泛应用于计算机视觉、语音识别、自然语言翻译等各个领域。然而,深度学习模型通常计算成本很高,这限制了在计算资源有限的移动设备上的进一步应用。
PocketFlow旨在为开发人员提供一个易于使用的工具包,以提高推理效率,而不会降低或降低性能。开发人员只需要指定所需的压缩比或加速比,然后PocketFlow将自动选择适当的超参数来生成高效的压缩模型以进行部署。
上图展示了PocketFlow的整个框架。该框架主要由两类算法组件组成,即学习器和超参数优化器,如上图所示。给定一个未压缩的原始模型,学习模块使用随机选择的超参数组合生成一个候选压缩模型。然后对候选模型的精度和计算效率进行评估,并将其作为反馈信号,用于确定学习模块要探索的下一个超参数组合。经过几次迭代,所有候选模型中最好的一个输出为最终的压缩模型。
上图展示了该工具中所包含的压缩方法。主要包括3大类:裁剪、权重稀疏和量化。
# 对网络进行裁剪操作
./scripts/run_seven.sh nets/resnet_at_cifar10_run.py \
--learner channel \
--cp_prune_option uniform \
--cp_uniform_preserve_ratio 0.5
# 对网络进行权重稀疏操作
./scripts/run_local.sh nets/resnet_at_cifar10_run.py \
--learner weight-sparse \
--ws_prune_ratio_prtl uniform \
--data_disk hdfs
# 对网络进行量化操作
./scripts/run_local.sh nets/resnet_at_cifar10_run.py \
--learner uniform \
--uql_use_buckets \
--uql_bucket_type channel \
--data_disk hdfs
上面分别展示了一个网络裁剪、网络权重稀疏、网络量化的实例。整个工具操作起来比较简单,用户仅仅需要确定自己需要的压缩比或者加速比即可,工具可以通过强化学习算法来帮你找到一个最优的结果。
2、TensorRT- 官网链接
Nvidia Tensorrt™是一个高性能深度学习推理平台。它包括一个深度学习推理优化器和运行时,为深度学习推理应用程序提供低延迟和高吞吐量。在推理过程中,基于Tensorrt的应用程序的执行速度比仅使用CPU的平台快40倍。使用Tensorrt,您可以优化在所有主要框架中训练的神经网络模型,高精度校准低精度,最后部署到超尺度数据中心、嵌入式或汽车产品平台。
Tensorrt建立在Nvidia的并行编程模型CUDA上,使您能够利用CUDA-X人工智能、自主机器、高性能计算和图形中的库、开发工具和技术,优化所有深度学习框架的推理。
Tensorrt为深度学习推理应用程序(如视频流、语音识别、推荐和自然语言处理)的生产部署提供了int8和fp16优化。降低的精度推断显著降低了应用程序延迟,这是许多实时服务、自动和嵌入式应用程序的一项要求。
上图展示了TensorRT的整体框架。输入到整个tensorRT中的是一个训练好的神经网络,该工具中包含了多个优化工具,具体包括精度矫正、动态张量内存、层/张量融合、内核自动微调、多级流执行等,通过这些操作,我们可以对原始的输入模型进行快速的压缩和加速,从而满足我们的需求。但是细心的你可能注意到了该工具只适合应用在NVIDIA显卡上,在CUDA的基础上进行优化,通用性较差!!!
3、distiller-官网链接
Distiller是一个用于神经网络压缩研究的开源python包。网络压缩可以减少神经网络的内存占用,提高其推理速度,节约能源。Distiller为原型制作和分析压缩算法提供了一个pytorch环境,如稀疏诱导法和低精度算法。
# 显示网络的稀疏度
python3 compress_classifier.py --resume=../ssl/checkpoints/checkpoint_trained_ch_regularized_dense.pth.tar -a=resnet20_cifar ../../../data.cifar10 --summary=sparsity
上图展示了使用该工具来显示某个网络的稀疏度。执行命令之后会输出一个文本表,详细说明参数张量的各种稀疏性。第一列是参数名,后面是它的形状、密集模型和稀疏模型中非零元素的数量(nnz)。下一组列显示列、行、通道、内核、过滤器和元素的稀疏度。概括起来就是元素绝对值的标准差、平均值和平均值。
上图展示的是裁剪敏感性分析图。该图可以辅助你在模型压缩的过程中快速的定位到不同网络层对裁剪的敏感程度,然后有针对性的执行一些操作。
4、TVM-官网链接
TVM是一个针对CPU、GPU和专用加速器的开放式深度学习编译器堆栈。它旨在缩小以生产力为中心的深度学习框架与以性能或效率为导向的硬件后端之间的差距。TVM提供以下主要功能:
TVM提供两个级别的优化。执行高级操作员融合、布局转换和内存管理等任务的计算图优化。然后是张量运算符优化和代码生成层,用于优化张量运算符。
上图展示了TVM工具的整体框图。整个工具具有如下的优势:
TVM装载ONNX模型并执行模型优化的简单案例
import onnx
import numpy as np
import tvm
import tvm.relay as relay
from tvm.contrib.download import download_testdata
######################################################################
# Load pretrained ONNX model
# ---------------------------------------------
# The example super resolution model used here is exactly the same model in onnx tutorial
# http://pytorch.org/tutorials/advanced/super_resolution_with_caffe2.html
# we skip the pytorch model construction part, and download the saved onnx model
model_url = ''.join(['https://gist.github.com/zhreshold/',
'bcda4716699ac97ea44f791c24310193/raw/',
'93672b029103648953c4e5ad3ac3aadf346a4cdc/',
'super_resolution_0.2.onnx'])
model_path = download_testdata(model_url, 'super_resolution.onnx', module='onnx')
# now you have super_resolution.onnx on disk
onnx_model = onnx.load(model_path)
######################################################################
# Load a test image
# ---------------------------------------------
# A single cat dominates the examples!
from PIL import Image
img_url = 'https://github.com/dmlc/mxnet.js/blob/master/data/cat.png?raw=true'
img_path = download_testdata(img_url, 'cat.png', module='data')
img = Image.open(img_path).resize((224, 224))
img_ycbcr = img.convert("YCbCr") # convert to YCbCr
img_y, img_cb, img_cr = img_ycbcr.split()
x = np.array(img_y)[np.newaxis, np.newaxis, :, :]
######################################################################
# Compile the model with relay
# ---------------------------------------------
target = 'llvm'
input_name = '1'
shape_dict = {input_name: x.shape}
mod, params = relay.frontend.from_onnx(onnx_model, shape_dict)
with relay.build_config(opt_level=1):
intrp = relay.build_module.create_executor('graph', mod, tvm.cpu(0), target)
######################################################################
# Execute on TVM
# ---------------------------------------------
dtype = 'float32'
tvm_output = intrp.evaluate()(tvm.nd.array(x.astype(dtype)), **params).asnumpy()
######################################################################
# Display results
# ---------------------------------------------
# We put input and output image neck to neck
from matplotlib import pyplot as plt
out_y = Image.fromarray(np.uint8((tvm_output[0, 0]).clip(0, 255)), mode='L')
out_cb = img_cb.resize(out_y.size, Image.BICUBIC)
out_cr = img_cr.resize(out_y.size, Image.BICUBIC)
result = Image.merge('YCbCr', [out_y, out_cb, out_cr]).convert('RGB')
canvas = np.full((672, 672*2, 3), 255)
canvas[0:224, 0:224, :] = np.asarray(img)
canvas[:, 672:, :] = np.asarray(result)
plt.imshow(canvas.astype(np.uint8))
plt.show()
5、tflite-官网链接
TensorFlow Lite 是一种用于设备端推断的开源深度学习框架,该工具专注于模型优化和模型部署,使得tensorflow的整个生态更加完善,首先使用tensorflow训练好的模型,然后通过tflite进行模型加速,最终将其部署在android或者ios设备上。
上图展示了tflite的整个流程。首先需要选择一个合适的模型;然后使用Lite converter将模型转换为FlatBuffer格式;接着将.tflite文件部署到嵌入式设备中;最后进行模型量化操作。
6、ncnn-添加链接描述
ncnn 是一个为手机端极致优化的高性能神经网络前向计算框架。ncnn 从设计之初深刻考虑手机端的部署和使用。无第三方依赖,跨平台,手机端 cpu 的速度快于目前所有已知的开源框架。基于 ncnn,开发者能够将深度学习算法轻松移植到手机端高效执行,开发出人工智能 APP,将 AI 带到你的指尖。ncnn 目前已在腾讯多款应用中使用,如 QQ,Qzone,微信,天天P图等。
7、MNN-官网链接
MNN是一个轻量级的深度神经网络推理引擎,在端侧加载深度神经网络模型进行推理预测。目前,MNN已经在阿里巴巴的手机淘宝、手机天猫、优酷等20多个App中使用,覆盖直播、短视频、搜索推荐、商品图像搜索、互动营销、权益发放、安全风控等场景。此外,IoT等场景下也有若干应用。
主要特点如下所示:
整体设计架构如下所示:
上图展示了MNN的整体设计架构。其支持的深度学习框架包括Tensorflow、Caffe、ONNX;Frontends包括Tensorflow、Caffe、ONNX;包含的图优化操作包括:融合操作、替换操作和调节操作;引擎包括图调度和CV处理;Backends包括CPU、Metal、OpenCL、Vulkan;底层的优化技术包括:Neon或者ASM、多线程、内存重复使用、异构计算等。
8、openVIO-官网链接
openVIO是Intel官方针对Intel cpu推出的一款加速工具。该工具专注于边缘端的推理;用户可以使用该工具对Intel的CPU/GPU/FPGA等产品进行加速;可以直接调用优化好的Opencv和OpenVX包。
如上图所示,openVIO不仅可以用来执行基于深度学习的一些CV任务,而且可以用来执行一些传统的CV任务。除此之外,它还可以对特定的硬件进行加速。通过openVIO,你可以让你的算法在CPU端实现4~5倍的加速,它让你的算法运行在CPU端成为了可能,在很多应用场景下面会具有更高的性价比。
9、Tengine-官网链接
Tengine是由开放式人工智能实验室开发的一个面向嵌入式设备的精简、高性能、模块化的推理引擎。Tengine引擎由六个模块组成core/operator/serializer/executor/driver/wrapper。
10、ARMNN-官网链接
ArmNN是Arm机构开源的基于arm嵌入式设备的inference框架,在Arm Cortex-A CPUs、Arm Mali GPUs、Arm Machine Learning processor都可以达到很高的加速效果。不过可惜的是,由于缺乏文档及教程,该框架在国内推广的程度不高,目前Github上star仅有359个。相对于其他竞品inference框架如NCNN、Tengine、Mace、MNN等等,ArmNN的知名度显得很小。不过笔者在项目的多次使用中,发现ArmNN是一个被低估的框架(在arm设备上的性能几乎都优于目前的前传框架),不亏是ARM家精心调教的SDK,对自家核心的性能调教到了极致。
ArmNN基于Arm的另外一个开源计算引擎ComputeLibrary做后端的核心计算,前端支持多种离线训练框架,如TensorFlow、TFLITE、CAFFE以及ONNX。从功能上来说,几乎实现了与市面上所有离线训练框架无缝对接。而且ArmNN在FP32、FP16及INT8上的加速非常可观,笔者在RK3399上做300x300的Mobilenet-SSD(depth_multiplier=1.0),效率可达90ms/ 帧,其余的框架大多在160ms左右徘徊。
11、Paddle Lite-官网链接
Plader Lite是Plader Mobile的更新版本,这是一个开源的深度学习框架,旨在使在移动、嵌入式和物联网设备上执行推理变得容易。它与飞桨和其他来源的预训练模型兼容。
[1] MMdnn链接
[2] ONNX链接
[3] X2Paddle链接
[4] PocketFlow链接
[5] TensorRT链接
[6] distiller链接
[7] TVMl链接
[8] tflite链接
[9] ncnn链接
[10] MNN链接
[11] openVIO链接
[12] Tengine链接
[13] ARMNN链接
[14] Paddle-Lite链接
[1] 该博客是本人原创博客,如果您对该博客感兴趣,想要转载该博客,请与我联系(qq邮箱:[email protected]),我会在第一时间回复大家,谢谢大家的关注.
[2] 由于个人能力有限,该博客可能存在很多的问题,希望大家能够提出改进意见。
[3] 如果您在阅读本博客时遇到不理解的地方,希望您可以联系我,我会及时的回复您,和您交流想法和意见,谢谢。
[4] 本文测试的图片可以通过该链接进行下载。网盘链接- 提取码:w81b。
[5] 本人业余时间承接各种本科毕设设计和各种小项目,包括图像处理(数据挖掘、机器学习、深度学习等)、matlab仿真、python算法及仿真等,有需要的请加QQ:1575262785详聊,备注“项目”!!!