AI算力碎片化:矩阵乘法的启示

news2024/12/25 22:32:06

c6f29ac475123cbf458ba029d0dc3250.jpeg

尽管AI的发展取得了巨大进步,但编译器LLVM之父Chris Lattner认为,AI技术应用并不深入,远远没有发挥出已有机器学习研究的所有潜力。而AI系统和工具的单一化和碎片化正是造成这一问题的根源。

为了让AI发挥其真正的潜力,计算碎片化是需要解决的重点问题之一,目标是让AI软件开发人员能够无缝地充分利用现有硬件和下一代创新硬件。但解决这一问题并不容易,硬件、模型和数据的多样性使得当前市场上的现有解决方案都只是单点性质的,Chris Lattner创立的Modular团队从矩阵算法的角度对此进行了深入分析。

(以下内容由OneFlow编译发布,译文转载请联系OneFlow获得授权。https://www.modular.com/blog/ais-compute-fragmentation-what-matrix-multiplication-teaches-us)

作者|Eric Johnson、Abdul Dakkak、Chad Jarvis

OneFlow编译
翻译|徐佳渝、杨婷

 

1

算力碎片化正在阻碍AI的发展

AI由数据、算法(即模型)和算力驱动,三者之间形成了良性循环。其中任意一方的发展会推动其他方面需求的增长,从而严重影响开发者在可用性和性能等方面的体验。如今,我们拥有更多的数据,做了更多的AI模型研究,但算力的扩展速度却没有跟上,这主要是由于物理限制。

如果你一直在关注AI和硬件的发展,可能听说过摩尔定律时代即将结束。过去60年,单核处理器每18个月翻一倍性能提升速度的情况已然改变。除了继续制造越来越小的晶体管的物理限制之外(例如,电流泄漏会导致功耗过高,从而引起发热),性能也越来越多地受到内存延迟的限制,而这种限制的增长速度比处理速度要缓慢得多。

ff815c6355987d5adc50d34384a93b54.png

Hennessy和Patterson的图灵演讲:不同时期CPU处理器性能提升的分析(性能提升的速度保持稳定))

然而,随着模型不断扩大,在边缘计算中创建和处理的企业数据更多,对AI计算的需求也在不断增加。因此,尽可能地利用硬件设备的性能已成为业界的关注焦点。

