TVM: Deep Learning模型的优化编译器(强烈推荐, 附踩坑记录)

本文介绍了使用TVM将Pytorch模型优化并部署在Android上的经历,通过Auto-TVM实现了性能提升8倍的效果。文章分享了在TVM中遇到的挑战和解决方案,包括编译错误、Android设备连接问题以及Auto-TVM调优时的各类问题。通过TVM,调优过程与硬件和模型框架解耦,便于未来迁移。
摘要由CSDN通过智能技术生成

(前排提醒,本文的人文内容部分稍稍带有艺术加工,请保持一定的幽默感进行阅读)

关注我最近想法的同学应该知道我最近都在把玩TVM,今天终于使用TVM得到了非常满意的结果,而专栏也很长时间没更新了,于是来安利(水)一篇。

本来可能用不到TVM,项目其实进展的很顺利,我们初始的tensorflow模型在android端得到了满意的latency,我也可以照常一边修炼我的仙,继续和有奶大定律, 自由单子, Kan-Extension等邪魔外道搏斗…一边稳稳的推进项目进度。

无奈scientist一意孤行要上Pytorch, 于是我们换了一个Pytorch模型…

先不说同样的SSD魔改模型,Pytorch在android端比tensorflow整整慢了5倍,光是把Pytorch模型移植到Android上都让开发团队整整褪层皮(Pytorch对Android的支持简直为0,tensorflow的工程支持相对pytorch简直无敌)。而这时候已经花了好多时间,项目眼看要delay…

头都炸了的我在打算手撸OpenCL调优之前,去问了下我们组的CV大神该怎么办,大神微微一笑,转身随风而去,只听云端传来3个字:“TVM~~~~~"

于是我就开始TVM的研究(踩坑)之路, 到今天为止终于把所有的路都踩平了之后,成功把我们的Pytorch模型用Auto-TVM调优成功且部署在了我们的android系统上,性能整整提高了8倍,比我们之前的tensorflow模型还要快。更重要的是,通过TVM,我们的调优完全不couple与硬件和模型Framework,就算以后换模型,换终端,或者哪天scientist想不开要换回tensorflow或是使用MXNet都无所谓,用auto-TVM自动调调就行了(只可惜了我的Cuda C编程调优都白学了)。

简单介绍下Auto-TVM的调优终端设备的用法
在这里插入图片描述

  1. 你可以有很多手机平板设备,安装好TVM RPC这个App之后,可以在App里输入Tracker的IP和端口,进行设备注册(另外输入一个设备ID来让Auto-TVM tuning程序找到)。
  2. Tracker是一个Python的程序,git clone TVM之后,按教程编译好,就可以按这个教程启动Tracker。
  3. Auto-TVM tuning程序也是一个python程序,它会连接Tracker(也可以和Tracker是一台机器)找到相应的设备ID的IP,然后和设备直接用RPC通信,Auto-TVM程序会根据程序预设的target(比如是不是arm cpu,要不要用OpenCL…) 来把你想要优化的Deep Learning模型直接编译为设备的machine code, 通过TVM RPC把code部署在终端,终端的TVM RPC App会测试这个模型的inference performance,然后回报给Auto-TVM tuning程序,然后Auto-TVM tuning程序会根据反馈,重新计算该如何优化编译,重新生成新的模型的machine code再次部署… 如此循环…直到达到预设的实验次数(比如2000),或太多次实验都没有提高提前结束(比如第一次就找到了最优优化结果)。最后TVM会根据调优时得到的最佳“编译参数”来最终编译你的deeplearning 模型为终端模型的machine code,最终完成优化编译过程。

以上只是简单介绍,具体请看TVM的论文,和去TVM官网看 tutorial,写得非常详细切提供了很多很好理解的范例代码。我的最终的tuning程序,就是魔改其中一个范例程序而来。

TVM踩坑记录
TVM目前还只是0.6版本,很多东西还不稳定,由于开发环境各异,有时候需要工程师自己解决一些开发团队在开发时没有碰到的问题,但是这些问题相对与TVM提供的巨大优势相比,都是小问题啦(工程能力越强,魔改力越强,你就可以越早体验新技术带来的好处呀。)。(我遇到的最坑的问题其实是公司网络各种IP禁止访问,封端口,使得android机和开发服务器一直连不上, 最终还是在自己的电脑上装了虚拟机,自建了一个小LAN才解决的这个问题)

