第五课:MindSpore自动并行

news2024/10/7 14:29:37

文章目录

  • 第五课:MindSpore自动并行
    • 1、学习总结:
      • 数据并行
      • 模型并行
        • MindSpore算子级并行
        • 算子级并行示例
      • 流水线并行
        • GPipe和Micro batch
        • 1F1B
        • 流水线并行示例
      • 内存优化
        • 重计算
        • 优化器并行
      • MindSpore分布式并行模式
      • 课程ppt及代码地址
    • 2、学习心得:
    • 3、经验分享:
    • 4、课程反馈:
    • 5、使用MindSpore昇思的体验和反馈:
    • 6、未来展望:

第五课:MindSpore自动并行

1、学习总结:

数据并行

image-20240122005322503

数据并行过程:

  • 每一张卡上放置相同的模型参数、梯度、优化器状态
  • 不同的卡送入不同的数据训练
  • 反向传播获得梯度后,进行AllReduce

数据并行的问题:

  • 要求单卡可以放下模型.
  • 多卡训练时内存冗余

模型并行

image-20240122005433124

**模型并行是算子层面的并行,它利用某些算子的特性将算子拆分到多个设备上进行计算。**因此并不是网络中所有的算子都可以拆分计算,可以拆分的算子需满足如下特性:

  • 可以并行计算的算子
  • 算子其中一个输入来自于Parameter
MindSpore算子级并行
  • MindSpore对每个算子独立建模,用户可以设置正向网络中每个算子的切分策略(对于未设置的算子,默认按数据并行进行切分)。
  • 在构图阶段,框架将遍历正向图,根据算子的切分策略对每个算子及其输入张量进行切分建模,使得该算子的计算逻辑在切分前后保持数学等价。
  • 框架内部使用Tensor Layout来表达输入输出张量在集群中的分布状态,Tensor Layout中包含了张量和设备间的映射关系,用户无需感知模型各切片在集群中如何分布,框架将自动调度分配。
  • 框架还将遍历相邻算子间张量的Tensor Layout,如果前一个算子输出张量作为下一个算子的输入张量,且前一个算子输出张量的Tensor Layout与下一-个算子输入张量的Tensor Layout不同,则需要在两个算子之间进行张量重排布(Tensor Redistribution)
  • 对于训练网络来说,框架处理完正向算子的分布式切分之后,依靠框架的自动微分能力,即能自动完成反向算子的分布式切分。
算子级并行示例

image-20240122005702566

由于第一个算子输出的Tensor Layout是第零维切分到集群,而第二个算子要求第一个输入Tensor在集群上复制。**所以在图编译阶段,会自动识别两个算子输出/输入之间Tensor Layout的不同,从而自动推导出Tensor重排布的算法。**而这个例子所需要的Tensor重排布是一个AllGather算子(注: MindSpore的AllGather算子会自动把多个输入Tensor在第零维进行合并)

流水线并行

  • 受server间通信带宽低的影响,传统数据并行叠加模型并行的这种混合并行模式的性能表现欠佳,需要引入流水线并行。流水线并行能够将模型在空间上按stage进行切分,每个stage只需执行网络的一部分,大大节省了内存开销,同时缩小了通信域,缩短了通信时间。
  • 流水线(Pipeline) 并行是将神经网络中的算子切分成多个阶段(Stage) ,再把阶段映射到不同的设备上,使得不同设备去计算神经网络的不同部分。

image-20240122010003392

GPipe和Micro batch

**简单地将模型切分到多设备上并不会带来性能的提升,因为模型的线性结构到时同一时刻只有一台设备在工作,而其它设备在等待,造成了资源的浪费。**为了提升效率,流水线并行进一步将小批次(MiniBatch)切分成更细粒度的微批次(MicroBatch),在微批次中采用流水线式的执行序,从而达到提升效率的目的。

image-20240122110357331

1F1B

**MindSpore的流水线并行实现中对执行序进行了调整,来达到更优的内存管理。**如图3所示,在编号为0的MicroBatch的正向执行完后立即执行其反向,这样做使得编号为0的MicroBatch的中间结果的内存得以更早地(相较于上图)释放,进而确保内存使用的峰值比上图的方式更低。