45d559c7e56b530c2401e1545a34d1a8.png

 (‍机器学习三个时代的算力走向(https://arxiv.org/pdf/2202.05924.pdf),Sevilla:计算需求随时间呈对数方式变化的分析。其中,2010年左右深度学习开始受到关注,2016年左右迎来了大型模型时代,这促使了算力需求急剧增长。)

那么,算力的碎片化是如何阻碍AI发展的呢?由于传统CPU无法扩展以满足更多的算力需求,因此,唯一的解决之道是创建并行的、用于特定领域的硬件平台,尽管这些硬件平台的通用性不强,但在特定的AI领域却表现良好——例如图形处理单元(GPU)、张量处理单元(TPU)和其他专用集成电路(ASIC)。

虽然这些创新推动了AI行业的发展,让边缘设备能够使用规模更大、效率更高的处理器,但硬件的多样性使得整个AI行业变得碎片化,AI开发者们需要努力解决以下问题:

1. 开发出能够充分利用硬件能力的软件,且能与其他软件协同工作。

2. 在任意一款设备上实现并行软件算法。

3. 将软件扩展到多设备的生态系统,甚至扩展到异构系统。

Modular公司致力于从零开始重建全球的AI基础设施。在本系列博客中,我们将探讨如何采用全新的方法解决AI行业的算力碎片化问题。我们会专注于单个运算符——矩阵乘法(matrix multiplication,matmul),这是机器学习算法中的关键计算。

通过这种方式,我们会看到构建真正统一的解决方案所面临的底层挑战。我们将深入研究矩阵乘法的内部运作,探讨其工作原理的一些细节,以了解矩阵乘法为什么如此困难。

2

矩阵乘法为何如此困难

矩阵对机器学习系统来说至关重要,因为它提供了一种简单而高效的方式来表示数据。例如,输入数据(图像中的像素集合)或者模型内部不同层之间的运作机制都可以用矩阵来表示。因此,矩阵相乘的运算在深度学习模型总计算量中占据很大比例。

实际上,在许多当前流行的Transformer模型BERT、CLIP以及ChatGPT中,矩阵乘法的运行时长约占其总运行时长的45-60%。矩阵乘法在计算卷积运算中扮演着重要角色,该运算是大多数计算机视觉模型的基础,也是许多高性能计算应用的核心。

考虑到矩阵乘法在机器学习和计算机视觉等领域的重要性,研究人员对其进行了广泛的算法研究,以编写出高效的矩阵乘法算法。自60年代(https://ieeexplore.ieee.org/abstract/document/1687427)、70年代(https://apps.dtic.mil/sti/pdfs/AD0705509.pdf)、80年代

https://dl.acm.org/doi/10.1145/356012.356020), 90年代(https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.54.9411&rep=rep1&type=pdf)、21世纪初至今(https://netlib.org/lapack/lawnspdf/lawn147.pdf),一直有论文在尝试使用当时的硬件来解决该问题。

24140e0f45cfb639ed5db877e55971c1.png

简单的O(n^3)矩阵乘法算法。

但是概念上的矩阵乘法并不是难点。相反,挑战在于编写一个足够高效的矩阵乘法,以在AI行业的所有硬件、模型和数据多样性上实现SOTA性能。此外,与其他AI算子的协同工作更具挑战性。

硬件

每种用于运行AI模型的设备都有其独特的特征,例如内存层次结构不同、乘法和累加单元(MAC)不同等等。

例如,CPU采用了这种内存层次结构——从慢速的RAM到越来越快的缓存,包括Level-3、Level-2、Level-1和CPU寄存器。内存大小与速度成反比,例如,L1缓存的访问速度通常为1纳秒量级,而RAM的访问速度为100纳秒量级。

要获得最高性能的矩阵运算,必须让算法有效地处理不同的内存级别和大小。因为原始矩阵太大,所以无法将其一次性放入寄存器或最快的内存缓存中。因此,挑战在于将原始矩阵分解为大小合适的block或tiles,以最大限度地利用最快内存。

此外,处理核心矩阵功能(core matrix functionality)单元的实际形状因硬件而异。就传统意义而言,CPU是一种标量(scalar)机器,这意味着它需要逐个处理指令。然而,在过去二十年中,所有CPU供应商都增加了向量单元(如SIMD),GPU则采用了SIMT(单指令多线程,Single Instruction, Multiple Threads)的方式,以最大限度地提高高度并行、重复运算的效率。

此外,更专业的硬件通过对二维矩阵进行运算来进一步实现这一点。最著名的是Google的TPU,不过苹果和英特尔已经增加了自己的矩阵乘法功能AMX。虽然更先进的MAC单元提高了性能,但也产生了相应的需求,即能够在标量、向量和矩阵处理器上工作的灵活算法。

b86a25164d832d92e16331b263cf1fd6.png

(深入了解谷歌的第一个张量处理单元:不同乘法和累加(MAC)单元形状。)

模型

AI模型具有多样性。虽然矩阵乘法是许多模型的基础,但它们的矩阵大小可能差异巨大。例如,模型具有不同的输入形状(如不同的序列长度)、不同的内部形状(即作为模型隐藏层一部分的相乘矩阵),以及不同的batch size大小(对于训练和推理效率至关重要)。因此,矩阵乘法在生产中有数百种不同的形状,使得难以将它们分解为不同的block,以实现内存效率最大化。

312533c7a089a529a3ea701fa9ef80ce.png

Transformer图解,Jay Alammar:多头注意力块中涉及的各种矩阵大小,Transformer模型(如BERT, GPT2和CLIP)的关键构建块。)

数据

数据也存在差异。大多数读者可能比较熟悉结构化和非结构化数据方面的差异,但在本文,我们重点关注数据类型(“dtype”)。在AI模型中,数据通常使用dtype FP32,但为了减少模型大小,提高模型性能,业界也接受较低精度的数据类型,如Bfloat16,Int8以及更特殊的FP4和Int4。用例不同,Matmul算法需要运行的数据精度也不同。

d26db973d4307c1550d9523ce2569ded.png

量化在AI中的重要性:将FP32量化为Int8。

3

当前的SOTA矩阵乘法算法

那么,目前的SOTA矩阵乘法算法是如何实现的呢?鉴于其重要性,matmul通常是硬件供应商最先优化的算法之一,一般来说,供应商会利用他们的库来实现优化,比如英特尔的MKL和OneDNN

库、AMD的AOCL和RocBLAS、ARM的performance库、Apple的Accelerate、Nvidia的CUBLAS。

就效率而言,在上述提及的硬件库中,当前的SOTA是有效地编写汇编代码:在最低层级向硬件提供直接指令来微观管理硬件,而无需抽象。

a96e1fdf0083ac4cbbd288b027a74149.png

面向AVX512,用x86汇编编写的矩阵算法

这样做的主要原因是什么?编写汇编可以实现任意特定用例的最佳性能,通过汇编编写,开发人员可以避免编译器的不可预测性,编译器将Python和C++等高级语言转换为汇编语言,可以执行编译器难以做到的优化,因为编译器必须泛化。更重要的是,它们可以利用编译器未意识到的指令和模式,因为扩展编译器以支持新的硬件功能需要时间。

4

手写汇编kernel无法扩展

那么,汇编能否真正解决用户的碎片问题呢?虽然汇编编写可以最大限度地提高个人用例性能,但它不可移植、组合、扩展且对用户不够友好。少数手工编写和微调汇编代码的专家怎么可能将他们的工作扩展到不同配置,同时整合到所有AI框架中呢?这简直就是不可能完成的任务。

23fb35c01262720f58b70ed862a73e52.png

(机器学习编译优化器介绍,Chip Huyen:不断增加的框架和硬件支持组合)

可移植性

汇编是使用特定于硬件的接口(指令集架构ISA)编写的,因此它不能跨硬件移植。事实上,汇编甚至无法在同一硬件供应商的多代芯片上实现最佳性能!

此外,即使我们在开发模型时考虑了目标硬件,也仍然存在两大实际问题:

1. 首先,我们无法在云上控制运行汇编的特定硬件。你可能会说“我选择了一个非常适合自己模型的实例”。但事实是,某些云提供商(如AWS)上的实例不能保证特定的CPU类型。比如,如果你选择了c5.4xlarge实例,那么相应的,你只能使用老一代英特尔SkyLake处理器或新一些的级联湖处理器(Cascade Lake processor)。汇编无法适应运行代码的特定芯片,更无法为其提供最佳性能。

2. 你的产品将继续迅速迭代,你可能希望完全迁移到不同的硬件架构。确定一种特定配置会限制你根据模型需求的变化或新一代硬件进行适应性调整的灵活性。

可扩展性和可组合性

如前所述,AI模型的多样性导致了矩阵形状差异。使用基于汇编的库意味着选择对内存tile大小等参数进行硬编码的特定处理器指令。这些硬编码的汇编库可以针对特定的张量形状进行优化,但需要对其他张量形状进行不同的实现。

因此,许多现有的kernel库膨胀到了千兆字节(例如,MKL为3.2GB,cuDNN最高可达2.5GB)。当这些库的大小影响到容器构建时间时,如果你想部署到不切实际的边缘端,或者想要部署供应商尚未手动优化的新创新和研究时,这将成为一个麻烦。

从整体来看,高性能矩阵乘法对性能确实很重要。但为了获得最佳结果,矩阵乘法运算可以与其他运算一起执行,例如Elementwise、跨步访问(strided accesses)、广播(broadcasts)等。通过减少内存数据流量,算子融合(Operator fusion)带来了显著的性能改进,但问题是有成千上万的AI算子。

此外,模型使用了很多不同运算的排列组合,手动融合所有重要组合是不切实际的(虽然有些人已经尝试过了!),特别是在AI高速发展的情况下。

用户友好性

最后,汇编对于用户来说并不友好,不利于跨组织的生产力。汇编编程在现代编程语言(如参数化和面向对象编程)中可用的功能有限,且不能在调试(debugging)、代码覆盖率(code coverage)、测试(testing)等方面提供有效助益。

虽然大多数想要编写新运算符的研究人员都对Python比较满意,但还是有一些众所周知的性能问题(https://en.wikipedia.org/wiki/Global_interpreter_lock)。为了应对这些问题,组织不得不花高价高薪聘请专家来填补鸿沟。
 

其他人都在看

  • “ChatGPT们”的淘金时代

  • 机器学习编译器的前世今生

  • 手把手推导分布式矩阵乘的最优并行策略

  • 谷歌科学家:ChatGPT秘密武器的演进与局限

  • LLVM之父Chris Lattner:编译器的黄金时代

  • 两大图灵奖得主力作:计算机架构的新黄金时代

  • GLM训练加速:性能最高提升3倍,显存节省1/3

欢迎Star、试用OneFlow: github.com/Oneflow-Inc/oneflow/icon-default.png?t=N3I4http://github.com/Oneflow-Inc/oneflow/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/455091.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle中实现恢复删除的表或表数据内容

一、需求说明 在我们进行项目开发或运维过程中,由于操作不当,引起的误删Oracle数据库表或指定表的数据内容,导致程序出现故障;而我们又没有对数据库进行备份,此时,如果不能及时恢复数据库内容将会导致严重的事故。我们需要一种能够补救的方法来挽回损失,恢复被误删的表或…

WEB攻防-弱口令暴力破解(包含工具、字典下载地址)

目录 一、弱口令概述 二、Web类-加密&验证码后台猜解 三、服务类-SSH&RDP远程终端猜解 四、应用类-ZIP&Word文件压缩包猜解 一、弱口令概述 弱口令(weak password) 没有严格和准确的定义,通常认为容易被别人(他们有可能 对你很了解&#…

025:Mapbox GL加载栅格高程模型raster-dem文件

第025个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中加载image图像文件。栅格 DEM 源。 仅支持 Mapbox Terrain-DEM,您可以将 Terrain-DEM 用于各种视觉和分析应用程序,从样式化地形坡度和山体阴影到为视频游戏生成 3D 地形网格。 直接复制下面的 vue+mapbo…

记录一个dpdk 19.11 hello world 跑不起来问题(编译和权限)

下载dpdk 源码后: git clone gitgithub.com:DPDK/dpdk.git 切到 19.11 git checkout v19.11 用usertool下的dpdk_setup.sh 选择 [38] x86_64-native-linuxapp-gcc 进行编译: 结果者是build 不过: Build kernel/linux/igb_uio Build kernel/linux/kni CC [M] /home/t…

Linux查看GPU信息和使用情况

1.Linux查看显卡信息 lspci | grep -i vga 2.使用nvidia GPU lspci | grep -i nvidia 个人感觉看不出什么信息,除了显存大小,另外就是可以通过加入前面的显卡编号,显示更加详细的信息。 lspci -v -s 00:0f.0 3.Linux查看Nvidia显卡信息及使…

软件测试之学习测试用例的设计(等价类法、边界值法、错误猜测法、场景法、因果图法、正交法)

文章目录 1. 测试用例的概念2. 为什么在测试前要设计测试用例3. 基于需求进行测试用例的设计1)功能性需求测试2)非功能性需求测试 4. 具体的测试用例设计方法1)等价类2)边界值3)错误猜测法4)场景法5&#x…

