- 作者:Qinghao Hu, Zhisheng Ye, Zerui Wang, Guoteng Wang, Meng Zhang, Qiaoling Chen, Peng Sun, Dahua Lin, Xiaolin Wang, Yingwei Luo, Yonggang Wen and Tianwei Zhang
- 机构:Shanghai AI Laboratory, S-Lab Nanyang Technological University, Peking University, Shanghai Jiao Tong University, SenseTime Research, Nanyang Technological University, CUHK
- 备注:The paper was accepted by the 21st USENIX Symposium on Networked Systems Design and Implementation (NSDI‘24) conference.
- 论文链接:https://www.usenix.org/system/files/nsdi24-hu.pdf
- 项目地址:https://github.com/InternLM
研究背景
大型语言模型(Large Language Models, LLMs)凭借其优越性能得到了工业界和学术界的关注。
现有的LLMs开发的流水线可以分为五个阶段,如下图所示:
- 数据准备
收集和预处理数据
数据可以分为两类:1)无标注数据的预训练数据;2)有标注的对齐数据
- 预训练
使用预训练数据进行自监督训练
- 对齐
在下游任务中根据用户意图调整 LLMs
两种主要范式:1)不更新模型参数的提示词方法;2)更新模型参数的微调方法
可以使用带有人工反馈的强化学习方法进一步优化对齐效果
- 评估
使用多种评价指标对模型进行评估
- 部署
投入实际环境中使用
其中,预训练过程中可以定期的进行对齐和评估,方便开发者评估模型性能并做出调整。
本文不涉及模型部署的内容。
研究动机
对集群的工作负载进行分析,有利于理解为LLMs定制的系统中存在的挑战与机会。
现有的深度学习工作负载分析工作是在LLMs兴起之前做的,不适用于LLMs开发过程,主要体现在三个方面:
- 范式的改变
深度学习负载通常是在某个领域的数据上训练模型从而解决特定任务
LLMs在广泛的数据上进行自监督训练从而产生一个基础模型
- 相关软件栈
出现了许多优化LLMs训练过程的技术,例如混合并行和切分模型状态的工作
- 统一的架构
深度学习负载模型架构众多,例如CNN,RNN
LLMs的模型架构都是Transformer架构
因此本文要解决的三个问题是:
- LLMs开发过程中,工作负载的特点是什么?
- 相比于深度学习工作负载,LLMs对数据中心提出了什么新要求?
- 如何为LLMs定制系统软件?
数据来源
本文的分析工作基于上海人工智能实验室的数据中心Acme 2023年3月份到8月份的traces,并将其与之前微软、商汤以及阿里的trace分析工作进行了对比。
数据中心Acme含有两个专用于LLMs开发的同构集群:Seren和Kalos,配备的是80GB NVIDIA A100-SXM GPU和Intel Xeon Platinum 8358P CPUs,GPU之间通过NVLink和NVSwitch连接,节点间的连接使用的是NVIDIA Mellanox 200Gbps HDR InfiniBand,不同的是Kalos的节点有五张InfiniBand,其中四张用于应用的通信,一张用于存储,两个集群的具体配置如下图所示:
集群中的LLMs负载全部基于Transformer Decoder架构,参数量从7B到123B,训练使用的是自研训练框架InternEvo。
从Acme收集的traces以及微软、商汤以及阿里的分析工作使用的traces的比较如下图所示:
需要注意的是,Acme是专用于LLMs开发的数据中心,而其他数据中心都是针对解决特定任务设计的深度学习负载设计的。
本文使用的traces的具体信息如下:
- 收集时段:2023年3月到8月
- 任务类型:410K CPU任务和684K GPU任务
- 数据来源:1)任务的日志;2)硬件检测数据;3)运行时日志;4)profiling的数据
数据中心的特点
LLMs与之前深度学习工作负载的对比
更短的任务持续时间以及两极分化的GPU利用率:
上图的左边描述了不同数据中心上的GPU任务持续时间的累积分布函数(cumulative distribution function,CDF),可以看到Acme的两个集群Seren和Kalos的任务持续时间更短,持续时间的中位数在2分钟左右,与其他数据中心相比持续时间缩短了1.7到7.2倍,并且从图中可以看出越新的数据中心任务的持续时间越短。这有四部分可能原因:1)硬件的升级缩短了迭代时间;2)用户经常申请较多的计算资源;3)许多小规模的任务,例如评估任务;4)较高的未完成率,大约40%的任务不会顺利完成。
上图的右边展示了GPU利用率分布,可以看到Seren和Kalos集群的GPU利用率分布集中在0%和100%,这与大家持有的LLMs任务是计算密集型的观点相对应,这也说明了基于GPU共享的调度技术(Lucid、Gandiva、Antman)不适用于LLMs开发。
高度倾斜的负载分布:
上图展示了所需GPU数量对应的任务分布情况,左图是所需GPU数量与任务数量的关系,可以发现绝大部分任务都是单GPU任务,只有少于7%的任务需要8个以上GPU;右图展示了所需GPU数量与任务占用的GPU时间的关系,在Seren和Kalos集群中单GPU任务只占了2%不到的GPU时间,而在Kalos中大规模任务(大于256GPU)占了超过96%的GPU时间,大部分资源分配给少数预训练任务,可能导致排队阻塞问题并导致严重的排队延迟。
负载特点
任务数量与资源利用的无关性:
评估任务是主要的任务类型,但是其需要的GPU时间很少;预训练任务占比很小,但是需要大量的GPU时间。
任务类型与GPU需求的相关性:
方格代表了第一个和第三个四分位数,方格内的黑线代表中位数。
从图中可以看出,评估任务需要的GPU数量通常小于4,而预训练任务通常需要超过100个GPU。
在Kalos上Debug任务分布范围很广,这是因为不同类型的任务都需要在不同规模下进行测试。
相似的时间分布:
少于5%的任务的持续时间会超过一天(86400s);尽管评估任务具有最低的GPU需求和最短的作业持续时间,但它具有最长的排队等待时间;
集群利用模式
较高的GPU利用率以及较低的其他资源利用率:
50%的GPU消耗超过75%的内存(60GB);两个集群使用的SM中位数约为40%,是PAI报告的20%的两倍,这两个发现与LLMs访存密集型和计算密集型的特点相符合。
CPU内存利用率保持在50%以下;网卡空闲的时间超过60%,使用的带宽很少超过IB提供的最大带宽的25%。
环境影响
GPU主导功耗:
约有 30% 的 GPU 处于闲置状态,仍需要消耗 60W 的功率;GPU 服务器的平均耗电量是 CPU 服务器的 5 倍。
在GPU服务器的总功耗中,GPU 约占三分之二。
负载Profiling
预训练负载
实验设置:123B参数量的LLM模型;2048 GPUs;
使用框架及并行策略:
- InternEvo v1: 3D并行;PP = 8; TP = 8;
- InternEvo v2:分层ZeRO;限制sharding group大小为64;
GPU SM利用率:
在相同Global batch size的情况下,与InternEvo V1相比,InternEvo V2 的SM峰值利用率更高,空闲时间更短,可实现约 16% 的加速;3D并行的SM利用率相对较低的原因在于位于关键路径上的通信操作,例如流水线的气泡。
GPU显存占用:
顶部动态部分表示激活值和梯度占用的内存,而底部静态部分则表示参数和优化器状态占用的内存。
相比于分层ZeRO,3D并行方法的激活值占用的内存较高。
不平衡的激活值大小:
Insight:采用特殊的划分方式来解决流水线并行中不同流水级之间内存使用不平衡的问题,以实现更高的效率,例如采用重计算方法。
评估负载
有必要定期评估预训练期间产生的检查点,以指导LLM预训练过程。
较大的模型加载和数据预处理开销:29.5%的时间用于模型加载以及数据预处理,并且这个开销会随着模型和数据集的增大而增大。
较大的评价指标计算开销:19%的时间用于评价指标的计算。
结论:大约50%的GPU时间被浪费了。
故障分析
数据来源:任务的运行时日志和硬件检测数据;从Kalos集群收集了31293个推理任务、647个预训练任务、560个Debugging任务的日志;从Seren集群收集了675个预训练任务的日志。
故障分类
从表中可以看出,故障主要分为三类:
- 集群故障:与硬件相关;通常发生在任务运行的过程中;故障恢复的时间开销最大。
- 框架故障:常见的运行时错误;通常发生在任务运行的初始阶段;通过修改配置可以解决。
- 脚本故障:最常见的故障类型;通常是编程错误,可以通过修改代码来解决。
故障特点
集群故障造成严重影响:从故障分类的表中可以看出,集群故障的任务通常会使用大量的GPU,并且需要很长的时间去进行任务的重启;集群故障的数量占所有故障的11%,却占用了82%的GPU资源。
高温和辅助服务造成的故障:GPU空闲时间较少的预训练任务中容易发生高温故障;InternEvo中连接外部组间进行日志记录、监控等,这些辅助服务受网络影响较大,当网络不稳定时容易出现故障。
评估任务很少出错:评估任务持续时间较短,对GPU和NVLink的压力较小。
Acme中的LLM系统
LLM预训练的容错
动机:为了减少集群故障导致的停机时间,现有的方法是安排值班人员手动解决错误,这增加了工程师和研究人员的负担,为了减轻这一负担并提高硬件效率,开发了一种能自动检测故障原因并帮助进行故障恢复的系统。
系统设计:
- 异步检查点:利用CPU的空闲内存,将模型状态存储在CPU内存中,并利用单独的线程定期将这些状态保存到远程持久存储中。
- 故障诊断:使用正则表达式作为过滤器过滤日志,并使用基于LLM的Log Agent对过滤后的输出进行处理,并更新过滤器使用的正则表达式,实现日志的压缩,并将检测到的错误信息传输给后续的故障诊断模块;故障诊断模块首先基于规则对错误信息进行分析,如果错误信息没有对应的规则,将其向量化存入检索库;然后Faliure Agent使用Query Engine从检索库中搜索出故障原因,并向故障恢复模块表明该故障是人为引起的还是硬件故障。
- 故障恢复:故障恢复模块能够自动从正确保存的检查点重新开始训练。三种必须重新启动任务的情况:1)任务运行中途出现故障;2)训练过程中指标出现异常,例如loss突然增加;3)任务卡住。对于硬件故障,首先通过两轮allgather通信确定故障节点,第一轮先将节点两两分成一组,第二轮将故障的组的节点与非故障组的节点分为一组;对于loss的突然增加,系统会自动从之前loss正常的检查点并丢弃检查点到loss增加这之前的训练数据重新开始训练。
系统性能:7B和123B LLM的检查点开销减少了3.6到58.7倍;故障诊断系统减少了约 90% 的人工干预,从而减轻了开发人员的负担。
评估任务的解耦调度
动机:InternEvo会基于模型的每个检查点在多种任务上进行评估,这样可以保证开发人员跟踪训练过程并选出性能最好的检查点;评估的结果需要进行及时反馈,以便开发人员作出调整,但是评估任务有最长的等待时间。
系统设计:
- 解耦模型加载:开发了一个试验协调器(trial coordinator),其会从集群调度器中获取可用节点列表,然后利用这些可用节点从远程加载检查点到本地内存,这样之后的评估任务就可以利用高带宽的PCIe进行检查点加载。
- 解耦评价指标计算:当评估任务中GPU计算完成后,将其输出保存到文件,然后启动CPU任务进行评价指标计算,将GPU交给后续评估任务使用。
- 基于先验的弹性调度:每个评估任务使用的数据集的计算时间相对固定,可以利用这一先验信息平衡每个 GPU 的工作量,在排好序的任务队列中采用轮循分配策略,并且可以通过批处理数据集避免模型加载过程。此外,系统会优先处理作业队列中CPU计算时间较长的评估任务,以便更好地重叠其计算。
系统性能:使用7B LLM在63个数据集上进行评估任务,在单节点和四节点的配置下进行实验,分别能够减少任务完成时间1.3和1.8倍。
总结
分析了数据中心Acme中的LLM工作负载和资源利用情况,揭示了LLM开发过程中的特点和挑战。
指出了LLMs训练系统可能的优化方向,并介绍了自己在预训练任务负载和评估任务负载上的优化工作。