0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

介绍大模型高效训练所需要的主要技术

深度学习自然语言处理 来源:RUC AI Box 作者:陈昱硕 2022-11-08 09:57 次阅读

本文分为三部分介绍了大模型高效训练所需要的主要技术,并展示当前较为流行的训练加速库的统计。

引言:随着BERT、GPT等预训练模型取得成功,预训-微调范式已经被运用在自然语言处理、计算机视觉、多模态语言模型等多种场景,越来越多的预训练模型取得了优异的效果。为了提高预训练模型的泛化能力,近年来预训练模型的一个趋势是参数量在快速增大,目前已经到达万亿规模。

但如此大的参数量会使得模型训练变得十分困难,于是不少的相关研究者和机构对此提出了许多大模型高效训练的技术。本文将分为三部分来介绍大模型高效训练所需要的主要技术:并行训练技术、显存优化技术和其他技术。文章最后会展示当前较为流行的训练加速库的统计。欢迎大家批评指正,相互交流。

29a2d9ac-5e9c-11ed-8abf-dac502259ad0.png

预训练模型参数量增长趋势

一、并行训练技术:

并行训练技术主要是如何使用多块显卡并行训练模型,主要可以分为三种并行方式:数据并行(Data Parallel)、张量并行(Tensor Parallel)和流水线并行(Pipeline Parallel)。

数据并行(Data Parallel)

数据并行是目前最为常见和基础的并行方式。这种并行方式的核心思想是对输入数据按 batch 维度进行划分,将数据分配给不同GPU进行计算。

在数据并行里,每个GPU上存储的模型、优化器状态是完全相同的。当每块GPU上的前后向传播完成后,需要将每块GPU上计算出的模型梯度汇总求平均,以得到整个batch的模型梯度。

29d30b90-5e9c-11ed-8abf-dac502259ad0.png

数据并行(图片来自 Colossal-AI 的文档)

目前 PyTorch 已经支持了数据并行 [1]:

https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html

张量并行(Tensor Parallel)

在训练大模型的时候,通常一块GPU无法储存一个完整的模型。张量并行便是一种使用多块GPU存储模型的方法。

与数据并行不同的是,张量并行是针对模型中的张量进行拆分,将其放置到不同的GPU上。比如说对于模型中某一个线性变换Y=AX,对于矩阵A有按列拆解和按行拆解两种方式:

29e8be7c-5e9c-11ed-8abf-dac502259ad0.png

我们可以将矩阵A1A2分别放置到两块不同的GPU上,让两块GPU分别计算两部分矩阵乘法,最后再在两张卡之间进行通信便能得到最终的结果。

同理也可以将这种方法推广到更多的GPU上,以及其他能够拆分的算子上。

下图是Megatron-LM[2] 在计算 MLP 的并行过程,它同时采用了这两种并行方式:

29feea12-5e9c-11ed-8abf-dac502259ad0.jpg

整个MLP的输入X先会复制到两块GPU上,然后对于矩阵A采取上面提到的按列划分的方式,在两块GPU上分别计算出第一部分的输出Y1Y2

接下来的 Dropout 部分的输入由于已经按列划分了,所以对于矩阵B则采取按行划分的方式,在两块GPU上分别计算出Z1Z2。最后在两块GPU上的Z1Z2做All-Reduce来得到最终的Z

以上方法是对矩阵的一维进行拆分,事实上这种拆分方法还可以扩展到二维甚至更高的维度上。在Colossal-AI中,他们实现了更高维度的张量并行:

https://arxiv.org/abs/2104.05343 https://arxiv.org/abs/2105.14500 https://arxiv.org/abs/2105.14450

对于序列数据,尤洋团队还提出了Sequence Parallel来实现并行:

https://arxiv.org/abs/2105.13120

流水线并行(Pipeline Parallel)

和张量并行类似,流水线并行也是将模型分解放置到不同的GPU上,以解决单块GPU无法储存模型的问题。和张量并行不同的地方在于,流水线并行是按层将模型存储的不同的GPU上。

比如以Transformer为例,流水线并行是将连续的若干层放置进一块GPU内,然后在前向传播的过程中便按照顺序依次计算hidden state。反向传播也类似。下图便是流水线并行的示例:

