Whale 基于 Tensorflow 深度学习分布式训练框架|学习笔记

简介: 快速学习 Whale 基于 Tensorflow 深度学习分布式训练框架。

开发者学堂课程【PAL 平台学习路线:机器学习入门到应用:Whale 基于 Tensorflow 深度学习分布式训练框架】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/855/detail/14097


Whale 基于 Tensorflow 深度学习分布式训练框架

 

内容介绍:

一、Whale 的特点

二、用户接口介绍

 

一、Whale 的特点

工业级深度学习分布式训练框架

image.png

1.支持多种不同分布式策略。

Whale 不仅支持最基础的数据并行,同时也支持模型并行、算子拆分、流水并行及各种不同并行化的混合并行化组合。

2. 支持用户自定义并行化策略,也支持自动并行化。

3. 高效的分布式训练效率。

4.接口灵活易用,完全兼容 Tensorflow。

用户定义好的单机单卡的 Tensorflow 代码只需要利用 Whale 简单的借口,就可以完成非常丰富的并行化策略。

 

二、用户接口介绍

Whale 提供了两组简单的用户接口。

image.png

1.cluster Virtual Devices 定义

Cluster 将物理设备分组成虚拟设备,最终生成的虚拟设备即 Virtual Devices ,其会将具体的模型部分映射到虚拟 Virtual Devices 上进行执行。

2.Scope 并用化原语

(1)用于描述并行化类型:

①replica(数据并行)

②stage(模型并行)

③split(算子拆分)

④pipeline(流水并行)

⑤auto-parallel(自动并行)

3.接口使用实例

实例介绍接口如何使用,具体主要有数据并行、算子拆分和流水并行的实例。

(1)数据并行实例

数据并行在每一个具体的计算设备上都会放置一个完整的模型副本,在完成前项后项之后,每个 Devices 上的模型副本都会生成出一个对应的 local batch 的梯度。经过全局的AllReduce 后,每张卡会拿到 AllReduce 之后的梯度,再进行本地 ApplyUpdate 的权重。这个过程用户本身定义单机单卡代码,即如下①所展示,只要用户定义好单机单卡的代码,在其前面加上 with wh.cluster():,里面不传参数即代表所有的 device 都会映射成一个虚拟 device,然后再通过 with wh.replica(): 接口来告诉 whale框架。下面定义的这些模型,在 replica 下面所有的代码都会以数据并行的方式 Place 到各个设备上,具体在背后如何进行梯度的聚合,全部由 whale 框架自动完成。

①数据并行代码

with wh.cluster():

with wh.replica():

out =Model()

②数据并行逻辑图

image.png

(2)算子拆分实例:大规模分类任务

·ResNet-50 with 100,000 classess

 image.png

该模型 ResNet-50 部分权重大约有90 M左右,而全连接层权重大约有782 M。在实际应用中如果用数据并行训练时,可以看到 Bottleneck 和 performing 得到的信息,整个全连接层的 allreduce 通信是整个训练中的一个瓶颈,这主要原因还是因为 FC 全连接层的参数量是 ResNet-50 的参数量的8.7倍,它的参数量太大,导致整个训练过程中全连接层的梯度同步是一个瓶颈。那针对这种场景下,如何进行更优的分布式训练呢?这里提供的策略就是通过算子拆分。

瓶颈的主要原因:

①FC 层参数量=8.7X ResTet50参数量

②数据并行场景下 FC 层的同时是瓶颈

 image.png

对于 ResNet-50 大规模分类任务,算子拆分实际上就是将模型分成两部分,一是 backbone 部分,也就是 Stage0 ,其划分完后剩下的一部分全连接层和 Softmax 层,会将其划分到 Stage1 里。这样模型就会被划分为两个部分,一是 Stage0 ,ResNet-50 部分,二是 Stage1 ,全连接层和 Softmax 层部分。

