查看原文
其他

如何在浏览器上跑深度学习模型?并且一行JS代码都不用写

2018-03-17 CSDN

点击上方“CSDN”,选择“置顶公众号”

关键时刻,第一时间送达!


翻译 | 林椿眄

编辑 | 周翔

2017 年 8 月,华盛顿大学的陈天奇团队发布了 TVM,和 NNVM 一起组成深度学习到各种硬件的完整优化工具链,支持手机、CUDA、OpenCL、Metal、JavaScript 以及其它各种后端,而且用户可以针对这些目标平台用 Python 来进行调优。


那么到底什么是 TVM 呢?


陈天奇在论文(https://arxiv.org/pdf/1802.04799.pdf)中解释到,TVM 其实是一个端到端优化堆栈,可以降低和调整深度学习工作负载,以适应多种硬件后端。TVM 的设计目的是分离算法描述、调度和硬件接口。


此外,TVM 具备两个优化层:计算图优化层;具备新型调度基元的张量优化层。通过结合这两种优化层,TVM 从大部分深度学习框架中获取模型描述,执行高层级和低层级优化,生成特定硬件的后端优化代码,如树莓派、GPU 和基于 FPGA 的专用加速器。


同一小组的刘洪亮在微博上解释到:“TVM 可以把模型部署到不同硬件,比如群众常问的能不能用 AMD 的 GPU,用 FPGA 怎么搞,TVM 提供这个中间层有效解决这个问题”。


总的来说,除了比较明显的多硬件支持,更重要的是 TVM 支持相对方便的自动调优和轻量级部署。


之后,陈天奇团队又发布了基于 TVM 工具链的深度学习编译器 NNVM compiler O(http://www.tvmlang.org/2017/10/06/nnvm-compiler-announcement.html),支持将包括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

bgl.py


和其他方法有什么不同?


在浏览器上运行神经网络模型已经不是一件多么新鲜的事了。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 53 32386 53 17363 0 0 9722 0 0:00:03 0:00:01 0:00:02 9721:和 OpenCL 设置一样,不过模型是被编译到 OpenGL 上。

  • WebGL:glue code 被编译到 LLVM 平台上,进而通过 Emscripten 的 Fastcomp LLVM 后端转换为 Javascript。设备的代码被编译到 WebGL 平台上,我们可以在Firefox 浏览器上运行该模型。


从以上得到的结果我们可以看到,TVM OpenGL 后端与 OpenCL 有相似的性能。更有意思的是,浏览器中的 WebGL 版本并不比桌面端的 OpenGL 运行效率慢。考虑到主机的代码是 JavaScript 编写的,出现这个现象的确让人惊讶。这可能是由于 Emscripten 生成了 asm.js,使得模型在 Firefox 浏览器中的运行效率得到了显著优化。


这个更新迈出了将深度学习模型自动编译到浏览器的第一步。我们会为 TVM 堆栈加入更多的优化,期待模型的性能能够得到更多的改进。


博客地址:http://www.tvmlang.org/2018/03/12/webgl.html


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存