ML2021 | (腾讯)PatrickStar:通过基于块的内存管理实现预训练模型的并行训练

简介: 目前比较常见的并行训练是数据并行,这是基于模型能够在一个GPU上存储的前提,而当这个前提无法满足时,则需要将模型放在多个GPU上。现有的一些模型并行方案仍存在许多问题,本文提出了一种名为PatrickStar的异构训练系统。PatrickStar通过以细粒度方式管理模型数据来更有效地使用异构内存,从而克服了这些缺点。

使用示例


先介绍一个大家比较关心的问题--复不复杂,好不好实现。


PatrickStar与模型定义无关,在PyTorch脚本上添加几行代码可以带来端到端的加速。

0b8ea1a2ace3ceffa1c1dc749e29e713.png

Background


现在人工智能的共识是采用PTMs(Pre-Trained Models)作为任务的骨干,而不是在与任务相关的数据集上从头开始训练模型。PTMs的高性能伴随着众多的参数,这对计算和存储资源提出了巨大的要求。

由于大型的模型数据在单个GPU的内存无法存储,所以最常用的数据并行技术不适用于PTM(比较常见的例子是2012年的AlexNet)。通过利用并行训练在多个GPU内存之间分配模型数据,例如ZeRO、模型并行和流水线并行,最新进展使得PTM规模的增长成为可能。SOTA解决方案是将它们组合成3D并行,它可以在数千个GPU上将PTM扩展到数万亿个参数。

 

创新思路


作者观察到在PTM训练期间必须管理的两类训练数据:模型数据由参数、梯度和优化器状态组成,它们的足迹与模型结构定义相关;非模型数据由operator生成的中间张量组成。非模型数据根据训练任务的配置(如批次大小)动态变化。模型数据和非模型数据相互竞争GPU内存。


现有的解决方案在不考虑非模型数据的情况下,在CPU和GPU内存之间静态划分模型数据,并且它们的内存布局对于不同的训练配置是恒定的。这种静态的分区策略导致了几个问题。


首先,当GPU内存或CPU内存不足以满足其相应的模型数据要求时,即使当时其他设备上仍有内存可用,系统也会崩溃。其次,当数据在张量粒度的不同内存空间之间传输时,通信效率低下,当可以将模型数据提前放置到目标计算设备上时,CPU-GPU通信量是不必要的


针对上述问题,本文提出了一种名为PatrickStar的异构训练系统。PatrickStar通过以细粒度方式管理模型数据来更有效地使用异构内存,从而克服了这些缺点。


作者将模型数据张量组织成块,即大小相同的连续内存块。在训练期间,根据组块的张量状态来动态编排组块在异构存储空间中的分布。通过重用不共存的块,PatrickStar还比SOTA解决方案进一步降低了模型数据的内存占用。


作者使用预热迭代(warm-up iteration)在运行时收集模型数据的可用GPU内存的统计信息。设计了一种高效的块回收策略和基于统计数据的设备感知操作符放置策略,以减少CPU-GPU的数据移动量。使用零冗余优化器,基于块的内存管理可以通过块的GPU内通信(intra-GPU communication)有效地与数据并行共生。

 

Contributions


1.从头开始构建了一个基于块的内存管理DNN训练系统,名为PatrickStar与现有的异构训练方法相比,该方法通过缩小非模型内存空间、提高内存效率和降低CPU-GPU通信量,支持更大的模型规模和更高的计算效率


2.基于块的管理与零冗余优化器数据并行自然是共生的。基于块的集体通信模式降低了GPU内带宽需求和提高了带宽利用率


3.作者在拥有8x V100 GPU、240 GB和120 GB DRAM内存CPU的云计算节点上对系统进行了评估。在240 GB内存的情况下,PatrickStar训练了一个120亿参数的类似GPT的模型,这是DeepSpeed最大模型规模的1.5倍。在120 GB内存的情况下,PatrickStar的模型比例是DeepSpeed的4倍。


4.PatrickStar的计算效率比DeepSpeed更高,在8x GPU上实现了超线性伸缩。

 

Design Overview


论文设计了一个并行PTM训练系统PatrickStar,它的工作原理如下图所示。

f88641848b90104055c572422c60daa8.png

PatrickStar通过将模型数据分块管理并存储在异构空间中,提高了现有异构训练的模型规模和效率。图中的圆圈表示参数的元素,它们在内存中以块的形式排列。当操作符的计算被触发时(右图的彩色部分),PatrickStar将参数所在的块安排到所需的计算设备上。

论文提出了在异构内存空间中高效编排块的优化方案。此外,它还可以与零冗余优化器相结合,扩展到多个GPU。必要时,在训练过程中将组块移动到所需设备。

 

System design on a single GPU


PatrickStar作为PyTorch和异构内存之间的中间件,如上图所示。

b95464cef464a8d80d1658e4ec733f0d.png


系统由在预处理阶段工作的静态模块和在训练阶段工作的运行时模块组成。PatrickStar的静态模块在训练前进行处理。