2a0c06b6-5e9c-11ed-8abf-dac502259ad0.png

但朴素的流水线并行实现会导致GPU使用率过低(因为每块GPU都要等待之前的GPU计算完毕才能开始计算),使流水线中充满气泡,如下图所示:

2a18c856-5e9c-11ed-8abf-dac502259ad0.png

有两种比较经典的减少气泡的流水线并行算法:GPipe[7] 和PipeDream[8]

GPipe 方法的核心思想便是输入的minibatch划分成更小的 micro-batch,让流水线依次处理多个 micro batch,达到填充流水线的目的,进而减少气泡。GPipe 方法的流水线如下所示:

2a3136e8-5e9c-11ed-8abf-dac502259ad0.png

PipeDream 解决流水线气泡问题的方法则不一样,它采取了类似异步梯度更新的策略,即计算出当前 GPU 上模型权重的梯度后就立刻更新,无需等待整个梯度回传完毕。相较于传统的梯度更新公式:

2a573f5a-5e9c-11ed-8abf-dac502259ad0.png

PipeDream 的更新公式为:

2a653f92-5e9c-11ed-8abf-dac502259ad0.png

由于这种更新方式会导致模型每一层使用的参数更新步数不一样多,PipeDream 对上述方法也做出了一些改进,即模型每次前向传播时,按照更新次数最少的权重的更新次数来算,即公式变为:

2a7c79be-5e9c-11ed-8abf-dac502259ad0.png

PipeDream 方法的流水线如下所示:

2a89b5fc-5e9c-11ed-8abf-dac502259ad0.png

对比总结

下面是对这三种并行技术从通用性、计算效率、显存开销和通信量这几个方面进行对比。

可以看出数据并行的优势在于通用性强且计算效率、通信效率较高,缺点在于显存总开销比较大;而张量并行的优点是显存效率较高,缺点主要是需要引入额外的通信开销以及通用性不是特别好;流水线并行的优点除了显存效率较高以外,且相比于张量并行的通信开销要小一些,但主要缺点是流水线中存在气泡。

2a989d9c-5e9c-11ed-8abf-dac502259ad0.png

二、显存优化技术:

在模型训练的过程中,显存主要可以分为两大部分:常驻的模型及其优化器参数,和模型前向传播过程中的激活值。显存优化技术主要是通过减少数据冗余、以算代存和压缩数据表示等方法来降低上述两部分变量的显存使用量,大致可分为四大类:ZeRO技术、Offload技术、checkpoint技术以及一些节约显存的优化器。

ZeRO 技术

ZeRO[9] 技术是微软的 DeepSpeed 团队解决数据并行的中存在的内存冗余问题所提出的解决方法。常驻在每块GPU上的数据可以分为三部分:模型参数,模型梯度和优化器参数。注意到由于每张 GPU 上都存储着完全相同的上述三部分参数,我们可以考虑每张卡上仅保留部分数据,其余的可以从其他 GPU 上获取。

即假如有N张卡,我们可以让每张卡上只保存其中1/N的参数,需要的时候再从其他 GPU 上获取。ZeRO 技术便是分别考虑了上述三部分参数分开存储的情况,下图中的PosPos+gPos+g+p就分别对应着将优化器参数分开存储、将优化器参数和模型梯度分开存储以及三部分参数都分开存储三种情况。

论文里不仅分析了三种情况可以节省的内存情况,还分析出了前两种优化方法不会增加通信开销,第三种情况的通信开销只会增加50%。

2aa5d552-5e9c-11ed-8abf-dac502259ad0.png

目前Pytorch也已经支持了类似的技术:

https://engineering.fb.com/2021/07/15/open-source/fsdp/ https://pytorch.org/docs/stable/fsdp.html

Offload 技术

ZeRO-Offload[10] 技术主要思想是将部分训练阶段的模型状态 offload 到内存,让 CPU 参与部分计算任务。

