Press "Enter" to skip to content

BLOOM培训背后的技术

近年来,训练规模越来越大的语言模型已成为常态。虽然关于这些模型没有被释放供进一步研究的问题经常被讨论,但如何训练这些模型的隐藏知识很少受到关注。本文旨在通过以1760亿参数语言模型BLOOM为例,揭示训练这类模型的技术和工程背后的硬件和软件的一些光芒。

但首先,我们想感谢那些使一个小团队能够训练一个1760亿参数模型的公司、关键人物和团队。

然后将讨论硬件设置和主要技术组成部分。

BLOOM培训背后的技术 四海 第1张

下面是项目的一个简要概述:

人物

该项目由Thomas Wolf(Hugging Face的联合创始人兼CSO)构思,他不仅敢于与这些巨头公司竞争,训练出一种最大的多语种模型,而且还使最终结果对所有人都可访问,从而使大多数人的梦想变为现实。

本文专注于模型训练的工程方面。BLOOM背后技术最重要的部分是那些分享他们的专业知识并帮助我们进行编码和训练的人和公司。

有6个主要的感谢人员群体:

  1. HuggingFace的BigScience团队,他们有超过半打全职员工致力于从构想到完成训练,并提供和支付了除了Jean Zay计算机之外的所有基础设施。
  2. Microsoft DeepSpeed团队,他们开发了DeepSpeed并将其与Megatron-LM集成,他们的开发人员在项目需求上花费了很多周的时间,并在训练之前和之中提供了很多令人惊叹的实践建议。
  3. NVIDIA Megatron-LM团队,他们开发了Megatron-LM,并在回答我们的众多问题和提供一流的实践建议方面非常有帮助。
  4. IDRIS / GENCI团队管理Jean Zay超级计算机,他们向该项目捐赠了大量计算资源并提供了出色的系统管理支持。
  5. PyTorch团队创建了一个非常强大的框架,其他软件都是基于它的,他们在训练准备期间对我们非常支持,修复了多个错误并改进了我们在训练期间依赖的PyTorch组件的可用性。
  6. BigScience工程工作组的志愿者

很难列出为项目的工程方面做出贡献的所有杰出人士,所以我只会列出Hugging Face之外的一些关键人物,他们是该项目在过去14个月中的工程基础:

Olatunji Ruwase、Deepak Narayanan、Jeff Rasley、Jared Casper、Samyam Rajbhandari和Rémi Lacroix

我们也对允许员工为该项目做出贡献的所有公司表示感谢。

概述

BLOOM的架构与GPT3非常相似,但在本文后面将讨论一些添加的改进。

该模型是在Jean Zay上训练的,Jean Zay是由GENCI管理的法国政府资助的超级计算机,安装在法国国家科学研究中心(CNRS)的国家计算中心IDRIS。该计算资源是由GENCI(授权号2021-A0101012475)慷慨捐赠给该项目的。

在训练过程中使用了以下硬件:

  • GPU:384个NVIDIA A100 80GB GPU(48个节点)+ 32个备用GPU
  • 每个节点使用8个GPU,使用NVLink 4个互连,4个OmniPath链接
  • CPU:AMD EPYC 7543 32核处理器
  • CPU内存:每个节点512GB
  • GPU内存:每个节点640GB
  • 节点间连接:Omni-Path架构(OPA)带非阻塞胖树
  • NCCL通信网络:完全专用子网
  • 磁盘IO网络:与其他节点和用户共享的GPFS

检查点:

  • 主要检查点
  • 每个检查点的fp32优化状态和bf16 + fp32权重为2.3TB,仅bf16权重为329GB。

数据集:

  • 46种语言,共1.5TB的去重大规模清理文本,转换成了350B个唯一标记
  • 模型的词汇量为250,680个标记
  • 详细信息请参见《The BigScience Corpus A 1.6TB Composite Multilingual Dataset》

176B BLOOM模型的训练发生在2022年3月至7月,并花费大约3.5个月的时间完成(约100万计算小时)。

Megatron-DeepSpeed