基于神经网络结构,构造了张量与组块之间的映射模式。


在训练过程中,运行时模块通过将张量重定向到所管理的基于块的存储空间来接管PyTorch的内存访问,并使用块管理器来智能地管理异构存储空间中的块。

 

Preprocessing Stage


在训练开始之前,在预处理阶段为模型数据的每个张量分配一块块空间,并生成块-张量映射模式。一个有效的映射模式需要具备以下三个特征:1.增加张量访问的局部性。2.降低峰值内存消耗。3.对并行友好。


论文提出了一个高效的映射模式。


简单来说,根据模型数据中张量的类型,将组块分为四种类型,即参数FP16列表、参数FP32列表、动量列表和方差列表,共14M字节(M为参数数)。组块具有相同的大小,因此不同的组块可以重用相同的内存,并且有利于并行训练中的集体通信。特别的是,PatrickStar没有分配分级FP16列表。梯度FP16张量可以重用参数FP16列表的块空间,消除了梯度FP16张量对参数FP16张量的依赖。


与最小模型数据内存占用为16M字节的ZeRO-Offload相比,PatrickStar减少了内存占用。此外,它还分配了额外的GPU内存,用于保存要移动到CPU的渐变,而PatrickStar则消除了这一开销。因此,与其他PTM训练方案相比,PatrickStar的模型数据存储空间最小。

 

Training Stage


在训练过程中,PatrickStar需要正确高效地编排异构存储空间中的数据块。论文介绍了导块正确移动的机制,并介绍了一种优化策略以提高其效率。此机制比较复杂,论文有非常具体的介绍,这里不予解读。

 

Scaling to Multiple GPUS


PatrickStar使用多进程在多个GPU之间执行数据并行化。假设进程数为nproc。每个进程负责单个GPU,而所有进程共享CPU。进程的异构内存空间由GPU的全部内存和1/nproc的CPU内存空间组成。该进程以与零冗余优化器相同的方式管理位于其本地异构存储空间中的总块的1/nproc。本地空间中的块称为本地块,而不在本地空间中的块称为远程块。


5fc12f026b8bc1e8b667af5e0b26ee02.png


如图所示,通信组由块列表的nproc连续块组成,其中每个块属于不同的进程。根据前面的块张量映射模式,我们可以设计一种以最小的进程间通信量实现数据并行的通信方案。进程只需要在FWD和BWD阶段传送参数FP16和梯度FP16。需要最大量数据(包括动量、方差、参数FP32和梯度FP16)的ADAM阶段在本地执行。


论文中有非常详细的过程介绍与算法,这里不予解读。


与相关工作相比,PatrickStar获得了更低的GPU内带宽需求和更高的带宽利用率。根据成本模型,PatrickStar的带宽要求为2(p−1)/p×2m(all-gathers)+(p−1)/p×2m(reduce-scatter)=6(p−1)/p×M,其中p为并行度,M为参数个数。在ZeRO-Offload和ZeRO-DP中,每层的参数由单个进程拥有并广播给其余进程。与all-gathers相比,广播将数据传输集中在单个GPU上,并未充分利用聚合带宽。


基于广播的带宽要求为4(p−1)/p×2M(广播)+(p−1)/p×2M=10(p−1)/p×M,比PatrickStar提高了2/3。虽然Zero-Infinity也采用了all-gathers的方式,但PatrickStar的带宽利用率仍然较高。


已经证明,将序列张量布置为大块(bucket)来传输的分组化策略可以导致更高的带宽利用率,因为它将在每次通信中传输更多的数据。PatrickStar中基于块的方法自然是分块的,而ZeRO-Infinity的传输单元是张量。PatrickStar进一步避免了数据复制开销,以提高性能。

 

Optimization


将模型数据托管在GPU内存中相比,异构训练方法引入了额外的CPU-GPU数据移动开销。对基于块的内存管理进行了优化,使其更加高效和强大。


首先,它可以以细粒度的方式布局运算符,使内存密集型运算符不在他们的首选设备上,但它可以减少数据移动量,提高系统的整体效率。为此,PatrickStar提出了一种Device-aware Opetator Placement优化。


其次,当数据不能永久驻留在运营商的计算设备上时,如果不使用,数据块就会被逐出。除了在更大的模型规模上进行改进外,PatrickStar还通过块逐出策略将块逐出量降至最低。


为了实现上述优化,我们必须在训练过程中很好地了解每台设备上有多少GPU内存空间可以分配给块,这在本节中称为可分块内存(Chunkable Memory)。因此,PatrickStar提供了在运行时收集可分块内存统计信息的方法。


这些方案细节均在论文有详细介绍。

 

Conclusion


PatrickStar通过缩小非模型内存空间、提高内存效率和降低CPU-GPU通信量,支持更大的模型规模和更高的计算效率。

6de54470bf1f3bf509cd65e319fead93.png

