QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

网易有道开源 EMLL:高性能端侧机器学习计算库,大幅提高计算性能

  • 2021-06-16
  • 本文字数:4055 字

    阅读完需:约 13 分钟

网易有道开源EMLL:高性能端侧机器学习计算库,大幅提高计算性能

在人工智能技术不断深入发展的今天,我们对于计算的性能要求越来越高。传统的计算处理多数是基于云侧的,把所有图像、音频等数据通过网络传输到云中心进行处理后将结果反馈。


但是随着数据的指数式增长,依靠云侧的计算已经显现了诸多不足,例如数据处理的实时性、网络条件制约、数据安全等,因此端侧的推理则愈发重要。在这样的背景下,网易有道 AI 团队自主设计研发了高性能端侧机器学习计算库——EMLL(Edge ML Library),并已在近日开源。


开源地址:https://github.com/netease-youdao/EMLL


EMLL 为加速端侧 AI 推理而设计,提供基于端侧处理器的高性能机器学习计算库,支持 fp32、fp16、int8 等数据类型,已在网易有道词典笔、翻译王和超级词典等智能硬件产品的 NMT、ASR、OCR 引擎中应用,大幅提高计算性能,提升用户体验。


端侧 AI

 

端侧 AI 具有以下优势:

  • 低延时

  • 保证数据隐私

  • 不依赖网络


端侧 AI 挑战:

  • 处理器算力有限,远低于云端计算能力,如何满足日益复杂的端侧 AI 性能的需求至关重要

  • 内存大小和带宽有限,对性能影响至关重要


ARM 处理器在智能设备中占主导地位,是端侧 AI 落地的主流平台。NPU、DSP、GPU 可以提供更高的计算能力,在端侧 AI 上有一定的应用场景,但生态环境较差,距离成熟还需要时间。


端侧 AI 最耗时的计算为全连接(FC)和卷积计算,底层核心计算为矩阵乘,底层计算库的性能对端侧 AI 能否落地起决定性作用。


ARM 第三方 BLAS 库

Eigen

线性代数运算的 C++ 模板库,矩阵的运算可直接用符号做。


OpenBLAS

由中科院计算所维护的一个开源的高性能 BLAS 库,基于 Kazushige Goto 的 GotoBLAS,支持 Fortran BLAS 和 CBLAS 接口调用。


ARM Compute Library

ARM 官方推出的计算库,支持 AI 的常见运算,其中矩阵乘法运算以模型推理层的形式封装,需要先初始化后才能调用。


表 1 各 ARM blas 库矩阵乘法特点

ARM blas

矩阵排列顺序

对特定核心的指令优化

对扁平矩阵的优化

Eigen

支持任意行/列主序

不充分

不充分

OpenBLAS

支持任意行/列主序

对一部分核心如A53有汇编调优

GEMV外没有专门对扁平矩阵的优化

ARM Compute Library

默认行主序,列主序需另调转置函数处理

对大部分核心均有汇编级别优化

权重矩阵固定时靠预重排提高效率,不固定时效率低


常规矩阵规模上的矩阵乘法进行了较好的优化,性能表现较好,然后在扁平矩阵上性能表现较差。端侧 AI 底层计算主要为扁平矩阵的乘法,第三方计算库性能表现较差,没有充分发挥硬件的性能,不利于 AI 应用在端侧平台上落地。


表 2 ARM cortex-A53 四核第三方库 GEMM 计算效率

端侧AI中部分矩阵乘法

Eigen

OpenBLAS

ARM Compute Library

M = 128, N = 16000, K = 128

25%

36%

35%

M = 7, N = 2048, K = 192

5%

6%

10%

M = 23, N = 1536, K = 320

12%

10%

25%


注:C(M, N) = A(M, K) * B(K, N),以上值取全行主序和全列主序的最好值,测试在相同的矩阵上重复 128 次,计算效率由 GEMM 计算 FLOPS 值除以硬件理论 FLOPS 值得到。


EMLL 特点


高性能

EMLL 实现的矩阵乘法函数,为端侧人工智能中常见的扁平矩阵的计算做了专门的优化,为各常见 ARM 处理器做了特定的优化。对于 cortex-A7/A35/A53/A55/A76 处理器,本库根据它们的流水线特点,使用了汇编级别的优化。


EMLL 多数情况下相对 Eigen、ARM compute Library 第三方库性能提升明显,尤其在端侧 AI 常用的扁平矩阵乘法中获得数倍的性能提升。下图展示了端侧 AI 中部分典型矩阵尺寸情况下得单精度矩阵乘法的性能结果。


图 1 EMLL 矩阵乘法性能


易用性

