简介:什么是前端智能推理引擎又该如何打造和利用呢?
什么是前端智能推理引擎
在前端智能推理引擎之前,咱们先来说一下什么是”端智能”。
端智能(On-Device Machine Learning)是指把机器学习的利用放在端侧做。这里的“端侧”,是绝对于云服务而言的。它能够是手机,也能够是 IOT 设施等。
传统的机器学习,因为模型大小、机器算力的问题,很多是放在服务端做的。比方 Amazon AWS 有“Amazon Rekognition Service”,Google 有“Google Cloud Vision Service”。而随着以手机为代表的端侧设施算力的进步,以及模型设计自身的演进,大小更小、能力更强的模型逐步可能部署到端上运行。
相比云端部署的形式,APP 端领有更间接的用户特色,同时具备如下劣势:
- 实时性高,端侧解决可节俭数据的网络传输工夫。
- 节俭资源,充分利用端侧算力和存储空间。
- 隐衷性好,产生数据到生产数据都在端侧实现,防止传输引起的隐衷泄露危险。
这些是端智能的劣势,但它不是万金油,依然存在一些局限性:
- 设施资源无限,端侧算力、存储是无限的,不能做大规模高强度的继续计算。
- 算法规模小,端侧算力小,而且单用户的数据,在算法上并不能做到最优。
- 用户数据无限,端侧数据不适宜长期存储,同时可用数据无限。
同理,前端智能是指将机器学习的利用放到前端上(web、h5、小程序等).
所以,什么是前端智能推理引擎呢?
如下图:
前端智能推理引擎实际上就是利用前端上算力去执行模型的那个货色。
业界现有的前端推理引擎
这里列出三个常见的推理引擎
- tensorflow.js(上面简称为 tfjs)
- ONNX.js
- WebDNN
对于一个端上推理引擎来说,最重要的是什么?当然是性能了!性能越好,也代表在端上的利用场景也会越多,上面咱们来看下这三个推理引擎的性能比照:
(上面数据应用模型为 MobileNetV2 分类模型)
cpu(js 计算)
能够看到,在纯 JS 环境下进行计算,仅仅做一次分类都要 1500ms 以上。构想一下如果一个相机须要实时对拍摄的物体做分类预测(比方预测拍摄的对象是猫还是狗),那么每预测一次须要 1500ms,这样的性能是无法忍受的。
WASM
在 WASM 环境下,性能最佳的 ONNX.js 达到了 135ms 的性能,也就是 7fps 左右,曾经到了勉强能用的水平了。而 tfjs 却是蹩脚的 1501ms。这里是因为 onnx.js 利用了 worker 进行多线程减速,所以性能最好。
WebGL(GPU)
最初是 GPU 环境,能够看到 tfjs 和 ONNXjs 的性能都达到了比拟好的性能程度,而 WebDNN 体现较为蹩脚。
除了下面这三种引擎,目前国内还有百度的 paddle.js 以及淘宝的 mnn.js 等,这里不做探讨。
当然,在抉择一个适合的推理引擎时,除了性能以外,还有生态、引擎保护状况等等一系列的思考。从综合的方面来说,tfjs 是当下市场上最适宜的前端推理引擎。因为 tfjs 能够依附 tensorflow 的弱小的生态、google 官网团队的全职保护等。相比之下 ONNX 框架比拟小众,且 ONNXjs 曾经有近一年没有保护了。WebDNN 性能及生态都没有任何竞争力。
前端上的高性能计算计划
从上一章节其实能看到,在前端上做高性能计算个别比拟广泛的就是 WASM 和基于 WebGL 的 GPU 计算,当然也有 asm.js 这里不做探讨。
WASM
WASM 大家应该是比拟相熟的,这里只做下简短的介绍:
WebAssembly 是一种运行在古代网络浏览器中的新型代码,并且提供新的性能个性和成果。它设计的目标不是为了手写代码而是为诸如 C、C++ 和 Rust 等低级源语言提供一个高效的编译指标。
对于网络平台而言,这具备微小的意义——这为客户端 app 提供了一种在网络平台以靠近本地速度的形式运行多种语言编写的代码的形式;在这之前,客户端 app 是不可能做到的。
而且,你在不晓得如何编写 WebAssembly 代码的状况下就能够应用它。WebAssembly 的模块能够被导入的到一个网络 app(或 Node.js)中,并且暴露出供 JavaScript 应用的 WebAssembly 函数。JavaScript 框架岂但能够应用 WebAssembly 取得微小性能劣势和新个性,而且还能使得各种性能放弃对网络开发者的易用性。–《摘自 MDNWebAssembly 概念》
WebGL
啥?WebGL 不是做图形渲染的吗?不是做 3D 的吗?为啥能做高性能计算?
可能一些同学据说过 gpgpu.js 这个库,这个库就是利用 webgl 做通用计算的,具体的原理是怎么样的呢?(为了可能持续往下浏览,请先疾速浏览下这篇文章):《利用 WebGL2 实现 Web 前端的 GPU 计算》。
将推理引擎的性能进行极致优化
好了,目前咱们晓得在前端上的两种高性能计算形式了,那么如果现有的框架 (tfjs、onnxjs) 性能上就是不满足咱们的需要怎么办呢?怎么样能力进一步晋升引擎性能,并落地生产环境呢?
答案是:手撕源码,优化性能。对,就是这么简略粗犷。以 tfjs 为例(其余的框架原理上是统一的),上面给大家介绍下如何用不同的姿态去优化引擎性能。
在去年年初时候,咱们团队和 google 的 tfjs 团队做了一次深刻交换,google 那边明确示意 tfjs 前面的倒退方向以 WASM 计算为主、webgl 计算不做新的 feature 以保护为主。然而现阶段各浏览器、小程序对 WASM 的反对并不残缺 (例如 SIMD、Multi-Thread 等个性),所以 WASM 临时无奈在生产环境落地。 所以,现阶段还是须要依赖 webgl 的计算能力。蹩脚的是,此时 tfjs 的 webgl 性能在挪动端上体现仍旧差强人意,尤其在中低端机上的性能齐全达不到咱们的业务要求。没方法,只能本人硬着头皮进去优化引擎。所以以下的内容都是针对于 webgl 计算进行介绍。
优化 WebGL 高性能计算的 n 种姿态
姿态一:计算向量化
计算向量化是指,利用 glsl 的 vec2/vec4/matrix 数据类型进行计算,因为对于 GPU 来说,最大的劣势就是计算并行化,通过向量去计算可能尽可能地达到并行化的成果。
例如一次矩阵乘法:
c = a1 b1 + a2 b2 + a3 b3 + a4 b4;
能够改为
c = dot(vec4(a1, a2, a3, a4), vec4(b1,b2,b3,b4));
向量化的同时也要配合内存布局的优化;
姿态二:内存布局优化
如果读了下面《利用 WebGL2 实现 Web 前端的 GPU 计算》这篇文章的同学应该理解到,在 GPU 内所有的数据存储都是通过 Texture 的,而 Texture 自身是一个 长 n 宽 m 通道(rgba)4 的货色,如果咱们要存一个 3 224 224 * 150 的四维矩阵进去要怎么办呢?必定会波及到矩阵的编码,即以肯定的格局把高维矩阵存进个性形态的 Texture 内,而 Texture 的数据排布又会影响计算过程中的读存性能。例如,举一个较简略的例子:
如果是惯例内存排布的话,计算一次须要按行或者案列遍历矩阵一次,而 GPU 的 cache 是 tile 类型的,即 n * n 类型的缓存,依据不同芯片 n 有所不同。所以这种遍历形式会频繁造成 cache miss,从而成为性能的瓶颈。所以,咱们就要通过内存排布的形式进行性能优化。相似下图:
姿态三:图优化
因为一个模型是一个一个的算子组成的,而在 GPU 内每个算子被设计成一个 webgl program,每次切换 program 的时候会造成较多的性能损耗。所以如果有一种伎俩可能缩小模型的 program 数量,对性能的晋升也是非常可观的。如下图:
咱们将一些能够交融的节点在图构造上进行交融(nOP -> 1OP),基于新的计算结点实现新的 OP。这样一来大大减少了 OP 的数量,进而缩小了 Program 的数量,所以晋升了推理性能。在低端手机上成果尤为显著。
姿态四:混合精度计算
以上所有的计算都是基于惯例浮点数计算,也就是 float32 单精度浮点数计算。那么,在 GPU 内是否能实现混合精度的计算呢?例如 float16、float32、uint8 混合精度的计算。答案是能够的,在 GPU 内实现混合精度计算的价值是在于晋升 GPU 的 bandwidth。因为 webgl 的 texture 每一个像素点蕴含 rgba 四个通道,而每个通道最高为 32 位,咱们能够在 32 位内尽可能存储更多的数据。如果精度为 float16,那么能够存储两个 float16,bandwidth 就是之前的 2 倍,同理 uint8 的 bandwidth 是之前的 4 倍。这个性能的晋升就是微小的。还是上图谈话吧:
姿态 n:…
优化的伎俩还有很多,这里就不一一列举了。
引擎落地的场景
目前,基于咱们深度优化的引擎曾经落地蚂蚁团体及阿里经济体多个利用场景,比拟典型的就是文章结尾演示的宠物辨认,还有卡证辨认、碎屏相机等等等场景。
业界的有之前比拟火的虚构试妆小程序等。
读到这篇文章的敌人们也能够关上你们的脑洞,挖掘出更多更好玩的智能场景。
将来瞻望
随着市面是机型的更新换代及引擎的深刻优化,我置信 tfjs 会在更多富交互的场景上大放异彩,例如领有 AI 能力的前端游戏、AR、VR 等等场景。当初咱们要做的就是静下心来,站在伟人的肩膀上继续打磨咱们的引擎,愿等花开。
作者:青壁
原文链接
本文为阿里云原创内容,未经容许不得转载