部署TVM Runtime
本文主要介绍如何在开发板上部署TVM Runtime, 在本地机器安装完整的TVM(包含了TVM Runtime以及编译功能), 并且使用一个简单的远程调用例子测试是否部署成功。本地机器使用的是Linux操作系统,开发板使用的是预装的Fedora系统。
开发板与TVM的概述
开发板
开发板(Embedded AI Development Kit),以 Arm SoC 为硬件平台,Tengine(Arm 中国周易平台)为核心的人工智能基础软件平台 AID,集成典型应用算法,所形成的 “软硬一体化”的 AI 开发套件; 专为 AI 开发者精心打造,面向边缘计算的人工智能开发套件。
硬件平台具备语音,视觉等传感器数据采集能力,适用于多场景的运动控制接口。
软件平台支持视觉处理与分析,语音识别,语义分析,SLAM 等应用和主流开源算法,满足AI 教育,算法应用开发,产品原型开发验证等需求。
软件是产品系列套件,主芯片采用具备主流性能 Arm SoC 的RK3228H,搭载 OPEN AI LAB 嵌入式 AI 开发平台 AID(包含支持异构计算库 HCL,嵌入式深度学习框架 Tengine,以及轻量级嵌入式计算机视觉加速库 BladeCV)。为 AI 应用提供简洁,高效,统一的 API 接口,加速终端 AI 产品的场景化应用落地。
TVM
TVM是一个针对CPU,GPU和专用加速器的开放式深度学习编译器堆栈,旨在缩小以算力为重点的深度学习框架与性能或效率为导向的硬件后端之间的差距。TVM提供以下主要功能:
将Keras, MXNet, PyTorch, Tensorflow, CoreML, DarkNet中的深度学习模型,编译成各种硬件后端上可部署的最小模块。
基础架构可在更多后端自动生成和优化张量运算符,同时得到更好的性能。
一些概念
• 远程设备,目标设备,本地机器
将开发板称为“远程设备(remote device)”和“目标设备(target device)”,用来执行生成的代码所编译出来的二进制可执行文件。因为远程连接开发板,目标是生成对开发板高效的代码。连接开发板的机器叫做“本地机器(local machine)”,用来实现生成代码,对代码进行优化,编译二进制可执行文件等功能。本地机器也拥有执行二进制可执行文件的功能。
• 架构
开发板使用的是ARM Cortex-A53处理器,架构为ARMv8,本地机器通常是x86架构。这两种架构使用了不同的指令集,使用不同指令集的程序不能够同时在不同的架构上运行。比如针对x86指令集编译的程序不能够ARM架构上运行,同样针对ARM指令集编译的程序不能够在x86架构上运行。TVM可以生成一份代码,将这份代码编译成x86的程序,在本地机器上进行调试;也可以将这份代码交叉编译成ARM程序,在目标设备也就是开发板上运行。
• 完整版的TVM 和 TVM Runtime
完整版的TVM支持生成代码,优化代码,编译,执行等功能;而TVM Runtime是TVM的一个部件,用来执行生成的二进制文件,其优点是能够更轻便地部署。
在开发板上编译TVM Runtime
将在开发板上编译TVM Runtime,在编译前,需要安装第三方依赖库。
安装第三方依赖库
TVM Runtime需要使用psutil这个Python库,获取系统的运行状态信息。而安装psutil前,需要安装两个软件包,让psutil能够成功地编译。
• psutil
默认的Python为Python3, 依次输入以下命令即可安装psutil.
sudo dnf install redhat-rpm-config python3-devel
sudo pip3 install psutil
如果想使用Python2,可以输入以下命令:
sudo dnf install redhat-rpm-config python-devel
sudo pip2 install psutil
安装完psutil后,就可以开始在开发板上编译TVM Runtime.
在开发板上编译TVM Runtime
在开发板的命令行界面下,下载TVM的代码:
git clone https://github.com/dmlc/tvm
Cloning into 'tvm'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 46164 (delta 0), reused 0 (delta 0), pack-reused 46157
Receiving objects: 100% (46164/46164), 15.88 MiB | 302.00 KiB/s, done.
Resolving deltas: 100% (31261/31261), done.
进入TVM的代码目录,并且输入git⊂mode–update−−recursive−−∈itgit⊂mode̲update--recursive--∈it,下载第三方依赖代码:
[openailab@localhost ~]$ cd tvm
[openailab@localhost tvm]$ git submodule update --recursive --init
Submodule 'dlpack' (https://github.com/dmlc/dlpack) registered for path '3rdparty/dlpack'
Submodule 'dmlc-core' (https://github.com/dmlc/dmlc-core) registered for path '3rdparty/dmlc-core'
Submodule '3rdparty/rang' (https://github.com/agauniyal/rang) registered for path '3rdparty/rang'
Cloning into '/home/openailab/tvm/3rdparty/dlpack'...
Cloning into '/home/openailab/tvm/3rdparty/dmlc-core'...
Cloning into '/home/openailab/tvm/3rdparty/rang'...
Submodule path '3rdparty/dlpack': checked out '0acb731e0e43d15deee27b66f10e4c5b4e667913'
Submodule path '3rdparty/dmlc-core': checked out '808f485387f9a03f78fa9f1159f387d0d91b7a28'
Submodule path '3rdparty/rang': checked out 'cabe04d6d6b05356fa8f9741704924788f0dd762'
(由于TVM的版本可能不同,checked out后的哈希值也可能不同)
输入make runtime -j2进行编译,数字2指用2个线程进行编译。
[openailab@localhost tvm]$ make runtime -j2
等待大概1到2分钟,出现以下提示说明编译成功:
[100%] Built target runtime
将TVM文件夹的Python目录添加到环境变量PYTHONPATH中:
[openailab@localhost tvm]$ cd ..
[openailab@localhost ~]$ vim .bashrc
在.bashrc的最后一行加入export PYTHONPATH=$PYTHONPATH:~/tvm/python
如果使用其它路径,需要对路径进行修改。

再退出编辑器,执行命令:source .bashrc,立即使用.bashrc中的设置。

在本地机器编译完整版的TVM
打开本地机器的命令行,同样需要下载TVM代码及其第三方依赖代码。
git clone https://github.com/dmlc/tvm
cd tvm
git submodule update --recursive --init
在tvm文件夹下,拷贝cmake配置并修改,然后开始编译:
cp cmake/config.cmake ./
sed -i "s/USE_LLVM OFF/USE_LLVM ON/" config.cmake # 将USE_LLVM设置为ON
make -j5 # 使用5个线程编译
执行完后没有任何错误信息,则说明编译完成。
设置TVM Python绑定的路径:
假如使用bash,在~/.bashrc的最后一行添加以下脚本(如果使用zsh, 则在~/.zshrc中添加):
export TVM_HOME=/path/to/tvm
export PYTHONPATH=$TVM_HOME/python:$TVM_HOME/topi/python:$TVM_HOME/nnvm/python:${PYTHONPATH}
将/path/to/tvm替换为TVM代码所在路径,该路径有python,topi,nnvm三个文件夹。
在本地机器安装好TVM后,可以进行以下测试:
打开Python并导入TVM模块
➜ ~ python
Python 3.7.4 (default, Jul 16 2019, 07:12:58)
[GCC 9.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tvm
>>>
没有任何错误提示,说明安装成功。
运行第一个TVM样例:交叉编译与远程过程调用(Cross Complication and RPC)
将使用TVM, 实现一个元素个数为1024的向量进行逐元素加1后,输出结果的核函数,在本地机器上进行调试,并在开发板开发板上运行。本样例来源于TVM的官方教程 - Cross Complication and RPC,对其进行稍许修改以适配开发板.
在开发板上启用TVM的RPC(远程过程调用)服务。
在开发板的命令行界面输入:python -m tvm.exec.rpc_server --host 0.0.0.0 --port=3939
3939为TVM RPC服务的端口,可以对其进行修改,注意开发板和本地机器上,其它程序都不要占用这个端口。TVM官方教程给的端口号为9090,本地机器的9090端口被占用了,修改为3939。
[openailab@localhost ~]$ python -m tvm.exec.rpc_server --host 0.0.0.0 --port=3939
INFO:root:If you are running ROCM/Metal, fork will cause compiler internal error. Try to launch with arg ```--no-fork```
INFO:RPCServer:bind to 0.0.0.0:3939
不要退出这个命令,以保持RPC服务的运行。
对本地机器进行配置
在本地机器的命令行界面,下载修改后的教程代码,并进入目录:
git clone https://github.com/wkcn/TVM_tutorials_for_EAIDK
cd TVM_tutorials_for_EAIDK
编辑config.py文件,将host和port修改为开发板的IP地址和开发板上TVM服务的端口。
假设开发板在局域网下的IP为192.168.43.33,TVM RPC的端口为3939,则将配置文件修改为下图:

因为开发板使用的是ARMv8指令集,所以LLVM的编译目标为aarch64-linux-gnu.

运行RPC例子
• 在本地机器调试
进入TVM_tutorials_for_EAIDK的目录,将cross_compilation_and_rpc.py文件中第115行的local_demo设为True,然后输入pythn cross_compilation_and_rpc.py.
➜ TVM_tutorials_for_EAIDK git:(master) ✗ python cross_compilation_and_rpc.py
1.225e-07 secs/op
命令行中将会输出核函数的实际调用时间。
• 在开发板上执行
将cross_compilation_and_rpc.py文件中第115行的local_demo设为False,然后输入python cross_compilation_and_rpc.py
TVM将会在本地机器上进行交叉编译,并将编译结果上传到开发板。开发板上的TVM RPC服务下载可执行的二进制文件,并执行,将结果返回到本地机器。
本地机器的命令行将输出核函数在开发板(目标设备)上的实际调用时间,不包含网络传输文件的时间。
➜ TVM_tutorials_for_EAIDK git:(master) ✗ python cross_compilation_and_rpc.py
4.3455e-06 secs/op
切换到开发板的命令行界面,可以看到:
INFO:RPCServer:bind to 0.0.0.0:3939
INFO:RPCServer:connection from ('192.168.43.57', 47010)
INFO:RPCServer:load_module /tmp/tmpge372920/lib.tar
INFO:RPCServer:Finish serving ('192.168.43.57', 47010)
说明开发板收到了本地机器(本地机器的IP为192.168.43.57)编译的可执行二进制文件的压缩包lib.tar,对其解包并执行模块,最终返回结果,结束服务。
这是一个TVM样例,可对TVM的例子进行分析,这些例子包括本文RPC例子,在开发板上运行一个分类模型,自动调整以生成适合开发板的代码。

部署TVM Runtime的更多相关文章

  1. Deep Learning部署TVM Golang运行时Runtime

    Deep Learning部署TVM Golang运行时Runtime 介绍 TVM是一个开放式深度学习编译器堆栈,用于编译从不同框架到CPU,GPU或专用加速器的各种深度学习模型.TVM支持来自Te ...

  2. 离线部署ArcGIS Runtime for Android100.5.0

    环境 系统:window 7 JDK:1.8.0_151 Maven:3.6.1 Android Studio:2.3 ArcGIS Runtime SDK for Android:100.5.0 1 ...

  3. TVMNN编译Compiler栈

    TVMNN编译Compiler栈 内容纲要 前言 调研目标 TVM介绍 TVM源码架构 FrontEnd Relay BackEnd VTA实现原理及设计思想提炼 整体结构 VTA Hardware ...

  4. TVM部署和集成Deploy and Integration

    TVM部署和集成Deploy and Integration 本文包含如何将TVM部署到各种平台以及如何将其与项目集成. 与传统的深度学习框架不同.TVM堆栈分为两个主要组件: TVM编译器,完成所有 ...

  5. 使用Apache TVM将机器学习编译为WASM和WebGPU

    使用Apache TVM将机器学习编译为WASM和WebGPU TLDR 在Apache TVM深度学习编译器中引入了对WASM和WebGPU的支持.实验表明,在将模型部署到Web时,TVM的WebG ...

  6. TVM编译机器学习到 WASM 和 WebGPU

    TVM编译机器学习到 WASM 和 WebGPU TLDR TVM 深度学习编译器对 WASM 和 WebGPU 的支持.实验表明,TVM 的 WebGPU 后端在将模型部署到 Web 时可以接近原生 ...

  7. 端到端TVM编译器(上)

    端到端TVM编译器(上) 摘要 将机器学习引入到各种各样的硬件设备中.AI框架依赖于特定于供应商的算子库,针对窄范围的服务器级gpu进行优化.将工作负载部署到新平台,例如手机.嵌入式设备和加速器(例如 ...

  8. TVM设计与构架构建

    TVM设计与构架构建 本文档适用于希望了解TVM体系结构和/或在项目上进行积极开发的开发人员.该页面的组织如下: 实例编译流程Example Compilation Flow描述TVM把一个模型的高级 ...

  9. TVM 架构设计

    TVM 架构设计 本文面向希望了解TVM体系结构和/或积极参与项目开发的开发人员. 主要内容如下: 示例编译流程概述了TVM将模型的高级概念转换为可部署模块的步骤. 逻辑架构组件部分描述逻辑组件.针对 ...

随机推荐

  1. text-align: justify 文本对齐

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. apk 脱壳

    在理解android的类加载后,我们可以愉快对apk来脱壳了.脱壳重要的是断点: 断点:在哪个位置脱壳,这里着重指的是在哪个方法 先介绍断点,我们只要知道加壳是用哪个方法来加载dex的,hook这个方 ...

  3. UVA11020 优势人群(multiset)

    题意:       给你N个人,每个人有两个权值,x,y对于某一个人,如果不存在某一个人x' y', x' < x && y' <= y 或者x' <= x & ...

  4. 一个或多个筛选器或者Listeners启动失败

    问题描述 运行ssm项目,tomcat启动后报下面的错误. org.apache.catalina.core.StandardContext.startInternal 一个或多个listeners启 ...

  5. java之泛型的使用

    在java中,普通的类和方法只能用具体的类型,这对代码的限制很大,代码的可重用性大大降低. 那么如何才能让同一个类和方法使用不同类型的对象呢?在接触泛型之前我们可能会想到通过类型转换的方法来实现. p ...

  6. Java枚举类、注解和反射

    本文主要介绍的是枚举类,注解和反射.还有一些基础知识:static,基本数据类型,运算符优先级放在文中,以便查阅复习. 其中牵扯到泛型的部分,可参考本人的另一篇博客:(Collection, List ...

  7. 逆向工程初步160个crackme-------4

    crackme–3因为涉及到浮点数操作以及一些指令和寄存器(由于本人对浮点指令不了解),所以先隔过去分析后面的程序. 工具:1. 按钮事件地址转换工具E2A 2. PEID 3. Ollydbg 首先 ...

  8. FreeSWITCH的安装与使用

    FreeSWITCH

  9. 黄衫女子,黄衫好.png

    正想着团队项目中数据该如何解析,就收到了来自软工课程组的一件小黄衫,真是意外之喜.详问其来源,竟是因结对项目做的"较好"而来,顿感受之有愧. 结对项目是两人对文件系统的一个小模拟, ...

  10. Java方法区的理解

    方法区逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩. 但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap,目的就是要和堆分开 所以方法区看作是一块 ...