大型语言模型的推理演算

68185dd365f82a915966119bb6d0aaf0.jpeg

作者|kipply

翻译|杨婷、徐佳渝、贾川‍‍

本文详细阐述了大型语言模型推理性能的几个基本原理,不含任何实验数据或复杂的数学公式,旨在加深读者对相关原理的理解。此外,作者还提出了一种极其简单的推理时延模型,该模型与实证结果拟合度高,可更好地预测和解释Transformer模型的推理过程。

为了更好地阅读本文,读者需了解一些Transformer模型的相关先验知识,比如《图解Transformer》的大部分内容。另外,了解与本文相关的参数计数文章也能更好地帮助读者理解本文内容。本文主要包括以下内容:

  • kv 缓存 (kv cache) 解释了在推理过程中缓存自注意力向量所带来的性能优化效果,以及可能导致的权衡(tradeoff)以及容量成本问题。

  • 容量(capacity)考虑了kv缓存的存储成本以及模型权重的存储成本之间的联系,并解释了容量大小对模型性能的影响。

  • 模型并行可帮助我们理解张量并行,以明确通信成本。

  • 时延计算需要从其他概念中获得理解,并创建用于确定推理速度底线(floorline)的方程。

  • 批大小(batch size)对性能的影响以及最优批大小为多少。

  • 通过transformer blocks执行flops(每秒浮点运算次数)计数操作,可以识别对flops速度有实质性贡献的操作。

  • 中间内存成本涵盖了激活(即激活函数的输出结果)占用额外内存,以及一些真实基准测试中的内存带宽成本。

  • 对比真实基准测试是指将计算出的内容与英伟达 FasterTransformer基准测试结果进行对比,并确定其中的差异。

