GPU训练的快速大规模分布式扩展-GPU多机多卡Machine Learning Middleware

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
NLP 自学习平台,3个模型定制额度 1个月
NLP自然语言处理_高级版,每接口累计50万次
简介: 我们设计了GPU多机多卡middleware,使得单机版机器学习程序可以通过插入middleware较快的实现基于ASGD或MA的多机多卡训练,此前各自基于open source工具所做的独有修改都可以得以充分保留。

在其他同学的文章中已经介绍过了,阿里新的自动语音识别系统的第一个落地点,被选定在客服电话语音识别上。
这个落地项目非常难,首先就在于我们面对的语音数据非常多样化:比如各种随意的对话、不完整的句子、各种话题以及各种传输差异和环境噪声。面对如此复杂的语音数据,我们后端的语音识别声学模型就一定要尽可能的覆盖各种可能的场景,包括各种对话、各种声道、各种噪音甚至各种口音,而要覆盖这些场景,就要求我们用海量的数据来训练语音识别声学模型。面对如此海量的数据,如何快速有效的、迭代式的训练语音识别声学模型、不断调优,从而体现大数据的价值,就成了一个非常紧迫的技术课题。
当今的工业界自动语音识别系统的声学模型都是基于海量的数据训练得到的。数万小时的训练数据是一种常见的声学模型训练配置,国际知名大公司(Google, Microsoft)以及国内的几大互联网巨头(腾讯、百度)莫不如此。要达到顶尖的识别率和顶级的语音识别公司抗衡,我们必须要具备大规模训练的能力。语音识别通常的帧率是100fps,对应每一万小时数据就有3.6 billion个训练样本。完成一次训练,还需要在这些样本上迭代多遍至收敛。这么多的样本是什么概念呢,按照样本数目算的话,Google Brain那个著名的猫的模型也不过用了10 million 样本 (randomly selected YouTube video thumbnails)。当然,不同领域不太好直接的去对比,但这也说明语音识别领域需要的数据是相当多的。如果用当今最新的单个GPU卡进行训练的话将会需要2到4周的时间。这样的周转周期对于互联网时代快速迭代更新模型上线的要求而言,显然是无法接受的。此外,模型训练还涉及到参数调优(tuning)的问题。如果一个模型需要2到4周才能调整一次训练参数,真正训练出合适的模型用于应用就更慢了。

什么是“GPU多机多卡middleware”

摆在我们面前的问题是如何快速的训练语音识别声学模型,进而加速迭代速度,降低参数调优的成本。通常的技术路线是改造现有GPU训练工具,变单机单卡为多机多卡,通过大规模分布式机器学习系统来加速。
但直接这么做会面临一个问题:大家知道,deep learning领域的研究近年来呈爆炸式增长,各种老的、新的模型层出不穷。在deep learning应用最广泛的语音领域也是一样,从一开始的DNN,到后来的CNN,再后来的RNN、LSTM,几乎所有传统上的模型甚至其组合都有被尝试过,并取得了性能上的进步。每一种模型的背后,都有一个甚至多个开源GPU训练工具,例如DNN的Kaldi、HTK;CNN的caffe、cuda-convnet;LSTM的CURRENNT等等。如果我们一个一个的将上述工具转换为多机多卡版本,其工作量可想而知。如果再有更新的模型及其训练工具被开放出来(如最近开源的Google TensorFlow),所有的多机多卡改造工作又得再重来一遍。
针对这一问题,我们想到:在对单机单卡程序进行改造的过程中,有很多工作是重复的、可以抽象的。例如:

  1. 多机多卡必然涉及运算节点间的通讯问题,将常用的通讯模式(p2p send / recv、AllReduce、Broadcast)、更优化的通讯方式(GPU Direct RDMA)等进行封装并优化是非常必要的;
  2. Scalable的多机多卡优化算法必然要涉及对传统SGD算法的修改,常用的方法包括ASGD、model averaging(MA)等,对这些优化算法进行封装将对极大的方便多机多卡改造;
  3. 多机多卡改造只是手段,其真正的目的是提供使用big data的能力。当训练数据上量以后,数据的流转、同步、caching等都需要统一的协调,计算任务的分配也需要scheduling,对这些支撑能力的封装也是有益的。
    基于上述思考,我们把典型的基于GPU的大规模分布式机器学习算法增加一层抽象,称为“GPU多机多卡middleware”,并构建以下的hierarchy:

b03810bc4c684cad4f452f96f3b980d9b9036a27_1_
其中,“单GPU程序”就是现有的任意一个open source GPU训练工具,通过对它进行尽可能少的代码修改,调用GPU多机多卡middleware的API,即可很容易的获得通讯、流程控制、参数更新、数据分发、辅助调参5大支持,并通过middleware将强有力的分布式存储运算资源提供给单GPU程序,使之得到快速的大规模扩展。
d7bd19f9bf5a0325590f57e75e31fb7e88ef3846_2_
例如,在上图的示例中,GPU多机多卡middleware可以帮助各GPU运算节点通过IB网络高速互联,并将存储于分布式共享存储中的数据(ODPS、OSS)源源不断送到运算节点。

为什么是“GPU多机多卡middleware”

我们选择开发GPU多机多卡middleware,而不是一个全能的多机多卡训练工具,是基于如下的设计理念:目前deep learning的研究和工程实践方兴未艾,各种新的模型结构、训练工具层出不穷,很难有一个“one size fits all”的工具同时满足所有人的需求。例如,在图像处理领域比较流行的caffe和cuda-convnet,在LSTM模型上比较流行的CURRENNT和RNNLib,都是各有各的优势与不足,并各有各的拥趸。更有意思的是,我们了解到很多用户在使用这些open source工具时,都或多或少对它们进行了自己的改造、升级与扩充,这样就产生了无数基于这些工具的变体。
但相同的是,这些林林总总的工具的变体在处理大数据时,都有将它们变身多机版、从而提高训练速度的需求。我们的GPU多机多卡middleware就基于这样的需求来设计抽象,使得以上的程序都可以通过插入middleware较快的实现基于ASGD或MA的多机多卡训练。对于用户来说,在插入middleware后,他们此前各自基于open source工具所做的独有修改都可以得以充分保留。他们熟悉的环境、已经生成的训练测试数据、乃至单机baseline都可以复用并与新的多机版本互相参照。一句话,middleware不是给你一个新的工具,而是将你手头熟悉的工具插上多机多卡的翅膀。

GPU多机多卡Middleware功能详解

GPU多机多卡middleware的主要功能是将GPU集群的硬件资源加以整合,提供通用的通讯、流程控制、数据分发、模型参数更新等模块,从而使得某个现成的单机版GPU程序通过较少的修改插入middleware后,就可以变身多机多卡程序。另外,考虑到集团内业务一般需要的模型大小,我们暂时只考虑data parallelism,暂不考虑model parallelism,这样就进一步简化了实现。
具体来说,GPU多机多卡middleware提供如下一些通用的基础功能,分别是:

  1. 通讯,通过包装MPI,提供计算节点之间p2p通讯(包括send / recv)和collective通讯(包括AllReduce等),并支持InfiniBand和GPU Direct RDMA以提高通讯效率。使得单机GPU程序不用考虑通讯的细节,通过简单调用middleware的通讯API即可实现高速多机通讯。
  2. 流程控制,主要用来控制整体机器学习的流程,协调各个GPU卡,实现data parallelism,包括什么时候进行参数更新,什么时候分发什么数据到哪个单卡GPU,什么时候调整参数等。
  3. 参数更新,负责从单卡GPU程序得到模型参数,然后在多机多卡之间进行参数更新。现在支持的有主流的MA (model averaging)以及ASGD (asynchronous stochastic gradient descent),只需要在需要的时候将模型参数交给Middleware,Middleware就会自动按照指定的模式完成参数更新。使得单机版GPU程序把自己算出的model parameters通过简单的调用middleware API即可完成模型的更新、同步。
  4. 数据分发,由于集团GPU集群现在不存在大规模分布式存储系统,而且在多机多卡训练之间也要有一定的数据分配机制,防止数据重复利用。数据分发正是用来输送训练数据到GPU卡,并实现智能的按需缓存,在运算的后台下载下一份训练数据,使得GPU不会“停工待料”。
  5. 辅助调参,负责在需要时控制所有机卡同时的进行各种参数调整,避免机卡训练参数不一致。
    为了尽可能的不影响单卡训练程序的效率,middleware的大部分功能都是在后台用另外的线程实现。另外,为了节省机卡资源,middleware并没有单独占用一块GPU卡来进行参数交换,而是在需要的时候利用每个卡自身的一小部分资源进行参数交换。这一点看起来很简单,要基于MPI实现却并非像想象的那么简单。我们通过巧妙的通讯设计,实现了一个master-slave通讯模型,且在rank 0节点上同时运行master线程和slave线程,并正常通讯。

