本文讨论了 Groq,一种新的计算机硬件方法,它彻底改变了 AI 解决现实世界问题的方式。
在讨论 Groq 之前,我们将分析 AI 的根本含义,并探讨用于运行 AI 模型的计算机硬件的一些关键组件。即 CPU、GPU 和 TPU。我们将从 1975 年的 Z80 CPU 开始探索这些关键硬件,然后通过探索计算机硬件的一些关键演变来加深对现代系统的理解。
在了解了计算机硬件的一些基本概念和权衡之后,我们将利用这些理解来探索 Groq 是什么、它如何彻底改变 AI 计算的方式以及为什么它很重要。
当然,从早期的 CPU 到价值数十亿美元的尖端 AI 初创公司,还有很多内容需要介绍。因此,这是一篇相当长的文章。系好安全带,这是值得的。
定义人工智能
很多人认为人工智能就像一个黑匣子。你把数据输入进去,人工智能会做一些晦涩难懂的数学运算,然后你就可以得到数据。
人工智能的常见直觉是,它本质上是一个接收东西并输出东西的魔盒。
这种直觉很受欢迎,因为人类有时很难理解模型的思维过程。
仅仅因为人工智能模型擅长某项任务并不意味着人类能够轻易理解模型的决策。
尽管从整体上理解模型决策背后的原理可能很困难,但人工智能模型实际上采用非常简单的数学运算来得出结论。
人工智能思考方式的概念图。该模型通过查看大量数据来学习参数(以蓝色突出显示并加下划线),从而做出正确的决策。
换句话说,人工智能模型之所以复杂,不是因为它们做复杂的事情,而是因为它们同时做大量简单的事情。
有很多硬件选项可用于运行 AI。让我们从描述最基本的一个开始。
中央处理器
大多数现代计算机的主要部件是 CPU,即“中央处理器”。CPU 几乎是每台现代计算机的心脏。
从最根本的角度来说,CPU 是基于“冯·诺依曼架构”的。
本质上,冯·诺依曼装置可以接受一些输入,并使用控制单元来控制某些算术单元中的计算方式。然后,这些计算会产生一些有意义的输出。来源。
冯·诺依曼架构相当抽象;在将其付诸实践方面有很大的余地。本文中我们将讨论的几乎所有硬件都可以看作是冯·诺依曼设备的特定版本,包括 CPU。
早期流行的计算机 ZX Spectrum 使用 Z80 CPU 来完成工作。从概念上讲,现代 CPU 与 Z80 并无太大区别,因此我们可以使用 Z80 作为简化示例来开始了解 CPU 的工作原理。
采用 Z80 CPU(右)的 ZX Spectrum 计算机(左)。来源。
即使是这个不起眼的 CPU 的图表也相当复杂,但我们可以将其拆开,了解一些核心组件,这些组件在现代 CPU 中基本仍然存在。
Z80 CPU 的近似框图。来源。
Z80 具有一个控制电路,它将低级指令转换为芯片内的实际动作,并跟踪记录事项,例如 CPU 应该执行哪些命令。
Z80 CPU 内的控制电路。来源。
Z80 配备了一个“算术逻辑单元”(简称 ALU),能够执行各种基本算术运算。这才是 Z80 CPU 中真正进行大量实际计算的部件。Z80 会将一些数据输入到 ALU 的输入端,然后 ALU 会根据 CPU 当前正在运行的指令对这些数据进行加法、乘法、除法或执行其他运算。
Z80 内的算术逻辑单元(或 ALU)。来源。
几乎任何复杂的数学函数都可以分解成简单的步骤。ALU 旨在执行最基本的数学运算,这意味着 CPU 能够通过使用 ALU 执行许多简单的运算来进行非常复杂的数学运算。
即使是最复杂的数学运算通常也可以分解为许多简单的计算。这种积分(来自微积分)只是乘法、除法和加法。
Z80 还包含一组寄存器。寄存器是 CPU 中微小的超快内存,用于存储某些关键信息,例如 CPU 当前正在运行的指令、数字数据、CPU 外部数据的地址等。
Z80 内的寄存器。来源。
当人们想到计算机时,很容易将注意力集中在进行数学运算的电路上,但实际上,需要进行大量的设计工作来研究数据存储的位置。数据如何存储和移动的问题是本文的核心主题,也是现代计算为何依赖如此多不同的专用硬件组件的重要原因。
CPU 需要与计算机中的其他组件通信,这是总线的工作。Z80 CPU 有三条总线:
- 地址总线传达 Z80 感兴趣的数据位置
- 控制总线传达了 CPU 想要做什么
- 数据总线传送来自 CPU 的实际数据
Z80 的三条总线。来源。
因此,例如,如果 Z80 想要从 RAM 读取一些数据并将该信息放入本地寄存器进行计算,它将使用地址总线来传达它感兴趣的数据,然后它将使用控制总线来传达它想要读取数据,然后它将通过数据总线接收该数据。
这整套程序的重点是让 CPU 执行“获取、解码、执行”循环。CPU“获取”某条指令,然后将该指令“解码”为 CPU 中特定组件要执行的实际操作,然后 CPU“执行”这些操作。然后 CPU 获取一条新指令,重新开始循环。
获取、解码、执行循环,这基本上就是 CPU 所做的全部工作。
此循环与程序协同工作。人们通常认为程序是用 Java 或 Python 等编程语言编写的,但在编译器将程序文本解释为机器代码,并将该机器代码传输到 CPU 后,程序最终看起来会大不相同。本质上,编译器将人类编写的程序转换为 CPU 可以根据其预定义的控制逻辑执行的指令列表。
编译器的概念图,它将人类编写的程序转换为 CPU 可以理解的指令列表。这些指令执行简单的操作,例如将两个数字相加、将数据从 RAM 加载到寄存器等。
代码编译完成后,CPU 只需获取一条指令,将其解码为 CPU 内的操作,然后执行这些操作。CPU 使用程序计数器跟踪其所在位置,该计数器通常会在每次调用指令时递增,但它也可能根据某些逻辑(如 if 语句)在程序中跳转。
基本上就是这样。事实证明,即使是一个简单的 CPU 也能够通过遵循一系列简单的指令来执行几乎任何可以想象到的计算。真正的诀窍是让 CPU 快速执行这些指令。
CPU 的设计约束
Z80 是一款相当简单的 CPU。首先,它只有一个“核心”。核心的实际细节可能有点复杂,但核心本质上是 CPU 上工作的东西。想象一下,我们不是只有一个 Z80,而是在单个芯片上封装了几个 Z80,它们各自做自己的事情。这基本上就是现代多核 CPU 的本质。
现代 CPU 主要组件的框图。每个核心都像我们之前讨论过的 Z80 CPU 的复杂版本。拥有多个核心可以让现代计算机同时处理多项任务。
CPU 中的内核可以相互通信,但在很大程度上它们通常负责不同的任务。这些“不同的任务”称为“进程”。在正式的计算机语言中,进程是原子存在的程序和内存。您可以在不同的内核上拥有多个进程,它们通常不会相互通信。
独立进程的概念图,每个进程都执行自己的任务,拥有自己的数据,本质上彼此完全隔离。
Chrome 实际上为每个选项卡使用一个单独的进程。这就是为什么当一个选项卡崩溃时,其他选项卡不会受到影响。每个选项卡都是一个完全独立的进程。这在很大程度上也是 Chrome 占用电脑内存如此之多的原因;所有这些选项卡几乎都是彼此独立运行的,这意味着它们每个都需要跟踪大量信息。
如果您曾经在 Windows 的任务管理器中查看过 Chrome,那么您可能已经注意到许多单独的子任务。这是因为 Chrome 为每个选项卡运行单独的进程。
有时,计算机能够将单个程序中的多个计算拆分并并行运行是很有用的。这就是为什么 CPU 的每个核心中通常有多个“线程”。线程可以共享(并协同工作)内存中的同一地址空间。
CPU 的每个核心都由多个线程组成。由于现代 CPU 很复杂,因此细节会变得有些复杂。线程通常共享 CPU 中的一些资源(如 ALU),但也有自己的资源(如寄存器),当某些任务可以并行执行时,可以实现更快的计算。这一点之后的细节对于我们的目的来说并不重要。
如果程序中有一系列不相互依赖的计算,线程就非常有用。您可以跨多个线程并行执行计算,而不必背靠背地执行这些计算。
单个进程可以在一个核心内使用多个线程,从而允许单个进程执行一些并行操作。
因此,CPU 可以有多个核心来运行单独的进程,并且每个核心都有线程,以实现一定程度的并行执行。此外,CPU 还包含计算单元 (ALU),可以执行几乎任何可以想象到的计算。所以……我们做对了吗?我们只需要制造更大、更强大的 CPU,我们就可以做任何事情。
不完全的。
正如我之前提到的,CPU 是计算机的心脏。CPU 必须能够执行运行任何程序所需的任意计算,并且必须能够快速完成这些计算,以保证计算机的响应时间接近即时。
为了同步 CPU 中的快速执行,您的计算机配有石英钟。石英钟以稳定的间隔滴答作响,使您的计算机能够保持有序的同步操作。
流行的单板计算机 Raspberry Pi 底部的石英钟。石英钟的作用是提供稳定的振荡,用于同步整个计算机的执行。
这些时钟非常快。上图所示的树莓派时钟振荡频率为 19.2MHz,但现代 CPU 可以达到千兆赫兹的范围。对于那些不熟悉这些单位的人来说,1 千兆赫兹是每秒 10 亿次振荡,并且每次振荡 CPU 都需要为每个核心获取并执行一条指令。以下是十亿个事物的图片,供参考:
地球上有 78 亿人。现代 CPU 的每个核心每秒执行的指令数量大约就是这个数字。现代 CPU 通常有多个核心。来源。
因此,CPU 运行速度很快。它们基于每秒振荡数十亿次的时钟运行。事实上,速度如此之快,以至于光速(宇宙的速度极限)开始发挥作用。
电流通过硅的速度约为每秒 6000 万米。典型的 CPU 时钟每秒可能振荡 30 亿次。这意味着电流在每个时钟周期内只能在 CPU 内传播 20 毫米(不到一英寸)。
如果 CPU 变得比现在大很多,那么设计师在保持芯片内操作同步方面将面临严峻挑战。想象一下,CPU 的一部分试图做加法,但其中一个值尚未完全到达,因为该信息的来源距离超过一英寸。这个问题当然是可以解决的……随着更多组件的出现,占用 CPU 内的空间,问题进一步加剧。
还有其他问题我不会去讨论,比如在圆形硅晶片上制造方形芯片的成本、冷却方面的复杂性等等。基本上,“只是让 CPU 变得更大”会带来很多严重的问题。
当我们考虑 CPU 主要负责什么时,就会出现另一个严肃的设计考虑。
我提到过 CPU 必须运行速度快。更具体地说,它们需要具有极低的延迟。延迟通常是指某件事从开始到结束所花费的时间。当您按顺序运行程序时,每次执行的延迟量对性能有很大影响。
如果程序有多个需要执行的任务,则每个任务可能需要一些设置或停机时间(蓝色),以及实际进行计算所需的时间(红色)。
因此,CPU 会尝试尽可能减少延迟。CPU 中的内核需要非常快,数据需要就在那里,随时可用。没有太多的回旋余地。
CPU 设计师的主要工作是更快地完成任务,并且以更少的开销成本来启动和完成任务。
CPU 可以通过多种方式来优化延迟。它们有一种称为缓存的特殊内存,用于将重要数据存储在靠近 CPU 的位置,以便快速检索。
CPU 包含各种级别的缓存,每个级别的缓存大小和吞吐速度都不同。通常,靠近核心的缓存较小且速度较快,而远离核心的缓存较大且速度较慢。CPU 设计人员做了很多工作,试图让核心尽可能地访问数据。
CPU 采用了许多其他花哨的技术,坦率地说,我并不完全理解。英特尔每年在研发上花费约 160 亿美元。其中很大一部分用于尽可能地提高这块石头的性能。对于 CPU 来说,这意味着更多核心、更多线程和更低的延迟。
直到 90 年代,计算的焦点都是越来越快的 CPU。然后,突然间,一类新的消费者出现了,他们对性能有了新的要求。
进入游戏玩家
对于视频游戏来说,CPU 根本没有任何机会。
CPU 非常适合运行顺序程序,甚至具有一定的并行计算能力,但是为了在屏幕上渲染视频,需要每秒多次渲染数百万个像素。
除此之外,像素值基于 3D 模型,每个模型可能由数千个多边形组成。将视频游戏转化为实际视频需要进行大量独立计算,这与 CPU 旨在处理的快速连续任务截然不同。
一个 3D 场景,由(从左到右)一个相机、一盏灯、一个球体、一只猴子和一个立方体组成。
从相机角度渲染的简单场景。您可能能够想象生成此类图像所需的计算。计算机需要计算每个模型的哪些部分对相机可见,以及它们应该根据光源呈现什么颜色。对于具有众多模型、光源和效果的复杂场景,这会很快导致计算成本高昂。
有各种各样的芯片被设计用来帮助 CPU 处理这种新负载。其中最著名的就是 GPU。
GPU的起源
第一款主流 GPU 是由 Nvidia 创建的 — GeForce 256。
Nvidia 的 GeForce 256,被誉为“世界上第一款 GPU”。来源。
这款设备背后的想法是将昂贵的图形处理任务转移到专用硬件上。GeForce 256 是一款非常严格和专用的机器,旨在处理“图形管道”。CPU 会向 256 提供大量有关 3D 模型、材料等的信息,而 GPU 会进行所有必要的处理,以在屏幕上生成图像。
图形管道本质上是一组操作,它获取有关某些 3D 场景的信息并将其转换为可以在屏幕上呈现的图像。
256 使用专门设计用于执行特定操作的芯片来实现这一点;用于在 3D 空间中移动模型的硬件、计算有关照明的信息、计算这是否在那之上等。我们不需要太深入地了解计算机图形学,可以直接切入要点:这种专用硬件将某些游戏的帧速率提高了 50%,这是一个相当大的性能提升。
当然,第一款 GPU 并不完美。由于设计过于死板,它无法灵活地满足不同应用程序的不同需求。GeForce 256 发布九年后,Nvidia 发布了第一款现代 GPU,它在很多方面都比原来的 GPU 有所改进。
现代 GPU
Nvidia GeForce 8 是第一款现代 GPU,为当今 GPU 的发展奠定了基础。
GeForce 8800 Ultra GTX。来源。
GeForce 8 系列并没有采用专门用于执行特定图形操作的组件,而是更像一个 CPU。它拥有可以执行任意计算的通用核心。
CPU 与现代 GPU 的概念图。GPU 与 CPU 非常相似,但在设计上有一些关键差异。
然而,GeForce 8 并不专注于顺序程序的低延迟计算,而是专注于并行计算的高吞吐量。换句话说,CPU 可以非常快速地连续执行任务。GPU 的设计目标是执行速度稍慢但并行的任务。这是 CPU 和 GPU 之间的区别,至今仍然存在。
CPU 专注于需要顺序执行的问题。您需要在运行下一个计算之前知道上一次计算的结果。因此,CPU 专注于尽快完成每条指令。GPU 专注于可以并行化的问题。GPU 执行给定操作的速度可能稍慢一些,但经过优化,可以高效地进行大量并行计算。
GPU 通过采用“单指令、多数据”(SIMD) 计算方法实现了并行计算,允许同时控制多个内核。此外,由于不太关心特定计算的延迟,GPU 可以节省一点设置时间,从而有足够的开销来设置大量计算。这使得 GPU 不适合运行顺序程序,但非常适合并行执行大量计算(例如渲染图形所需的计算)。此外,由于 GPU 旨在执行图形的特定计算(而不是像 CPU 那样执行任何计算),因此 GPU 可以使用较小的内核和不太复杂的控制逻辑。最终结果是设计了许多内核来执行尽可能多的并行计算。
CPU(左)与 GPU(右)。它们采用类似的核心组件,但它们的设计优先级允许截然不同的用例和性能配置文件。
为了让您了解功能之间的差异,Intel Xeon 8280 CPU 在其所有内核中拥有 896 个可用线程。Nvidia A100 GPU 在其所有内核中拥有 221,184 个可用线程。这是进行并行计算的线程数量的 245 倍,这一切都成为可能,因为 GPU 并不像 CPU 那样关心延迟。
GPU 和 AI
您可能可以想象,图形并不是唯一能从并行计算中受益的东西。随着 GPU 的兴起,其用例也随之增加。GPU 很快成为包括 AI 在内的各种学科的基本组成部分。
在文章的开头我提供了 AI 的简化演示。
回想一下这个人工智能背后的数学简化演示。
使用 CPU 运行这个简单的 AI 模型可能看起来像这样:
- 将第一个向量中的所有值相加。这将需要 24 次计算。
- 将结果乘以 3、2 和 -0.1。这又需要进行三次计算。
- 将这些结果加在一起,再进行两次计算。
- 将该结果乘以 0.03 和 0.003,再进行两次计算。
这是 31 个连续计算。相反,你可以将其并行化。
并行化加法的示例。将 24 个连续步骤变成 5 个并行步骤。
如果您并行化此特定示例中的加法和乘法,则最终会将 31 个连续操作缩减为 9 个并行步骤。假设其他所有条件相同,以并行方式运行此模型将快 2.4 倍。
这个例子说明了要点,但实际上它不如现实世界的例子那么引人注目。实际的现代人工智能模型经常在后台使用矩阵乘法。在矩阵乘法中,每一行都与每一列相乘,然后将结果相加以构成结果矩阵。
许多 AI 模型(例如密集网络)实际上都是底层的矩阵乘法。摘自我关于 LoRA 的文章。
矩阵乘法。一个矩阵中的每一行都与另一个矩阵中的每一列相乘,然后相加以定义结果矩阵中的一个元素。现代机器学习模型使用矩阵乘法将模型参数与输入数据相乘以生成推断。来源
现代机器学习模型很大,这意味着它们中的矩阵也很大。对M x N
和N x P
矩阵进行矩阵乘法所需的计算次数为M * N * P
。因此,如果您有两个形状为 的方阵256 x 256
,则必须进行超过 160 亿次运算才能计算它们之间的矩阵乘法。想象一下,在一个庞大的数十亿参数模型中一遍又一遍地出现这种情况。
由于机器学习中存在大量并行操作,因此在机器学习任务中使用 GPU 而非 CPU 变得至关重要。为了并行化矩阵乘法,GPU 使用一种称为“融合乘加”(FMA) 的技术快速将行乘以列,然后多次执行该操作以快速计算结果矩阵中的所有单个元素。
回想一下,矩阵乘法是行乘以列的和。在底层,GPU 会尽可能快地并行执行一系列乘法和加法,以完成矩阵乘法。
GPU 执行矩阵乘法的速度比 CPU 快得多,但它们还可以更快。为了更快地执行矩阵乘法,我们需要引入一种新的硬件。
钟摆摆动
如上一节所述,GPU 的一般风格在近十年内一直占据主导地位。任何改进主要都是扩大架构。更小的晶体管可将更多计算整合到单个芯片中,从而实现更高的计算能力和更好的性能。
2015 年,人工智能开始成为一门大生意。正因如此,GPU 被用于执行大量“张量”运算。“张量”听起来像是一个奇特的概念,但实际上你已经很熟悉它们了。向量是一维张量,矩阵是二维张量,等等。张量只是某个维度上的一些数字块。
各种维度的张量。实际上,张量可以存在于无限多的维度中。实际上,在人工智能中,它们通常最多只有三维,有时是四维。
人工智能可以看作是一堆张量运算。矩阵乘以矩阵,向量加向量等等。虽然 GPU 在执行张量运算方面比 CPU 好得多(因为它们具有并行处理能力),但它们并非专门为张量计算而构建。GPU 当然可以执行张量运算,但 GPU 执行这些运算需要开销,这会降低性能。
谷歌一如既往地在幕后悄悄创新。他们开发了一个名为 TensorFlow 的机器学习框架,并尝试改进自己的 AI 流程。在众多问题中,有两个问题开始凸显:
- 如果我们降低 GPU 的精度会怎样?
- 如果我们专门为张量运算构建一个 GPU 会怎么样?
于是,TPU诞生了。
TPU
TPU 代表“张量处理单元”,在很多方面与 GPU 类似,但它并不专注于主要由矢量和各种计算控制的图形,TPU 专注于使用张量进行计算,旨在适应相对较少的计算选择。
TPU。来源。
TPU的主要工作是进行矩阵乘法。
TPU 的主要组件。它由许多小部件组成,但您可能会注意到,仅用于执行矩阵乘法的单元就占据了芯片的 24%。来源。
TPU 使用的数字精度较低;对于 AI 来说仍然足够精确,但不如物理模拟和图形处理所需的数字精确。这意味着 TPU 可以在相同的尺寸下完成更多操作。此外,通过使用专门的矩阵乘法模块,TPU 可以更快地进行矩阵乘法。它通过对整个向量进行运算来实现这一点;比仅仅并行化单个数值计算要高出一步。本质上,GPU 处理数字向量,TPU 处理向量向量。这使得 TPU 的通用性不如 GPU,但较窄的范围可以提高计算效率。
在某些方面,你可以将 TPU 视为一种倒退。回想一下,最初的 GPU 有专门为图形管道构建的硬件,后来的 GPU 采用了通用计算方法。现在,TPU 正在回归专用方法,但适用于 AI 应用程序。
随着制造技术越来越先进,所有类型的处理器都将变得更加强大。然而,由于在一块硅片上塞入更多晶体管变得越来越困难,硬件设计师一直在尝试设计出最大程度满足特定用例需求的设计。
设计新芯片时需要考虑的几个关键性能权衡的概念图。
Nvidia 意识到了这个想法的威力。自从 2017 年发布 Volta 微架构以来,Nvidia 就一直在 GPU 中引入“Tensor Cores”,就像在 GPU 中放置微型 TPU 一样。
这是 Nvidia 制作的一段很棒的视频,从高层次强调了张量核心的性能提升,并且有一个特别方便的视频演示了不同类型的并行性如何实现更快的计算。
我不会在本文中过多地谈论 TPU,因为在很大程度上,它们具有与 GPU 相同的许多一般属性和用例,只是在某些应用程序上性能略高一些。此外,由于许多现代 GPU 中都有张量核心,因此两者之间的区别往往有点模糊。
用两种方法处理延迟
我之前提到过,CPU 使用缓存将数据保持在靠近核心的位置,以便尽快完成计算。GPU 也使用缓存,但这并不是为了减少往返延迟。相反,GPU 使用缓存来维持吞吐量。
回想一下,CPU 使用缓存(一种内存)来将有价值的数据尽可能靠近核心。这样做的目的是使 CPU 的延迟尽可能低。GPU 也包含缓存以及许多其他类似组件,但目的是促进高效的并行计算。
我不会试图从超额订阅、计算强度和内存效率的角度来描述这个想法 (如果你真的想深入了解的话,我推荐这个视频),我认为核心思想可以用下图来解释:
CPU 可以非常快速地完成单个计算,而 GPU 可以并行完成更多计算,但速度较慢。最终,GPU 可以完成更多计算,但您必须等待它们完成。
尽管特定计算通过 GPU 进行的速度可能相当慢,但它会使用缓存来让所有工作线程保持忙碌,因为有大量积压数据可供处理。另一方面,CPU 通过优化缓存来尽快将数据提供给正确的核心,从而快速完成计算,但一次只能处理少量计算。这种细微的区别在很大程度上就是 Groq 存在的原因。
延迟如何影响训练与推理
训练人工智能模型的过程基本上包括向模型输入大量数据,并要求其更新内部参数以获得更好的输出。
培训流程概述
在训练中,我们其实并不太在意延迟。如果一个模型需要 3 天的时间来训练,那么没人会关心模型是早几毫秒还是晚几毫秒完成。训练 AI 模型是一个典型的吞吐量问题,它是 GPU 或 TPU 的完美用例。
另一方面,推理是实际使用模型的过程。你给训练好的模型提供数据,并期望得到一些合理的响应。
简而言之,推论
在某些推理用例中,延迟确实会成为问题。例如,我在关于 GPT 的文章中介绍了自回归生成。
摘自我关于 GPT 的文章。基本上,语言模型(这里称为解码器)接收输入序列并预测下一个单词。然后它一遍又一遍地重复这个过程,直到构建出一个输出。
ChatGPT 中使用的大型语言模型只是大型的下一个单词预测器。说我们不关心给模型的输出增加几毫秒的延迟是完全可以的,但给输出序列中每个预测单词增加几毫秒的延迟则是另一回事。
例如,在我的一次测试中,Groq 能够使用 Mixtral 8x7b 每秒生成 572.60 个预测。也就是说,每个预测需要 1.7 毫秒。效率低下的硬件会在每个预测中增加几毫秒的延迟,这会使输出时间增加一倍,甚至更长。
类似地,如果你的预测是按照某种操作顺序进行的,那会怎样?你需要等待特定预测完成才能继续执行数据管道,这可能会对互联网规模应用程序的性能和成本产生实际影响。
随着思路链等高级提示技术以及需要 LLM 思考问题的代理系统变得越来越普遍,这些语言模型能够更快地生成结果变得越来越重要,以免模型输出的延迟导致最终产品和服务不可接受的下降。
我们遇到了一个问题。当我们训练模型时,GPU 完全没问题。但是,当我们进行预测时,我们需要等待 GPU 完成所有缓慢的并行化工作。我们仍然不能使用 CPU,因为虽然它们的延迟很低,但它们无法完成运行大型 AI 模型所需的计算量。TPU 可能比 GPU 快一点,但实际上并没有好多少。
进入 Groq。
Groq:扔掉一切
现在我们了解了计算硬件的历史,以及各种硬件方法的一些细微的设计约束,我们就具备了理解 Groq 所需的知识。
Groq 是一款执行张量运算的芯片。它由硅制成。它有晶体管和寄存器……这就是 Groq 与传统计算机的所有相似之处。Groq 不仅仅是一个芯片,它还是一张卡,位于节点上、服务器中、云端。Groq 是一整套统一的计算机架构,专门设计用于实现互联网规模 AI 推理的高吞吐量和低延迟。
Groq 是一种特殊的芯片,位于卡上、节点上、机架上。全部专为运行 AI 模型而设计。来源。
在准备这篇文章时,我与 Groq 软件工程副总裁 Andrew Ling 进行了交谈。他将 Groq 描述为一个第一原则项目。他们研究了人工智能、运行人工智能所需的计算类型、用于制作人工智能的软件等,并围绕此设计了整个计算机系统。
Groq 打破了这一格局。通过专注于 AI 应用,Groq 在吞吐量和延迟方面超越了 GPU 和 TPU,在 CPU 无法处理的应用中与 CPU 数量相媲美。这一切都是可能的,因为 Groq 高度专注于运行 AI,而不是通用计算。
与设计用于执行与 AI 完全不同类型的任务的 CPU、基于 CPU 设计用于偶然执行类似 AI 的任务的 GPU 或修改 GPU 以使其更适合 AI 的 TPU 不同,Groq 从一开始就是一个用于 AI 的计算机系统。
整个系统的核心是“张量流处理器”(TSP)。这是一个巨大的单核芯片,专门设计用于在机器学习环境中执行张量运算。称其为“单核”很奇怪,因为里面有太多东西在运行。
Groq 的 TSP。来源
基本上,TSP 被组织成称为超级通道的行。每个通道都包含运行 AI 模型所需的所有计算资源。
TSP 有 21 条超级通道。为了提高互联网规模应用程序的稳健性,一条超级通道被保留用于故障转移。因此,在任何给定时间,TSP 上都有 20 条可用的超级通道。来源
最极端的是专门为矩阵乘法设计的单元。这些单元有点像 Nvidia 的张量核心,或者 TPU 中的核心。它们可以实现闪电般的矩阵乘法。
TSP 中的矩阵乘法单元。来源
矩阵乘法单元旁边是开关单元。这些单元专门用于执行非常常见的操作,例如转置(旋转)或移位矩阵。常见的计算是将矩阵乘以转置矩阵,因此开关单元直接位于矩阵乘法单元旁边是合适的。
T
SP 内的切换单元。来源
大块的黑色区域是内存。内存非常多。TSP 在单个芯片上集成了 220MB 的 SRAM。这看起来可能不多,但 SRAM 是用于在 CPU 和 GPU 核心内制作超高速寄存器的内存。大多数 GPU 每个芯片仅包含约 20MB 的 SRAM,而大多数 GPU 内存是 DRAM(比 SRAM 慢一个数量级)。因此,Groq 能够比 GPU 挤入大约 10 倍的高速内存。
TSP 内的 SRAM 存储器。来源
TSP 的核心是矢量单元。矢量单元包含传统的 ALU,就像我们在文章开头讨论过的 CPU、GPU 和 Z80 中的 ALU 一样。这些 ALU 允许 TSP 执行逐点矢量运算、使用自定义激活函数以及诸如此类的事情。您可以将它们视为 Groq 中的微型 GPU,允许 Groq 根据需要进行一些更通用的计算。
TSP 中的向量单元。来源
TSP 的顶部是控制整个核心的所有控制电路,TSP 的底部是用于将数据传入和传出芯片的 I/O。
TSP 顶部的控制电路和 TSP 底部的 I/O。来源
正如您所见,这与 CPU 或 GPU 相差甚远。它只有一个核心和一个控制电路,缓存层次结构被抛弃,取而代之的是一堆高速寄存器,而 GPU 之类的东西,即矢量单元,是芯片中间的一个条带。
事情变得更加奇怪了。
让我们通过观察数据如何流经该芯片来更好地了解该芯片的工作原理。
TSP 如何处理张量流
考虑到 Groq 旨在高效运行现代 AI 模型,数据流经 TSP 的方式与数据流经 AI 模型的方式有相似之处也就不足为奇了。几乎每个 AI 模型都会接收一些张量,输出一些张量,并在中间进行一系列张量运算。
现代 AI 模型的一个例子,它是一堆计算块,它们接收一些输入并输出一些推理
Groq 使用了一种称为“流”的东西,它允许向量以类似的方式流经 Groq TSP。我提到过 Groq 拥有贯穿整个芯片的横向超级通道。“流”流经超级通道,并允许数据与 TSP 的各个组件进行交互。
当我说“流”时,我的意思确实是“流”。数据不断地在 TSP 中移动,流经芯片,流经各种功能组件。这意味着 Groq 不需要一些带有一堆复杂控制逻辑的缓存层次结构,Groq 直接将数据从一个组件传递到另一个组件。
数据如何流经 TSP 的概念图。数据被加载到内存中,然后沿着芯片横向流动,使数据能够沿途与各种功能组件进行交互。最终,一旦计算完成,数据就会通过交换单元从 TSP 中输出。
这与 CPU 和 GPU 非常不同,它们从缓存中获取数据进行某些计算,然后将数据发送回缓存。
对于 GPU、CPU 和 TPU,数据需要在缓存和核心之间来回流动。这通常需要几个时钟周期来协调,并且需要复杂的控制逻辑才能高效完成。
Groq 的 TSP 在处理指令执行的方式上更加奇怪。CPU 或 GPU 有一些控制电路,可以按顺序读取指令。它获取数据,然后执行计算。
CPU 和 GPU 执行指令的概念图。有一些中央控制器告诉某些核心执行操作或以某种方式与缓存交互。
另一方面,Groq 会提前为每个功能单元分配一个指令列表,包括什么都不做的指令。当数据流经 Groq 时,功能组件会随机排列指令。如果功能单元有数据和要执行的指令,它就会执行。
给定的功能单元有数据流入和流出,以及与该数据流相对应的指令列表。对于每个时钟滴答,Groq 内的功能单元都会循环到下一个排队指令。
当然,这种方法在传统程序中没有任何意义,因为您可能事先不知道要执行哪些操作。但是,我们的机器学习模型已经定义好了,我们知道进行推理所需的所有计算,因此我们知道需要提前计算哪些操作。
我认为 TSP 就像是许多复杂的太空入侵者游戏。数据在芯片中来回移动,每个功能组件都必须在恰当的时间做出决策,以执行(或不执行)操作。
您可以将 TSP 视为同时发生的多个太空侵略者游戏,当数据通过时指令就会触发。
Groq 知道有多少数据会被输入到芯片中、数据最终会流向何处、需要进行哪些计算以及这些计算需要多长时间;所有这些都是在编译时计算和优化的。这一切都是因为 Groq 最重要的基本设计特征之一:确定性。
决定论
确定性是指在事情发生之前就知道会发生什么。如果你编写了一个简单的程序,并且已经知道会发生什么,那么这就是一个确定性程序。
一个简单的程序,包含一系列简单的连续步骤。人们可以合理地将其视为确定性过程。
计算机由 1 和 0 组成,还有一堆使用这些 1 和 0 进行简单数学运算的电子元件。从下到上,计算机都知道发生了什么。因此,计算机是确定性的。
但实际上,大多数 计算机都不是确定性的。
CPU 负责根据您的反馈以及计算机中复杂软件的运行情况运行一系列随机操作。您可能会关闭一个选项卡。某个软件可能会启动一系列进程。计算机中会发生很多疯狂而复杂的事情,所有这些都基于随机而复杂的反馈,这使得 CPU 基本上不可能跟踪所有事情。
实际的真实代码包含复杂的逻辑、条件分支、与人类或其他计算机的交互以及其他复杂性,这些复杂性使“代码是某种简单的确定性过程”这一概念发生了分歧。来源。
因此,CPU 非常贪婪。它们得到数据,然后根据这些数据进行计算,并尽可能快地完成计算。事实上,现代 CPU 的速度通常比可能的速度要快。有些 CPU 会猜测它们需要做的工作,并希望程序会要求它们完成这些工作。有时 CPU 猜对了,有时猜错了,所有这些都是为了尽可能快地执行程序。
很多人认为计算机就像一台滴答作响的时钟,完美和谐地执行大量计算。但实际上,它就像一群快餐厨师,将半成品食材相互扔来扔去。
CPU 执行的实际情况看起来更像是许多厨师按照个人订单匆忙行事,而不是某种有凝聚力和秩序井然的机器。
GPU 和 TPU 在继承了 CPU 的核心思想的同时,也继承了这种非确定性。它们是贪婪的计算系统,试图尽快完成大量计算,并具有复杂的缓存和控制系统,以帮助协调数据在一系列本质上独立的计算系统中的分布方式。这种混乱在很大程度上是必需的,而且有许多聪明的人已经对这种混乱进行了优化,但确实会导致在不必要的执行上浪费精力、时间和金钱。
另一方面,Groq 是确定性的。对于 1.25GHz 时钟的每一次滴答,Groq 都知道数据在哪里、数据要去哪里以及正在执行哪些操作。这就是 Groq 能够毫不费力地玩多场最复杂版本的太空侵略者游戏的原因。这一切都是可能的,因为 Groq 处理的是可以确定性执行的问题。您有一个预定义的 AI 模型,您需要将数据传递到该模型以进行一些推理。
Groq 非常像一台滴答作响的时钟,Groq 可以通过专门针对 AI 模型进行定制而不是进行一般计算来完成这一顺序。
扩展到云
您可能能够想象计算机就像是一座纸牌屋。CPU 是一台贪婪的执行机器,它尽最大努力尽快完成命令。它必须与 GPU 通信,而 GPU 也在做它自己的事情。想象一下像 OpenAI 这样的公司;您在大型服务器机房中拥有一堆这样的计算机,它们都相互通信,您试图让它们高效地运行一个单一的、庞大的、数万亿参数的 AI 模型。
一句话,混乱。用三个词来概括,绝对的、纯粹的混乱。
虽然服务器看起来井然有序,但实际上它们只是一群独立的参与者,彼此之间沟通效率低下。要协调整个过程,需要进行大量的开销计算。我不是专家,但根据我所做的研究,在一个复杂的计算机系统中,大部分资源似乎都用于通信,而不是实际计算。换句话说,更多的资源用于跟踪正在发生的事情,而不是做实际的工作。
Groq 的员工经常谈论异构系统。基本上,当你的计算机系统由一群独立的参与者组成,每个参与者都做着自己的事情时,它会带来很多麻烦。这些服务器由专为运行一堆独立程序而设计的硬件组成,而不是同时运行一个庞大的 AI 模型。Groq 的 TSP 存在于卡内,卡内存在于节点内,节点存在于机架内。从端到端,Groq 是一个专为 AI 设计的整个统一计算系统。
这让我大吃一惊;他们设法在整个系统中保持了确定性。在一个拥有一堆大型机器的大型服务器机房中,Groq 可以将一个向量从一个芯片发送到另一个芯片,并且知道它何时到达,精确到大约 10 个时钟滴答。如果你对网络很熟悉,你就会知道这是多么疯狂。
TSP 的这种完全确定性使他们能够将确定性构建到服务器机房,从而使 Groq 能够优化从单芯片执行到如何通过多张卡发送大量数据以最大限度地减少延迟的所有方面。此外,由于 Groq 对所有事情都了如指掌,因此它不必担心数据包。它可以将原始数据直接从一个芯片发送到另一个芯片。没有标头,没有开销。速度更快。很容易看出,当您拥有一个遍布整个服务器机房的多万亿参数语言模型,它们都在努力回答一个问题时,这种凝聚力对于快速生成响应非常有用。
结论
这篇文章可以一直写下去。我可以谈谈 Groq 如何使用蜻蜓拓扑来优化组件之间的通信,或者我可以谈谈 Groq 如何由几乎同步的准同步链路组成,以及 Groq 如何使用软件和硬件去偏移技术来保持全局同步。
除非你打算创办自己的硬件公司,否则很多细节并不重要。重要的是:
- CPU、GPU 和 TPU 是许多应用中的重要工具,但它们也有缺点
- 延迟是硬件中非常重要的概念,如何管理延迟对于哪种硬件在给定应用程序中有用有很大影响。
- 通过高度专注于 AI 模型推理,Groq 具有出色的延迟和吞吐量,将自己定位为硬件加速推理的前沿选择。
- 随着硬件限制变得越来越难以克服,性能要求变得越来越苛刻,我们可能会在不久的将来看到专用硬件时代的到来。
RA/SD 衍生者AI训练营。发布者:chris,转载请注明出处:https://www.shxcj.com/archives/3907