性能概述
性能概念
性能在本文中,指机器(GPU、NPU或其他平台)在指定模型和输入数据的背景下,完成一次端到端训练所需要花费的时间,考虑到不同模型的训练数据量和训练轮次(epoch)差异,此处定义的性能是指完成一个batch训练所需花费的时间。而这里的端到端,我们通常是指完成一个人工智能模型单步训练的过程,也就是说,本文所讨论的性能的衡量和性能的优化,都是站在模型角度上。
对于一个batch而言,时间主要由以下部分构成:
单batch总时间 = 数据加载时间 + 模型前反向时间 + 优化器时间 + 模型后处理时间 + 通信时间 + 调度时间
各组成成分介绍如下:
- 数据加载时间:模型在加载自身所需要的数据(如图片、视频和文本等)的时间,包括将数据从硬件存储设备读取到CPU(Central Processing Unit)中、CPU中数据的预处理(编解码等操作)、CPU数据放到device上的时间。对于一些需要切分在若干张卡上的模型,数据加载还包括从数据加载卡广播到其他卡上的时间。
- 模型前向和反向时间:深度学习模型的前向过程和反向过程的时间,即Forward和Backward过程,包含前向的数据计算和反向的数据微分求导的时间。
- 优化器时间:模型参数更新时间。
- 模型后处理时间:优化器更新后的时间,包括数据的后处理或者一些必要的同步操作,通常取决于模型特有操作。
- 通信时间:单节点时卡之间和多节点时节点之间的通信时间。由于PyTorch的特殊机制,在通信和计算可以并行的情况下,表示未被计算掩盖的通信时间。
- 调度时间:模型从CPU的指令到调用NPU侧的核(Kernel)所需要的时间。
性能指标介绍
在计算性能指标中,优先级排序为:吞吐率 > 单步迭代时间 > 线性度 > 内存占用 > 带宽占比 > 训练效率 > 浮点计算次数每秒 > 算力利用率。
吞吐率
神经网络的吞吐率(Throughput)定义为网络模型在单位时间(例如1s)内可以处理的最大输入的训练样本数据。
与涉及单个样本数据处理的延迟latency不同,为了实现最大吞吐率,我们希望在集群训练的过程中有效并行处理尽可能多的样本数据。这种有效的并行性显然依赖于数据、模型和设备规模。
因此,为了正确测量吞吐率,可以执行以下两个步骤:
- 估计允许最大并行度的最佳训练样本数据批量大小,即batch size;
- 在AI训练集群中给定这个最佳batch size,测量网络在1秒钟内可以处理的训练样本数据。
要找到最佳batch size值,一个有效的经验法则是达到Ascend昇腾处理器对给定数据类型的内存限制,即batch size占满内存。这取决于硬件类型、网络的大小以及输入数据的大小。
要找到这个最大的batch size,最快方法是执行二分搜索。当时间不重要时,简单的顺序搜索就足够了。不过在模型训练的过程中,batch size的值会影响到重计算、Pipeline并行、Tensor并行等不同并行模式的配比,还有micro batch size的数据配比。因此默认batch size为16的倍数比较合理。
这确定了AI加速卡上可以处理的最大批量大小,用于训练模型及其处理的输入训练样本数据。
在确定最佳batch size值后,可以使用以下公式计算实际吞吐量:

- BS为batch size per DP,即每个数据并行维度的batch size。
- N为集群中数据并行维度的大小。
- step_time为在分布式集群中,执行完一个total batch size的时间(单位为s)。
对于固定shape的NLP任务,吞吐率的单位为samples/s时,可通过seq_len,将吞吐率指标单位换算为tokens/s,吞吐率换算公式为:

假设GLM10B网络模型的吞吐率为25 samples/s,max seq_len为1024,那么按照tokens来计算吞吐率为25 * 1024=25600 tokens/s,也就是每秒能处理2万多个tokens。
单步迭代时间
单步迭代时间是最为常见的性能指标之一。单步迭代时间指模型完成一个批次(batch)输入数据迭代所需要的时间,单位一般是秒(s)。单步迭代时间具有直观性,可以量化看出算子、调度和通信等耗时对总体性能的直观影响。相反地,单步迭代时间的缺点在于其没有对当前模型的批次大小、是否存在梯度累积等要素有很好的量化。一般而言,会结合模型配置,将单步时间和吞吐率进行相互转化。
线性度
设置线性度为单卡训练扩展到多卡,单机扩展到集群的效率度量指标,又名加速比(speed up),计算方式如下:

单机多卡总吞吐率,NLP在模型中以tokens/s为基本单位,在CV模型中以samples/s为基本单位。