这里又通过 class 定义了两个 Virtual Device,其实际上是可以通过 Whale 定义出两个相同的 Virtual Device,也可以定义出两个不同的 Virtual Device。这里举的例子是第一个 Virtual Device 其背后映射的具体物理资源是相同的,映射完后,其背后的混合映射执行图如下图所示,数据并行部分会全部以副本的形式放在 GPU0到 GPU5上。对于全连接层和Softmax 部分会通过分片的方式放在 GPU0到 GPU5上,中间会通过 Features Allgather50输出的 Feature,通过 Allgather 的操作再分发到具体的全连接层分片上,完成前项,后项也是同理。这样一个复杂的逻辑,通过 Whale 如何进行分布式的实现呢?如下代码。

import whale as wh

cluster = wh.cluster(layout = {"a1l"})

with cluster:

with wh. replica():

features = ResNet50(inputs)

with wh. split():

logits = FC(features)

predictions = Softmax(logits)

对于简单的单机单卡代码来说,用户只需要定义 feature 、ResNet-50的模型部分、FC 和 Softmax 部分,这里是按照前面的介绍需要对 ResNet-50 部分采用数据并行的逻辑操作,只需要通过对 ResNet-50添加 whih.replica 操作就可以完成 ResNet-50数据并行部分的实现。FC 层和 Softmax 层,按照前面的逻辑来说是需要进行 soft 拆分的,只需要在它的前面加上 with wh.split,这个 scope 接口就让 whale 在底层框架层自动的将 FC 层和 Softmax 层进行分片的放置在所有的物理 Devices 上,在最外层套的是 class,按照刚才的描述,需要生成一个相同的 class 即可。

 image.png

这里就可以用 which class logits 来进行完成,通过这样一个简单的接口,就可以实现非常复杂的算子拆分便易化,这样的接口非常简单,而且通过这样的接口实现,可以将模型的分类扩展到亿级分类,这种场景实际上对数据并行无法实现,但是通过算子拆分,可以提高模型的规模。这里也对10万分类进行了一个测试,10万分类的测试的 Bottleneck 是 whale 的数据运行,可以看到,在10万分类上,64卡训练性能是数据运行的14.8倍,这个也得益于通过算子拆分。这里只需要去同步通梯度,梯度的通信只需要去通信 ResNet-50部分。算子拆分的 FC 部分,就不需要进行梯度通信了,只需要用一些的feature map通信来替代算子拆分 FC 部分的梯度通信,这样可以大大降低通信的成本。

(3)流水并存实例:BertLarge 任务

介绍一下流水运行,这里是以 BertLarge 任务为例。单机单卡的任务,这是 bert 的 encoders embedding加一个24层的 encoder 最后加一个 pooler 层。

 image.png

由于这个模型比较大,通过数据并行的时候,通梯度的通信开销比较高,那首先想到需要把这个模型进行分片,放到不同的卡上,所以第一步,把分片放到不同卡上,就是这里的意思是将 embedding 的1到8层的 encoder 放在了 GPU0(stage0)上,把第9层和第16层的 encoder放在 GPU1(stage1),把第17到24层 encoder 放在 GPU2(stage2)上。

这样的模式运行还具有一些问题,与下面的持续图一样,当训练的过程中,在同一时刻,只有一张卡会正在使用,其他卡都处于空闲状态,所以也就是 bubble 的时间会非常长。为了解决这个问题,需要在此基础上再加上流水并行的策略。流水并行就是如下图所示,先加一个模型,按照模型并行的方式拆分完之后,再输入的时候喂进去多个不同的macbatch,这样可以将整个时序上的 gpu 使用率拉的更满,可以明显的看到右侧的时序图和比左侧的时序图空白的部分要少很多,只在一个模型的模型并行的基础上进行流水并行是远远不够的,因为在大规模训练时,常常具体计算硬件资源,有时到达几十上百张卡,这种情况很难将一个模型把它拆分成上百份,这个性能会非常差,而且模型不一定能够拆得这么多。因此,应该先将一个模型在机内进行拆分,拆分成 N 份之后,在不同的机器间做数据并行,第一个副本放在 work0上,第二个副本也同样的以模型并行加流水并行的方式放在 work1上,work2上也有同样的副本。这是一种并行化的方式。另一种更优的变化方式,可以先做跨级流水,也就是 work0、work1、work2上的 GPU0,这是三张卡。然后分别放一个模型副本的stage0、stage1、stage2,像 work0 只保存三个 stage0 的副本。

 image.png

