翻译 | 林椿眄
编辑 | 周翔
2017 年 8 月,华盛顿大学的陈天奇团队发布了 tvm,和 nnvm 一起组成深度学习到各种硬件的完整优化工具链,支持手机、cuda、opencl、metal、javascript 以及其它各种后端,而且用户可以针对这些目标平台用 python 来进行调优。
那么到底什么是 tvm 呢?
陈天奇在中解释到,tvm 其实是一个端到端优化堆栈,可以降低和调整深度学习工作负载,以适应多种硬件后端。tvm 的设计目的是分离算法描述、调度和硬件接口。
此外,tvm 具备两个优化层:计算图优化层;具备新型调度基元的张量优化层。通过结合这两种优化层,tvm 从大部分深度学习框架中获取模型描述,执行高层级和低层级优化,生成特定硬件的后端优化代码,如树莓派、gpu 和基于 fpga 的专用加速器。
同一小组的刘洪亮在微博上解释到:“tvm 可以把模型部署到不同硬件,比如群众常问的能不能用 amd 的 gpu,用 fpga 怎么搞,tvm 提供这个中间层有效解决这个问题”。
总的来说,除了比较明显的多硬件支持,更重要的是 tvm 支持相对方便的自动调优和轻量级部署。
之后,陈天奇团队又发布了基于 tvm 工具链的深度学习编译器 ,支持将包括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 中使用方式的例子:
▌和其他方法有什么不同?
在浏览器上运行神经网络模型已经不是一件多么新鲜的事了。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 堆栈加入更多的优化,期待模型的性能能够得到更多的改进