为了避免 GPU 和 CPU 之间的通信开销,以及 CPU 本身计算效率低于 GPU 这两个问题的影响。Offload 的作者在分析了 adam 优化器在 fp16 模式下的运算流程后,考虑只将模型更新的部分下放至 CPU 计算,即让 CPU 充当 Parameter Server 的角色。如下图所示:

2aba0db0-5e9c-11ed-8abf-dac502259ad0.png

同时为了提高效率,Offload 的作者提出可以将通信和计算的过程并行起来,以降低通信对整个计算流程的影响。

具体来说,GPU 在反向传播阶段,可以待梯度值填满bucket后,一边计算新的梯度一边将bucket传输给CPU;当反向传播结束,CPU基本上获取了最新的梯度值。同样的,CPU在参数更新时也同步将已经计算好的参数传给GPU,如下图所示:

2ad5942c-5e9c-11ed-8abf-dac502259ad0.png

最后作者也分析了多卡的情况,证明了他提出的方案具有可扩展性。

Checkpoint 技术

在模型前向传播的过程中,为了反向传播计算梯度的需要,通常需要保留一些中间变量。例如对于矩阵乘法

2b064aa4-5e9c-11ed-8abf-dac502259ad0.png

AB的梯度计算公式如下所示

2b150f4e-5e9c-11ed-8abf-dac502259ad0.png

可以看出要想计算AB的梯度就必须在计算过程中保留AB本身。这部分为了反向传播所保留的变量会占用不小的空间。Checkpoint技术的核心是只保留checkpoint点的激活值,checkpoint点之间的激活值则在反向传播的时候重新通过前向进行计算。可以看出,这是一个以算代存的折中方法。最早是陈天奇将这个技术引入机器学习中 [11]:

https://arxiv.org/abs/1604.06174

目前该方法也以及被 PyTorch 所支持。

https://pytorch.org/docs/stable/checkpoint.html

节约显存的优化器

比较早期的工作是如Adafactor[12] 主要是针对 Adam 进行优化的,它取消了 Adam 中的动量项,并使用矩阵分解方法将动量方差项分解成两个低阶矩阵相乘来近似实现 Adam 的自适应学习率功能。

后来也有使用低精度量化方式存储优化器状态的优化器,如8 bit Optimizer[13],核心思想是将优化器状态量化至 8 bit 的空间,并通过动态的浮点数表示来降低量化的误差。还有更加激进的使用 1 bit 量化优化器的方法,如1-bit Adam[14] 和1-bit LAMB[15]。他们主要是使用压缩补偿方法的来减少低精度量化对模型训练的影响。

三、其他优化技术:

大批量优化器

在目前模型训练的过程中,直接使用大批量的训练方式可能导致模型训练不稳定。最早有 Facebook 的研究[16] 表明,通过线性调整学习率,并配合 warmup 等辅助手段,让学习率随 batch 的增大而线性增大,即可在ResNet-50上将 batch size 增大至 8K 时仍不影响模型性能。

但该方法在 AlexNet 等网络失效,在LARS[17] 优化器这篇论文中,作者尤洋在实验中发现不同层的权值和其梯度的 2 范数的比值差异很大,据此基于带动量的SGD优化器提出LARS优化器。核心算法如下图所示:

2b2834a2-5e9c-11ed-8abf-dac502259ad0.png

基于以上的思路,尤洋将上述方法扩展到Adam优化器,提出了LAMB[18] 优化器:

2b35743c-5e9c-11ed-8abf-dac502259ad0.png

FP16

FP16[19] 基本原理是将原本的32位浮点数运算转为16位浮点数运算。一方面可以降低显存使用,另一方面在 NVIDIA 的显卡上 fp16 的计算单元比 fp32 的计算单元多,可以提升计算效率。在实际的训练过程中,为了保证实际运算过程中的精度,一般还会配合动态放缩技术。目前的主流框架都已实现该功能。

算子融合

算子融合实际上是将若干个 CUDA 上的运算合成一个运算,本质上是减少了 CUDA 上的显存读写次数。举个例子,对于一个线性层 + batch norm + activation 这个组合操作来说:

2b529b48-5e9c-11ed-8abf-dac502259ad0.png