176B BLOOM模型是使用Megatron-DeepSpeed进行训练的,它是两种主要技术的结合:

  • DeepSpeed是一个优化深度学习的库,使分布式训练变得简单、高效和有效。
  • Megatron-LM是由NVIDIA的应用深度学习研究团队开发的一种大型、强大的Transformer模型框架。

DeepSpeed团队通过将DeepSpeed库的ZeRO分片和管道并行性与Megatron-LM的Tensor并行性相结合,开发了一种基于3D并行性的实现。有关每个组件的更多详细信息,请参见下表。

请注意,BigScience的Megatron-DeepSpeed是原始Megatron-DeepSpeed存储库的分支,我们添加了多个补充。

下表列出了每个框架提供的组件,用于训练BLOOM:

请注意,Megatron-LM和DeepSpeed都有管道并行性和BF16优化器实现,但我们使用了DeepSpeed的实现,因为它们与ZeRO集成。

Megatron-DeepSpeed实现了3D并行性,可以以非常高效的方式训练大型模型。让我们简要讨论一下这个3D组件。

  1. DataParallel(DP) – 多个相同的设置被复制多次,并且每个设置都被提供数据的一个切片。处理是并行进行的,并且在每个训练步骤结束时进行同步。
  2. TensorParallel(TP) – 每个张量被分割为多个块,因此每个张量的分片都位于其指定的GPU上,而不是整个张量位于一个GPU上。在处理过程中,每个分片在不同的GPU上分别并行处理,并在步骤结束时进行同步。这是一种所谓的水平并行性,因为拆分是在水平层面上进行的。
  3. PipelineParallel(PP) – 模型在多个GPU上垂直(层级)划分,因此只有一个或几个模型层放置在单个GPU上。每个GPU并行处理管道的不同阶段,并处理批处理的一个小块。
  4. Zero Redundancy Optimizer(ZeRO) – 也执行张量的分片,与TP类似,不同之处在于整个张量会在前向或后向计算时重新构建,因此不需要修改模型。它还支持各种卸载技术来弥补有限的GPU内存。

数据并行性

使用几个GPU的大多数用户可能熟悉DistributedDataParallel(DDP)PyTorch文档。在这种方法中,将模型完全复制到每个GPU上,然后在每次迭代之后,所有模型都将其状态与彼此同步。这种方法可以通过投入更多资源来加快训练速度,但只适用于模型能够适应单个GPU的情况。

ZeRO数据并行性

ZeRO数据并行性(ZeRO-DP)在这篇博客文章中有详细描述:BLOOM培训背后的技术 四海 第2张

理解起来可能有些困难,但实际上,概念非常简单。这只是通常的DDP,但是,不是复制完整的模型参数、梯度和优化器状态,每个GPU只存储其中的一部分。然后在运行时,当给定层需要完整的层参数时,所有GPU都会同步,以彼此提供它们缺少的部分 – 就是这样。

这个组件由DeepSpeed实现。

张量并行性

在张量并行性(TP)中,每个GPU只处理张量的一个切片,并且仅对需要整个张量的操作进行聚合。

在本节中,我们使用了Megatron-LM论文中的概念和图表:在GPU集群上进行高效的大规模语言模型训练。

任何Transformer的主要构建块都是一个完全连接的nn.Linear,后面跟着一个非线性激活函数GeLU

根据Megatron论文的符号表示法,我们可以将其点积部分表示为Y = GeLU(XA),其中XY是输入和输出向量,A是权重矩阵。

如果我们以矩阵形式考虑计算,很容易看出矩阵乘法可以在多个GPU之间进行拆分:BLOOM培训背后的技术 四海 第3张

如果我们将权重矩阵AN个GPU上按列拆分,并行执行矩阵乘法XA_1XA_n,那么我们将得到N个输出向量Y_1, Y_2, ..., Y_n,可以独立地输入到GeLU中:BLOOM培训背后的技术 四海 第4张。注意,由于Y矩阵沿列拆分,我们可以沿其行拆分第二个矩阵乘法,这样它可以直接接收GeLU的输出,而无需进行任何额外的通信。