Middleware应用于语音识别DNN声学模型训练

我们在Kaldi的DNN训练工具上插入了middleware进行了大规模机器学习扩展,并在不同的机卡规模上测试了计算加速比,即训练同样多数据所花的时间。同时在3个epoch的训练数据后(这里3个epoch是我们baseline的配置),我们对比了模型的最终效果,如下表所示:

Frame Acc. (%) CER (%) 处理一个 epoch 所需时间(小时) End-to-end 训练时间
单机单卡(Baseline) 59.9 4.98 120.0 15天
4机8卡(Middleware) 59.6 4.89 16.6 2天
8机16卡(Middleware) 59.1 4.92 8.4 1 天

这里Frame Acc是帧准确率(越大越好),CER是字错误率(越小越好),都是我们用来检验DNN声学模型的客观指标,其中CER是最终的指标。我们可以看到,相对于单机单卡的Baseline,当我们增加机卡数目达到8机16卡时,整体3个epoch的训练时间可以从15天缩短到1天,而且最终的指标CER比Baseline还略好。也就是说,之前我们在单机单卡时两周才能迭代一次,而现在在8机16卡的情况下一周可以迭代7次了。

Middleware应用于自然语言处理LSTM模型训练

如何使机器看起来更像一个人?一方面是让机器可以向人一样出色的完成一些任务,另一个方面就是使机器能够自由的跟人对话。我们iDST-NLP团队的同学就开发过一个功能丰富的自由聊天引擎,业内的很多大公司也有一些类似的聊天引擎,比如Apple的Siri,微软的Cortana以及百度的小度,这些聊天引擎这些年正在变得越来越好,一方面是由于采用了大量的数据来训练背后的模型,另一方面是出现了更强大的模型,比如RNN/LSTM等。
RNN/LSTM等模型之所以能够更好的利用数据主要是因为考虑了前后相关信息,而这一点会使得模型训练速度变慢。虽然可以通过stream等方式进行一定程度的加速,但LSTM模型的训练仍然很痛苦。比如我们iDST-NLP团队的同学在一个不大的训练集上训练一个LSTM聊天模型,花费的时间就至少需要两天。一旦增加训练集,那么花费的时间也随之增加。因此,我们在Kaldi的LSTM模型训练工具上插入了Middleware,这里的训练工具实际上是Kaldi的变体,已经经过了我们相关同学在算法上的修改,在插入Middleware之后,并不会改变单卡程序的行为,能够最大限度保留用户的修改,减少重复建设。实际的训练效果如下表所示:

最好的Validation Acc. (%) 处理一个 epoch 所需时间(小时)
单机单卡 (Baseline) 33.4 3.75
2机4卡(Middleware) 34.5 1.12

具体的收敛曲线如下图所示:
a28ee3fa1be889447eabffbea661804858f5bed1_1_

我们可以看到,Baseline在第10个epoch才收敛,达到了33.2%,而Middleware版本的训练工具在第8个epoch收敛,达到了34.5%。通过对比两者计算一个epoch数据的时间,我们可以得到计算加速比为3.35,而如果按照Baseline在第10个epoch收敛来计算的话,收敛加速比可以达到3.74。至于为什么多机多卡工具反而比单机SGD收敛的更快更好,这主要是因为我们采用了ASGD来训练模型,并且利用middleware的辅助调参功能进行必要的参数调整,使得最终在更短的时间内用更少的epoch得到了更好的模型。

Middleware应用于语音识别BLSTM声学模型训练