上述公式变换后可推出:

线性度的取值范围为0~1,数值越接近于1,其性能指标越好。
如果机器本身是多卡或多机的加速比接近高线性度(即线性度接近于1),说明在扩展时通信不是瓶颈,则通过改变或者增加通信带宽的性能提升,对于整体AI深度学习模型训练的性能提升在通信问题中空间就会比较小。
当线性度不高(例如小于0.8)时,排除数据IO和CPU本身的因素影响后,可以判断此时分布式通信存在瓶颈。
算力利用率指标
算力利用率指负载在集群上每秒消耗的实际算力占集群标称算力的比例。
标称算力是指硬件或设备在正常工作状态下的理论计算能力,通常以单位时间内能够完成的浮点运算次数(FLOPS)或整数运算次数(IOPS)来衡量。
考虑一个具有I个Transformer层的模型负载,F表示一个iteration中负载消耗的算力。注意,F为真实FLOPs统计的lower bound。真实的计算过程中,负载还有少量的vector算力和padding带来的额外算力(占比极少)。
下面的计算公式,B代表batch size,s代表sequence length,I是Transformer层的数量,h是hidden size,V是vocabulary size。
一个Amk×XknA_{mk} × X_{kn}的矩阵乘法需要2mnk个浮点运算(乘加运算算两次)。Transformer层由一个注意力模块(attention)和一个2层前馈网络(FFN)组成。对于注意力模块,主要的贡献者是键(key)、查询(query)和值(value)的转换(6Bsh2次运算),注意力矩阵计算(2Bs2h次运算),对值进行注意力计算(2Bs2h次运算)和注意力后的线性投影(2Bsh2次运算)。前馈网络将隐藏大小增加到4h,再将其缩小回h。这需要16Bsh2个浮点运算。
将上面的这些加起来,每个Transformer层的正向传递结果为24Bsh2 + 4Bs2h个FLOPs。反向传递需要两倍于此的FLOPs,因为我们需要计算相对于输入和权重张量的梯度。
此外,如果我们使用了激活重计算技术,这需要在反向传递之前进行额外的前向传递。因此,每个Transformer层的总FLOP数为:

所以,考虑I层GPT负载一个iteration中GEMMs的FLOPs算力(前向计算+重计算+反向计算)为:

集群算力利用率的公式为:

其中,C为集群中每块AI处理器的标称算力,N为集群中AI处理器的个数,step_time为一个iteration的时间。
算力利用率可以衡量AI处理器算力的发挥程度,也可以衡量对负载和AI处理器的亲和优化。对于昇腾或GPU等重算力AI处理器,我们希望尽量多的算力都在CUBE/TensorCore上,如果Vector算力成为瓶颈,较少的算力花了较多的时间,此时step_time增加,算力利用率降低。所以,算力利用率可以反映实际的算力发挥情况,牵引软硬件栈的优化。同时,算力利用率和吞吐成正比关系,可以纵向反映性能问题。
影响算力利用率的因素是所有非矩阵运算花的时间,包括AICORE内部的数据搬运、VECTOR计算及卡间不可掩盖的通信时间等。
通信性能指标
针对同一通信算子在不同卡之间通信时间的波动的分析,其主要目的在于需要识别一些可能存在的通信算子内部瓶颈单元。在分析过程中,主要采用以下几个指标:
-
算子的执行时间以及内部等待耗时的变化和比例

该指标可以用来初步识别是否存在慢卡瓶颈,对每块卡上的wait_ratio,通过比较max_wait_ratio (等待时间长) - min_wait_ratio(等待时间短)与wait_ratio_threshold(当前设置为0.2)的关系,识别是否存在慢节点,当max和min的差值大于阈值threshold时,认为出现了慢节点,慢节点为min_wait_ratio(等待时间短)对应的卡。
-
通信带宽分析
DMA(Direct Memory Access)指的是直接内存访问。当CPU完成传输配置后,将不再参与传输过程,由DMA控制器将数据从一个地址空间复制到另外一个地址空间。
按照传输介质,可以将DMA分为RDMA和SDMA。
- RDMA指的是其他节点通过网卡对当前节点进行直接内存访问。
- SDMA代表在节点内进行的直接内存访问。
通信数据一般通过DMA机制在不同卡和不同节点间传输。在单节点内,遵循如下逻辑分析快慢卡。
-
对比通信算子在各卡上的数据传输耗时,通信算子执行最短的rank,即为慢卡。
-
通过传输数量sdma_data、rdma_data和传输时间sdma_transit_time、rdma_transit_time计算得到传输带宽。