PyTorch、DeepSpeed和PatrickStar在同一GPU上的训练吞吐量。OOM表示超内存。


af13ed007784662ccfcb5e7dbd5ea005.png

在多个GPU上使用DP训练PyTorch、DeepSpeed和PatrickStar的吞吐量。

 

论文提出了一种创新的异构训练系统,称为PatrickStar。它将模型数据组织成块,从而在异构存储空间中更灵活地编排它们。该系统与零冗余优化器数据并行是共生的。PatrickStar成功降低了PTM培训的硬件要求,并更高效地扩展到多个GPU。

在云计算平台的8xGPU 240 GB CPU节点上,它在最大模型规模上比SOTA提高了2倍,速度也比SOTA快。


未来的一些工作可以在PatrickStar上进行研究。


首先,通过对非模型数据检查点和卸载策略的联合优化,可以得到更好的块清除方法。其次,基于组块的异构方法可以与其他并行训练方法相结合进行多节点伸缩。


相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
7月前
|
机器学习/深度学习 存储 PyTorch
【AMP实操】解放你的GPU运行内存!在pytorch中使用自动混合精度训练
【AMP实操】解放你的GPU运行内存!在pytorch中使用自动混合精度训练
254 0
|
3月前
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
56 2
|
2月前
|
机器学习/深度学习 算法 物联网
大模型进阶微调篇(一):以定制化3B模型为例,各种微调方法对比-选LoRA还是PPO,所需显存内存资源为多少?
本文介绍了两种大模型微调方法——LoRA(低秩适应)和PPO(近端策略优化)。LoRA通过引入低秩矩阵微调部分权重,适合资源受限环境,具有资源节省和训练速度快的优势,适用于监督学习和简单交互场景。PPO基于策略优化,适合需要用户交互反馈的场景,能够适应复杂反馈并动态调整策略,适用于强化学习和复杂用户交互。文章还对比了两者的资源消耗和适用数据规模,帮助读者根据具体需求选择最合适的微调策略。
166 5
|
6月前
|
NoSQL Java Redis
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
86 0
|
4月前
|
机器学习/深度学习 数据采集 PyTorch
构建高效 PyTorch 模型:内存管理和优化技巧
【8月更文第27天】PyTorch 是一个强大的深度学习框架,被广泛用于构建复杂的神经网络模型。然而,在处理大规模数据集或使用高性能 GPU 进行训练时,有效的内存管理对于提升模型训练效率至关重要。本文将探讨如何在 PyTorch 中有效地管理内存,并提供一些优化技巧及代码示例。
187 1
|
5月前
|
机器学习/深度学习 自然语言处理 算法
ICML 2024:零阶优化器微调大模型,大幅降低内存
【7月更文挑战第14天】ICML 2024研究表明,零阶优化用于大模型微调能大幅降低内存需求。该论文通过避免反向传播,减少LLM(大型语言模型)微调的内存开销,提出新方法,适用于资源受限环境。虽然性能可能不及一阶优化器,但为高效NLP计算开辟了新途径。论文链接:[arxiv.org/abs/2402.11592](https://arxiv.org/abs/2402.11592)**
93 3
|
6月前
|
安全 Java Python
GIL是Python解释器的锁,确保单个进程中字节码执行的串行化,以保护内存管理,但限制了多线程并行性。
【6月更文挑战第20天】GIL是Python解释器的锁,确保单个进程中字节码执行的串行化,以保护内存管理,但限制了多线程并行性。线程池通过预创建线程池来管理资源,减少线程创建销毁开销,提高效率。示例展示了如何使用Python实现一个简单的线程池,用于执行多个耗时任务。
45 6
|
5月前
|
存储 算法 安全
Java面试题:给定一个可能产生内存泄漏的场景,如何诊断并解决?实现一个生产者-消费者模型,使用适当的同步机制与并发工具类,Java并发工具包与框架:性能与调优
Java面试题:给定一个可能产生内存泄漏的场景,如何诊断并解决?实现一个生产者-消费者模型,使用适当的同步机制与并发工具类,Java并发工具包与框架:性能与调优
36 0
|
6月前
|
机器学习/深度学习 算法 存储
Bengio等人新作:注意力可被视为RNN,新模型媲美Transformer,但超级省内存
【6月更文挑战第3天】Bengio等人提出的新模型Aaren视注意力为特殊RNN,以解决Transformer在资源受限环境中的计算成本高和内存使用问题。Aaren模型通过并行前缀和算法实现高效计算和常数级内存使用,性能接近Transformer,同时在时间序列任务中表现优秀,尤其适合移动设备和嵌入式系统。尽管可能在某些复杂任务上不如Transformer,但其高效性为实时数据处理提供了潜力。论文链接:[https://arxiv.org/pdf/2405.13956](https://arxiv.org/pdf/2405.13956)
104 2
|
6月前
|
程序员 编译器 C++
C++内存分区模型(代码区、全局区、栈区、堆区)
C++内存分区模型(代码区、全局区、栈区、堆区)