利用这个原理,我们可以在每个行列序列之后同步GPU,更新任意深度的多层感知机(MLP)。Megatron-LM论文的作者提供了一个有帮助的插图:BLOOM培训背后的技术 四海 第5张

这里,f在前向传递中是一个恒等操作符,在后向传递中是一个全局合并操作符,而g在前向传递中是一个全局合并操作符,在后向传递中是一个恒等操作符。

并行化多头注意力层甚至更简单,因为它们本身就是天然并行的,因为有多个独立的头部:BLOOM培训背后的技术 四海 第6张

特殊考虑:由于每层在前向和后向传递中都有两个全局合并操作,Tensor Parallelism(TP)需要设备之间非常快速的互连。因此,不建议在多个节点上进行TP,除非您拥有非常快速的网络。在我们的情况下,节点间的互连速度比PCIe慢得多。实际上,如果一个节点有4个GPU,则最高的TP程度为4。如果您需要8个TP程度,则需要使用至少有8个GPU的节点。

Megatron-LM实现了这个组件。Megatron-LM最近扩展了张量并行性,包括沿序列维度拆分无法像上述那样拆分的操作,例如LayerNorm。论文《Reducing Activation Recomputation in Large Transformer Models》提供了有关这种技术的详细信息。序列并行性是在BLOOM训练之后开发的,因此在BLOOM训练中未使用。

管道并行性

简单的管道并行性(简称PP)是将模型层组合在多个GPU上,然后将数据从一个GPU传输到另一个GPU,就像它是一个大的复合GPU一样。机制相对简单-将所需的层.to()到所需的设备,现在当数据进出这些层时,将数据切换到与层相同的设备,并保持其余部分不变。

这实现了纵向模型并行性,因为如果您记得大多数模型是如何绘制的,我们会将层垂直切割。例如,如果以下图表显示了一个8层模型:

===================  ===================
|  0 | 1 | 2 | 3  |  |  4 | 5 | 6 | 7  |
===================  ===================
        GPU0                 GPU1

我们只是将其在垂直方向上切割为2个部分,将层0-3放在GPU0上,将层4-7放在GPU1上。

现在,当数据从层0传输到1,从1传输到2,从2传输到3时,这就像在单个GPU上进行正向传递一样。但是,当数据需要从层3传输到层4时,它需要从GPU0传输到GPU1,这引入了通信开销。如果参与的GPU在同一个计算节点上(例如,同一台物理机上),这种复制非常快,但如果GPU位于不同的计算节点上(例如,多台机器),通信开销可能会显著增加。

然后第4层到第5层到第6层到第7层就像一个普通的模型一样,当第7层完成时,我们经常需要将数据发送回第0层,那里有标签(或者将标签发送到最后一层)。现在可以计算损失并让优化器进行工作。

问题:

  • 主要的缺陷,也是为什么这个被称为“naive”(幼稚)PP的原因,是除了一个GPU之外,其他GPU在任何给定时刻都是空闲的。因此,如果使用4个GPU,几乎等同于将单个GPU的内存增加四倍,并忽略其他硬件。而且还有在设备之间复制数据的开销。因此,使用naive PP,4张6GB的卡片将能够容纳与1张24GB卡片相同大小的模型,只是后者训练速度更快,因为它没有数据复制的开销。但是,假设你有40GB的卡片,需要适应一个45GB的模型,你可以使用4张40GB的卡片(但由于梯度和优化器状态,勉强可以)。
  • 共享嵌入可能需要在GPU之间来回复制。

管道并行(PP)几乎与上面描述的naive PP相同,但它解决了GPU空闲的问题,通过将传入的批次划分为微批次,并人为地创建管道,从而允许不同的GPU同时参与计算过程。

以下是GPipe论文中的示意图,顶部是naive PP,底部是PP:

BLOOM培训背后的技术 四海 第7张

从底部的图表中可以看出,PP的“死区”较少,GPU处于空闲状态。空闲部分被称为“bubble”(气泡)。