image-20240122110446353

流水线并行示例
  • 流水线并行需要用户去定义并行的策略,通过调用pipeline_ stage接口来指定每个layer要在哪个stage上去执行。
  • pipeline_ stage接口的粒度为Cell。所有包含训练参数的Cell都需要配置pipeline_ stage,并且pipeline_ stage要按照网络执行的先后顺序,从小到大进行配置。
class ResNet(nn.Cell):
    """ResNet"""

    def __init__(self, block, num_classes=100, batch_size=32):
        """init"""
        super(ResNet, self).__init__()
        self.batch_size = batch_size
        self.num_classes = num_classes
        self.head = Head()

        self.layer1 = MakeLayer0(block, in_channels=64, out_channels=256, stride=1)
        self.layer2 = MakeLayer1(block, in_channels=256, out_channels=512, stride=2)
        self.layer3 = MakeLayer2(block, in_channels=512, out_channels=1024, stride=2)
        self.layer4 = MakeLayer3(block, in_channels=1024, out_channels=2048, stride=2)

        self.pool = ops.ReduceMean(keep_dims=True)
        self.squeeze = ops.Squeeze(axis=(2, 3))
        self.fc = fc_with_initialize(512 * block.expansion, num_classes)

        # 下面就是流水线并行的配置
        self.head.pipeline_stage = 0
        self.layer1.pipeline_stage = 0
        self.layer2.pipeline_stage = 0
        self.layer3.pipeline_stage = 1
        self.layer4.pipeline_stage = 1
        self.fc.pipeline_stage = 1

内存优化

重计算

在计算某些反向算子时,需要用到一些正向算子的计算结果,导致这些正向算子的计算结果需要驻留在内存中,直到依赖它们的反向算子计算完,这些正向算子的计算结果占用的内存才会被复用。这一现象推高了训练的内存峰值,在大规模网络模型中尤为显著。如:

  • Dropout
  • Activations

解决办法是通过时间换空间,为了降低内存峰值, 重计算技术可以不保存正向计算结果,让该内存可以被复用,然后在计算反向部分时,重新计算出正向结果。

image-20240122111217824

重计算效果

以GPT3模型为例,设置策略为对每层layer对应的Cell设置为重计算,然后每层layer的输出算子设置为非重计算。72层GPT3网络开启重计算的效果如下图所示:

image-20240122111325256重计算使用方式

为了方便用户使用,MindSpore提供了针对单个算子和Cell设置的重计算接口。当用户调用Cell的重计算接口时,这个Cell里面的所有正向算子都会被设置为重计算。

class ResNet(nn.Cell):
    """ResNet"""

    def __init__(self, block, num_classes=100, batch_size=32):
        """init"""
        super(ResNet, self).__init__()
        self.batch_size = batch_size
        self.num_classes = num_classes

        self.conv1 = conv7x7(3, 64, stride=2, padding=0)

        self.bn1 = bn_with_initialize(64)
        self.relu = ops.ReLU()
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode="same")

        self.layer1 = MakeLayer0(block, in_channels=64, out_channels=256, stride=1)
        self.layer2 = MakeLayer1(block, in_channels=256, out_channels=512, stride=2)
        self.layer3 = MakeLayer2(block, in_channels=512, out_channels=1024, stride=2)
        self.layer4 = MakeLayer3(block, in_channels=1024, out_channels=2048, stride=2)

        # 这里就是对每层进行重计算的方式
        self.layer1.recompute()
        self.layer2.recompute()
        self.layer3.recompute()
        self.layer4.recompute()

        self.pool = ops.ReduceMean(keep_dims=True)
        self.squeeze = ops.Squeeze(axis=(2, 3))
        self.fc = fc_with_initialize(512 * block.expansion, num_classes)
优化器并行
  • 在进行数据并行训练时,模型的参数更新部分在各卡间存在冗余计算,优化器并行通过将优化器的计算量分散到数据并行维度的卡上,在大规模网络上(比如Bert、 GPT) 可以有效减少内存消耗并提升网络性能。

  • 传统的数据并行模式将模型参数在每台设备上都有保有副本,把训练数据切分,在每次迭代后利用通信算子同步梯度信息,最后通过优化器计算对参数进行更新。数据并行虽然能够有效提升训练吞吐量,但并没有最大限度地利用机器资源。其中优化器会引入冗余内存和计算,消除这些冗余是需关注的优化点。