直接使用 PyTorch 实现的会在计算y1,y2,y3的过程中分别产生一次显存的读和写操作,即3次读和写。如果将其按下面的公式合并成一个算子进行计算,那么中间的结果可以保留在 GPU 上的寄存器或缓存中,从而将显存读写次数降低至1次。

2b6f8b68-5e9c-11ed-8abf-dac502259ad0.png

目前 PyTorch 可以使用 torch.jit.script 来将函数或 nn.Module 转化成 TorchScript 代码,从而实现算子融合。

https://pytorch.org/docs/stable/generated/torch.jit.script.html

设备通信算法

在之前介绍的模型分布式训练中,通常需要在不同 GPU 之间传输变量。在 PyTorch 的 DataParallel 中,使用的是Parameter Server架构,即存在一个中心来汇总和分发数据:

2b8043fe-5e9c-11ed-8abf-dac502259ad0.png

但上述方式的缺点是会导致 Parameter Server 成为通信瓶颈。之后PyTorch的Distributed DataParallel则使用了Ring All-Reduce[20] 方法,将不同的GPU构成环形结构,每个GPU只用与环上的邻居进行通信:

2b8f3904-5e9c-11ed-8abf-dac502259ad0.png

稀疏attention

稀疏Attention技术最开始是运用在长序列的Transformer建模上的,但同时也能有效的降低模型计算的强度。稀疏Attention主要方法可以分为以下五类 [21]:

2b9e74be-5e9c-11ed-8abf-dac502259ad0.png

目前DeepSpeed已经集成了这个功能:

https://www.deepspeed.ai/tutorials/sparse-attention/

自动并行

目前并行训练技术在大模型训练中已被广泛使用,通常是会将前面介绍的三种并行方法结合起来一起使用,被称之为 3D 并行。

但这些并行方式都有不少的训练超参数,之前的一些研究者是使用手动的方式来设置这些超参数。目前也出现了不少自适应的方法来设置超参数,被称为自动并行技术。

这些方法包括动态规划、蒙特卡洛方法、强化学习等。下面的 GitHub 仓库整理了一些自动并行的代码和论文:

https://github.com/ConnollyLeon/awesome-Auto-Parallelism

四、训练加速库概览

下面是本人对当下比较流行的训练加速库的统计,可供大家进行参考。

2bceabde-5e9c-11ed-8abf-dac502259ad0.png





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • gpu
    gpu
    +关注

    关注

    27

    文章

    4417

    浏览量

    126705
  • GPT
    GPT
    +关注

    关注

    0

    文章

    300

    浏览量

    14869
  • MLP
    MLP
    +关注

    关注

    0

    文章

    56

    浏览量

    4073
  • 大模型
    +关注

    关注

    2

    文章

    1516

    浏览量

    1115

原文标题:Huge and Efficient! 一文了解大规模预训练模型高效训练技术