Python入门教程+项目实战-11.1节: 元组的基础概念

目录 11.1.1 理解元组类型 11.1.2 元组的类型名 11.1.3 元组的定义 11.1.4 元组的解包 11.1.5 遍历可迭代对象 11.1.6 本节知识要点 11.1.7 系统学习python 11.1.1 理解元组类型 元组与列表有着相同的数据结构,区别在于,元组是静态的数据类型&am…

本地如何搭建一个Stable Diffusion 的AI绘画工具?

实现AI绘画自由指南 前期准备安装1.安装 Homebrew 工具2. 安装Python33.下载 Stable Diffusion -webui4.下载大模型5. 安装 GFPGAN(神坑)5. 允许 stable diffusion-webui 如何使用效果图 最近看到网上各种AI工具很是火爆,心里也是有点痒痒&am…

消防应急照明和疏散指示系统在轨道交通中的设计应用

摘要:本文分析了消防应急照明和疏散指示系统的特点与设计要点,介绍了系统在城市轨道交通中的设计应用,轨道交通设计中新的消防应急照明和疏散指示系统的备用照明仍由EPS供电,新增一套疏散指示照明系统,增加疏散照明指示…

Beta成果测试总结

Beta成果测试总结 Beta是一个项目的早期测试,通过 Beta能够初步的了解整个系统的稳定性,测试系统是否能够满足客户的需求。我们可以在测试过程中发现一些问题,从而快速解决。 当我们在测试一个新系统时,我们需要进行测试前的准备工…