ZeRO (1-3)

  • 优化器状态切分pos:切分优化器状态到各个计算卡中,在享有普通数据并行相同通信量的情况下,可降低4倍的内存占用
  • 添加梯度切分pos+g:在pos的基础上,进一步将模型梯度切分到各个计算卡中,在享有与普通数据并行相同通信量的情况下,拥有8倍的内存降低能力
  • 添加参数切分pos+g+p:在pos+g的基础上,将模型参数也切分到各个计算卡中,内存降低能力与并行数量成线性比例,通信量大约有50%的增长

image-20240122113208786

参数分组(Weights Grouping)
将参数和梯度分组放到不同卡上更新,再通过通信广播操作在设备间共享更新后的权值。该方案的内存和性能收益取决于参数比例最大的group。当参数均匀划分时,理论上的正收益是N- 1/N的优化器运行时间和动态内存,以及N- 1/N的优化器状态参数内存大小,其中N表示设备数。而引入的负收益是共享网络权重时带来的通信时间。

image-20240122113708901

参数切分(Weights Sharding)
**对参数做层内划分,对每一个参数及梯度根据设备号取其对应切片,各自更新后再调用通信聚合操作在设备间共享参数。**这种方案的优点是天然支持负载均衡,即每张卡上参数量和计算量一致,缺点是对参数形状有整除设备数要求。该方案的理论收益与参数分组一致,为了扩大优势,框架做了如下几点改进。

  • **对网络中的权重做切分,可以进一步减少静态内存。**但这也需要将迭代末尾的共享权重操作移动到下-轮迭代的正向启动前执行,保证进入正反向运算的依旧是原始张量形状。
  • **优化器并行运算带来的主要负收益是共享权重的通信时间,如果我们能够将其减少或隐藏,就可以带来性能上的提升。**通信跨迭代执行的一个好处就是,可以通过对通信算子适当分组融合,将通信操作与正向网络交叠执行,从而尽可能隐藏通信耗时。通信耗时还与通信量有关,对于涉及混合精度的网络,如果能够使用fp16通信,通信量相比fp32将减少- -半

image-20240122113918114

image-20240122114425413

MindSpore分布式并行模式

  • 数据并行:用户的网络参数规模在单卡上可以计算的情况下使用。这种模式会在每卡上复制相同的网络参数,训练时输入不同的训练数据,适合大部分用户使用。

  • 半自动并行:用户的神经网络在单卡上无法计算,并且对切分的性能存在较大的需求。用户可以设置这种运行模式,手动指定每个算子的切分策略,达到较佳的训练性能。

  • 自动并行:用户的神经网络在单卡上无法计算,但是不知道如何配置算子策略。用户启动这种模式,MindSpore会自动针对每个算子进行配置策略,适合想要并行训练但是不知道如何配置策略的用户。

  • 混合并行:完全由用户自己设计并行训练的逻辑和实现,用户可以自己在网络中定义AllGather等通信算子。适合熟悉并行训练的用户。

课程ppt及代码地址

  • github地址(网络不好的可以访问下面我克隆到gitee上的地址):Parallel

  • gitee地址:Parallel

2、学习心得:

​ 通过本次学习,更加熟悉了华为Mindspore这个国产深度学习框架,同时也对mindspore的各种并行策略有所了解,峰哥通过resnet50这个示例把各种并行策略实现都做了一个详细的讲解,还是比较印象深刻的,课后不懂的还可以再跑跑相关的代码示例,总之各种并行策略在代码上的实现方式还是挺简单的,基本就是一行代码就搞定了。

3、经验分享:

​ 在启智openI上的npu跑时记得使用mindspore1.7的镜像,同时安装对应mindnlp的版本,不然可能会因为版本不兼容而报错。另外就是各种并行策略的代码都要跑一跑,结合视频去加深理解。