EMLL 使用的函数接口在参数设计上力求简洁直接,矩阵乘法去掉了不常用的 LD*参数,矩阵和向量的传递通过指针和整数维度分别传递。本库不依赖第三方计算库。


扩展性

对于矩阵乘法和量化函数,EMLL 库提取了它们和架构无关的代码作为通用的宏,这些宏可以在支持新的 CPU 架构时大大节省所需的代码量。

EMLL 性能优化方法


在端侧设备上优化计算库的性能,需要从访存效率和计算效率两个角度考虑,下面以(稠密)矩阵乘法为例,介绍 EMLL 采用的优化方法。


分块

矩阵乘法的计算过程中需要频繁地访存。当矩阵规模较大时,CPU 缓存容量不足以装下其全部内容,访存时就会频繁出现缓存缺失,降低程序效率。此时,EMLL 会对矩阵乘法问题进行必要的拆解,把较大的矩阵切分成小块的矩阵,这就是分块的手段。经过切分,每个子任务只计算一小块矩阵对结果的贡献,只会密集访问这个小块矩阵的区域,大大提高了缓存命中率。对于两个较大矩阵之间的乘法,EMLL 参照已有的优化工作[1],通过多级的分块,充分利用 CPU 多级缓存,主要采用如下两种切分方式:



图 2 分块方法


L1 - L3 代表不同矩阵块所利用的 CPU 缓存


CPU 的寄存器可以看成“速度最快的缓存”。为了充分利用寄存器,在上述分块的基础上,EMLL 进行了进一步拆分,左边的小矩阵拆成 m×k 的最小矩阵 a1,右边的小矩阵拆成 k×n 的最小矩阵 b1。计算这一对最小矩阵的乘法,如果直接用三重循环的方式,需要 2×m×n×k 次元素访问,如果不利用寄存器,则都为访存操作;利用了寄存器,则只需要在乘法开始前把两个小矩阵放到寄存器中,后续的乘法就不再访存,使访存减少到 (m + n) ×k 次。


综上,大尺度的分块可以提高 CPU 各级缓存的利用率,小尺度的分块可以利用 CPU 寄存器以减少访存次数,两者对性能均有明显帮助。


重排

上文提到,为了充分利用寄存器,子矩阵块的读取被划分为更小的小块 m×k 或 k×n (1 < m, n, k < 20),计算中逐个读取这些小块。而通常情况下,矩阵在内存中的存储方式为行主序或列主序。无论哪种存储方式,按小块读取会存在很多跳跃访问的情况。跳跃访问对性能不利,这里列举三点:


  • 消耗额外的缓存带宽:L2/L3 缓存与 L1 的数据交互以缓存行的形式进行。跳跃访问 L2/L3 缓存的数据时,缓存行数据的利用率低,浪费传输带宽。


  • 无法充分利用向量化的加载单元:很多支持 SIMD 的 CPU 上配备了向量化的加载单元,支持一条指令加载若干个地址连续的元素,若是跳跃访问则没法利用此特性。


  • 增加页表查询的开销:访存操作常涉及虚拟地址向物理地址的转换,需要查询页表。一个页表的覆盖地址范围有限。如果跳跃的步长过大,则需频繁查询新的页表。


在两个子矩阵块的乘法中,每个子矩阵块通常会被读取多次,每次读取的顺序可以相同。B 的子矩阵块在与它相乘的 A 块的行数多于 m 时会被读多次;A 的子矩阵块在与它相乘的 B 块的列数多于 n 时会被读多次。EMLL 参照已有的优化工作 1,在计算开始前,将两个子矩阵块先按计算时的读取顺序(即上一段所述按更小的小块读取)重新排列元素,这样计算时对两个子矩阵块的访问全部变成了顺序访问,此即重排的优化方法。虽然计算前重新排列元素会有额外的开销,但计算过程中对矩阵块的多次访问被顺序化后的收益更大,因此带来总体的性能提升。


对于特殊尺寸的矩阵,重排的开销可能大于收益,需要选择性地重排或不重排[2]。当源矩阵 A 的行数 M 很少而源矩阵 B 较大时,B 的子块被重复读取的次数大大降低,对 B 的子块重排的收益大大降低,甚至开始低于开销。这种情况在端侧 AI 推理中非常普遍。EMLL 会判断 M 的大小,当 M 小于一个阈值时,对矩阵 B 不再重排,而是调整计算顺序,对 B 的所有元素进行顺序的一次读取。类似地,当源矩阵 B 的列数 N 明显偏小时,EMLL 对矩阵 A 不再重排,调整计算顺序,对 A 的元素一次顺序读完。通过对特殊尺寸矩阵的特别处理,EMLL 在这些尺寸上的性能明显超过了 Eigen 和 OpenBLAS 等开源库。


汇编优化

