共计 8882 个字符,预计需要花费 23 分钟才能阅读完成。
AI 计算力的指数增长意味着,为了解决越来越简单的用例,即便是 1000 倍的计算性能增长也很容易被耗费。因而,须要通过软件生态系统的助力,能力达到更好的性能。咱们置信,构建 AI 软件生态系统,是将人工智能和数据迷信我的项目推向生产的要害。本文整顿自龙蜥大讲堂技术直播第四期,由龙蜥社区 AI SIG 核心成员、英特尔 AI 软件开发⼯程师黄文欢分享——用技术和实例解说英特尔 x86 平台 AI 能力演进的要害。
以下是本期龙蜥大讲堂技术直播回顾文:
人工智能的倒退为社会各个领域带来了有限可能,但这些利用都须要很强的计算性能和优化来提供精确、及时的后果。人工智能模型复杂性的增长速度是飞速的,大概三年前,像 ELMo 这样的自然语言模型只有 9400 万个参数,而往年最大的模型达到了超过 1 万亿个参数。
一、英特尔 x86 平台 AI 能力演进
自 Skylake 以来,英特尔通过从 AVX256 降级到 AVX512,将 AVX 的能力进步了一倍,这极大地提高了深度学习训练和推理能力。一年后,在 Cascade Lake 中引入 DL Boost VNNI,大大提高 INT8 乘加吞吐量。自 Cooper Lake 之后,英特尔将 BFloat16(BF16) 增加到 DL Boost 指令集中,以进一步提高深度学习训练和推理性能。硬件始终在向前倒退,AMX 自 Sapphire Rapids 开始推出,将会进一步提高 VNNI 和 BF16 从 1 维 - 向量到 2 维 - 矩阵的能力。英特尔可扩大处理器通过英特尔 Deep Learning Boost (Intel®DL Boost) 将嵌入式 AI 性能晋升到一个新的程度。英特尔的 Deep Learning Boost (DL Boost) 是 x86-64 上指令集架构性能的名称,旨在进步深度学习工作(例如训练和推理)的性能。DL Boost 蕴含两组关键技术:
- AVX-512 VNNI:次要用于卷积神经网络的疾速乘法累加。
- AVX-512 BF16:用于更快计算的低精度 BFloat16 浮点数。
图 1. 英特尔 x86 平台 AI 能力演进
Intel® DL Boost – VNNI
英特尔深度学习减速包含 AVX512 VNNI,VNNI 代表向量神经网络指令,是对规范英特尔指令集 AVX512 的扩大。AVX512 VNNI 旨在减速基于卷积神经网络的算法。AVX512 通过引入 4 个新指令放慢外部卷积神经网络环路。AVX512 VNNI 扩大背地的次要动机是察看到许多严密的循环须要两个 16 位值或两个 8 位值的反复乘法,并将后果累加到 32 位累加器。
图 2. 利用根底 AVX 512 vs. 利用 AVX512 VNNI 做向量乘加
深度学习的外围计算能够简化为乘加运算。在 VNNI 之前,咱们须要做图 1 中这样的向量乘加,应用根底 AVX-512,对于 16 位,这能够应用两条指令实现 VPMADDWD 用于将两个 16 位对相乘并将它们加在一起,而后将 VPADDD 增加累加值。利用根底 AVX512 须要 3 条指令,而 VNNI 只须要 1 个周期就能够实现。通过将三条指令交融为一条,能够最大化利用计算资源,晋升 cache 利用率及防止潜在的带宽瓶颈。因而,在这个意义上,VNNI 通过与非 VNNI 比拟,将为 INT8 带来 3x 峰值计算的晋升。此外,因为在一个 AVX512 寄存器中,与 FP32 相比能够包容 4 倍 INT8 数据,如果与 FP32 相比又能够带来 4x 峰值计算的晋升。
Intel® DL Boost – BFloat16
BFloat16(BF16) 次要思维是提供 16 位浮点格局,其动静范畴与规范 IEEE-FP32 雷同,但精度较 FP32 变低。相当于指数区和 FP32 放弃了雷同的 8 位,并将 FP32 分数字段的小数区缩减到到了 7 位。大多数状况下,用户在进行神经网络计算时,BF16 格局与 FP32 一样精确,然而以一半的位数实现工作。因而,与 32 位相比,采纳 BF16 吞吐量能够翻倍,内存需要能够减半。此外,fp32 到 bf16 的转化,绝对于 fp32 到 fp16 的转化更加简略。
图 3. BFloat16 数据类型介绍
英特尔® 深度学习减速技术包含以下 BFloat16 指令:
二、英特尔 AI 软件开发及部署生态系统
随着 AI 利用在视觉、语音、举荐零碎等方面一直增长和多样化,英特尔的指标是提供一套优越的 AI 开发和部署生态系统,使每个开发人员、数据科学家、钻研人员和数据工程师尽可能无缝应用,以放慢他们从边缘到云端的 AI 之旅。对于所有硬件和软件优化以及模型量化算法,咱们须要理解它们以更好地利用,为了使每个用户都能够便捷应用这些优化,英特尔提供了一套自顶向下的全栈 AI 软件系统。对于不同需要的工程师,都能够在英特尔 AI 软件生态系统中找到适宜他们的利用。对于想要开发本人的高性能应用程序或库的深度开发人员,能够间接调用相干的指令。对于想要解脱框架开销的框架开发人员或 AI 工程师,你能够间接应用 OneDNN。对于那些曾经领有 TensorFlow/PyTorch 等 AI 框架训练的模型的人来说,Intel 曾经将大部分补丁上流到开源中,间接应用它们并享受性能,或者进一步应用英特尔对于这些框架的扩大优化。对于那些想要谋求更多特定于推理的优化的人,能够应用 INC 工具库。
2.1 深度神经网络库 OneDNN
oneDNN 是一个开源的跨平台高性能库,蕴含用于深度学习应用程序的根本构建模块。基于英特尔平台,oneDNN 对深度神经网络进行 op 级以及指令集级的优化。
- 帮忙开发人员创立高性能深度学习框架
- 雷同的 API 为英特尔 cpu 和 gpu,应用最好的技术来实现这项工作
- 反对 Linux、Windows 和 macOS
该底层库围绕四个概念建设:
1. 原语(Primitive):是一个封装了特定计算过程的函数对象,特定计算过程如前向卷积,LSTM 反向计算等。能够通过原语的属性来管制原语表白更简单的交融操作,例如前向卷积和 ReLU 的交融。这里须要留神的是创立原语是重量级操作,最好的形式是一次创立、重复使用。或者能够通过缓存具备雷同参数的原语来缩小原语创立老本。
2. 引擎(Engine):是计算设施的形象,包含 CPU,特定 GPU 卡等。创立的大多数原语是在一个特定引擎上执行计算,引擎相似于异构计算的 host 和 device 概念的对立,是可执行计算的设施的形象。
3. 流(Stream):是绑定到特定引擎的执行上下文的封装。
4. 内存对象 (memory):封装了调配给特定引擎的内存句柄、tensor 的维度、数据类型、数据排布等信息。内存对象在执行期间被传递给原语进行解决。能够通过内存描述符 (memory::desc) 创立内存对象。
图 4. OneDNN 关系图
劣势:
- 反对要害数据类型:float32、float16、bfloat16 和 int8
- 实现了丰盛的操作:convolution, matrix multiplication, pooling, batch normalization, activation functions, recurrent neural network (RNN) cells, and long short-term memory (LSTM) cells
- 反对自动检测硬件指令,进步神经网络在指定硬件,特地是英特尔 CPU 和 GPU 上的执行速度。
2.2 优化深度学习框架:TensorFlow, PyTorch
深度学习框架通过高级编程接口为数据科学家、AI 开发人员和钻研人员提供模块,以构建、训练、验证和部署模型。
英特尔通过 oneDNN 库进行的软件优化为几个风行的深度学习框架带来了数量级的性能晋升,而且大多数优化曾经上传到默认框架散发版中。然而,对于 TensorFlow 和 PyTorch,咱们还保护独自的 Intel 扩大作为尚未上传的优化的缓冲区。
2.2.1 Intel® Optimization for TensorFlow*
英特尔对于 TensorFlow 的优化次要包含以下三个方面:
1)在算子优化局部,将默认的 (Eigen) 内核替换为 (应用 oneDNN) 高度优化的内核,OneDNN 优化了一系列 TensorFlow 操作。OneDNN 库是开源的,在构建 TensorFlow 时主动下载。
2)在图优化方面,图优化次要是心愿在不影响模型的数值个性的根底上,通过图变换达到简化计算、资源开销,晋升性能,所以是性能优化时的首选办法之一。Intel® Optimization for TensorFlow* 中所做的图优化包含算子交融及布局流传。
- 算子交融
算子交融是一个常见的性能优化办法,在交融之前,每个算子计算前后都须要把数据从内存读到缓存,再从缓存写回到内存。而交融之后,能够防止算子之间内存读写从而进步性能。
图 5. 算子交融
所以在做算子交融的时候实质上便是把多个 Tensor 整合到一个 Node 下。尽管只是简略的算子交融,然而在计算过程中能够进步速度。
- 布局流传
在布局流传方面,数据布局是会很大水平影响性能的,因而,咱们须要做到:
程序拜访
尽可能在最内层的循环中进行迭代,进步向量利用率
尽可能的重用数据,例如卷积层中的权重
通常,对于 CPU 上的某些张量操作,原生 TensorFlow 数据格式并不是最无效的数据布局。对于 TensorFlow 中的 tensor, 所有 OneDNN 中的算子应用都是高度优化的数据布局。在这种状况下,咱们插入一个从 TensorFlow 原生格局到外部格局的数据布局转换操作,在 CPU 上执行操作,并将操作输入转换回 TensorFlow 原生格局。须要留神的是咱们应该防止冗余的转化开销。而这些转换会带来性能开销,因而带来的挑战在于如何防止不必要的转换。所以,咱们应该采纳布局传播方式,布局流传就是用于辨认出相邻的互逆 reorder,并打消它们,从而缩小了有效的操作。也就是最左边的这张图中的构造。
图 6. 布局流传
在布局流传方面,Intel® Optimization for TensorFlow* 中所做的优化为
- 查找子图,这个子图中所有算子都有 OneDNN 反对
- 在这样的子图的边界上,引入数据布局转换
3)在零碎级优化方面,包含负载平衡与内存调配两局部。对于负载平衡,咱们晓得不正确的设定线程模型参数会引发性能问题。因而,能够参阅 TensorFLow 里的相干阐明文档,正确的为模型设置参数。对于内存调配,TensorFlow 中的神经网络算子会调配大量的内存。但 TensoeFlow 中默认的 CPU 分配器不能很好地解决这种状况: 频繁 alloc/dealloc 会带来频繁的 mmap/munmap。在 Intel® Optimization for TensorFlow* 中实现了 Pool allocator 来解决这个问题。
2.2.2 Intel®Optimization for PyTorch*
咱们曾经将大部分优化上传到 社区版本的 PyTorch 中,同时还保留了一个独自的英特尔 PyTorch 扩大包(Intel® Extension for PyTorch*(IPEX))作为目前尚未 upstream 的这些优化的一个缓冲区。
图 7. Intel® Extension for PyTorch*
IPEX 在英特尔硬件上比照社区版本的 pytorch 具备额定的性能晋升。大多数优化最终将蕴含在社区 PyTorch 版本中,扩大包的目标是在英特尔硬件上为 PyTorch 提供最新的个性和优化,包含 AVX512 VNNI) 和 Intel®AMX。
IPEX 能够作为 Python 程序中的模块进行加载,也能够作为 C++ 程序的 C++ 库链接。用户能够通过导入 intel_extension_for_pytorch 在脚本中动静启用这些优化。
优化扩大包 IPEX 中所蕴含的优化有:
- 算子优化:为进步性能,IPEX 优化了算子并实现了多个定制的算子。(通过 ATen 注册机制,一些 ATen 操作符会被在 Intel® Extension for PyTorch* 的优化版本所取代。)还针对几种风行的拓扑实现了一些定制算子。如 Mask R-CNN 中的 ROIAlign and NMS.
- 图优化:IPEX 反对罕用的算子交融,如 Conv2D+ReLU, Linear+ReLU 等。算子交融带来的益处以通明的形式传递给用户。IPEX 反对 FP32 和 BF16 交融模式,以及 INT8 交融模式
-
Runtime 优化:为用户提供了多个 PyTorch 前端 API,以便对线程运行时进行更细粒度的管制。它提供
通过 Python 前端模块 MultiStreamModule 进行多流推理 从 Python 和 C++ 前端生成异步工作 从 Python 和 C++ 前端为 OpenMP 线程配置外围绑定
2.3 优化工具 INC
INC 全称为 Intel® Neural Compressor,是一个运行在 Intel CPU 和 GPU 上的开源 Python 库,它为风行的网络压缩技术 (如量化、剪枝、常识蒸馏) 提供跨多个深度学习框架的对立接口。
图 8. INC 根底架构图
能够看到,这个工具反对主动的精度驱动的调优策略,帮忙用户疾速找到最佳量化模型。这些调优策略包含贝叶斯 /MSE/TPE…
对于量化局部,模型量化次要是通过升高模型中 tensor 和 weights 精度的伎俩,从而缩小计算需要和数据存储与传输需要,来达到减速的目标。次要办法分两派:一是训练后量化(Post-training Quantization),二是量化感知训练(Quantization-Aware Training)。
INC 工具反对
- 训练后动态量化(Post-training Static Quatization)
- 训练后动静量化(Post training dynamic Quatization)
- 量化感知训练(Quantization-aware training)
对于剪枝局部,深度学习网络模型从卷积层到全连贯层存在着大量冗余的参数,大量神经元激活值趋近于 0,将这些神经元去除后能够体现出同样的模型表达能力,这种状况被称为过参数化,而对应的技术则被称为模型剪枝。INC 中采纳多种剪枝算法,如非结构化剪枝 (Magnitude-based 基于幅度剪枝),结构化剪枝(Gradient sensitivity 梯度敏感剪枝),生成具备预约义稠密性指标的剪枝模型。
同时 INC 也反对常识蒸馏。模型蒸馏采纳的是迁徙学习的办法,通过采纳事后训练好的简单模型 (Teacher Model) 的输入作为监督信号去训练另外一个简略的网络 (Student Model),最初把 Student Model 用于推理。
以在 TensorFlow 上的应用举例,用户模型能够是 saved model、ckpt、pb 各种模式,通过 INC 工具运行后,失去一个优化后的模型,仍然为之前的用户模型格局,能够在 Tensorflow 上应用,相较于原始模型来说取得更好的性能成果。
图 9. INC 性能体现
这是在 150+ 个业内罕用的模型,应用 INC 工作后的评估后果。这些模型波及各个领域,包含图像分类中罕用的 ResNet、GoogLeNet、Inception,指标检测中罕用的 Mobilenet、Yolo、Faster RCNN,举荐中罕用的 Wide&deep、DLRM,自然语言解决中罕用的 bert 等。这张图展示的是 int8 绝对于 fp32 的性能后果比拟。横轴为相应的精度扭转,纵轴为 Int8 与 fp32 相比在实时 latency 的晋升。能够看到几何平均晋升达到 2.3 倍。
三、性能优化办法及案例分享
3.1 性能优化办法
在推理的性能优化方面, 工作可归成四类:算子优化、图优化、模型压缩和部署优化。
算子优化:算子优化中微架构优化的次要焦点是如何充分利用好微架构的内置加速器的能力去最大化算子的性能。OneDNN 底层库就能够帮大家很好的做这部分的优化。
图优化:次要通过子图变换和算子交融等形式来达到缩小计算量或者其余零碎开销(如访存开销),从而达到性能优化的目标。图优化次要是心愿在不影响模型的数值个性的根底上,通过图变换达到简化计算、资源开销,晋升性能,所以是性能优化时的首选办法之一。英特尔对于深度学习框架 tensroflow, pytorch 的优化蕴含这些图优化。
模型压缩:如果还须要额定的性能增益,这时候须要思考模型压缩计划。模型压缩 (Compression) 次要伎俩有:模型量化、剪枝和模型蒸馏。工程师们也能够通过刚刚介绍的 INC 压缩工具来便捷的应用到这些压缩计划。
部署优化:次要通过调整模型在部署时的资源分配和调度的参数来进一步优化性能。
3.2 案例分享:Bfloat16 优化在第三代英特尔至强可扩大处理器上晋升阿里云 BERT 模型性能
BERT 模型是一个自然语言解决中的一个罕用模型。阿里巴巴阿里云团队与 Intel 工程师密切合作进行 BERT 推理性能优化。接下去介绍咱们是怎么一步步发展这些优化的。首先,咱们在原始数据类型,即 fp32 的状况下,咱们首先应用“模型转换”将多层多操作的简单 BERT 模型替换为单个 BERT 操作。为了在 TensorFlow 上实现高效的 BERT op,咱们须要创立一个优化的 Kernel,从而产生一个新的自定义 BERT 算子。这是一个具备 算子 交融和优化的实现。
在 TensorFlow 中,“前端”负责图形容,“后端”负责算子的执行。因而,咱们能够将模型从原始 BERT 模型转换为前端带有 BERT op 的新模型,并将新的 BERT 内核实现注册到后端。因而,咱们不须要重新安装 TensorFlow 框架。咱们只须要加载实现 BERT 代码的动静库即可,并通过 oneAPI 深度神经网络库 (oneDNN)等高性能工具,来晋升性能。
图 10. BERT 模型优化计划
对于优化实现,咱们剖析 BERT 图进行层交融和张量交融。这张图显示了 12 层 BERT 中的一层细节。
在这个案例中,又能够进行横向交融和纵向交融。对于横向交融,咱们能够看到三个张量,即查问 query、键 key 和值 value,都须要进行 MatMul 和 BiasAdd 操作。咱们能够把这些操作交融为一个操作,即 QKV MatMul 和 BiasAdd。对于纵向交融,能够参照下图。
图 11. 新 BERT 模型实现
接下去,咱们剖析优化的 FP32 BERT 模型时,咱们留神到推理过程中超过 80% 的运行工夫破费在 MatMul 操作中。如何优化 MatMul 运算以缩小提早已成为最紧迫的挑战之一。家喻户晓,缩小内存拜访、优化缓存、进步并行度能够优化程序性能。随着第 3 代英特尔至强可扩大处理器的引入,应用最开始介绍的英特尔 DL Boost 的 bfloat16 指令,与 FP32 的点积相比,在实践上能将 BF16 的点积减速 2 倍。
英特尔® 深度学习减速技术包含以下 BFloat16 指令:
为了缩小内存拜访,咱们将 FP32 权重转换为 BF16 权重,像下图中左边的图构造所示。咱们将 FP32 权重转换为 BF16 权重并将 BF16 权重缓存在 BF16 MatMul op 中以供重用,并在每次执行时并行的将 FP32 输出转换为 BF16 输出。
图 12. BFloat16 优化计划
在这样的转化下,咱们能够应用 bfloat16 的点积计算 MatMul op,能够看到输出为 BF16 类型,输入为 fp32 类型。这些实现是利用了 oneDNN 的 反对。因而,咱们只须要创立一个新的 BF16 MatMul op 来替换优化的 FP32 解决方案(Baseline)MatMul op,而后咱们就能够实现 BF16 与 FP32 优化相比带来的性能晋升。
对于 BF16 优化计划,通过简略的运算替换来进步性能,能够放弃尽可能高的精度。对于 BiasAdd 操作,咱们依然放弃 FP32 操作,以缩小精度损失。
最初是一个优化后计划的性能和进度评估后果,为了比拟优化后的 FP32 Bert 和优化后的 BF16 Bert 的性能差别,咱们将 batch size 设为 1,token size 设为 128,这也符合实际的线上业务。输出是 MRPC 数据集。以延时为 21.70 毫秒的 FP32 解决方案为基准,能够看到优化的 BF16 解决方案与基线相比,提早为 11.83 毫秒,端到端的性能晋升达到了 1.83 倍,并且没有 Accuracy 的损失。
敲重点啦
本次直播视频回放已上线至龙蜥社区官网(首页 - 社区 - 视频),直播 PPT 获取形式:关注龙蜥社区公众号,后盾回复【龙蜥课件】或【龙蜥视频回放】即可。
相干链接地址:
【1】龙蜥社区 AI SIG 地址:
https://openanolis.cn/sig/AI_SIG
【2】BERT 模型更具体的性能阐明内容链接:
https://www.intel.com/content…
【3】oneDNN 开源地址:
https://github.com/oneapi-src…
【4】IPEX 开源地址:
https://github.com/intel/inte…
【5】INC 的开源地址:
https://github.com/intel/neur…
—— 完 ——
退出龙蜥社群
退出微信群:增加社区助理 - 龙蜥社区小龙(微信:openanolis_assis),备注【龙蜥】与你同在;退出钉钉群:扫描下方钉钉群二维码。欢送开发者 / 用户退出龙蜥社区(OpenAnolis)交换,独特推动龙蜥社区的倒退,一起打造一个沉闷的、衰弱的开源操作系统生态!
对于龙蜥社区
龙蜥社区(OpenAnolis)是由企事业单位、高等院校、科研单位、非营利性组织、集体等在被迫、平等、开源、合作的根底上组成的非盈利性开源社区。龙蜥社区成立于 2020 年 9 月,旨在构建一个开源、中立、凋谢的 Linux 上游发行版社区及翻新平台。
龙蜥社区成立的短期指标是开发龙蜥操作系统 (Anolis OS) 作为 CentOS 停服后的应答计划,构建一个兼容国内 Linux 支流厂商的社区发行版。中长期指标是摸索打造一个面向未来的操作系统,建设对立的开源操作系统生态,孵化翻新开源我的项目,凋敝开源生态。
目前,龙蜥 OS 8.4 已公布,反对 X86_64、Arm64、LoongArch 架构,欠缺适配 Intel、飞腾、海光、兆芯、鲲鹏、龙芯等芯片,并提供全栈国密反对。
欢送下载:
https://openanolis.cn/download
退出咱们,一起打造面向未来的开源操作系统!
https://openanolis.cn