4、课程反馈:

​ 本次课程中的代码串讲我觉得是做的最好的地方,没有照着ppt一直念,而是在jupyter lab上把代码和原理结合到一块进行讲解,让学习者对代码的理解更加深入。我觉得内容的最后可以稍微推荐一下与Mindspore大模型相关的套件,让学习者在相关套件上可以开发出更多好玩和有趣的东西!

5、使用MindSpore昇思的体验和反馈:

MindSpore昇思的优点和喜欢的方面:

  1. 灵活性和可扩展性: MindSpore提供了灵活的编程模型,支持静态计算图和动态计算图。这种设计使得它适用于多种类型的机器学习和深度学习任务,并且具有一定的可扩展性。
  2. 跨平台支持: MindSpore支持多种硬件平台,包括CPU、GPU和NPU等,这使得它具有在不同设备上运行的能力,并能充分利用各种硬件加速。
  3. 自动并行和分布式训练: MindSpore提供了自动并行和分布式训练的功能,使得用户可以更轻松地处理大规模数据和模型,并更高效地进行训练。
  4. 生态系统和社区支持: MindSpore致力于建立开放的生态系统,并鼓励社区贡献,这对于一个开源框架来说非常重要,能够帮助用户更好地学习和解决问题。

一些建议和改进方面:

  1. 文档和教程的改进: 文档和教程并不是很详细,希望能够提供更多实用的示例、详细的文档和教程,以帮助用户更快速地上手和解决问题。
  2. 更多的应用场景示例: 提供更多真实场景的示例代码和应用案例,可以帮助用户更好地了解如何在实际项目中应用MindSpore。

6、未来展望:

​ 大模型的内容还是很多的,希望自己能坚持打卡,将后面的内容都学习完,并做出一些有趣好玩的东西来!最近准备尝试做做社区大模型相关的代码迁移+精度验证任务了,希望能够学以致用,提高自己的技术水平!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1405527.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android 内存优化 内存泄漏

内存抖动 内存抖动是由于短时间内有大量对象进出新生区导致的,内存忽高忽低,有短时间内快速上升和下落的趋势,分析图呈锯齿状。 它伴随着频繁的GC,GC 会大量占用 UI 线程和CPU 资源,会导致APP 整体卡顿,甚…

Jupyter Notebook安装使用教程

Jupyter Notebook 是一个基于网页的交互式计算环境,允许你创建和共享包含代码、文本说明、图表和可视化结果的文档。它支持多种编程语言,包括 Python、R、Julia 等。其应用场景非常广泛,特别适用于数据科学、机器学习和教育领域。它可以用于数…

安装ROS2-ubuntu

相较于ROS1,ROS2在设计之初就考虑了在产品环境下⾯临的⼀些挑战,具体来说,ROS2采⽤(或者计划采⽤)以下策略以提升其在产品环境的适⽤度: ⽀持多机器⼈ 对⼩型嵌⼊式设备和微控制器的⽀持 实时系统&am…

《WebKit 技术内幕》学习之四(1): 资源加载和网络栈

第四章 资源加载和网络栈 使用网络栈来下载网页和网页资源是渲染引擎工作的第一步 1.WebKit 资源加载机制 1.1 资源 网页本身就是一种资源、网页还需要依赖很多其他的资源(图片、视频) (1)HTML 支持的资源主要包括以下几种类型: HTML 页…

Linux Shell alias的简单用法:给shell起别名

alias:显示该用户所有起过别名的命令 alias lla‘ls -al’:给ls -al起别名为lla unalias lla:取消lla的别名 1、该命令所有的操作只对个人用户生效,给普通用户起的别名在root用户下不生效,只有回到普通用户才生效。 2…

JOSEF约瑟 中间继电器JZ14-44Z/4 不带外罩和接线座

系列型号 JZ14-014Z/0中间继电器;JZ14-014Z/1中间继电器; JZ14-014Z/2中间继电器;JZ14-014Z/4中间继电器; JZ14-014J/0中间继电器;JZ14-014J/1中间继电器; JZ14-014J/2中间继电器;JZ14-014J/3中间继电器; JZ14-014J/4中间继电器;JZ14-140Z/0中间继电器; JZ14-140Z/1中间继…

