翻译 | 林椿眄
编辑 | 周翔
2017 年 8 月,华盛顿大学的陈天奇团队发布了 TVM,和 NNVM 一起组成深度学习到各种硬件的完整优化工具链,支持手机、CUDA、OpenCL、Metal、JavaScript 以及其它各种后端,而且用户可以针对这些目标平台用 Python 来进行调优。
那么到底什么是 TVM 呢?
陈天奇在论文中解释到,TVM 其实是一个端到端优化堆栈,可以降低和调整深度学习工作负载,以适应多种硬件后端。TVM 的设计目的是分离算法描述、调度和硬件接口。
此外,TVM 具备两个优化层:计算图优化层;具备新型调度基元的张量优化层。通过结合这两种优化层,TVM 从大部分深度学习框架中获取模型描述,执行高层级和低层级优化,生成特定硬件的后端优化代码,如树莓派、GPU 和基于 FPGA 的专用加速器。
同一小组的刘洪亮在微博上解释到:“TVM 可以把模型部署到不同硬件,比如群众常问的能不能用 AMD 的 GPU,用 FPGA 怎么搞,TVM 提供这个中间层有效解决这个问题”。
总的来说,除了比较明显的多硬件支持,更重要的是 TVM 支持相对方便的自动调优和轻量级部署。
之后,陈天奇团队又发布了基于 TVM 工具链的深度学习编译器 NNVM compiler O,支持将包括MxNet、Pytorch、Caffe2,、CoreML 等在内的深度学习模型编译部署到硬件上并提供多级别联合优化,速度更快,部署更加轻量级。
如今,谷歌工程师谈至勋又将 TVM 向前推进了一步:支持 WebGL/OpenGL 平台并可以在浏览器运。也就是说,未来你将不需要写一行 JavaScript 代码,就可以把深度学习模型自动编译生成 WebGL 并且跑在浏览器中 。
MxNet 的作者李沐评价到,“这是 Mxnet JavaScript frontend 往前的一大进步”。
以下是此次更新的完整内容解析:
▌OpenGL / WebGL 后端支持
TVM目前已经能够支持多个硬件后端:CPU,GPU,移动设备等......这次我们添加了另一个后端:OpenGL / WebGL。
OpenGL / WebGL 允许我们能够在未安装 CUDA 的环境中使用 GPU。目前这是在浏览器中使用 GPU 的唯一方式。
这个新的后端允许我们通过以下 3 种方式使用 OpenGL / WebGL:
-
本地 OpenGL:我们可以将一个深度学习模型编译成 OpenGL,并直接在本地机器上运行,整个过程只用到了 Python。
-
带 RPC 的WebGL:我们可以将深度学习模型编译为 WebGL,通过 Emscripten 将其作为一个共享库导出,包含 JavaScript 主机代码和 WebGL 设备代码。然后,我们可以通过 RPC 将这个共享库部署到 TVM JavaScript 运行时间系统(runtime system)中,并在浏览器上运行。
-
带静态库的 WebGL:我们可以将深度学习模型编译为 WebGL,将其与 TVM JavaScript 运行时间系统相连接,并导出整个包。然后我们就可以不需要任何依赖库,直接在浏览器的网页中运行模型。详细流程如图 1 所示。
我们通过 Emscripten 及其 fastcomp LLVM 后端来生成 JavaScript 后端。
图 1
以下是 3 中使用方式的例子:
https://github.com/dmlc/nnvm/blob/master/tutorials/from_mxnet_to_we
▌和其他方法有什么不同?
在浏览器上运行神经网络模型已经不是一件多么新鲜的事了。Andrej Karpathy 提出的ConvNetJS,及 Google 的 DeepLearning.JS 都能够实现这种想法。
那么,TVM 的 WebGL 有何独特之处呢?最大的区别就在于 TVM 的 WebGL 中操作内核是自动编译的,而不是人工编译的。如图 2 所示,TVM 使用统一的 AST 来定义其内核,并将其编译为用于不同的平台的代码。
图 2
这就意味着:
-
你不需要额外编写大量的代码就可以将现有模型部署到 WebGL 上。NNVM/TVM 模型的定义对于所有的目标来说都是一样的,因此你只需要将其编译到新的目标中。
-
如果要添加新的操作系统内核,你只需要在 TVM 中定义一次即可,而不需要为每个目标执行一次。你也不需要知道如何编写 GLSL 代码才能向 WebGL 添加新的内核,因为这一切都能够自动生成。
▌测试基准
在这里,我们针对一个典型的工作负载进行了基准测试:使用 resnet18 模型进行图像分类。
我使用的是一台工作了 5 年的,配备 8 核英特尔酷睿™ i7-3610QM 处理器以及 GTX650M 显卡的笔记本。在基准测试中,我们从 Gluon 模型库里下载了 resnet18 模型,并对猫的图像进行端到端的分类。我们只测量了模型执行时间(这不包含模型/输入/参数的加载),每个模型运行 100 次,最终得到运行时间的平均值,其结果如图3所示。
图3
该基准测试在 4 中不同的设置下运行的:
-
CPU(LLVM):模型被编译到 LLVM IR 和 JIT'ed 上,因此它完全运行在 CPU 上。
-
OpenCL:模型被编译到 OpenCL 上。还有一部分的 glue code 编译在 LLVM 上,用于设置并启动 OpenCL 内核。然后我们在本地的机器上运行该模型。
-
OpenGL:和 OpenCL 设置一样,不过模型是被编译到 OpenGL 上。
-
WebGL:glue code 被编译到 LLVM 平台上,进而通过 Emscripten 的 Fastcomp LLVM 后端转换为 Javascript。设备的代码被编译到 WebGL 平台上,我们可以在Firefox 浏览器上运行该模型。
从以上得到的结果我们可以看到,TVM OpenGL 后端与 OpenCL 有相似的性能。更有意思的是,浏览器中的 WebGL 版本并不比桌面端的 OpenGL 运行效率慢。考虑到主机的代码是 JavaScript 编写的,出现这个现象的确让人惊讶。这可能是由于 Emscripten 生成了 asm.js,使得模型在 Firefox 浏览器中的运行效率得到了显著优化。
这个更新迈出了将深度学习模型自动编译到浏览器的第一步。我们会为 TVM 堆栈加入更多的优化,期待模型的性能能够得到更多的改进