图表的两个部分都显示了4个并行的程度。也就是说,有4个GPU参与管道。因此,有4个管道阶段F0、F1、F2和F3的正向路径,然后是B3、B2、B1和B0的反向路径。

PP引入了一个新的需要调整的超参数,称为chunks。它定义了通过相同的管道阶段连续发送多少个数据块。例如,在底部的图表中,你可以看到chunks=4。GPU0在块0、1、2和3(F0,0、F0,1、F0,2、F0,3)上执行相同的正向路径,然后它等待其他GPU完成它们的工作,只有当它们的工作开始完成时,GPU0才开始执行反向路径,处理块3、2、1和0(B0,3、B0,2、B0,1、B0,0)。

请注意,从概念上讲,这与梯度累积步骤(GAS)是相同的概念。PyTorch使用chunks,而DeepSpeed将相同的超参数称为GAS。

由于存在块,PP引入了微批次(MBS)的概念。DP将全局数据批次大小分成小批次,因此如果DP的程度为4,全局批次大小为1024,则分成4个小批次,每个小批次大小为256(1024/4)。如果chunks(或GAS)的数量为32,则最终得到的微批次大小为8(256/32)。每个管道阶段一次处理一个微批次。

要计算DP + PP设置的全局批次大小,我们使用以下公式:mbs*chunks*dp_degree8*32*4=1024)。

让我们回到图表。

chunks=1时,你得到了naive PP,这非常低效。当chunks的值非常大时,你得到了微小的微批次大小,这也可能不太高效。因此,必须进行实验,找到能够最高效地利用GPU的值。

虽然图表显示存在一个“死”时间的气泡,因为最后一个正向阶段必须等待反向阶段完成管道,但找到chunks的最佳值的目的是实现所有参与GPU的高并发利用,从而减小气泡的大小。

这种调度机制被称为全向前全向后。其他一些选择是一前一后和交错的一前一后。

虽然Megatron-LM和DeepSpeed都有自己的PP协议实现,但Megatron-DeepSpeed使用DeepSpeed实现,因为它与DeepSpeed的其他方面集成在一起。

这里还有一个重要问题是词嵌入矩阵的大小。通常情况下,词嵌入矩阵消耗的内存比变换器块少,但在我们的情况下,由于庞大的25万个词汇量,嵌入层需要7.2GB的bf16权重,而变换器块只需4.9GB。因此,我们必须指示Megatron-Deepspeed将嵌入层视为变换器块。所以我们有一个管道有72层,其中有两层专门用于嵌入(第一层和最后一层)。这样可以平衡GPU内存消耗。如果我们不这样做,我们将会让第一和最后阶段消耗大部分的GPU内存,而95%的GPU将使用较少的内存,因此训练远非高效。

DP+PP

以下来自DeepSpeed管道教程的示意图演示了如何将DP与PP结合。

BLOOM培训背后的技术 四海 第8张

在这里,重要的是要看到DP rank 0看不到GPU2,而DP rank 1看不到GPU3。对于DP来说,只有GPU0和1,它将数据作为只有2个GPU一样提供。GPU0“秘密地”使用PP将一部分负载转移到GPU2上。GPU1也通过将GPU3列为帮助者来做同样的事情。

由于每个维度至少需要2个GPU,所以在这里至少需要4个GPU。

DP+PP+TP

为了实现更高效的训练,PP与TP和DP结合,称为3D并行。下图展示了这个过程。

BLOOM培训背后的技术 四海 第9张

这个图来自一篇博文《3D parallelism: Scaling to trillion-parameter models》,也是一篇不错的阅读材料。

由于每个维度至少需要2个GPU,所以要实现完全的3D并行,至少需要8个GPU。

ZeRO DP+PP+TP

DeepSpeed的主要特性之一是ZeRO,它是DP的超可扩展扩展。在《ZeRO Data Parallelism》中已经讨论过。通常它是一个独立的特性,不需要PP或TP。但它可以与PP和TP结合使用。

当ZeRO-DP与PP(和可选的TP)结合时,通常只启用ZeRO stage 1,它仅分片优化器状态。ZeRO stage 2还分片梯度,stage 3还分片模型权重。