编写这样一个模型并行、流水并行、数据并行的 Bertlarge 的训练通过 word 接口怎么写?这里举一个编写代码的例子。

首先是单机单卡的代码,先定义好 embedding 以及 encoder layer,然后最后加 pooler。

output = embedding (inputs )

output = encoder_layer 0_24(output)

output = pooler(output )

首先要做的是把此模型变成一个模型并行的代码,模型并行代码通过stage接口,这里有三个 with stage。用户只需要将三个 with stage 接口放在相应的模型定义的地方。举个例子:像 embedding 和 encoder layer 的0到8被当作第一个 stage,放在第一个 with stage 下面,那 encoder layer 的8到16层,就用另外一个 with stage 来进行进行嵌套 with。同样的道理定义第三个stage,定义好这三个 stage 之后,这就是一个标准的模型并行的代码了,需要对这个模型并行的代码再增加一个流水并行的逻辑,所以只需要在它到外面再嵌套一个 with pipeline ,Michael 的number 数填成4,这样就完成了模型并行加流水并行的代码的撰写。刚才也提到,当卡数特别多的时候,只用流水并行是完全不够的,那还需要套一个 replica 接口,通过 with replica会自动的将模型放置到不同的 work 上的 Devices 上,自动完成数据并行的 placement。另外最外层还需要加一个 with class,其是有默认的 Layout 来进行生成 class ,自己也可以按照自己需要指定 class 的 layout 类型。通过这样一个简单的代码撰写,就可以完成复杂的数据并行、流水并行以及模型并行的混合并行的 BertLarge 任务的训练。

import whale as wh

with wh.cluster():

with wh. replica():

with wh. pipeline(micro_ batch=4):

with wh. stage():

output . embedding inputs )

output . encoder layer _0 8(output)

with wh.stage():

output . encoder layer 8 16(output)

with wh. stage():

output . encoder layer 16 24(output)

output . pooler( output)

image.png

通过这样的混合并行的效果,这里也做了测试。在64卡的任务上,当 Batch Size=6时,流水变形的性能比 whale 数据并行有1.34倍的提升。另外比 horovod 数据并行有2.32倍的提升。Whale 数据并行之所以比 horovod 数据并行更优秀,是因为 whale 数据并行的在逻辑上有大量的优化,以及通项的优化。