现今主流的 CPU 为了提高数据计算的效率,支持了“单指令多数据”(SIMD)的处理模式,即一条指令对多个数据进行相同的操作。调用 SIMD 指令集,可以在不增加指令吞吐量的情况下,提高数据计算的吞吐量。ARM 平台提供了 NEON 指令集支持 SIMD 操作。


当 m = n = 4 而 k = 1 时,做最小矩阵小块之间的乘法并累加结果,如果使用标量计算,需要 16 次乘法和 16 次加法。NEON 指令集提供了广播模式的融合乘加操作,只需 4 条指令,即可完成相同的任务,如下图所示。其他 m,n 和 k 的取值,大多也可以用 NEON 指令加速运算。NEON 指令可以通过汇编的方式显式调用,也可通过编译器提供的 intrinsics 函数调用,后者可读性更好但性能指标的不确定性更大。


端侧的中低端平台配备的处理器,为了节省成本和功耗,在执行核心通常砍掉了乱序执行的能力,而是严格按照指令在指令流中的顺序来执行它们,如 ARM 的 cortex-A7, A35, A53, A55 等。部分型号的处理器可以在顺序执行的前提下同时执行相邻的两条指令。对于这些处理器,指令之间如果存在数据依赖或者执行单元冲突,则指令的顺序会对性能产生明显的影响,若追求极致性能,需要在汇编级别重排相关的指令。对于存在数据依赖的两条指令(比如一个运算指令的输入依赖于另一个加载指令的结果),应尽可能地使它们远离,避免因依赖关系的等待造成流水线空闲。

EMLL 功能


支持的计算函数

表 3 支持的计算函数

计算函数

支持的数据类型

偏置

float32int32

全连接fc

float32

反量化

int32 -> float32

矩阵乘法

float32float16int8

重量化

int32 -> int16/int8int16 -> int8

量化

float32 -> int8/int16


支持的架构

armv7a, armv8a


支持的端侧操作系统

Linux, Android


应用案例

网易有道词典笔,是网易有道打磨的一款学习型智能硬件,网易有道词典笔,具有“多行扫描翻译”功能,支持整段翻译的智能学习硬件。


网易有道超级词典打造高效的智能英语学习系统,强化端侧功能,提供了拍照学英语、查词翻译、背单词、听力练习、对话翻译、语音助手等功能。


网易有道翻译王支持 43 种语言互译,畅游全球 191 个国家和地区,支持 21 种语言在线、7 种语言端侧拍照翻译,指示牌、菜单等即拍即译。


网易有道词典笔、超级词典、翻译王均内嵌了网易有道自主研发的神经网络翻译 NMT、光学字符识别 OCR、语音识别 ASR、语音合成 TTS 等业内领先的 AI 技术,并且支持离线功能。


网易有道自研端侧机器学习计算库已在网易有道词典笔、超级词典、翻译王等智能硬件产品中使用,带来以下好处:


  • 端到端性能相对于使用 eigen 库加速 1.3 到 2.43 倍,效果显著,大大降低了端侧推理引擎的延迟。除了在有道智能硬件带来了较好的性能提升,我们在配置骁龙 855 的某款手机上也做了性能测试,端到端性能相对于 eigen 提升了 25%-55%,效果明显。


  • 端侧推理引擎采用 EMLL 之后,可以上线更大的 AI 模型,提高质量,并保证实时性,如端侧 NMT 质量(BLEU)提升 2 个点,端侧 ASR 准确度提升 4.73%。


  • EMLL 可以保证在更低端芯片上实时性,如在 cortex-A7 上使用 Eigen 库无法达到实时性,使用 EMLL 之后延迟大幅降低,并保证实时性效果。EMLL 可以让智能硬件更多的芯片选择,从而降低成本,提高市场竞争力。


表 4 测试平台

平台

CPU型号

主频(GHz)

有道词典笔

A35

1.2

有道超级词典

A53

1.5

有道翻译王

A53

2.0

某手机(骁龙855)

A76

2.8

RV1126

A7

1.5


图 3 端侧 NMT、ASR、OCR 在不同平台上使用 EMLL 和 eigen 端到端性能加速比


EMLL 高性能端侧机器学习计算库,已经在网易有道多款智能硬件产品中实际应用并取得显著的效果,大幅提升性能,给用户带来更好的产品体验。


未来,网易有道将持续维护和优化 EMLL,帮助更多企业、科研机构等伙伴提升端侧 AI 计算能力。

2021-06-16 10:002426
用户头像
刘燕 InfoQ高级技术编辑

发布了 1112 篇内容, 共 545.4 次阅读, 收获喜欢 1978 次。

关注

评论 1 条评论