尽管在Pipeline Parallelism中理论上可以使用ZeRO stage 2,但它会对性能产生不良影响。每个小批次都需要额外的reduce-scatter集合来聚合梯度,然后再分片,这增加了潜在的通信开销。由于Pipeline Parallelism的特性,使用的是较小的小批次,重点是尝试平衡算术强度(小批次大小)和最小化Pipeline泡沫(小批次数量)。因此,这些通信成本会对性能产生负面影响。

此外,由于PP已经减少了层数,因此内存节省并不会很大。PP已经将梯度大小减少了1/PP,因此在此基础上进行梯度分片的节省并不像纯DP那样显著。

ZeRO stage 3也可以用于训练这个规模的模型,但与DeepSpeed 3D并行实现相比,它需要更多的通信。在我们一年前进行仔细评估的环境中,我们发现Megatron-DeepSpeed 3D并行性能最好。自那时以来,ZeRO stage 3的性能有了显著改进,如果我们今天进行评估,也许我们会选择stage 3。

BF16Optimizer

在FP16中训练庞大的LLM模型是不可取的。

我们通过花费几个月的时间训练了一个104B模型来证明这一点,从tensorboard上可以看出它是完全失败的。在与lm-loss不断分歧的过程中,我们学到了很多东西:

BLOOM培训背后的技术 四海 第10张

我们在Megatron-LM和DeepSpeed团队训练了530B模型后也得到了同样的建议。最近发布的OPT-175B也报告说他们在FP16上的训练非常困难。

因此,早在一月份,我们就知道我们将在支持BF16格式的A100上进行训练,所以Olatunji Ruwase开发了一个BF16Optimizer来训练BLOOM。

如果你对这种数据格式不熟悉,请看一下位布局。BF16格式的关键是它具有与FP32相同的指数,因此不会像FP16那样遭受溢出的问题!对于FP16来说,它的最大数值范围是64k,你只能乘以很小的数。例如,你可以做250*250=62500,但如果你尝试255*255=65025,你就会遇到溢出的问题,这是训练过程中主要的问题。这意味着你的权重必须保持很小。一种称为损失缩放的技术可以帮助解决这个问题,但是当模型变得非常庞大时,FP16的有限范围仍然是一个问题。

BF16没有这个问题,你可以轻松地做10_000*10_000=100_000_000,没有问题。

当然,由于BF16和FP16的大小都是2字节,所以并不是免费的午餐,使用BF16时会付出非常差的精度。然而,如果你记得使用随机梯度下降及其变体进行训练是一种跌跌撞撞的过程,所以如果你不能立即得到完美的方向,也没有关系,你会在下一步中纠正自己。

无论是使用BF16还是FP16,都会有一份权重的副本始终以FP32格式存在,这是由优化器更新的。因此,16位格式仅用于计算,优化器以完整精度更新FP32权重,然后将其转换为16位格式进行下一次迭代。

所有的PyTorch组件都已经更新,确保它们在FP32中执行任何累积,所以不会有任何损失。

一个关键问题是梯度累积,这是管道并行的主要特性之一,因为每个微批次处理的梯度都会累积起来。在FP32中实现梯度累积是保持训练准确性的关键,这就是BF16Optimizer的作用。

除了其他改进,我们相信使用BF16混合精度训练将潜在的噩梦转变为一个相对平稳的过程,这可以从下面的lm loss图中观察到:

BLOOM培训背后的技术 四海 第11张

融合CUDA核心

GPU可以执行两个任务。它可以将数据从内存复制到GPU并对该数据进行计算。当GPU在复制数据时,计算单元处于空闲状态。如果我们要有效地利用GPU,我们需要尽量减少空闲时间。

内核是一组指令,用于实现特定的PyTorch操作。例如,当你调用torch.add时,它会经过PyTorch调度程序,该调度程序查看输入张量和其他各种情况,决定应该运行哪些代码,然后运行它。CUDA内核是使用CUDA API库的特定实现,仅能在NVIDIA GPU上运行。