相关实践学习
在云上部署ChatGLM2-6B大模型(GPU版)
ChatGLM2-6B是由智谱AI及清华KEG实验室于2023年6月发布的中英双语对话开源大模型。通过本实验,可以学习如何配置AIGC开发环境,如何部署ChatGLM2-6B大模型。
相关文章
|
11月前
|
数据采集 存储 数据可视化
分布式爬虫框架Scrapy-Redis实战指南
本文介绍如何使用Scrapy-Redis构建分布式爬虫系统,采集携程平台上热门城市的酒店价格与评价信息。通过代理IP、Cookie和User-Agent设置规避反爬策略,实现高效数据抓取。结合价格动态趋势分析,助力酒店业优化市场策略、提升服务质量。技术架构涵盖Scrapy-Redis核心调度、代理中间件及数据解析存储,提供完整的技术路线图与代码示例。
1116 0
分布式爬虫框架Scrapy-Redis实战指南
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
ICLR 2025 | EDiT:一种基于 Local SGD 策略的大模型高效分布式训练方法
蚂蚁 AI Infra 团队在深度学习最核心之一的训练框架方向上持续投入与创新,实现了提升资源利用率、加速训练、提升训练稳定性等目标。我们提出的 EDiT 方法,即为其中一项工作。
|
4月前
|
存储 监控 算法
117_LLM训练的高效分布式策略:从数据并行到ZeRO优化
在2025年,大型语言模型(LLM)的规模已经达到了数千亿甚至数万亿参数,训练这样的庞然大物需要先进的分布式训练技术支持。本文将深入探讨LLM训练中的高效分布式策略,从基础的数据并行到最先进的ZeRO优化技术,为读者提供全面且实用的技术指南。
|
4月前
|
机器学习/深度学习 监控 PyTorch
68_分布式训练技术:DDP与Horovod
随着大型语言模型(LLM)规模的不断扩大,从早期的BERT(数亿参数)到如今的GPT-4(万亿级参数),单卡训练已经成为不可能完成的任务。分布式训练技术应运而生,成为大模型开发的核心基础设施。2025年,分布式训练技术已经发展到相当成熟的阶段,各种优化策略和框架不断涌现,为大模型训练提供了强大的支持。
|
7月前
|
机器学习/深度学习 人工智能 API
AI-Compass LLM训练框架生态:整合ms-swift、Unsloth、Megatron-LM等核心框架,涵盖全参数/PEFT训练与分布式优化
AI-Compass LLM训练框架生态:整合ms-swift、Unsloth、Megatron-LM等核心框架,涵盖全参数/PEFT训练与分布式优化
|
8月前
|
存储 机器学习/深度学习 自然语言处理
避坑指南:PAI-DLC分布式训练BERT模型的3大性能优化策略
本文基于电商搜索场景下的BERT-Large模型训练优化实践,针对数据供给、通信效率与计算资源利用率三大瓶颈,提出异步IO流水线、梯度压缩+拓扑感知、算子融合+混合精度等策略。实测在128卡V100集群上训练速度提升3.2倍,GPU利用率提升至89.3%,训练成本降低70%。适用于大规模分布式深度学习任务的性能调优。
388 3
|
9月前
|
监控 Java 调度
SpringBoot中@Scheduled和Quartz的区别是什么?分布式定时任务框架选型实战
本文对比分析了SpringBoot中的`@Scheduled`与Quartz定时任务框架。`@Scheduled`轻量易用,适合单机简单场景,但存在多实例重复执行、无持久化等缺陷;Quartz功能强大,支持分布式调度、任务持久化、动态调整和失败重试,适用于复杂企业级需求。文章通过特性对比、代码示例及常见问题解答,帮助开发者理解两者差异,合理选择方案。记住口诀:单机简单用注解,多节点上Quartz;若是任务要可靠,持久化配置不能少。
820 4
|
11月前
|
并行计算 PyTorch 算法框架/工具
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
本文探讨了如何通过技术手段混合使用AMD与NVIDIA GPU集群以支持PyTorch分布式训练。面对CUDA与ROCm框架互操作性不足的问题,文章提出利用UCC和UCX等统一通信框架实现高效数据传输,并在异构Kubernetes集群中部署任务。通过解决轻度与强度异构环境下的挑战,如计算能力不平衡、内存容量差异及通信性能优化,文章展示了如何无需重构代码即可充分利用异构硬件资源。尽管存在RDMA验证不足、通信性能次优等局限性,但该方案为最大化GPU资源利用率、降低供应商锁定提供了可行路径。源代码已公开,供读者参考实践。
972 3
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
|
数据采集 人工智能 分布式计算
MaxFrame:链接大数据与AI的高效分布式计算框架深度评测与实践!
阿里云推出的MaxFrame是链接大数据与AI的分布式Python计算框架,提供类似Pandas的操作接口和分布式处理能力。本文从部署、功能验证到实际场景全面评测MaxFrame,涵盖分布式Pandas操作、大语言模型数据预处理及企业级应用。结果显示,MaxFrame在处理大规模数据时性能显著提升,代码兼容性强,适合从数据清洗到训练数据生成的全链路场景...
692 5
MaxFrame:链接大数据与AI的高效分布式计算框架深度评测与实践!
|
人工智能 分布式计算 大数据
MaxFrame 产品评测:大数据与AI融合的Python分布式计算框架
MaxFrame是阿里云MaxCompute推出的自研Python分布式计算框架,支持大规模数据处理与AI应用。它提供类似Pandas的API,简化开发流程,并兼容多种机器学习库,加速模型训练前的数据准备。MaxFrame融合大数据和AI,提升效率、促进协作、增强创新能力。尽管初次配置稍显复杂,但其强大的功能集、性能优化及开放性使其成为现代企业与研究机构的理想选择。未来有望进一步简化使用门槛并加强社区建设。
575 8