谈谈NLP下一个主战场:万亿参数的预训练模型!

自从BERT诞生以来,各大互联网巨头之间就展开了预训练语言模型军备竞赛,XLNet、ERNIE、RoBERTa、T5、GPT-3....

但当事情进展到号称自己是zero-shot learner的GPT-3时,批判的声音变得明显多了。

这么大,能用吗?
真的能做到zero-shot吗?
领域外泛化不行啊...
小学数学题都解不好?
GPT-3生成的内容侵犯了我的隐私!
我魔改下BERT就能小样本学习上吊打它啊...
生成的内容不合逻辑...
给出的医疗建议不靠谱!

很多人开始质疑,一味的让模型变大、让参数量爆炸式增长,真的能带来真正的语言智能吗?

但不可否认的是,GPT-3做到了许多早期预训练模型做不到、做不好的事情,如故事生成、文本->结构生成、Closed-book QA等,相比GPT-2,这个千亿参数规模的语言模型不仅生成的文本更流畅了,甚至内容的事实性也有了显著的改善。

但归根结底,GPT-3的零样本和小样本学习能力主要还是来源于预训练阶段对海量语料的大量记忆,其次是语义编码能力、远距离依赖关系建模能力和文本生成能力的强化,以及自然语言进行任务描述等设计。而在训练目标/损失函数方面GPT-3并没有显式的引导模型去学习零样本/小样本泛化能力,因此在一些互联网上公开较少的语料(如一些toB场景)上GPT-3经常出现翻车也是可以理解的。

那么问题来了,如果我们将语言模型的规模从千亿提升至万亿,能不能复现GPT-3创造的奇迹呢?

我觉得这个问题要从目标来看。

举个例子。

假如你的目标是要解决网友吐槽的“GPT-3小学数学题都解不好”的问题,那训万亿参数模型绝对是个不能更错误的路线,这类不可枚举的数值计算问题需要专用的设计,靠增加数据量和模型容量,只能解决更多数值计算的特定输入,而永远无法真正像计算机那样建立起稳定的函数关系。

但是,如果你确信你的目标场景数据分布是在互联网上存在且公开的,或者你能通过某种渠道得到海量同分布或近分布数据,那么你去训一个万亿参数的模型是确实可能产生进一步肉眼可见的飞跃。再或者,你仅仅想要模型会解更多fancy的任务,以及对同一个任务能在开放域解更多的case,那去提升规模确实有意义的。

而在一些影响因素更加繁杂的任务,如推荐、广告点击率预估、搜索等,特征维度高达千亿、万亿更是非常合理的事情,毕竟这些工业界产品端不仅坐拥海量用户交互数据,且无论用户侧还是物料侧,均是一个足够大、足够复杂的开放域问题,怎么拟合都不为过。

那问题来了,比拼语言模型规模这件事情难道没个上限吗?

  1. 数据瓶颈
  2. 算力瓶颈
  3. 分布式训练技术瓶颈

数据

数据怎么成瓶颈啦?这不是个信息爆炸的时代吗?

没错,信息是爆炸的,但互联网上大量数据是dirty、重复、无意义的,而在移动互联网时代,互联网也变得越来越封闭,要连接起一座座信息孤岛极其困难。对模型训练来说,需要的不仅是数据绝对规模,数据来源的丰富度和干净程度同样是模型能力的天花板。

因此,在数据层面没有相比上一代模型取得质的飞跃的情况下,近期那些去训千亿、万亿参数语言模型的工作基本就是在烧钱赚吆喝。

贴一下三代GPT模型的数据变化:

  • GPT-1仅用了包含1w本书的BookCorpus,25亿词;
  • GPT-2的数据来自互联网,用了800w在Reddit被link过的网页并做了清洗,大概40GB(名曰WebText);
  • GPT-3则将语料规模扩大到570GB的CC数据集(4千亿词)+WebText2(190亿词)+BookCorpus(670亿词)+维基百科(30亿词)。

可以看到,数据层面每一代均相比前一代有了数量级的飞跃,无论是语料的覆盖范围(丰富度)还是绝对规模。因此,下一代万亿模型使用的数据相比GPT-3若在质量、来源和规模上没有量级的改变,至少我是不相信有多大提升的。

ps: 近期一顿操作猛如虎,一看提升一点点的工作真心太多了(手动狗头)

算力

不讲了,money的问题。

分布式训练技术

好了,终于到讨论技术的环节了。

千亿、万亿参数的模型大概有三种设计方案/场景挑战:

  1. 万亿维度特征,模型非常宽,但是比较浅,训练稀疏
  2. 特征维度不高,但是模型非常深,万亿稠密参数
  3. 又宽又深,百亿、千亿的稀疏特征维度且存在数十层、上百层网络编码得到的稠密特征

第一种方案适用于一些影响因素非常多的场景(如推荐、搜索),例如商品推荐中的点击率预估,用户的性别年龄学历等画像、浏览历史、购买记录、商品的类型、标签、价格、标题、封面图乃至当下的时间节点和地理位置等,均可能影响用户当下对一个商品的点击,因此这类场景就更适合宽模型。