发布
用户头像
火烈云智能客服系统:
1功能强大:人工总控制中心:便于整个系统的操作管理;24小时高效智能化机器人,做到全天接待,高效答疑,不遗漏客户;智能工单系统:自主创建、流转,并能逐级提醒,同时提供快速检索功能;CRM体系:精准的记录访客的各项信息,并对访客进行分类标注,让企业更懂客户。
2:超高性价比:功能如此齐全的火烈云智能客服系统,现在新人注册还可以领取30天的免费试用福利 ,更有根据企业的实际需求订制的多种套餐,同时首年充值免费赠送2个客服席位,真正的最优之选。
3:高灵活度:便捷、高效始终都是火烈云的设计理念,无需复杂的操作,官网搜索,注册即用,免除了下载客服端、插件的烦恼,并支持多平台接入,做到客户无遗漏,代码插入就可以运行客服,实现真正的简便,高度的自定义设置,能够让您的客服更有辨识度,在操作是遇到的任何问题,都可以咨询客服协助您解决。
火烈云智能客服系统功能齐备,助力双赢,是您智能化办公的不二之选。火烈云智能客服真挚地期待与您的合作。

展开
2021-06-16 17:14
回复
没有更多了
发现更多内容

MAC系统初始化

焦振清

macos 重装系统

深圳泰利能源有限公司涉嫌传销 共计2.7亿元

CECBC

区块链 基金

融云Geek Online 2020 编程挑战赛重磅来袭

InfoQ_967a83c6d0d7

某程序员毕业进UC,被阿里收购!跳去优酷土豆,又被阿里收购!再跳去饿了么,还被阿里收购!难道阿里想收购的是他?

程序员生活志

职场 阿里

SpreadJS 纯前端表格控件应用案例:MHT-CP数据填报采集平台

葡萄城技术团队

关于显性知识和隐性知识

Tanmer

知识管理 知识产权

华为云FusionInsight大数据技术普惠创新,释放千行百业数据价值

数据湖洞见

大数据 FusionInsight 华为云

云原生如何来进行HTTPS升级

soolaugust

架构 云原生 设计模式

技术分享:即构互动白板音视频同步、多端有序协作技术实践

ZEGO即构

音视频 在线教育 SVG

XSKY对象存储获全球备份领域领导者Commvault官方认证

XSKY星辰天合

从 Node.js(JavaScript) 到 Golang,我的开发体验

Garfield

node.js Go 语言

读懂k8s 容器编排控制器 Deployment

Garfield

k8s pod k8s入门

C语言内存泄露很严重,如何应对?

华为云开发者联盟

c 内存泄露 内存 代码 函数

Cassandra Gossip协议的二三事儿

华为云开发者联盟

源码 三次握手 开发者 Cassandra Gossip协议

LeetCode题解:155. 最小栈,单个栈存储入栈元素与最小值之差,JavaScript,详细注释

Lee Chen

大前端 LeetCode

3种双集群系统方案设计模式详解

华为云开发者联盟

数据库 数据仓库 数据 双集群系统 双ETL模式

你问我答:现有的应用有必要做微服务改造吗?

BoCloud博云

容器 DevOps 微服务 云平台 博云

数字货币交易平台源码,数字货币交易所开发核心功能

13530558032

面试必备知识点:悲观锁和乐观锁的那些事儿

鄙人薛某

面试 乐观锁 悲观锁 CAS 并发控制

1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知

YourBatman

Hibernate-Validator Bean Validation 数据校验 JSR380

话题讨论 | 当你敲代码累了时,一般喜欢吃点什么补充能量?

InfoQ写作社区官方

加班 写作平台 代码 话题讨论

挽救你的视频号:能够把PPT转换成视频,把备注转换成语音的开源项目

陈磊@Criss

凡泰极客与Rancher达成深度战略合作,加速企业构建私有化小程序生态

FinClip

数字资产钱包开发,数字加密货币app搭建

13530558032

区块链支付新模式开发,USDT支付系统搭建

13530558032

anyRTC Native 4.1.0.1与Web SDK 4.0.11上线

anyRTC开发者

学习 WebRTC 语音 直播 sdk

案例分享丨红外自动感应门设计与实现详解

华为云开发者联盟

物联网 传感器 感应探测器 SMT32处理器 感应门

人的转型才是关键 数字化时代你具备数字领导力么

CECBC

区块链 数字化时代

SpreadJS 纯前端表格控件应用案例:雨诺订单管理系统(雨诺OMS)

葡萄城技术团队

Spring Bean处理器

语霖

Spring Framework

区块链助力军事人力资源配置

CECBC

区块链 军事

网易有道开源EMLL:高性能端侧机器学习计算库,大幅提高计算性能_AI&大模型_网易有道技术团队_InfoQ精选文章