(本文经授权后由OneFlow编译发布,译文转载请联系OneFlow获得授权。原文:https://kipp.ly/blog/transformer-inference-arithmetic/)

1

kv 缓存

采样时,Transformer模型会以给定的prompt/context作为初始输入进行推理(可以并行处理),随后逐一生成额外的token来继续完善生成的序列(体现了模型的自回归性质)。在采样过程中,Transformer会执行自注意力操作,为此需要给当前序列中的每个项目(无论是prompt/context还是生成的token)提取键值(kv)向量。这些向量存储在一个矩阵中,通常被称为kv缓存或者past缓存(开源GPT-2的实现称其为past缓存)。past缓存通常表示为:[batch, 2, num_heads, seq_len, features]。

b99e4671e41c685d40d98ba432f76374.png

kv缓存是为了避免每次采样token时重新计算键值向量。利用预先计算好的k值和v值,可以节省大量计算时间,尽管这会占用一定的存储空间。每个token所存储的字节数为:

 60bd804159574ae5b853d632579517d0.png

第一个因子2表示k和v这两个向量。在每一层中我们都要存储这些k,v向量,每个值都为一个7eece9d058b8ca6bf13ca9f719661bb8.png矩阵。然后再乘以2,以计算每个向量所需的字节数(在本文中,我们假设采用16位格式)。

我们乘以token嵌入(token embeddings)得到的权重为c6b1b4beb31cab8dfe7ddb45690b25e4.png58461ad7593a12d9f7eb97d308f6d175.png,其中每个token嵌入为991b89ecec034f5d061509be0beb89b2.png。这样,我们就可以算出所有层的k和v需进行的浮点运算次数为:

e215082786dc918d30879d70eaacd354.png

8399e224f8b9d7510876eb2b829197d9.png乘以e3f4391cb11238a91eb7fe894ba1442b.png需要进行56aa40118fe0d684a5cd733a3808e72c.png次浮点运算。另一个2表示我们需要重复两次这样的操作,一次用于计算k和一次用于计算v,然后再重复所有层数f131ba696a6d37b42ffb0dd0fa656fd4.png

矩阵乘法(matmul)中的浮点运算次数为多少?

矩阵-向量(matrix-vector)乘法的计算公式是8c4f724e82493503e037c198577104f0.png,其中a544fe71f0d76df91fa5bc024f763c81.png10120b6a591aea62516a193fa733e62c.png149773551f26f02105f2e461bae19f92.png。对于矩阵-矩阵(matrix-matrix)乘法,计算公式是 4d127770975f4b0a9793ae56a6d49913.png,其中7b981c1293164113e2ad8e433a553839.png745f9b104dd312026698757b21c5fd4e.pngfdadb64f8244bf3f943134409ab8804f.png因子十分重要,因为它反映了矩阵乘法中由乘法和加法组成的组合方式,即“乘法(1)-加法(2) 操作组合”。更多内容见讲义(lecture notes)。

这意味着对于一个520亿参数的模型来说 (以Anthropic中的模型为例,3bd24cc68d2ab6f78862c9404a5449fb.png ,9b11c622019ddd38a5c7910af4274175.png),其浮点运算次数为:

b030fd41d6d178944b1dad4a29a4072a.png

假设有一个A100 GPU,其每秒可执行的浮点运算次数为bded525c9a55f6d78edf1399df298d68.png,其内存带宽可达4e1e94ee208e1f941e727f7a7e1b9a4a.png字节/秒。以下数字仅涉及kv权重及计算的数值:

92a8967fdfcee20b92817732dfc7570f.png

Flops vs 内存有界性(Boundedness)

英伟达使用了数学带宽这个术语,我觉得这个术语真的很可爱。从技术上讲,这种描述存在于每个内核中,但可以抽象为操作组。 

Flops vs 内存有界性是Transformer推理和深度学习优化的常见问题。为了完成所需计算,通常需要加载权重,加载过程会占用内存带宽。假设通过加载权重已经得到了很好的优化,那么我们可以在加载权重的同时开始计算。

在这种情况下,flop bound意味着一段时间内存中没有任何数据传输;memory bound则意味着没有进行任何计算操作。

英伟达使用数学带宽(math bandwidth)来描述该情况,我觉得相当有意思。从技术上讲,这种划分通常是指每个内核(kernel)中的计算量受限,但也可以指这些操作组的计算量受限,将每一组视为抽象意义上的单元。

现在模型架构不再重要了——在给定硬件规格的情况下,我们得到了一个明显的比率208。这意味着,我们计算一个token的kv所需的时间,与处理208个token的时间相同。若低于该值,会出现内存带宽限制,若高于该值,会出现flops限制。如果我们使用剩余的权重来完成完整的前向传递(即运行剩余的transformer),那么结果仍然是208(分子和分母各乘以6)。这一点我们会在后面的章节详细介绍。


下图的交点是208,不过实际上内存线(memory line)会有一些倾斜,这是因为中间计算(intermediate calculation)存在内存成本(上一节讨论过)。

e99084e7723303001c7adfcfe28b3ed2.png

对于拥有520亿参数的模型来说,一次完整的前向传递需要c4b66f011d05d4d31e5be03f4280adfe.png毫秒,这是处理208个token所需的时间(实际上我们会使用四个GPU进行并行处理,因此实际需要的时间约为17毫秒,后续章节将做详细介绍)。如果语言环境存在416个token(即双倍token),那么处理时间将翻倍,而处理312个token所需的时间是处理208个token的1.5倍。

计算kv缓存的token时,一个token所需的计算成本为模型中传递该token计算成本的1/6。总的来说,这些前向传递(获取logits、嵌入和训练时我们深有体会)非常便宜,因为可以进行并行计算。相比之下,采样的成本要高得多,因为它需要强制读取每个token的所有权重,进行自回归预测。

但这并不意味着时间节省了1/6!假设出现了flops bound,在每个采样步骤中,我们可以少进行81e98bdc8590cf228f480a63df9a8859.png次浮点运算,而解码步骤(step)需要进行10b74d37697278f64d9edde6f866bf16.png次浮点运算。


因此,在每个步骤中,我们节省的每秒浮点运算次数是序列中每个token每秒浮点运算次数的1/6(很大!),而且该数值会随着采样token数量的增加而增加。在没有kv缓存的情况下,随着token数量的增加,采样的时间复杂度(time complexity)将以平方级增加。

考虑到存储缓存相关的开销和权衡(tradeoffs),以上说法并不全面。如果我们进行小批量设置,可能会出现内存带宽受限,而非flops bound。在这种情况下,我们可能不会使用过去的缓存,而是倾向于重新计算,这会消耗flops(因为我们已经支付了采样的内存成本)。

2

容量

我们对于GPU中存储的kv缓存和权重有了一定认识,并且了解到GPU容量确实对Transformer模型的推理性能有着重要影响,也就有了充分的理由对其进行评估。

一般来说,Nvidia A100 GPU是用于推理的最佳GPU,其容量标准为40GB。虽然有一些GPU的容量高达80GB,并且具有更高的内存带宽(为 2e12 而非 1.5e12),但它们尚未被任何大型云服务提供商采用,因此,于我而言它们缺乏实际价值。

将给定的参数计数(parameter count)乘以2,我们就可以获取相应字节数,进而算出拥有520亿参数的模型的权重大小。

 28598f43dba05fc6e0447c8dcc9e3e3b.png

46292793038e25020875784a57edc5dc.png

不过这显然不能在一个GPU上完成,我们至少需要三个GPU才能加载所有权重(稍后将讨论如何进行分区(sharding))。但这样就只剩下82f5c0ddbac97d4140a49bfd12a4d202.png 可用kv缓存了,这足够吗?让我们回到kv缓存内存中每个token的方程式,再次使用520亿参数大小的模型运行。

dd3a673bf8d6cc596c849546802deb54.png

使用这种GPU设置,我们可以将7fc6de4f12993e218e5e46cc2bb97549.png个token存储在kv缓存中。或者我们可以将batch size设置为4,其中每个请求最多包含2048个token(token越少所需batch size越大)。

难办的是,我们想要做更高的batch size,但却受到容量限制。batch size越大,GPU处理相同请求所需的时间就越短,就能更有效地利用GPU资源。然而,batch size小,内存又会受到限制。在这种情况下,应该放弃使用kv缓存,选择支付flops成本。

同时使用四个GPU,就能处理504fc1b9e41416391f5701c8026dd18f.png个token。要想batch size更大,处理更多的数据,我们肯定会选择四个GPU。若只用一个GPU,会降低2/3的效率,这显然不是明智的做法。这不仅是batch size的问题,如果有大量的数据需要处理,那应该使用多个模型实例。我们的目标应该是,尽可能让每个实例都可以通过更大的batch size处理,因为无法避免支付存储权重的成本。

中间计算步骤会占用一些额外空间,但这些空间可以忽略不计。

3

模型并行

这方面已有许多相关介绍,所以我就不再详细介绍模型并行(model parallelism)及其实现细节了,仅提供一些有用信息,以帮助读者做性能决策并计算通信成本。

模型并行的最终结果:通过内存和flops传输的所有权重成本都被分摊到使用的加速器数量上。

我们将采用张量并行(一种模型并行),将模型的中间进行划分。每个加速器将使用其权重分片(shards)尽可能多地执行操作,并在需要同步时进行通信。相比之下,流水并行(pipeline parallel)更为简单,其中每个GPU将保留模型的一部分层。虽然这种方法的确平衡了权重加载成本,但存在明显缺陷:只有一个GPU运转,其他的都被闲置!

在训练过程中,你可以采用流水并行(第一批数据移向下一个GPU时,新一批数据重新于第一个GPU开始),以便有效利用各个GPU。虽然处理多个样本请求时该方法十分有用,但在处理单个样本请求时,这种方法就不太奏效了。此外,无论flops是否受限,流水线并行都无法充分利用内存带宽。简而言之,流水并行适用于通信,而模型并行适用于计算。流水并行会在每个加速器之间进行d0da6e30bd78f63422025a9e0f0cff83.png次通信,而模型并行会在每个层内进行cab5516d652ab42de41cb63fcb25403d.png次通信,其中b87b5ae172e19fd93ccf74ffb27ea2b0.png是加速器的数量。

A100 GPU的通信带宽为300GB/s,而文档将其标记为600GB/s,这是因为NVIDIA 在每颗芯片上叠加了300GB/s的带宽,同时向外输出300GB/s的带宽,而没有使用双向数值(对于计算,这种方法更为直观)。

2334df1ad0d5bb24585b9110167a04bf.png

首先,我们在图中黄色区域将token嵌入(token embedding)插入到模型底部。紫色盒子描述了权重在加速器上的分配情况,此处我们使用的是一个非常小的框架,以便能够按比例绘制所有内容。

普遍的做法是,我们可以将两个矩阵a7767420eba31060c2207081d285e229.png1cad9fd81bf4d06eff734d4d11987f65.png进行划分,并计算shards的乘积,但这并不能完成d0e832f4554f82d2d94a5f1c7d0b1262.png 的矩阵乘法(matmul)。换言之,如果我们只是简单地将shards的乘积连接在一起,那么得到的矩阵就会太大,无法存储或进行计算。相反,如果我们想要进行传输,可以计算出shard sum,并将shard sum进行通信,然后进行连接到输出b3fb2db3231dfb3b36f25c9a7656bcae.png

注意力机制通常涉及多头(head),因此采取并行计算非常直观。几乎不需要通信就能走完大部分注意力层,因为注意力头(attention head)是连接在一起的,需要乘以权重160c9d6f8b0a2f446cc465712ca28fd2.png进行计算。在乘以607749c6794eab6dc31d1dd5e146ba8a.png后,我们需要将结果乘以shard的a4da6830d65476ad66ede5faf3bff9f1.png,以得到6287f6c7bd7a6bf7a2430af12e13f374.png 。

然后,每个加速器会将自身的shard传递给其他加速器,其他加速器也会将其shard返回,其通信成本为c97f75fbc726f7e9f6786927c02bea40.png。每个加速器平等分配相加的shard,以获得输出投影(output projection,译者注:输出层的输出被称为输出投影,它是一种将神经网络的输出转换为特定格式的过程。)然后,他们会重复上次进行的通信,各个主机进行连接(近似瞬间就能完成)。

其本质与MLP(Multi-Layer Perceptron)层类似!就像我们使用权重55ca5ae082b598c7b63695447ca50443.png将多头注意力(multi-headed attention)的结果投射回长度为339fbe13c05ba91cca7d772b55c4f503.png的向量一样。同样,我们也使用91207d735902c3147babf7f19544e31d.png01cba22888b92436cbec41fb74571968.png将向量维度扩大4倍,并将其重新投射回原始值大小。因此,在MLP的末端完成了两次同样的通信。

我们最终的通信量为256e348b4aa6909e6c094273bb4673d7.png字节。GPU将对整个kv缓存进行划分,并将其分配到各个头部。

4

时延计算

我们已经较全面地讨论了容量(capacity)、模型并行中的通信,以及一般的计算步骤。接下来我们将其构建到估计时延的方程中!

745cc9edcd6771f73466a1711d1fcfe1.png

时延计算大多与flops和内存有界性相关。如果每个参数需要进行的乘法运算很少,那么我们可能会受到内存带宽的限制。浮点运算量增加取决于批处理大小和参数数量,而内存只受参数数量的影响。

通信方面,关键不是有界性问题,而是增加时延项和吞吐量项(即300GB/s)。由于时延方面的数据不透明,最理想化的估计也是每条消息发送大约需要8微秒。该数据源于Citadel的一篇论文,但该论文针对的是V100 NVLink。

受计算因素的影响,计算单个token解码步骤的时延时间需要两个公式:一个用于内存带宽bound(小batch),另一个用于 flops bound(大batch)。处理大batch数据时,我们通常会忽略通信的时延因素。

针对小batch(当batch size=1时,可以忽略batch因素)的方程如下(其中N为加速器数量,P为参数数量,b表示字节单位):

6ab5202a2047e80a258fa9c67db5f371.png

因为我们需要通过内存传递所有参数,且每个参数都是2字节,所以这里是2*P。f28af35bff32eb5aba53ee20b5d0526c.png是加速器内存带宽,成本在加速器之间分摊。每层有ef29612c48b992c3e353f3e60d7ae69c.png个通信请求,每个请求的时延较小,通常可以忽略。通信还有吞吐成本,但也可以忽略。

有时读取kv缓存的时间也会对计算产生重要影响。不过,由于该因素取决于前后token的数量,而数量在同一批次内会有所变化,我们要采样的总token数量也有所不同,因此暂时将其排除在计算之外。这个时间会被计算为内存带宽时间。另一个缺失的内存带宽时间是读取unembeddings,以计算每个采样步骤的logits,即e7405ebb9edd91a140283c73de8ce4a3.png

如前所述,内存实际上并非保持不变,每个批次会使用一些额外的内存来存储中间激活值。我们之所以不计算这些额外内存,是因为其数量深受软件堆栈、编译器优化等因素的影响,很难精确计算。

针对大batch(batch size=512)的方程如下(其中 B 是批量大小):

9f70c84196c4960e436a7541ddd77f32.png

其中,947af8c914fea3417e22b2c039b4acf4.png表示加速器的浮点运算能力,3dbe5f0dc76163144f3fe0fc883e27f5.png表示处理单元之间的通信带宽。公式中做了2*P次浮点运算,这从对所有参数进行矩阵相乘也可看出。如前所述,因为385268eff1da568343c078733dd8a5e7.png,所以矩阵向量乘法是2mn。

在模型并行部分,每个层需要进行四次(N-1个因子,四舍五入为至N)4825c7ed7ecec13aff337b743899dd2d.png大小向量的通信。考虑到时延可以忽略不计,这里使用吞吐量来计算通信时间。将需要传输的总数据量除以通信带宽,可以得到通信所需时间。

接下来,在16个GPU上使用2600亿参数的Gopher模型来进行推理。使用小batch推理时,生成一个token需要22毫秒的时间。通过大batch公式计算出来的通信吞吐量成本约为35微秒,因此可以放心地降低该成本。

993c51e2b064dd658451a2ae567a6ac0.png

对于512的大batch,生成每个token所需的时间为53毫秒(即在62毫秒内生成512个token)。通信的时延成本也为3毫秒(由于消息可以一起准备,因此延时延不会随着batch的增加而增加),这对于减少时延来说有一定的意义,但如果假设通信和计算是并行的,那么这也可以接受。

d64c2bc2b338d40a3af589330d616c47.png

在假定并行处理的情况下,我们会选择计算和通信中较大的值。因此,我们希望避免通信时间大于计算时间(这是防止随着芯片数量的增加趋近于零时延的机制,最终通信时间将占用越来越多的时间)。但并不能保证所有系统都能够完美地并行处理。

这些数值明显比“沙箱环境”中获得的值要低得多(译者注:“沙箱环境”即一个独立于操作系统和其他程序运行的安全环境。在这个环境中,程序只能使用被授权的资源,无法对系统或其他程序产生影响),因为它假设了最佳的硬件使用,没有考虑softmax,假设没有通信时延,并忽略了许多其他较小的因素。尽管如此,这些数学推理仍有助于思考如何优化性能以及未来优化所带来的变化。

5

Batch sizes

(Batch sizes)批大小是性能的一个重要因素,尤其是对特定用途性能的理解。

我们在前面部分进行了两个计算,用于确定何时是内存带宽bound,何时是flops bound。为了确定主导因素,我们可以对这些数值进行对比。

583a946640f0463e8e6a57e688ee00d3.png

我们正在处理与kv缓存部分相同的比率。内存带宽bound的最小batch size为9510f66f9417653691c6b650823452af.png。该比率非常有用!在足够负载的情况下,我们更倾向于flops bound,因为这样计算效率更高。但是,如果是flops bound,增大batch size并不会提高计算速度。

很容易计算出容量中的主流何时从kv缓存转变为权重,但这之间并没有明显的二进制分界点(当kv缓存开始占用更多内存时并不会有特别的变化)。此外,也没有特别重要的通信因素。随着batch size增加,吞吐量开始超过时延,所以我们不再考虑时延因素。正如之前观察到的,时延变得不重要的时间相对较晚(例如,52B通信成本上的512批大小仍有11%的时延)。

将其简化一下,即通信需要在四个不同的步骤中进行,这意味着我们不仅希望计算时间比通信时间长,而且在每个步骤中都是如此(如果我们可以同时进行计算和通信)。为了达到这个目标,我们使用一个更奇特的比率,即每个字节的通信量需要多少次浮点运算。下图是一个很好的计算表,后续内容也将会用到。

02296fc9597f37bd1f9552b0dcb085a7.png

A100芯片每字节通信的浮点运算次数为(312e12/300e9)=1040次。我们希望最后一行的值大于硬件每字节的浮点运算次数,以保持flops bound(假设没有memory bound)。对于任何embedding维度超过1024(每个芯片)的模型,相对比较安全!但对于512维度的模型而言,情况就有些棘手。

API负载较低时,会出现较小的batch sizes,这时会考虑放弃kv缓存等决策。当API负载较高时,为了优化每个请求的时延,会选择提供最低batch size,以达到flop bound,即使仍有容量剩余。在AlphaCode等大规模推断任务中,我们通常会尽可能多地插入芯片,然后利用这些容量执行最大的batch操作。虽然我经常使用“可能”一词,但这些情况都是绝对存在的。

6

Flops计算

之前:

从所有参数的matmul操作来看,我们的flops运算为2*P次。

这是很合理的推理,我们还可以检查transformer步骤来分解推理,以核查是否能得出2P这个结论。

以下是对token和layer的计算。准确来说,77cd65c0583126d24128eda8b09f04cf.png13895cbaf3a5105c10730757e5ed1aba.png应该表述为75c34a1a5450738b040169b6798806f8.png86f3df143569da42df8d558762365e2e.png,其中i最大为6a594d9ca6ade41bbb852cbdcb2e98b0.png。为了计算时延,我简化了0edb8749345a5ae3e84e66ef0d898127.png,以包含所有heads。

>qkv计算

   >将060dea944b21ecc90d687dc0d40ed3c5.png乘以ebb456bff5de89d77dcfa57bd4778082.png

   >Flop次数:df0ea2b6040b3e4c4995e7ab740948df.png

>计算z

   >公式为:bdc1062432dd198e92ccde3f6292366a.png

   >这里不需要矩阵乘,flops为193788c57c15f819de0029a71d07c488.png的某个因子。

>乘以输出投影矩阵(projection matrix)

   >将82eb83a285b5e36a42c9f5fcf709edc5.png乘以cfb281167ff84b3f585ee98780bfd5f1.png

   >Flop次数:8561a4c439a937ba15b287d84771b373.png

>前馈

   >我们有用于两个线性变换的MLP权重e810d741b7baaacd20541bd84290296e.png4f25d29a35b7c4573a3eb7a6674f284d.png(中间有一个小的ReLU)。

   >Flop次数:6976cd83f5a9b5718479618945939106.png

>其他

   >通常每次attention后都会运行layernorm,其中权重为长度向量9c5a4efe95912003587aa35e19b1b9af.png

   >这里还有另一个线性层,然后是位于顶部的softmax,softmax就是我们的输出(token)嵌入(embedding)、解嵌(unembedding )、反嵌(de-embedding)或嵌入d2b231023d0f462ade5d29b4f7f1b82a.png( embedding4f1c80e2da0b173d1444f649ffa664aa.png)。

   >原始transformer有余弦绝对位置编码(cosine absolute positional encoding scheme),它是token嵌入的加法操作。

将所有flops相加!

ea90328646880e7cc2fd708255295d98.png

在8192模型中,flops大约为100B;

1206b9bc9a478a312f118d0e74c5f0f6.png

103079215104除以2约等于515亿。我们得到的结果为515亿,比520亿略少一些,这是因为token(un)embeddings的参数接近了10亿,相比b2b0bee5037aaa99923ea8c632ed1835.png69ad556855a273647ec035e32b2f7828.png更适合用来计算时延,但这两者的差异不到2%。

该如何计算Z和其他步骤呢?这些都是向量到向量(甚至向量到标量)的运算,所以它们都是围绕aef5ca055e8e09035486c7823d591a9b.png因子建造起来的,而不是588ab8db7ac85db9b35b83a394d86239.png因子。即使每一层(layer)要运行100次这样的操作,最终也会有一亿次flops, 占已计算flops的0.1%。

7

中间内存成本

Data Movement Is All You Need(https://arxiv.org/pdf/2007.00072.pdf,主要内容是优化transformers的低层级数据移动,与本文内容不太相关)一文提出了一个很好的分类操作方法。首先,在大矩阵(包括线性层)当中,张量缩并(tensor contractions)是最重要的,统计归一化(包括softmax和layernorm)次之,最后是逐元素操作,比如偏置( biases)、dropouts和激活(activations)等。

那么我们该如何计算矩阵、layernorms等的时延呢?我们硬件上报告的flops是专门针对乘加运算的,因此即使我们可以计算flops,其结果也不对。幸运的是,这只是为了占用内存来进行softmax读/写,因为这有利于带宽和flops比率。这是已知的时延因素!

在这里我将抛开第一性原则,讨论 Data Movement Is All You Need一文中的表格A.1。我们发现softmax的时延时间略长于qkv的计算时间(softmax时延时间是qkv操作时间的三倍)。这有点令人担忧,可能会影响整个神经网络的性能。

ffbbc642a331d06b3946ff7319ff3356.png

出于同样的原因,softmax会受到内存限制,所以qk、ReLU和dropout的乘法(multiplication)操作也相当昂贵。

GPU内核融合(Fusion)

GPU 以“内核”为单位执行操作。内核融合意味着2个内核可以融合为一个,这样我们就可以在内存中重复利用负载,减少冗余负载和存储。例如,一个乘加(multiply-add)是一个内核。但是如果一个乘加有两个内核,一个内核负责加载+加法+存储,另一个内核负责加载+乘法+存储。内核融合以后,我们可以运行加载+加法+乘法+存储,以简化步骤。

通过计算所需的读写次数,我们发现这里的softmax没有完美融合。理论上它可以是一次读取和一次写入(标准次数为四次)。qk是两次读取和一次写入(两次读取可能可以保存)。三比一的比率表示softmax执行的内存传递量多于最佳值。我这样说是因为,这表明了计算的软件依赖程度,并且需要通过实验来验证,因为从理论上来说成本可能为0。

值得注意的是,随着模型大小的增加,操作所花费的时间百分比会迅速降低,因为每层内存将以038a8744824f52bb70a7aa4815fdde55.png增加,flops将以 3756809ee3120a558adbf1e1db1aa2e3.png增加。本文为336M参数模型,765ed6f3adf884664db5080b0f10c79f.png

我将“Ours”列中内存限制的所有值的时延相加(包括 element-wise操作)。结果显示,中间步骤占用了43%的时间。可以看到,这些操作在大小为520亿(b9dcd36176fd320e250170652cde5bdf.png 是这个模型的八倍)的模型中没有那么重要。

这些memory bound中间操作的持续时间将延长8倍,因为这些操作是长度bdda988a3e716b50e109b5a00595c827.png的向量。但是,flops次数将增加64倍,这意味着flop时间会延长64倍。

9cd01023542800d1f1a94ffd296b7645.png

因此,若不考虑时延,使用 Data Movement Is All You Need中的优化方法,520亿参数模型的推理时延大约会是中间计算的 5%。

8

实际基准对比

我在语言建模公司工作,我们公司有自己的基础设施和基准,但IP是公司面临的一大难题。可悲的是缺乏可用于模型并行推理的公共基准。目前我只知道Nvidia的FasterTransformer和Microsoft的Deepspeed,可能其他我不了解的论文也提出了一些基准。无论如何,我们可以根据真实基准来验证计算!

因为我只想用2个GPU,所以使用了FasterTransformer来运行了一个130亿参数的模型。该模型执行一连串内核融合,并提供张量并行功能。模型有40层,每层有40个头,每个头的维度为128,总维度大小为5120。这里是配置文件截图,这些截图显示了许多有趣的细节,可能值得单独撰写一篇文章。

首先是输出的512个上下文长度(context length)、batch size为1和10个token。对于2个GPU上的一个小batch的token,我们预计为8.4毫秒,大约1毫秒的通信,那么一个GPU则是16.8毫秒,0毫秒的通信。(2x40x12x5120^2/1.5e12)

在这里我应该将内存宽带(mem bandwidth)设置为1.555,而不是1.5。

实测结果表明,1个GPU应该是22.0ms,这意味着,我们的猜测的准确率为76%。可以确定,其中一部分时间花在了中间激活操作上,从理论上来说,我们可以获得100%的内存带宽,但实际上并没有。

对于这些维度,测试表明我们可以获得高达90%的内存带宽利用率(我们将矩阵乘法的预期成本与单个矩阵乘法内核的持续时间进行比较,由于加载的张量不同,带宽利用率会有所变化)。考虑到这一点,我们预计需要18.5毫秒。加上中间激活操作的成本后(我们可以从测试结果中获得),需要额外的2.2毫秒,总共需要20.7毫秒!

为了解释剩下的1.4毫秒,我们考虑到了一些其他的亚毫秒级操作,比如token嵌入、top-(k|p)操作、少于90%的带宽利用率(不想计算平均值,直接取了我能找到的最高带宽利用率),或者是内核启动时间。

实验结果显示,使用2个GPU时,总时间为13.5毫秒。相比一个GPU,这次我们只占了内存宽带的76%,离目标还有很大的差距。为了解决这个问题,我们重新检查了配置文件,发现内存带宽稍微差了一些,因为张量较小获取的带宽也比较少。

经过计算,宽带没有达到90%,只有87%,总时间为9.5毫秒,中间的激活时间需要大约2毫秒,这使得总时间为11.7毫秒。剩余的1.5毫秒需要找出通信问题。但是这个问题很容易解决,因为我们之前计算的1毫秒通信时间没有被并行化。根据配置文件的数据,每个层的通信时间为40-50微秒,总共约为1.7毫秒,这就是很好的证明。

上述两种操作的中间激活计数都比应有的要高一些,因为配置文件提供的时延始终略高于原始基准测试运行。基准测试运行的输出为180.86ms(上下文时间:45.45ms)和 283.60ms(上下文时间:63.17ms)。

在前向传递过程中,模型需要将所有token发送到每个GPU上,然后每个GPU都会对其进行自己的注意力头计算并存储kv。由于这个过程需要发送大量的数据并进行并行计算,因此预计前向传递需要的时间会比解码步骤长num_tokens/flops_to_bw_ratio倍。

更新的内存带宽为:312e12/(1.5e12x0.9)=231。在1个GPU的设置中,22ms是我们预期的解码步骤,我们可以得到22*(512/231)= 48,并不是63。在2个GPU设置中,我们通过计算得到了更加糟糕的结果:13.5*(512/231)=30ms。

单个GPU只缺失了部分kv储存时间。查看配置文件,我们发现kv储存时间每层为18微秒,总共为0.7毫秒。Memsets占了0.2毫秒。我们预计其中一个MLP乘法的flop时间(flop bound)为512x4x5120^2x2/312e12 = 344微秒。实际上,最低浮点运算时间应该是476微秒,也就是说,我们得到了预期flops的72%。

对于attention中的投影(projection),我们期望是512x5120^2x2/312e12 =86微秒。但是在配置文件中,我们发现最低是159微秒。请参阅本文的图14,其中512x4000x4000的最终结果低于150TFLOPs/s。

9

练习

1.在给定batch size、上下文长度和next_n的情况下,我们该如何计算kv缓存节约的宽带?

2.kv缓存会增加内存时间开销吗?

3.我们是否可以在前向传递时选择memory bound,在采样步骤中选择flops bound?

4.在GPU超过容量所需的情况下,我们应该进行怎样的权衡和计算?例如,一个520亿参数大小的模型(拥有8或16个GPU)。

5.如果我们有计算预测一个token时间的公式。我们应该如何计算执行整个样本的时间呢? 是否应该先在上下文上进行前向传递,再预测所有的请求token?

6.在容量部分,我曾提到中间计算的内存可以忽略不计。那么这些内存到底有多小呢?

7.在batch size部分,我们讨论了每字节通信的token数。如果我们的嵌入维度为512,我们需要做怎样的权衡?

8.假设GPU都连接到了同一主机,但可以像训练那样在主机之间进行GPU通信。AWS 有400GB/s。这种情况该怎么办呢?

9.在模型并行部分,我们可以实际沟通所有分片(shards),然后让每个加速器执行所有添加(不只是其中一部分添加)。这部分会对时延产生怎样的影响呢?

10.在batch size为256的4xGPUs上计算520亿的大批量速度。计算约为21毫秒,通信约为4毫秒。

11.从最后一层中取出向量,将其乘以未嵌入矩阵,存储logits,然后进行top-k或top-p采样(需要排序)。对于一个包含520亿参数的模型,这个过程需要多长时间,我们可以在这里并行化什么操作?

12.如何进行分片token嵌入?在输入token嵌入和未嵌入token之间,是否需要以不同的方式划分分片和使用层归一化(Layernorms),这会引起额外的通信开销吗?

其他人都在看

  • “ChatGPT们”的淘金时代

  • GPT-4,大增长时代的序幕

  • GPT-4创造者:第二次改变AI浪潮的方向

  • ChatGPT作者Schulman:我们成功的秘密武器

  • 比快更快,开源Stable Diffusion刷新作图速度

  • OneEmbedding:单卡训练TB级推荐模型不是梦

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

试用OneFlow: github.com/Oneflow-Inc/oneflow/icon-default.png?t=N2N8http://github.com/Oneflow-Inc/oneflow/

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chatgpt赋能python:Python中颜色的使用及其SEO影响

Python中颜色的使用及其SEO影响 在Python编程中,使用颜色是一种常见而又实用的技巧。通过给代码添加颜色,可以让代码更加的清晰易懂,从而提高编写代码的效率和质量。但是,对于SEO优化来说,我们也需要关注颜色的使用是…

CV多模态和AIGC的原理解析:从CLIP、BLIP到Stable Diffusion、Midjourney

前言 终于开写本CV多模态系列的核心主题:stable diffusion相关的了,为何执着于想写这个stable diffusion呢,源于三点 去年stable diffusion和midjourney很火的时候,就想写,因为经常被刷屏,但那会时间错不…

chatgpt赋能Python-python_print彩色

Python print彩色:让你的输出更加生动活泼! Python print是我们在学习和使用Python语言的过程中经常使用的一个功能。它可以帮助我们在程序运行时输出信息,方便我们了解程序的执行情况。但是,有时候我们需要更好的视觉提示&#…

详谈大模型训练和推理优化技术

详谈大模型训练和推理优化技术 作者:王嘉宁,转载请注明出处:https://wjn1996.blog.csdn.net/article/details/130764843 ChatGPT于2022年12月初发布,震惊轰动了全世界,发布后的这段时间里,一系列国内外的…

ChatGPT插件全宇宙爆炸级开放!无需排队,本周可用,GPT-4突然「紫」了

OpenAI 和谷歌,已经打得急红了眼,ChatGPT Plus 用户,本周就可以体验联网和插件功能,无需再排队。鲨疯了,真的鲨疯了! ChatGPT,本周开始联网,并开放插件功能! OpenAI Ch…

用GPT写的CSDN付费专栏被订阅——感谢ChatGPT带来的第一桶金

从大一就开始写CSDN,但是一直没有开付费专栏,直到两天前把用GPTchat写的一篇文章发到CSDN付费专栏,第三天就被订阅了。 这下得注意点文章质量了。。。 一个用户也是用户哈哈~~~ 这哥们既然放心订阅我高低得给你更新出来讲明白了! …

为什么我选择订阅ChatGPT Plus计划?

自从ChatGPT诞生以来,它的强大功能和表现一直备受好评。作为一个长期使用者,我一直对其性能和智能感到惊叹。最近,我决定升级我的用户体验,订阅了ChatGPT Plus计划。在这篇博客中,我将向您详细介绍ChatGPT Plus的优势和…

5月有哪些值得传播人关注的企业新闻稿?

传播人如何紧跟时事? 向世界传递品牌故事的美通社,就是你的好途径。记得每天都来美通社官网逛一逛,这里总能发现你感兴趣的企业新闻。 美通社官网:www.prnaisa.com您还可按照行业、区域、上市公司等类别快速阅读兴趣新闻 比如这个…

保姆级教程:5分钟, AI 你自己

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了人工智能中文站https://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT资源 今天周末,新开一个系列,《从入门到精通 多媒体篇》 第一课 来点轻松的,AI 你自己 教你在短短…

脉脉风格网名自动生成器

今天突然需要自己起一个网名,而且要准备随时跑路的那种,不能带有明显的个人信息,因为自己在脉脉上的社区身份是平台自动生成的,我很喜欢,于是花了几分钟弄了一个脉脉风格的网名生成器。 网名格式 名词 “在” 地点 …

GPT-4国内有免费平替吗?

免费/平替永远是最贵的 就如同我们生活中买口红一样,总想找到平替,但永远比不上看中的那只! 但在寻找平替过程中 花出去的时间、金钱成本都是翻倍的。 那么GPT-4呢? GPT-4优于GPT-3.5闪光点,想必大家都十分清楚 不…

学习笔记 | 基于大模型的优质 Prompt 开发课

文章目录 一、前言二、主要内容三、总结 🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、前言 手把手带你构建高质量 Prompt,掌握以文心一言为代表的大模型对话技巧与高级用法,与大模型高效交流从而释放大模型强大的生成能…

chatgpt赋能python:Python颜色检测:探索现代计算机视觉技术的基础

Python颜色检测:探索现代计算机视觉技术的基础 计算机视觉作为一门新兴的学科,正越来越受到人们的关注。在计算机视觉的众多应用中,颜色检测是一个非常重要的方面。Python作为一种高级编程语言,有很多强大的库可以用于颜色检测。…

玩小红书不会写文案?推荐文案生成法宝!

小红书越来越流行了,很多商家和个人都在上面搞运营推广~想要在这个平台众多的内容和用户中脱颖而出,就需要付出很多的时间和精力。你想知道如何快速写出爆款文案,吸引更多的用户浏览、点赞以及关注吗? 介绍一个好用而且很简单的方…

520 | ChatGPT会是一个完美情人吗?

A GENERATIVE AI EXPERIMENT 机器人能感受到爱吗?这个困扰了科学家们多年的未解之谜,如今随着ChatGPT的爆火再次回到人们的视线中。虽然我们尚未准备好为机器赋予情感,但机器已经可以借助生成式AI来帮助人类表达自己的情感。 自然情感表达 …

梁宁:为什么中国没有像 ChatGPT 和 Vision Pro 这样的创新产品?

6 月 10 日,产品战略专家梁宁和图灵联合创始人刘江围绕“ ChatGPT 真需求”主题进行直播对谈。 梁宁,产品战略专家,曾任湖畔大学产品模块学术主任,联想、腾讯高管,CNET集团副总裁。 工作经历横跨 BAT,与美团…

九龙证券|科技股竟成避风港!3月份恒生科技指数领跑全球

3月份欧美多家银行迅速关闭,引发了全球金融安稳性问题,却意外带来了全球科技股的狂欢。 据Wind数据统计,3月份,恒生科技指数再次成为全球金融商场的领先目标,涨幅到达9.65%,A股科创板50指数3月大涨9.19%&a…

夸张!昆仑万维「天工」尚未开悟,却陡增了300亿市值

4月17日下午,昆仑万维CEO方汉发布了公司的大语言模型——天工3.5。 这是国内继“文心一言”,“360智脑”等为数不多已进行内测的中文大语言模型。发布会现场,天工大模型分别展示了写周报、写招聘岗位、写代码,以及回答网友奇怪提问…

百度将凭借人工智能改变游戏规则并实现盈利?

来源:猛兽财经 作者:猛兽财经 稳健的财务业绩 在2022年第四季度,百度(BIDU)的收入为48亿美元(331亿人民币),比分析师预测的高出了1.72亿美元,但同比下降了约8%。从细分业务来看,百度…

研报精选230410

目录 【行业230410西南证券】医药行业2023年4月投资月报:看好创新药和中药行情 【行业230410国信证券】汽车行业4月投资策略:3月新能源乘用车批发销量预计同比增长32%,持续关注板块年报季报行情 【行业230410西南证券】医药行业周报&#xff…