[UI5 常用控件] 01.Text

文章目录 前言1. 普通文本2. 长文本:3. 设置最大显示行数 ( maxLines3 )4. 单行显示 ( wrappingfalse )5. 显示空白符 ( renderWhitespacetrue )6. 使用 - 连接单词:只适用于英文 ( wrappingTypeHyphenated )7. 空白时使用 - 代替 ( emptyIndicatorModeOn )8. JSON数…

Linux之权限(内容详细,细节满满)

个人主页:点我进入主页 专栏分类:C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 数据结构初阶 Linux 欢迎大家点赞,评论,收藏。 一起努力 目录 一.前言 二.权限修改的两种方法 …

爬虫入门到精通_基础篇1(爬虫基本原理讲解, Urllib库基本使用)

01 爬虫基本原理讲解 1.什么是爬虫:请求网站并提取数据的自动化程序 2.爬虫基本流程: 发起请求:通过HTTP库向目标站点发起请求,即发送一个Request,请求可以包含额外的headers等信息,等待服务器响应。获取响应内容:如…

python实现归并排序

归并排序 归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,拍好各数组的顺序,再合并数组。 将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取…

银行常用操作指引:浦发

文章目录 引言浦发2.1 设置查询密码2.2 微信公众号绑定2.3 查询卡转账额度II 其他银行常用操作see also引言 浦发 2.1 设置查询密码 2.2 微信公众号绑定 入口:点击菜单的微信通知 用途:查询余额和明细 口令:解除绑定 2.3 查询卡转账额度 II 其他银行常用操作

06 栈

目录 1.栈 2.实现 3.OJ题 1. 栈 1. 栈的概念和结构 栈: 这一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out&…

OSS存储引擎如何使用以及如何添加图片【建议收藏】

Aliyun OSS对象存储,可以用来做文件服务器,存放一些文件,图片等资源,那么我们使用OSS,需要经历以下步骤: 这里就从如何开通OSS服务开始进行,到如何上传一个资源文件到OSS结束。 1、阿里云注册 …

最新AI系统ChatGPT网站系统源码,支持AI绘画,GPT语音对话,ChatFile文档对话总结,DALL-E3文生图,MJ绘画局部编辑重绘

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧。已支持GPT…

Python中==和is有什么区别

是比较两个对象的内容是否相等,即两个对象的“值”是否相等,不管两者在内存中的引用地址是否一样。 is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。即is比较两个条件:1.内容相…

LeetCode670.最大交换

我真的怀疑他是不是难度等级评错了,因为感觉没到中级,总之先看题吧 给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。 示例 1 : 输入: 2736 输出: 7236 解释: 交换数字2和数字7。示例 2 : 输入: 9973 输出:…

数字拆分--完全背包问题

一、题目 https://acm.ecnu.edu.cn/problem/3034/ 二、思路 本来算法就很弱,加上很久没刷题,做这道题真的是一言难尽~ 一开始我以为是找规律写递推式,写到f(9)的时候就觉得不对劲,又想了一会,还是没想到&#xff0…

【Linux配置yum源以及基本yum指令】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、yum是什么? 二、什么是软件包? 三、三种安装软件包的方式 四、yum的相关操作 4.1、搜索软件 4.2、安装软件 4.3、卸载软件 4.4、那…

Python | 七、栈 Stack、队列 Queue

栈的基础知识 是一种数据结构,在Python中常使用列表来模拟实现特点:先进后出 栈的基本操作 因为Python中通过列表模拟实现栈,所以以下的基本操作实际是列表的一些操作获取长度,使用len(stack)方法进栈,使用stack.app…

Element组件完整引入、按需引入、样式修改(全局、局部)、简单安装less以及npm命令证书过期等

目录 一、npm 安装二、完整引入三、按需引入四、样式修改1.按需加载的全局样式修改2. 局部样式修改1. 在 css 预处理器如 less scss 等直接使用::v-deep2. 只能用在原生 CSS 语法中:/deep/ 或者 >>> 五、 拓展:npm 安装less报错,提示证书过期六…