第二种方案则适用于影响因素不多,但抽象程度很高的任务,如NLP、CV等。

第三种方案则是一种更加复杂的场景,例如搜索、计算广告中计算query与网页/广告的相关性进而排序,我们不仅要考虑文本语义层面的相关性,还需要考虑网页/广告的banner对用户的吸引力等,进而需要点击率预估(CTR),这时网络不仅具备大型NLP模型的深度,又兼具大型CTR模型的宽度。

下面以百度飞桨(PaddlePaddle)为例,分别谈谈这三类场景的关键技术方案。

等等,为啥是百度飞桨?

贴几个可能鲜为人知的milestone,可能只有比较关注大规模机器学习/分布式训练相关工作的小伙伴才比较了解。

  • 2016年,百度提出Ring-Allreduce[1],极大的缓解了多机多卡训练时的通信带宽压力,使之不随网络中计算节点的数量增加而增加,而在Tensorflow生态中流行的分布式训练框架Horovod的核心,就是Ring-Allduce...
  • 2017年,百度提出大名鼎鼎的混合精度训练[2],如今已成为训练/微调预训练模型的标配加速技术
  • 早在 2018 年,飞桨的纯 CPU 参数服务器模式就可以支持万亿规模稀疏参数的模型训练...
  • 2020年,百度打破GPU显存限制,提出分布式层级化 GPU 参数服务器PaddleBox
  • 2021年,提出 4D 混合并行策略,可训千亿规模超大语言模型

换句话说,Paddle的全称是Parallel Distributed Deep Learning,直译为“并行分布式深度学习”。当Tensorflow忙着做生态、Pytorch忙着做易用性的时候,只有Paddle自始至终做着以分布式计算为代表的硬核底层优化,以支撑百度搜索、推荐、广告业务的十亿乃至千亿的流量和恐怖的模型复杂度。

因此,毫不夸张的讲,从百度飞桨就能窥见如今工业界训练万亿模型的前沿解决方案。

万亿稀疏参数模型训练:第一代架构

如前所述,搜索推荐场景经常面临数据量大、特征维度高且稀疏化的问题。对于这种宽模型,最合适的分布式训练架构便是—— Parameter Server(PS)

如图所示,PS架构将计算节点分为 server 与 worker,其中,worker用于执行模型的前向与反向计算,而server则对各个worker发回的梯度进行合并并更新模型参数,这种模型参数中心化管理的方式非常易于存储超大规模模型参数。

百度搜索作为全球最大的中文搜索引擎,对模型的规模、性能等要求非常高。为了应对严苛的实际业务挑战,早在 2018 年,飞桨的纯 CPU 参数服务器模式就可以支持万亿规模稀疏参数的模型训练。

但是随着模型网络越来越复杂,对算力要求越来越高,在数据量不变的情况下,CPU 计算性能差的弱势就会显现,虽然可以通过增加 CPU 机器数量来解决,甚至可以增加上百台,但是这种方法不仅成本大幅提高,而且集群的稳定性和扩展性也存在较大的问题。因此百度飞桨引入了纯 GPU 参数服务器来提升计算性能,之前 100 台 CPU 机器才能训练的模型,仅需 1 台多卡 GPU 机器即可完成训练。当然,同时也要解决因为硬件更替所带来的问题。

第二代架构:纯GPU参数服务器

GPU 强大的算力毋庸置疑可以提升集群的计算性能,但随之而来的是,不仅模型规模会受到机器显存和内存的制约,而且通信带宽也会由于集群网卡数量降低而成为瓶颈

为了解决这两个问题,百度飞桨引入了两大技术 SSD-MEM-HBM 三级存储RPC&NCCL 混合通信 到纯 GPU 参数服务器[3]。

具体来讲,SSD-MEM-HBM 三级存储策略允许全量参数使用 SSD 硬盘存储,高频参数存储于内存,当前 Batch 训练所用参数使用显存,并且同时支持 SSD 的参数在硬盘、内存、显存之间快速拷贝。这样通过异步流水线执行机制,隐蔽了 IO 带来的额外性能开销,在保证训练速度的同时,使训练的模型大小不再受制于显存和内存,极大提升模型的规模。

而 RPC&NCCL 混合通信策略可以将部分稀疏参数采用 RPC 协议跨节点通信,其余参数采用卡间 NCCL 方式完成通信,充分利用带宽资源。

▲GPU参数服务器

百度飞桨纯 GPU 参数服务器虽然解决了之前纯 CPU 模式所面临的问题,但新的问题又出现了——如何提高训练资源的利用率?

第三代架构:异构参数服务器,兼顾网络宽度与深度

在纯 GPU 的参数服务器下,所有的训练都在 GPU 中,当模型中部分网络层比较复杂(并行难,而串行链条长)的时候,GPU 利用率很难被打满,而 GPU 机器中 CPU 与 GPU 的硬件配比是固定的,无法灵活调整。针对这种情况,有两种解决方案:

  • 定制化 GPU 机型,调整机器内 CPU 与 GPU 的硬件配比。
  • 混布 CPU 和 GPU 机器节点,来调整机器间的硬件配比。

