LLM - 训练与推理过程中的 GPU 算力评估
LLM - 训练与推理过程中的 GPU 算力评估
在大语言模型(LLM)时代,GPU算力对于模型的训练和推理至关重要。本文将详细介绍如何评估LLM任务所需的GPU算力,包括FLOPs和TFLOPs的基本概念、训练和推理阶段的影响因素、具体的计算公式和Python代码示例,以及基于Token的计算方式。
一.引言
LLM大模型时代,GPU显卡的算力至关重要,无论是训练还是推理都离不开大规模GPU的支持。由于工作需要,需要评估LLM任务所需显卡算力,搜了一下发现网上关于GPU评估计算的文章并不多,特此记录,有不妥的地方欢迎大家评论区多多交流。
二.FLOPs 和 TFLOPs
介绍GPU算力评估之前,首先我们需要了解下GPU计算能力的常见评估指标。
FLOPs [Floating point Opearation Per Second]
表示设备每秒所执行的浮点运算数量。
TFLOPs [Tera Floating point Opearation Per Second]
表示设备每秒执行一万亿次浮点运算的数量,即10^12次方。
其中浮点运算是指涉及小数点的计算,例如加减乘除。TFLOPs比FLOPs单位更大,其用于衡量计算机或处理器的更高性能。以L40S为例,在精度为FP32的情况下,其算力可达91.6TFLOPs,而A800则只有19.5TFLOPs,RTX3060大约是12.5TFLOPS。如果是超级计算机其TFLOPS性能指标可达1000万亿次每秒。
三.训练阶段的 GPU 消耗
影响训练的因素
计算前先看下训练阶段有哪些因素会影响训练的进程。
- 训练数据大小
- 模型参数规模
- 训练Epoch次数
- 显卡算力
GPT-3 训练统计
上面我们介绍了FLOPs和TFLOPs,这里ZettaFLOPs代表每秒十万京(10^21)次的浮点运算,不同指标之间主要是单位的差异。以GPT-3为参照,其为1750亿参数的模型,45TB训练数据,训练一次大约需要175ZFLOPs即1.75x10^23次浮点数运算。由于这里我们没有获取到175ZFLOPs是一个Epoch还是完整训练,所以后续的计算我们先统一按完整训练所需为参照。
自定义训练 GPU 评估
这里假定我们训练的模型是LLaMA-33B,参数量为330以,训练数据量为50G,GPU算力以A800下FP32计算即19.5TFLOPs,则训练该模型需要GPU算力为:
NeedFLOPs = (330 / 1750) * (0.048828125 / 45) * 1.75 * 10^23 FLOPs
我们使用设备为A800,则其可提供的算力为:
CalcByA800 = 19.5 * 10^12 FLOPs
最后结合我们需要的天数,例如训练5天结束,则5天的s数为:
TrainTime = 86400 * 5
最终所需GPU数量为:
GPUCount = NeedFLOPs / (CalcByA800 * TrainTime)
为了方便计算我们直接改写为Python代码:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
Returns the estimated number of GPUs
Parameters
----------
args_num : 当前模型参数数量,单位为亿
data_size : 当前训练数据大小,单位为GB
Returns
-------
count : 所需GPU数量,未向上取整
"""
def calc_gpu_num(_args_num, _data_size, _train_days):
need_flops = (_args_num / 1750) * (_data_size / 45) * 1.75 * 10 ** 23
calc_by_a800 = 19.5 * 10 ** 12
train_time = 86400 * _train_days
gpu_count = need_flops / (calc_by_a800 * train_time)
return gpu_count
if __name__ == '__main__':
args_num = 330 # LLaMA-33B
data_size = 0.048828125 # 50G
train_days = 5 # 训练5天
count = calc_gpu_num(args_num, data_size, train_days)
print(count)
计算得到count=4.250628165558721,我们向上取整可得5天训练50G数据的LLaMA-33B模型需要5张A800,不过这里并未考虑显存或者性能损耗等问题,只是粗略估算。
四.推理阶段的 GPU 消耗
影响推理的因素
- 输入输出数据
- 模型参数规模
- 显卡算力
推理阶段需要计算输入与输出的文本之和,实际计算中,需要将文本tokenizer到token_ids以便transformers计算,中文字符与token比例大概为1:2即1个中文字符对应2个token_ids。GPU推理计算时,其与输入输出文本和L、模型维度D和模型层数N成正比。
自定义推理 GPU 评估
假设输入的query文本数为100,输出的文本书为1000,则L=(100+1000)*2=2200,按模型维度D=1280,层数N=96,则计算所需算力:
NeedFLOPs ≈ L * D * N ≈ 270336000 = 2.7 * 10^8
假设我们使用A800用1s时间完成本次推理请求:
CalcByA800 = 19.5 * 10^12 FLOPs
则需要GPU数量:
count = 270336000 / (19.5 * 10**12) = 1.3863384615384615e-05
反过来CalcByA800/NeedFLOPs可以计算一张A800可以满足约7.2w用户1s内获取回复,不过这只是理想情况:
people = (19.5 * 10**12) / 270336000 = 72132.45738636363
计算差异
推理时涉及到文字和计算,例如生成连贯的剧情、生成数学逻辑的推理。这些处理对算力的消耗几乎相同,这是LLM的本质是语言模型,只要在输入输出相同的情况下,其处理的都是token_ids,推理得到的也都是next_token的分布,还是token_ids,所以与具体的表现形式无关,即不同类型的任务,只要输入输出相近,则其对算力的消耗也相近。
五.基于 Token 的计算方式
上面的方式都是基于FLOPs为基准计算的,但是由于实际场景下很多信息我们获取的并不完整。例如GPT-3的训练FLOPs是否准确,训练的FLOPs是一个epoch还是一整个训练流程,因此实际场景下还可以采用另一种方式,即基于Token处理效率的计算,但是这种计算方式有一个前提,就是需要你事先测算出对应GPU设备每秒处理的token数量,即ProcessTokens/s。
以实际测算为例,P40即4090的token处理能力约为25Token/s,假设我们一天需要请求1000次,每次输入输出共1000个汉字,共花费10h处理完成,则需要P40的数量可通过下述公式计算:
def calc_gpu_num_by_token(post_token_num, post_time_all, token_process):
return post_token_num / (post_time_all * token_process)
if __name__ == '__main__':
token_num = 1000 * 1000 * 2 # 1000次请求、1000个汉字对应2000个token
time_cost = 10 * 3600 # 总处理时间
token_process_num = 25 # 每s可处理token数目
print(calc_gpu_num_by_token(token_num, time_cost, token_process_num))
算下来10h处理完这些需求需要2.223台P40,则向上取整得到需要3台P40。
六.总结
这里分享了几种GPU算力计算的方法,上面的计算都是基于理想状态,实际情况下还需要考虑多机多卡的IO延迟,机器的网络延迟,以及模型大小与GPU显存的供需关系等等。更多的数据还是需要自己实践出真知,有问题欢迎大家在评论区一直讨论,因为现在网上这方面的信息还是相对较少,可以一起分享一起进步!