现在,当指示GPU计算c = torch.add(a, b); e = torch.max([c,d])时,一种朴素的方法,也是PyTorch默认会执行的方法,是启动两个单独的内核,一个用于执行ab的相加,另一个用于在cd之间找到最大值。在这种情况下,GPU从其内存中获取ab,执行相加,然后将结果复制回内存。然后它获取cd,执行max操作,然后再次将结果复制回内存。

如果我们将这两个操作合并,即将它们放入一个单一的“融合内核”中,并仅启动该内核,我们就不需要将中间结果 c 复制到内存中,而是将其保留在GPU寄存器中,并且只需要获取 d 来完成最后的计算。这样可以节省很多开销,防止GPU空闲,并使整个操作更加高效。

融合内核就是这样。主要是用来替代多个离散计算和数据移动到/从内存的融合计算,其中内存移动很少。此外,某些融合内核还会重写数学,以便可以更快地执行某些计算组。

为了快速高效地训练BLOOM,需要使用Megatron-LM提供的几个自定义融合CUDA内核。特别是有一个优化的内核用于执行LayerNorm,以及用于融合各种缩放、掩码和softmax操作的内核。使用PyTorch的JIT功能,还将偏置项与GeLU操作融合在一起。这些操作都是内存限制的,因此将它们融合在一起以最大化从内存检索值后执行的计算量非常重要。因此,例如,当已经执行内存限制的GeLU操作时,添加偏置项不会增加额外的时间。所有这些内核都可以在Megatron-LM存储库中找到。

数据集

Megatron-LM的另一个重要特性是高效的数据加载器。在初始训练启动期间,每个数据集被分成请求的序列长度的样本(对于BLOOM为2048),并创建一个索引来编号每个样本。根据训练参数,计算数据集的时期数,并创建相应数量的顺序,并对其进行洗牌。例如,如果一个数据集有10个样本,并且应该通过两次,系统首先按顺序排列样本索引[0,…,9,0,…,9],然后对该顺序进行洗牌,以创建数据集的最终全局顺序。请注意,这意味着在看到另一个样本之前,训练不会简单地遍历整个数据集然后重复,可能会看到相同的样本两次,但在训练结束时,模型将看到每个样本两次。这有助于确保整个训练过程中平稳的训练曲线。为了避免每次启动训练过程时重新计算它们,这些索引,包括每个样本的基本数据集的偏移量,都保存在文件中。然后,几个这样的数据集可以以不同的权重混合到训练过程中看到的最终数据中。

嵌入层归一化

当我们试图阻止104B发散时,我们发现在第一个词嵌入之后添加一个额外的LayerNorm可以使训练更加稳定。

这个想法来自于对bitsandbytes的实验,其中包含一个StableEmbedding,它是一个带有layernorm的普通嵌入,并使用均匀的xavier初始化。

位置编码

我们还用基于AliBi的方法替换了通常的位置嵌入-基于论文:Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation,这样可以对比模型训练的长度为2048的序列,模型在推理过程中也可以处理更长的序列。

训练困难

有了体系结构、硬件和软件,我们能够在2022年3月初开始训练。然而,从那时开始,并不一帆风顺。在本节中,我们讨论了我们遇到的一些主要障碍。

在训练开始之前,有很多问题需要解决。特别是我们发现在48个节点上开始训练时才会出现的几个问题,并且在小规模上不会出现。例如,需要使用CUDA_LAUNCH_BLOCKING=1来防止框架挂起,我们需要将优化器组分成较小的组,否则框架会再次挂起。您可以在训练前传编年史中详细了解这些问题。

在训练过程中遇到的主要问题类型是硬件故障。由于这是一个拥有约400个GPU的新集群,平均每周会发生1-2次GPU故障。我们每3小时(100次迭代)保存一次检查点,所以平均每次硬件崩溃会损失1.5小时的训练时间。然后,Jean Zay的系统管理员将更换故障的GPU并重新启动节点。与此同时,我们有备用节点可供使用。