基于这两种解决方案,百度飞桨在 2.0 版本发布了通用异构参数服务器,使训练任务对硬件类型和型号不敏感,即可以同时使用不同的硬件混合异构训练,如 CPU、AI专用芯片以及不同型号的 GPU 如 v100、P40、A100 等。同时还可以解决大规模稀疏特征模型训练场景下 IO 占比过高导致的芯片资源利用率过低的问题。通过异构参数服务器训练模式,用户可以在硬件异构集群中部署分布式训练任务,例如云服务器集群,高效利用不同算力芯片,为用户提供更高吞吐、更低资源消耗的训练能力。

▲异构参数服务器

异构参数服务器的最大亮点是硬件感知的任务切分,因此甚至可以支持文首提到的最复杂结构的万亿模型——网络又宽又深。如上图所示,针对类似 ERNIE+CTR 这样计算密集型与 IO 密集型兼有的训练任务,可以被切分成多个子任务。其中的 IO 密集型任务(如数据读取、Embedding 查询)切分给 CPU 机器,计算密集型任务切分给 GPU 机器;用户可以根据子任务的计算复杂度来灵活决定机器配比,并且还可以兼容传统纯 CPU 参数服务器和纯 GPU 参数服务器所支持的训练任务。

4D混合并行:超大规模稠密模型训练

前面的三代架构解决了第一类和第三类万亿参数模型的训练问题(网络极宽;网络宽且深),那么对于第二类万亿参数模型(网络极深的大规模稠密模型)有没有好的解决方案呢?

百度最新提出的 4D 混合并行策略 就是为该场景量身定制的,目前已经支持了高达 2300 亿参数规模的100多层的 ERNIE 预训练模型的分布式训练。

不同于前述的三代参数服务器的模式,4D混合并行策略采用的是 集合通信模式 。这种模式没有管理模型参数的中心节点,每个节点都是 Worker,每个 Worker 负责模型训练的同时还需要掌握当前最新的全局梯度信息。而百度于2016年提出的Ring-Allreduce就是一种可以大大减少点对点通信次数的先进的集合通信方式,目前已成为飞桨、Tensorflow、Pytorch等深度框架的分布式训练标配方案。

首先来看一个公式:

总训练速度 ∝ 单卡速度 * 卡数 * 多卡加速比

其中单卡速度由数据读取和计算速度决定;多卡加速比由计算/通信效率决定。除了单卡可以使用的算子融合、混合精度之类的基础性能优化策略之外,分布式训练还引入一系列并行策略。

并行策略的核心思想是将数据和计算有关的图 / 算子切分到不同设备上,同时尽可能降低设备间通信所需的代价,合理使用多台设备资源,实现高效的并发调度训练,最大化提升训练速度。常见并行策略有:

  • 数据并行(Data Parallel,DP)
  • Layer 间并行/流水线并行(Pipeline Parallel,PP)
  • Layer 内并行/模型并行(Model Parallel,MP)

我们从设备资源和计算/通信效率来分析三种策略的优缺点:

  1. 数据并行训练加速比最高,但要求每个设备上都备份一份模型,显存占用比较高
  2. 模型并行,通信占比高,适合在机器内做模型并行且支持的模型类型有限。
  3. 流水线并行,训练设备容易出现空闲状态,加速效率没有数据并行高;但能减少通信边界支持更多的层数,适合在机器间使用。

而4D混合并行策略的思想就是集三种策略的优势于一身,实现取长补短。具体来说,先在单机内使用模型并行和分组参数切片组合的 2D 策略,这么选择的原因是这两个策略通信量较大,适合使用机器内的卡间通信;而后,为了承载千亿规模模型,再叠加流水线并行策略,使用多台机器共同分担;最后为了做到高效,在外层又叠加了数据并行来增加并发数量,提升整体训练速度。这样业内首个 4D 混合并行策略就诞生了。

▲4D混合并行

4D 混合并行策略的性能如何呢?

百度飞桨从理论性能角度对比分析了几组混合并行策略,即 DP2 + PP32 + Sharding2 + MP4、PP64 + Sharding2 + MP4 和 DP2 + PP32 + MP8。如下表所示,与两种 3D 方式相比,4D 混合并行策略在通信量和 Bubble 时间上并未明显增长,但是大幅提升了数据并行路数!

此外,百度飞桨使用64台8卡v100机器在 2300 亿参数规模的100+层的ERNIE模型上进行了性能实测。如图,可以看到 4D 混合并行策略训练速度高于其它两种 3D 混合并行策略,达到了8698 tokens/s,至少可以提速 23.7%。

至此,千亿规模的超大稠密模型的问题在百度飞桨先进的4D混合并行策略下,仅仅通过64台8卡V100机器就解决了;万亿规模的超大稀疏模型和稀疏稠密混合的复杂模型在百度飞桨的异构参数服务器下也得到了很好解决。

那么,万亿规模的稠密模型呢?以及万亿稠密+十万亿稀疏的模型会怎样呢?让我们拭目以待,作下个时代的见证者吧!

(0)

相关推荐