文章出处:【微信号:zenRRan,微信公众号:深度学习自然语言处理】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何才能高效地进行深度学习模型训练

    分布式深度学习框架中,包括数据/模型切分、本地单机优化算法训练、通信机制、和数据/模型聚合等模块。现有的算法一般采用随机置乱切分的数据分配方式,随机优化算法(例如随机梯度法)的本地训练
    的头像 发表于 07-09 08:48 1.4w次阅读
    如何才能<b class='flag-5'>高效</b>地进行深度学习<b class='flag-5'>模型</b><b class='flag-5'>训练</b>?

    如何在SAM时代下打造高效的高性能计算大模型训练平台

    在一起,从而显著提升模型的泛化能力。SAM 的设计初衷是简化图像分割的过程,减少对专业建模知识的依赖,并降低大规模训练所需的计算资源。
    的头像 发表于 08-21 04:02 1357次阅读
    如何在SAM时代下打造<b class='flag-5'>高效</b>的高性能计算大<b class='flag-5'>模型</b><b class='flag-5'>训练</b>平台

    芯耀辉DDR PHY训练技术简介

    DDR接口速率越来越高,每一代产品都在挑战工艺的极限,对DDR PHY的训练要求也越来越严格。本文从新锐IP企业芯耀辉的角度,谈谈DDR PHY训练所面临的挑战,介绍芯耀辉DDR PHY训练
    的头像 发表于 01-05 10:27 671次阅读
    芯耀辉DDR PHY<b class='flag-5'>训练</b><b class='flag-5'>技术</b>简介

    Pytorch模型训练实用PDF教程【中文】

    本教程以实际应用、工程开发为目的,着重介绍模型训练过程中遇到的实际问题和方法。在机器学习模型开发中,主要涉及三大部分,分别是数据、
    发表于 12-21 09:18

    医疗模型训练系统是什么?

    医疗模型训练系统是为满足广大医学生的需要而设计的。我国现代医疗模拟技术的发展处于刚刚起步阶段,大部分仿真系统产品都源于国外,虽然对于模拟人仿真已经出现一些产品,但那些产品只是就模拟人
    发表于 08-19 08:32

    如何进行高效的时序图神经网络的训练

    训练过程与数据传输过程进行流水线化处理。具体来说,我们将GPU的显存划分为三部分:第一部分存储固定的数据(神经网络参数以及源点的特征向量),第二部分存储当前神经网络训练所需的数据( 包括边数据和汇点
    发表于 09-28 10:37

    人工智能可以预测物体运动吗

    研究人员也承认,即便训练所需的数据量相对较少,但模型在实际应用中仍很难使用。
    发表于 02-28 14:48 691次阅读

    基于速度追踪原理实现目标模拟训练系统的设计

    军队靶场训练基地用于跟踪高速运动目标的主要手段是光电跟瞄设备。对于光电跟瞄系统而言,操作训练需要外部目标环境的紧密配合,因此,训练所需的目标
    的头像 发表于 08-13 09:04 2378次阅读
    基于速度追踪原理实现目标模拟<b class='flag-5'>训练</b>系统的设计

    多模态图像-文本预训练模型

    在某一方面的智能程度。具体来说是,领域专家人工构造标准数据集,然后在其上训练及评价相关模型及方法。但由于相关技术的限制,要想获得效果更好、能力更强的模型,往往
    的头像 发表于 09-06 10:06 3428次阅读
    多模态图像-文本预<b class='flag-5'>训练</b><b class='flag-5'>模型</b>

    探究超大Transformer语言模型的分布式训练框架

    模型的预训练计算。 上篇主要介绍了大模型训练的发展趋势、NVIDIA Megatron的
    的头像 发表于 10-20 09:25 2129次阅读

    DGX SuperPOD助力助力织女模型高效训练

      “强悍的织女模型在京东探索研究院建设的全国首个基于 DGX SuperPOD 架构的超大规模计算集群 “天琴α” 上完成训练,该集群具有全球领先的大规模分布式并行训练技术,其近似线
    的头像 发表于 04-13 15:13 811次阅读

    一种基于乱序语言模型的预训练模型-PERT

    由于乱序语言模型不使用[MASK]标记,减轻了预训练任务与微调任务之间的gap,并由于预测空间大小为输入序列长度,使得计算效率高于掩码语言模型。PERT模型结构与BERT
    的头像 发表于 05-10 15:01 1224次阅读

    如何更高效地使用预训练语言模型

    本文对任务低维本征子空间的探索是基于 prompt tuning, 而不是fine-tuning。原因是预训练模型的参数实在是太多了,很难找到这么多参数的低维本征子空间。作者基于之前的工作提出
    的头像 发表于 07-08 11:28 986次阅读

    深度学习如何训练出好的模型

    算法工程、数据派THU深度学习在近年来得到了广泛的应用,从图像识别、语音识别到自然语言处理等领域都有了卓越的表现。但是,要训练出一个高效准确的深度学习模型并不容易。不仅需要有高质量的数
    的头像 发表于 12-07 12:38 660次阅读
    深度学习如何<b class='flag-5'>训练</b>出好的<b class='flag-5'>模型</b>

    谷歌模型训练软件有哪些?谷歌模型训练软件哪个好?

    谷歌在模型训练方面提供了一些强大的软件工具和平台。以下是几个常用的谷歌模型训练软件及其特点。
    的头像 发表于 03-01 16:24 278次阅读