LSTM模型考虑了单向的序列相关信息,如果要考虑双向的序列信息,那就是BLSTM模型了。这种模型训练更慢,但是对speech/NLP等领域而言,效果会更好。对自动语音识别来说,BLSTM是一种比较新的声学模型,业内很多公司还是停留在探索的阶段。我们用很短的时间,在团队同学修改过的Kaldi BLSTM训练工具上插入了middleware,大幅度提高了效率,具体效果如下:

CER(%) 处理一个 epoch 所需时间(小时)
单机单卡 (Baseline) 12.9 12.3
4机8卡(Middleware) 13.0 1.8

从上面的数据我们可以得到计算加速比为6.83倍,并且两者的收敛epoch数没有明显的区别(多机多卡版甚至需要更少的epoch就收敛了),因此收敛加速比应该是类似的。需要指出的是,我们这里的实验仅仅是在几百小时的数据集上的结果,如果是5000~10000小时的大数据集,那么一个epoch的时间将会是上百小时,需要一周左右的时间,如果是3个epoch就会是将近一个月,对快速迭代的业务来说已经不可接受。而采用4机8卡,一个epoch就只需要一天多,3个epoch不到4天时间;如果进一步增加机卡数目,加速比还会进一步的提高。

Middleware应用于Caffe图像分类AlexNet模型训练

我们还跟YunOS相册分类团队的同学合作,在他们修改过的Caffe上插入了middleware,使他们的Caffe迅速成为多机多卡版Caffe,并且完全保留他们之前所做的修改。
在图像分类领域,比较有名的数据集是ImageNet-1k,包含128万张图片,一般的训练需要进行几十个epoch。比如在AlexNet上官方的结果就是在第62个epoch上得到的。而这在单个Nvidia K40卡上一般需要5、6天的时间,这一点对于调整参数来说是很痛苦的。如果后续有更大规模的数据处理模型训练的需求,花费更多的时间几乎就是不可接受的。
在扩展中,我们发现如果让Caffe来动态的加载middleware分发的数据,会比较麻烦。因此我们采用的方法是预先处理得到各卡对应的数据,而不用Middleware数据分发功能,只使用Middleware参数更新功能和辅助调参功能。这样,几乎只需要对Caffe进行非常少量的修改就可以达到多机多卡扩展的目的。
但是,虽然工程上的工作不多,我们却需要花费一定的时间来调试参数。由于CNN对参数比较敏感,而且每次实验只有到最后才能知道最终的准确率,虽然我们加速了训练过程,整个调整参数的过程仍然是很痛苦的。
到现在,我们在官方验证集上得到的top1准确率的结果如下表所示:

Acc.(%) 处理一个 epoch 所需时间(小时)
官方Baseline(单机单卡) 57.1 2.22
2机4卡(Middleware) 55.5 0.625

因此,计算加速比为3.55,准确率为官方Baseline的97%,是第53个epoch的时候得到的。

总结及展望

