大模型--Megatron TP张量并行-15

news/2024/11/13 18:19:01/文章来源:https://www.cnblogs.com/cavalier-chen/p/18544497

目录
  • 1. 参考
  • 2. 介绍
  • 3. 权重的切分
    • 3.1 按行切分权重
    • 3.2 按列切分权重
  • 4. MLP层
  • 5. Self-Attention层
  • 6. Embedding层
  • 7. Cross-entropy层
  • 8. 张量模型并行 + 数据并行

1. 参考

https://zhuanlan.zhihu.com/p/622212228

2. 介绍

流水线并行
数据并行(DP,DDP和ZeRO)

介绍最重要,也是目前基于Transformer做大模型预训练最基本的并行范式:来自NVIDIA的张量模型并行(TP)。
基本思想就是把模型的参数纵向切开,放到不同的GPU上进行独立计算,然后再做聚合。
之前的将的都是 模型 按照层 进行切割。

全文结构如下:
一、切分权重的两种方法
二、MLP层
三、self-attention层
四、Embedding层
五、Cross-entropy层
六、经典并行:TP + DP (Megatron + ZeRO)
七、实验效果与GPU利用率
八、参考

3. 权重的切分

设输入数据为X,参数为W。X的维度 = (b, s, h),W的维度 = (h, h')。其中:

  • b:batch_size,表示批量大小
  • s:sequence_length,表示输入序列的长度
  • h:hidden_size,表示每个token向量的维度。
  • h':参数W的hidden_size。

orward的过程如下:

图中所绘是b=1时的情况。

假设现在W太大,导致单卡装不下。我们需要把W切开放到不同的卡上,则我们面临三个主要问题:

  • 怎么切分W。
  • 切完W后,怎么做forward。
  • 做完forward后,怎么做backward,进而求出梯度,更新权重。

一般来说,我们可以沿着W的行(h维度),或者列(h'维度)切分W。下面我们分别介绍这两种切割办法,并说明它们是如何做forward和backward的。

3.1 按行切分权重

forward
我们用N来表示GPU的数量。有几块GPU,就把W按行维度切成几份。下图展示了N=2时的切割方式:

W按照行维度切开后,X的维度和它不对齐了,这可怎么做矩阵乘法呢?很简单,再把X“按列切开”就行了,如下图所示:

backward
做完forward,取得预测值Y,进而可计算出损失L,接下来就能做backward了。我们重画一下forward的过程,并在其中加入backward的部分,整体流程图如下:

f 和 g:分别表示两个算子,每个算子都包含一组forward + backward操作。
其中 forward:
f算子:X 竖直方向切割成x1 x2即可
g算子:y1 + y2 即可

图中的每一行,表示单独在一块GPU上计算的过程

f 和 g算子的backward
g 的backward:

需要把同时广播到两块GPU上,两块GPU就可以独立计算各自权重的梯度了。

f 的backward:

3.2 按列切分权重

按列切分权重后,forward计算图如下:

这个forward还是比较简单的直接切分别计算 再接到一起 即可

g的backward:
貌似都等于X
因此只要计算各自GPU上的

f 的backward:因为对于损失L,X既参与了XW1的计算,也参与了XW2的计算,因此,其中表示第i块GPU上计算到X时的梯度。

已分别介绍完了“按行”和“按列”切分权重的方法。在Megatron-LM中,权重的切分操作就是由这两个基础算子组合而成的。接下来,针对Transformer模型,我们依次来看在不同的部分里,Megatron-LM是怎么做切分的。

4. MLP层

MLP层构造最简单,所以我们先来看它。MLP层计算过程如下图:

GELU是激活函数,A和B分别为两个线性层。在Transformer里,一般设h' = 4h。
h为embedding的维度
h'为隐藏层的维度
也就是会将embedding的维度 升维到4h的一个更高的维度。

假设现在有N块GPU,我们要把MLP层的权重拆到上面做计算,要怎么拆分呢?Megatron提供的拆分办法如下:

在MLP层中,对A采用“列切割”,对B采用“行切割”。

f 的forward计算:把输入X拷贝到两块GPU上,每块GPU即可独立做forward计算。
g 的forward计算:每块GPU上的forward的计算完毕,取得Z1和Z2后,GPU间做一次AllReduce,相加结果产生Z。

g 的backward计算:只需要把拷贝到两块GPU上,两块GPU就能各自独立做梯度计算。
f 的backward计算:当当前层的梯度计算完毕,需要传递到下一层继续做梯度计算时,我们需要求得 则此时两块GPU做一次AllReduce,把各自的梯度相加即可。

为什么我们对A采用列切割,对B采用行切割呢?
这样设计的原因是,我们尽量保证各GPU上的计算相互独立,减少通讯量。

对A来说,需要做一次GELU的计算,而GELU函数是非线形的,它的性质如下:

也就意味着,如果对A采用行切割,我们必须在做GELU前,做一次AllReduce,这样就会产生额外通讯量。但是如果对A采用列切割,那每块GPU就可以继续独立计算了。一旦确认好A做列切割,那么也就相应定好B需要做行切割了。

MLP层的通讯量分析:
MLP层做forward时产生一次AllReduce,做backward时产生一次AllReduce。

AllReduce的过程分为两个阶段,Reduce-Scatter和All-Gather,每个阶段的通讯量都相等。
现在我们设每个阶段的通讯量为
则一次AllReduce产生的通讯量为,MLP层的总通讯量为
根据上面的计算图

5. Self-Attention层

看稍微复杂一点的self-attention层切割方式(Transformer中Encode和Decoder之间还有做cross-attention,但计算逻辑和self-attention一致,因此这里只拿self-attention举例)。

当head数量为1时,self-attention层的计算方法如下:

seq_len,d_model分别为本文维度说明中的s和h,也即序列长度和每个token的向量维度
attention层需要做训练的三块权重。

理清了单头,我们来看多头的情况,下图展示了当num_heads = 2时attention层的计算方法。
即对每一块权重,我们都沿着列方向(k_dim)维度切割一刀。

此时每个head上的 的维度都变成(d_model, k_dim//2)

每个head上单独做矩阵计算,最后将计算结果concat起来即可。整个流程如下:

这不就是竖直切割的方式吗?
可以发现,attention的多头计算简直是为张量模型并行量身定做的,因为每个头上都可以独立计算,最后再将结果concat起来。也就是说,可以把每个头的参数放到一块GPU上。则整个过程可以画成:

对三个参数矩阵Q,K,V,按照“列切割”,每个头放到一块GPU上,做并行计算。对线性层B,按照“行切割”。切割的方式和MLP层基本一致,其forward与backward原理也一致,这里不再赘述。

最后,在实际应用中,并不一定按照一个head占用一块GPU来切割权重,我们也可以一个多个head占用一块GPU,这依然不会改变单块GPU上独立计算的目的。所以实际设计时,我们尽量保证head总数能被GPU个数整除

Self-Attention层的通讯量分析
self-attention层在forward中做一次AllReduce,在backward中做一次AllReduce。总通讯量也是,其中
self-attention层拼接起来看整体的计算逻辑和通讯量:

6. Embedding层

输入层Embedding,
word embedding:维度(v, h),其中v表示词表大小。
positional embedding:维度(max_s, h),其中max_s表示模型允许的最大序列长度。
对positional embedding来说,max_s本身不会太长,因此每个GPU上都拷贝一份,对显存的压力也不会太大。
但是对word embedding来说,词表的大小就很客观了,因此需要把word embedding拆分到各个GPU上,具体的做法如下:

对于输入X,过word embedding的过程,就是等于用token的序号去word embedding中查找对应词向量的过程。
例如,输入数据为[0, 212, 7, 9],数据中的每一个元素代表词序号,我们要做的就是去word embedding中的0,212,7,9行去把相应的词向量找出来。

假设词表中有300个词,现在我们将word embedding拆分到两块GPU上,第一块GPU维护词表[0, 150),第二块GPU维护词表[150, 299)。
当输入X去GPU上查找时,能找到的词,就正常返回词向量,找到不到就把词向量中的全部全素都置0。按此方式查找完毕后,每块GPU上的数据做一次AllReduce,就能得到最终的输入。
例如例子中,第一块GPU的查找结果为[ok, 0, ok, ok],第二块为[0, ok, 0, 0],两个向量一相加,变为[ok, ok, ok, ok]

输出层Embedding

输出层中,同样有一个word embedding,把输出再映射回词表里,得到每一个位置的词。一般来说,输入层和输出层共用一个word embeding。其计算过程如下:

需要注意的是,必须时刻保证输入层和输出层共用一套word embedding。
而在backward的过程中,我们在输出层时会对word embedding计算一次梯度,在输入层中还会对word embedding计算一次梯度。在用梯度做word embedding权重更新时,我们必须保证用两次梯度的总和进行更新。

当模型的输入层到输入层都在一块GPU上时(即流水线并行深度=1),我们不必担心这点(实践中大部分用Megatron做并行的项目也是这么做的)。但若模型输入层和输出层在不同的GPU上时,我们就要保证在权重更新前,两块GPU上的word embedding梯度做了一次AllReduce。

7. Cross-entropy层

终于来到了计算损失函数的一层回顾一下4.2中,输出层过完embedding后的样子:

正常来说,我们需要对Y1和Y2做一次All-Gather,把它们concat起来形成Y,然后对Y的每一行做softmax,就可得到对于当前位置来说,每个词出现的概率。接着,再用此概率和真值组做cross-entropy即可。

但是All-Gather会产生额外的通讯量,当词表v很大时,这个通讯开销也不容忽视。针对这种情况,可以做如下优化:

  1. 每块GPU上,我们可以先按行求和,得到各自GPU上的GPU_sum(e)
  2. 将每块GPU上结果做AllReduce,得到每行最终的sum(e),也就softmax中的分母。此时的通讯量为
  3. 在每块GPU上,即可计算各自维护部分的e/sum(e),将其与真值做cross-entropy,得到每行的loss,按行加总起来以后得到GPU上scalar Loss。
  4. 将GPU上的scalar Loss做AllReduce,得到总Loss。此时通讯量为N。

这样,我们把原先的通讯量从 大大降至

8. 张量模型并行 + 数据并行

基本把张量模型并行的计算架构说完,对Transformer类的模型,采用最经典方法是张量模型并行 + 数据并行,并在数据并行中引入ZeRO做显存优化。具体的架构如下:

node表示一台机器,一般我们在同一台机器的GPU间做张量模型并行。在不同的机器上做数据并行。图中颜色相同的部分,为一个数据并行组。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FreeModbus RTU 从机Hal库裸机移植避坑指南

首先说明 : FreeModbus 有很多个库!!!! 不同库的实现方法是略有不同的!!! 本次 FreeModbus RTU 移植 主要依据 这个网友分享的工程他人移植的库 你可能会在csdn看到他的文章, 但是完全跟着那个文章走很混乱 而且跟库的文件不一样. 故而 我重新整理了工程, 并写了一个详细的移植…

修改 NIKKE PC 端游戏缓存位置

本文记录如何使用 mklink 命令修改 NIKKE PC 端游戏缓存位置前言 NIKKE 每次版本更新都要下载大约 5~10G 的数据,以至于成为了我 AFK 的一部分原因 [允悲] 但是看游戏安装目录的大小却只有 1G 多,我还奇怪数据存哪去了,看到越来越小的 C 盘的空间才明白,草 搜索了一下后立马…

导包不对如何解决

问题: 这里这个包是自动导入的我们并不需要这个时候导致下面代码报错如何解决 2.解答:比如下面这给词爆红我们需要alt+enter,IDEA 会显示一个选择框,允许您选择 okhttp3.Request。选中后,它将使用您指定的正确包。,这里就是我是重新导入了maven依赖就好了

一图看懂云消息队列 RabbitMQ 版对比开源优势

随着企业对消息队列的性能和稳定性要求越来越高,运维成本也随之增加。 云消息队列 RabbitMQ 版通过架构优化:避免了消息积压导致的内存泄漏和服务器故障等稳定性问题; 解决了分布式系统中的脑裂难题; 并支持弹性伸缩和按量计费,有效降低资源和运维成本!那么,与开源 Rabb…

GIS工具哪家强?五款优质GIS工具箱对比分析

本文将为大家介绍五款功能各异的GIS工具箱,包括GISBox、QGIS、MapTiler、Saga GIS和Whitebox GAT。每款工具箱都有其独特的功能和应用场景,能够满足不同类型的GIS任务需求。无论是数据处理、空间分析、影像处理还是可视化需求,这些工具都能为用户提供丰富的解决方案。本文将…

安装Kibana__基于Windows系统

在此之前,请先安装Elasticsearch并启动一、下载安装包并解压安装https://www.elastic.co/downloads/kibanaterminal进入Kibana安装目录,通过.\bin\kibana.bat指令启动 二、配置后登录Kibana页面 启动成功,访问http://localhost:5601/,页面会要求你填入EnrollmentToken(此…

【Maya 2025软件下载与安装教程 含补丁】

1、安装包 「maya2025」: 链接:https://pan.quark.cn/s/de0d9d452470 提取码:Rhjp 「maya2024」: 链接:https://pan.quark.cn/s/887e52b68f51 提取码:jvyp 「maya2023」: 链接:https://pan.quark.cn/s/71f46b3d26e5 提取码:b6mA 「maya2020」: 链接:https://pan.qua…

Prometheus + Grafana 监控平台搭建

1、下载 prometheus和node_exporter:https://prometheus.io/download/ 下载完后上传到服务器解压 tar -zxvf prometheus-3.0.0-rc.1.linux-amd64.tar.gztar -zxvf node_exporter-1.8.2.linux-amd64.tar.gz2、启动 node_exporter nohup ./node_exporter --web.listen-address…

阿里云可观测 2024 年 10 月产品动态

阿里云可观测 2024 年 10 月产品动态

题解:CF2025E Card Game

在这 权当卡特兰数的复习题吧。不会卡特兰数的可以先看文末。如果没有花色 \(1\) 这道题就很简单了,对于每个别的花色都有 \(C(m)\) 种分配方案。\(C(n)\) 表示卡特兰数的第 \(n\) 项,答案就是乘起来。 发现除了花色 \(1\) 每种花色的牌都是独立的。这启示我们枚举每种牌用了…

应用网关的演进历程和分类

网关作为互联网流量的入口,其形态也在跟随软件架构持续演进迭代中。我们下面就聊一聊网关的演进历程以及在时下火热的 AI 浪潮下,网关又会迸发怎样新的形态。作者:耿蕾蕾(如葑) 唯一不变的是变化,在现代复杂的商业环境中,企业的业务形态与规模往往处于不断变化和扩大之中…

Vue网站发布到iis后提示404页面不可访问

vue重定向和跨域配置:https://zhuanlan.zhihu.com/p/5306882511.安装组件:URL Rewrite:https://www.iis.net/downloads/microsoft/url-rewriteApplication Request Routing:https://www.iis.net/downloads/microsoft/application-request-routing2.新建一个web.config 放到…