Node.js的简介

一、什么是node.js Node.js是JavaScript语言的服务器运行环境。 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行…

一文带你全面了解最火爆的ChatGpt

导读 OpenAI近期发布聊天机器人模型ChatGPT,迅速出圈全网。它以对话方式进行交互。以更贴近人的对话方式与使用者互动,可以回答问题、承认错误、挑战不正确的前提、拒绝不适当的请求。高质量的回答、上瘾式的交互体验,圈内外都纷纷惊呼。 为什…

【ONE·C++ || 继承】

总言 主要介绍继承相关内容。 文章目录 总言1、继承介绍1.1、继承是什么1.2、继承方式与访问限定符1.3、继承作用域 2、基类和派生类对象赋值转换2.1、子类对象可以赋值给父类对象/指针/引用2.2、基类对象不能赋值给派生类对象2.3、基类的指针可以通过强制类型转换赋值给派生类…

flask学习-实践02

项目实战 入门文当(2条消息) python flask框架详解_flask python_尘世风的博客-CSDN博客(2条消息) python flask框架详解_flask python_尘世风的博客-CSDN博客 入门项目 抄作业了!6 大 Flask 开源实战项目推荐_小詹学 Python的博客-CSDN博客 (66 条消息) GitHub 上有…

DataStructure--Tree