我们通过GPU多机多卡middleware将我们用于语音识别的DNN、LSTM、BLSTM等单机版程序通通插上了多机多卡的翅膀,并每天在训练模型;我们用middleware帮助iDST-NLP团队将聊天LSTM模型训练变为多机多卡训练;我们用middleware和云OS同学合作,将他们的改版caffe变为多机多卡版,训练CNN进行相册分类……我们希望middleware能够插入更多的已有单机版程序,并实现更大的业务价值。

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
目录
相关文章
|
1月前
|
并行计算 Shell TensorFlow
Tensorflow-GPU训练MTCNN出现错误-Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED
在使用TensorFlow-GPU训练MTCNN时,如果遇到“Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED”错误,通常是由于TensorFlow、CUDA和cuDNN版本不兼容或显存分配问题导致的,可以通过安装匹配的版本或在代码中设置动态显存分配来解决。
47 1
Tensorflow-GPU训练MTCNN出现错误-Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED
|
14天前
|
机器学习/深度学习 自然语言处理 并行计算
DeepSpeed分布式训练框架深度学习指南
【11月更文挑战第6天】随着深度学习模型规模的日益增大,训练这些模型所需的计算资源和时间成本也随之增加。传统的单机训练方式已难以应对大规模模型的训练需求。
58 3
|
16天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
18天前
|
机器学习/深度学习 并行计算 Java
谈谈分布式训练框架DeepSpeed与Megatron
【11月更文挑战第3天】随着深度学习技术的不断发展,大规模模型的训练需求日益增长。为了应对这种需求,分布式训练框架应运而生,其中DeepSpeed和Megatron是两个备受瞩目的框架。本文将深入探讨这两个框架的背景、业务场景、优缺点、主要功能及底层实现逻辑,并提供一个基于Java语言的简单demo例子,帮助读者更好地理解这些技术。
42 2
|
22天前
|
人工智能 语音技术 UED
仅用4块GPU、不到3天训练出开源版GPT-4o,这是国内团队最新研究
【10月更文挑战第19天】中国科学院计算技术研究所提出了一种名为LLaMA-Omni的新型模型架构,实现与大型语言模型(LLMs)的低延迟、高质量语音交互。该模型集成了预训练的语音编码器、语音适配器、LLM和流式语音解码器,能够在不进行语音转录的情况下直接生成文本和语音响应,显著提升了用户体验。实验结果显示,LLaMA-Omni的响应延迟低至226ms,具有创新性和实用性。
41 1
|
2月前
|
存储 并行计算 数据处理
使用GPU 加速 Polars:高效解决大规模数据问题
Polars 最新开发了 GPU 加速执行引擎,支持对超过 100GB 的数据进行交互式操作。本文详细介绍了 Polars 中 DataFrame(DF)的概念及其操作,包括筛选、数学运算和聚合函数等。Polars 提供了“急切”和“惰性”两种执行模式,后者通过延迟计算实现性能优化。启用 GPU 加速后,只需指定 GPU 作为执行引擎即可大幅提升处理速度。实验表明,GPU 加速比 CPU 上的懒惰执行快 74.78%,比急切执行快 77.38%。Polars 的查询优化器智能管理 CPU 和 GPU 之间的数据传输,简化了 GPU 数据处理。这一技术为大规模数据集处理带来了显著的性能提升。
69 4
|
3月前
|
机器学习/深度学习 并行计算 PyTorch
GPU 加速与 PyTorch:最大化硬件性能提升训练速度
【8月更文第29天】GPU(图形处理单元)因其并行计算能力而成为深度学习领域的重要组成部分。本文将介绍如何利用PyTorch来高效地利用GPU进行深度学习模型的训练,从而最大化训练速度。我们将讨论如何配置环境、选择合适的硬件、编写高效的代码以及利用高级特性来提高性能。
646 1
|
3月前
|
UED 存储 数据管理
深度解析 Uno Platform 离线状态处理技巧:从网络检测到本地存储同步,全方位提升跨平台应用在无网环境下的用户体验与数据管理策略
【8月更文挑战第31天】处理离线状态下的用户体验是现代应用开发的关键。本文通过在线笔记应用案例,介绍如何使用 Uno Platform 优雅地应对离线状态。首先,利用 `NetworkInformation` 类检测网络状态;其次,使用 SQLite 实现离线存储;然后,在网络恢复时同步数据;最后,通过 UI 反馈提升用户体验。
88 0
|
3月前
|
机器学习/深度学习 TensorFlow 数据处理
分布式训练在TensorFlow中的全面应用指南:掌握多机多卡配置与实践技巧,让大规模数据集训练变得轻而易举,大幅提升模型训练效率与性能
【8月更文挑战第31天】本文详细介绍了如何在Tensorflow中实现多机多卡的分布式训练,涵盖环境配置、模型定义、数据处理及训练执行等关键环节。通过具体示例代码,展示了使用`MultiWorkerMirroredStrategy`进行分布式训练的过程,帮助读者更好地应对大规模数据集与复杂模型带来的挑战,提升训练效率。
80 0
|
15天前
|
弹性计算 人工智能 Serverless
阿里云ACK One:注册集群云上节点池(CPU/GPU)自动弹性伸缩,助力企业业务高效扩展
在当今数字化时代,企业业务的快速增长对IT基础设施提出了更高要求。然而,传统IDC数据中心却在业务存在扩容慢、缩容难等问题。为此,阿里云推出ACK One注册集群架构,通过云上节点池(CPU/GPU)自动弹性伸缩等特性,为企业带来全新突破。