我们遇到了各种问题,导致了5-10小时的停机时间,其中一些与PyTorch中的死锁错误有关,另一些是由于磁盘空间不足。如果您对具体细节感兴趣,请参阅训练记录。

在决定训练这个模型的可行性时,我们计划了所有这些停机时间-我们选择了与可行性和我们希望模型消耗的数据量相匹配的模型大小。尽管有所有的停机时间,我们设定的训练时间仍然得以完成。正如前面提到的,完成训练大约需要1百万个计算小时。

另一个问题是SLURM并不适合一个团队使用。一个SLURM作业只属于一个用户,如果该用户不在,小组中的其他成员无法对正在运行的作业进行任何操作。我们开发了一个绕过方法来允许小组中的其他用户终止当前进程,而不需要启动进程的用户在场。这在90%的情况下运行良好。如果SLURM的设计者看到这篇文章,请增加Unix组的概念,这样一个SLURM作业就可以属于一个组。

由于训练是全天候进行的,我们需要有人负责值班-但由于我们在欧洲和加拿大西海岸都有人,因此没有人需要携带寻呼机,我们只需要很好地安排时间。当然,周末也需要有人监督训练。我们自动化了大部分事务,包括从硬件故障中恢复,但有时也需要人为干预。

结论

训练前两个月是最困难和最紧张的部分。我们承受了很大的压力,希望尽快开始训练,因为资源分配是有限的,并且在最后一刻之前我们无法使用A100。因此,考虑到BF16Optimizer是在最后一刻编写的,我们需要调试它并修复各种错误,这是一个非常困难的时期。正如前一节所述,我们发现了一些问题,这些问题只在我们开始在48个节点上进行训练时才会出现,在小规模上不会出现。

但是一旦我们解决了这些问题,训练本身就非常顺利,没有遇到重大问题。大部分时间我们只有一个人监控训练,只有少数几次需要多人协助进行故障排除。我们得到了Jean Zay的管理团队的大力支持,他们在训练过程中迅速解决了大部分需求。

总的来说,这是一个非常紧张但非常有回报的经历。

训练大型语言模型仍然是一项具有挑战性的任务,但我们希望通过在开放中构建和共享这项技术,其他人可以在我们的经验基础上继续发展。

资源

  • 主要训练文档
  • tensorboard
  • 训练slurm脚本
  • 训练记录

论文和文章

我们不可能在这篇文章中详细解释所有内容,所以如果这里呈现的技术引起了您的好奇心,并且您想了解更多,以下是需要阅读的论文:

Megatron-LM:

  • 在GPU集群上进行高效的大规模语言模型训练。
  • 减少大型Transformer模型中的激活重计算。

DeepSpeed:

  • ZeRO: 优化内存,实现训练万亿参数模型。
  • ZeRO-Offload: 使亿级规模的模型训练变得更加民主化。
  • ZeRO-Infinity: 打破GPU内存壁垒,实现极限规模的深度学习。
  • DeepSpeed: 适用于所有人的极限规模模型训练。

联合Megatron-LM和Deepspeed:

  • 使用DeepSpeed和Megatron来训练Megatron-Turing NLG 530B,一个大规模生成语言模型。

ALiBi:

  • Train Short, Test Long: 使用线性偏差的注意力实现输入长度外推。
  • 如果您拥有100万个GPU小时,应该训练哪种语言模型?-在这里,您将找到导致我们选择ALiBi的实验。

BitsNBytes:

  • 通过块状量化实现8位优化器(在嵌入层归一化的上下文中,但其他部分的论文和技术都很棒-之所以我们没有使用8位优化器是因为我们已经通过DeepSpeed-ZeRO节省了优化器内存)。

博客致谢

非常感谢以下友善的人们,他们提出了很好的问题并帮助提高了文章的可读性(按字母顺序列出):Britney Muller、Douwe Kiela、Jared Casper、Jeff Rasley、Julien Launay、Leandro von Werra、Omar Sanseviero、Stefan Schweter和Thomas Wang。

主要图形由Chunte Lee创建。

Leave a Reply

Your email address will not be published. Required fields are marked *