1. 编译tvm4j-core出错: cannot find symbol [ERROR] symbol: class SharedSecrets
JDK11会遇到这个问题,因为JDK11已经把sun.misc.SharedSecrets换到别的地方了,建议不要尝试修改TVM源代码来fix这个问题,因为你会遇到其他更多问题,请下载JDK8,把JAVA_HOME设为JDK8的,一切就会很顺利

2. Android TVM RPC编译出错: #error "Unable to determine endianness of your machine; use CMake to compile"
Android RPC server fails to build

按上边link里的修改endian.h文件即可,参见我下边的修改

diff --git a/include/dmlc/endian.h b/include/dmlc/endian.h
index 5bf53fb..9422fce 100644
--- a/include/dmlc/endian.h
+++ b/include/dmlc/endian.h
@@ -23,7 +23,9 @@
 #elif defined(__EMSCRIPTEN__)
 #define DMLC_LITTLE_ENDIAN 1
 #else
- #error "Unable to determine endianness of your machine; use CMake to compile"
+ #include <endian.h>
+ #define DMLC_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
+ /*!#error "Unable to determine endianness of your machine; use CMake to compile" */
 #endif
 #endif

3. Auto-TVM运行时出错"Do not know how to handle return type code 113"
Auto-TVM failed on Android Device, with error msg of “Do not know how to handle return type code 113”

可以根据我上边在TVM Discussion里的自问自答来解决。

4. 找不到TVM_NDK_CC
[SOLVED] Android_rpc_test.py failed

按照dayanandasiet的回复设定TVM_NDK_CC即可

Follow the below steps to generate toolchian and try to generate application with below export command
Tool chain generate with below instruction
./make-standalone-toolchain.sh --platform=android-24 --use-llvm --arch=arm64 --install-dir=/home/user/software/android-toolchain-arm64/
Download Java and SDK, set proper path
export TVM_NDK_CC=/home/user/software/android-toolchain-arm64/bin/aarch64-linux-android-g++
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export ANDROID_HOME=/home/user/software/android-sdk-linux
build mxnet model with nnvm with below config/parameter and use same library, param and graph on your android application
target = “llvm -target=arm64-linux-android”
target_host = None
reference mobile_darknet_save.py 2
Compile application android deploy 1 using this config.mk 2 configuration for CPU flavor

5. LLVM only Large Small are allowd on AArch64

https://github.com/dmlc/tvm/issues/2005 可解。

6. Auto-TVM自动优化时出错:Cannot find config for target=cuda

https://discuss.tvm.ai/t/what-does-this-warning-cannot-find-config-for-target-cuda-mean/798/3 不是什么大问题,某operator不能调,对我来说其他的可以调就行了。。。。

7. Auto-TVM自动优化OpenCL时出错: No OpenCL platform matched given existing options

No OpenCL platform matched given existing options

也是自己问最终自己解决的,很反直觉,编译TVM的时候,选择OpenCL=OFF,就没有这个问题,选择OpenCL=ON,为终端Cross Compile OpenCL就不work了… 应该是bug.

8. Auto-TVM自动优化OpenCL时出错: CL_INVALID_WORK_GROUP_SIZE
CL_INVALID_WORK_GROUP_SIZE error after auto-tuning for OpenCL on Android Device

应该是我trial number设的太小了,以至于TVM找不到一个valid的kernel,顺着这个问题,发现了CL_INVALID_WORK_GROUP_SIZE的一个undocumented的错误源,即OpenCL kernel使用过多的register file也会造成CL_INVALID_WORK_GROUP_SIZE错误,这一点在查OpenCL文档的时候是查不到的, 有点tricky。

9. Auto-TVM自动优化时Android TVM RPC Crush,一切白调。。。

目前TVM还不支持checkpoint,不过我们可以很简单的魔改measure_methods.py这个文件,把190行set_task(): 这个函数里的check remote失败直接raise RuntimeError退出程序,改成循环多次check即可,这样使得Auto-TVM一方持续等待Android程序上线,比一点网络问题,或者终端问题,就废掉之前n多个小时的auto-tuning成果要好的多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值