文章摘录链接 1.树基本概念 计算机数据结构中的树就是对显示中的树的一种抽象(倒置现实中的树)。 1.1 树 有层次关系N(N≥0)个节点的有限集合空树: N0 非空树: 有且只有一个根节点1.2 节点 根节点 分…

MongoDB【MongoRepository MongoTemplate】实现增删改查

目录 1:文章评论 1.1:需求分析 1.2:表结构分析 1.3:技术选型 1.3.1:mongodb-driver 1.3.2:SpringDataMongoDB 1.4:文章微服务模块搭建 1.5:文章评论实体类的编写 1.6&#x…

【计算机网络】为什么 TCP 每次建立连接时,初始化序列号都要不一样呢?

【计算机网络】为什么 TCP 每次建立连接时,初始化序列号都要不一样呢? 为什么 TCP 每次建立连接时,初始化序列号都要不一样呢? 主要原因是为了防止历史报文被下一个相同四元组的连接接收。 TCP 四次挥手中的 TIME_WAIT 状态不是会…

现代操作系统和 TCP/IP(第二篇)

接着 现代操作系统和 TCP/IP 继续。 现代分时系统的时间片轮转机制让人们可以 “同时使用计算机”,从而滋生了 “同时使用网络” 的需求,现代分时系统是分组交换网的原动力。 从来没有超过一个人同时使用同一部电话,因此独占线路的电路交换…

2023蓝桥杯省模拟赛附近最小

2023蓝桥杯省模拟赛附近最小 这个题算是一个经典的数据结构入门题了&#xff0c;写了几个解法水一篇文章 map维护 时间复杂度nlgn&#xff0c;但是常数比较大&#xff0c;所以只能过90%数据 #include <iostream> #include<vector> #include<map> #include…

卖房子真是稳赚不赔

上面是一段很长的语音&#xff0c;对话是用的我们河池的桂柳话&#xff0c;不过桂柳话和普通话有很多相识之处&#xff0c;理解起来并不困难。 大概的意思是 A公司要给员工一批福利房&#xff0c;然后就让开发商来竞标&#xff0c;竞标的时候开发商就会说明清楚到时候给员工的房…