分布式训练


分布式训练

数据并行(DP & DDP)

DataParallel

image-20240327152041750

DP 是较简单的一种数据并行方式,直接将模型复制到多个 GPU 上并行计算,每个 GPU 计算 batch 中的一部分数据,各自完成前向和反向后,将梯度汇总到主 GPU 上。其基本流程:

  1. 加载模型、数据至内存;
  2. 创建 DP 模型;
  3. DP 模型的 forward 过程:
    1. 一个 batch 的数据均分到不同 device 上;
    2. 为每个 device 复制一份模型;
    3. 至此,每个 device 上有模型和一份数据,并行进行前向传播;
    4. 收集各个 device 上的输出;
  4. 每个 device 上的模型反向传播后,收集梯度到主 device 上,更新主 device 上的模型,将模型广播到其他 device 上;
  5. 3-4 循环。

在 DP 中,只有一个主进程,主进程下有多个线程,每个线程管理一个 device 的训练。因此,DP 中内存中只存在一份数据,各个线程间是共享这份数据的。DP 和 Parameter Server 的方式很像。

DistributedDataParallel

  1. 准备阶段

    • 环境初始化:在各张卡上初始化进程并建立进程间通信,对应代码:init_process_group

    • 模型广播:将模型 parameter、buffer 广播到各节点,对应代码:model = DDP(model).to(local_rank)

    • 创建管理器 reducer,给每个参数注册梯度平均 hook。

  2. 准备数据

    • 加载数据集,创建适用于分布式场景的数据采样器,以防不同节点使用的数据重叠。
  3. 训练阶段

    • 前向传播

      • 同步各进程状态(parameter 和 buffer);
      • 当 DDP 参数 find_unused_parametertrue 时,其会在 forward 结束时,启动一个回溯,标记未用到的参数,提前将这些设置为 ready
    • 计算梯度

      • reducer 外面:各进程各自开始反向计算梯度;
      • reducer 外面:当某个参数的梯度计算好了,其之前注册的 grad hook 就会触发,在 reducer 里把这个参数的状态标记为 ready
      • reducer 里面:当某个 bucket 的所有参数都是 ready 时,reducer 开始对这个 bucket 的所有参数开始一个异步的 all-reduce 梯度平均操作;
      • reducer 里面:当所有 bucket 的梯度平均都结束后,reducer 把得到的平均梯度正式写入到 parameter.grad 里。
    • 优化器应用梯度更新参数。

DDP 与 DP 的区别

DPDDP
多线程
1. 受到 GIL 的限制
2. 单机工作
多进程
1. 多机多卡
迭代更新传输数据包括 梯度和参数
1. 全程维护 一个 optimizer
2 梯度 汇总到主 GPU, 主 GPU 进行参数更新
3. 主 GPU Broadcast 参数 给其他的 GPU
传输数据包括 梯度
1. 每个进程具有 自己的 optimizer
2. 各进程自己计算梯度
3. Ring All-Reduce 将 梯度 汇总平均
4. 各进程用梯度来独立的更新参数
通信效率通信成本随着 GPU 数量线性增长Ring All-Reduce 通信成本恒定,与 GPU 数量无关

DDP 中由于各进程中的模型,初始参数一致 (初始时刻进行一次 broadcast),而每次用于更新参数的梯度也一致,因此,各进程的模型参数始终保持一致。

TP (Tensor Parallelism)

每个张量都被 水平 分成多个块,因此张量的每个分片都位于其指定的 GPU 上,而不是让整个张量驻留在单个 GPU 上。在处理过程中,每个分片在不同的 GPU 上分别并行处理,结果在步骤结束时同步。

image-20240325202756320

MLP 的并行化:权重 A 矩阵竖着切 B 矩阵横着切 最后 MERGE

  1. 对于输入 X X X,它的行数是批量大小 B B B 乘以序列长度 L L L,列数是隐藏层的宽度即 D D D
    其隐藏层的模块里面其实就是两个全连接层
  2. 假定第一个隐藏层的权重是 A A A ( [ D , D ′ ] [D, D'] [D,D] D ′ D' D 一般是 D D D 的 4 倍),则先做矩阵乘法,然后再接一个激活函数比如 GELU (GELU 类似把 ReLU 的拐点顺滑下)
  3. 假定第二个隐藏层的权重是 B B B ( [ D ′ , D ] [D', D] [D,D]),最终 σ ( X ⋅ A ) B = Y \sigma(X \cdot A) B= Y σ(XA)B=Y
  4. 如果是输入数据比较大,则优先选择做数据并行,即对输入做拆分
    如果是模型本身比较大,则优先选择做模型并行,即对矩阵做拆分:
    1. A A A 按行拆 ( A = [ A 1 A 2 ] A =\left[\begin{matrix} A_1 \\ A_2\end{matrix}\right] A=[A1A2]) , 则相应的 X X X 按列拆,导致的结果是两个 GPU 之间需要通讯。
    2. A A A 按列拆 ( A = [ A 1 , A 2 ] A =\left[\begin{matrix} A_1 , A_2\end{matrix}\right] A=[A1,A2]) ,则相应的 X X X 按行拆,或者在两个 GPU 上都得有一份才行,此时则无需任何额外的通信。
  5. 使用第 2 种拆分方式,通过执行矩阵乘法得到 X A 1 XA_1 XA1 X A n XA_n XAn, 它们可以独立输入 GeLU: [ Y 1 , Y 2 ] = [ GeLU ⁡ ( X A 1 ) , GeLU ⁡ ( X A 2 ) ] \left[Y_{1}, Y_{2}\right]=\left[\operatorname{GeLU}\left(X A_{1}\right), \operatorname{GeLU}\left(X A_{2}\right)\right] [Y1,Y2]=[GeLU(XA1),GeLU(XA2)], 然后再得到 n n n 个输出向量 Y 1 , Y 2 , ⋯ , Y n Y_1, Y_2, ⋯, Y_n Y1,Y2,,Yn
  6. 同理, B B B 按行拆分 ( B = [ B 1 B 2 ] B =\left[\begin{matrix} B_1 \\ B_2\end{matrix}\right] B=[B1B2]) ,通过执行矩阵乘法得到 Y 1 B 1 Y_1B_1 Y1B1 Y n B n Y_nB_n YnBn, 即 n n n 个输出向量 Z 1 , Z 2 , ⋯ , Z n Z_1, Z_2, ⋯, Z_n Z1,Z2,,Zn, 最终 merge 得到完整的 Z Z Z
  7. 通过上述操作,我们可以更新任意深度的 MLP,只需在每个 拆列-拆行 序列之后同步 GPU

Self-Attention 的并行化:各个头各自计算

  1. 对于输入 X X X,它的行数是批量大小 B B B 乘以序列长度 L L L,列数是隐藏层的宽度即 D D D,在自注意力机制中,输入 X X X 会被复制成三份,分别对应为 X X X Q Q Q K K K V V V 向量矩阵。
  2. 对于多头注意力,头的维度为 D / h D/h D/h, 假定 h = 2 h=2 h=2,之后针对每个头中 X X X 输入矩阵中各个单词的 Q Q Q 向量,会与各自上下文的 K K K 向量做缩放点积然后做 softmax 得到一个注意力分数或权重,之后再与 V V V 相乘,得到一个 [ L , D / h ] [L,D/h] [L,D/h] 的输出
  3. 每个头的计算是各自独立并行的,那意味着一个头可以放在 GPU 0 上,另一个头可以放在 GPU 1 上,最后 all reduce 每个头的结果

由于前向和后向传播中每层都有两个 all reduce,因此 TP 需要设备间有非常快速的互联。因此,除非你有一个非常快的网络,否则不建议跨多个节点进行 TP。实际上,如果节点有 4 个 GPU,则最高 TP 度设为 4 比较好。如果需要 TP 度为 8,则需要使用至少有 8 个 GPU 的节点

PP (Pipeline Parallelism)

模型在多个 GPU 上 垂直 (即按层) 拆分,因此只有一个或多个模型层放置在单个 GPU 上。每个 GPU 并行处理流水线的不同阶段,并处理 batch 的一部分数据

image-20240326092738269
  1. 把网络分成 4 块,每一块放在一个 GPU 上,不同的颜色表示不同的 GPU),于是就有了 F0、F1、F2、F3 这 4 个管级的前向路径,然后是 B3、B2、B1、B0 的逆序后向路径。

  2. b 部分表示朴素 PP 方案: 在每个时间点只有一台设备在处理计算逻辑,完成计算后将结果发送给下一台设备。

  3. c 部分是 PP 方法:

    1. PP 引入了一个新的超参数来调整,称为 块 (chunks)。它定义了通过同一管级按顺序发送多少数据块。图中 chunks = 4 \text{chunks} = 4 chunks=4.

    2. GPU 0 在 chunk 0、1、2 和 3 (F0,0、F0,1、F0,2、F0,3) 上执行相同的前向路径,然后等待,等其他 GPU 完成工作后,GPU 0 会再次开始工作,为块 3、2、1 和 0 (B0,3、B0,2、B0,1、B0,0) 执行后向路径。

      请注意,从概念上讲,这与梯度累积 (gradient accumulation steps,GAS) 的意思相同。PyTorch 叫它 ,而 DeepSpeed 叫它 GAS

    3. 因为 块 (chunks),PP 引入了 micro-batches (MBS) 的概念。

      DP 将全局 batch size 拆分为小 batch size,因此如果 DP 度为 4,则全局 batch size 1024 将拆分为 4 个小 batch size,每个小 batch size 为 256 (1024/4)。而如果 块 (或 GAS) 的数量为 32,我们最终得到的 micro batch size 为 8 (256/32)。每个管级一次处理一个 micro batch。
      计算 DP + PP 设置的全局批量大小的公式为: mbs ∗ chunks ∗ dp_degree  ( 8 ∗ 32 ∗ 4 = 1024 ) \text{mbs}*\text{chunks}*\text{dp\_degree }(8*32*4=1024) mbschunksdp_degree (8324=1024)

    4. 将 mini-batch 进一步划分成更小的 micro-batch,同时利用 pipipline 方案,每次处理一个 micro-batch 的数据,得到结果后,将该 micro-batch 的结果发送给下游设备,同时开始处理后一个 micro-batch 的数据,通过这套方案减小设备中的 Bubble(设备空闲的时间称为 Bubble)

<think>好的,用户之前已经询问过Transformer模型中的TPPPDP通信机制,现在他们想进一步了解如何优化这些通信,特别是提到了allgather等操作。需要给出具体的优化方法,并且要有示例。 首先,用户可能是从事大模型训练的研究人员或工程师,遇到了通信瓶颈,想要优化训练效率。他们可能已经尝试过基本的并行策略,但发现通信开销过大,需要更深入的优化技巧。 接下来,需要分析TPPPDP各自的通信特点。TP中的All-Gather和Reduce-Scatter,PP中的点对点通信,DP中的All-Reduce。每个部分的优化策略可能不同,需要分别讨论。 然后,考虑常见的优化方法,比如重叠计算与通信、调整并行策略减少通信量、使用高效的通信库(如NCCL)、量化或压缩通信数据、流水线优化等。需要结合具体示例,让用户更容易理解。 例如,在TP中,可以通过将权重矩阵的切分方向从行改为列,从而减少All-Gather的数据量。或者在PP中,使用梯度累积和微批次来隐藏通信延迟。DP中,可能使用梯度压缩来减少All-Reduce的数据传输量。 还要注意用户提到的allgather,这可能意味着他们对集合通信操作特别关注,需要详细说明如何优化这些操作,比如调整通信组的大小,或者使用分层通信策略。 此外,用户可能需要实际代码示例或配置建议,比如在DeepSpeed或Megatron-LM中的具体配置参数,或者如何调整模型并行度来平衡计算和通信。 需要确保回答结构清晰,分点说明每个优化策略,并给出实际例子。可能还需要比较不同方法的适用场景,帮助用户根据具体情况选择最优方案。 最后,总结混合并行的策略,强调综合使用多种优化方法,并根据模型结构和硬件配置进行调整。确保内容准确,技术细节正确,同时易于理解。</think>以下是大模型训练中通信优化方法及示例的逐步解析: --- ### 一、**通信瓶颈分析** 大模型训练中通信开销主要来自: 1. **张量并行(TP)**:All-Gather/Reduce-Scatter操作 2. **流水线并行(PP)**:层间激活值和梯度的点对点传输 3. **数据并行(DP)**:All-Reduce同步梯度 4. **混合并行**:多类通信叠加 --- ### 二、**优化策略与示例** #### **1. 张量并行(TP)优化** **问题**:All-Gather操作传输量随隐藏层维度$d$增长 **优化方法**: - **调整切分维度**: 将权重矩阵$W$按列切分而非行切分,减少All-Gather数据量。 *示例*: 原行切分:All-Gather传输$d \times d$张量的$\frac{d}{2} \times d$部分 改为列切分:All-Gather仅传输$d \times \frac{d}{2}$部分,减少50%通信量 - **通信与计算重叠**: 在前向传播中,提前启动All-Gather通信,同时进行非依赖计算。 *代码示例*(伪代码): ```python # 前向传播中的通信重叠 allgather_handle = start_allgather(partial_output) # 异步启动All-Gather compute_local_gradients() # 计算本地梯度 wait(allgather_handle) # 等待通信完成 ``` #### **2. 流水线并行(PP)优化** **问题**:层间激活值传输延迟导致流水线气泡 **优化方法**: - **微批次(Micro-Batching)**: 将单个批次拆分为多个微批次,填充流水线。 *示例*: 若流水线阶段数为4,设置微批次数≥4,使各设备始终处于工作状态。 - **梯度累积优化**: 合并多个微批次的梯度计算,减少通信频率。 *配置示例*: ```bash # DeepSpeed配置片段 "gradient_accumulation_steps": 8 # 累积8个微批次梯度后通信 ``` #### **3. 数据并行(DP)优化** **问题**:All-Reduce同步梯度带宽压力大 **优化方法**: - **梯度压缩**: 使用FP16/FP8精度或Top-K稀疏化压缩梯度。 *示例*: ```python # PyTorch梯度压缩(伪代码) compressed_grad = quantize(grad, dtype=torch.float8) # 8-bit量化 all_reduce(compressed_grad) # 传输压缩后梯度 ``` - **分层All-Reduce**: 将通信分为节点内和节点间两级,减少跨节点流量。 *拓扑示例*: ``` 节点内:4 GPU通过NVLink全连接 → 高速通信 节点间:通过InfiniBand分层聚合 ``` #### **4. 混合并行综合优化** **问题**:TP+PP+DP混合时通信路径冲突 **优化方法**: - **通信优先级调度**: 优先执行小数据量通信(如梯度同步),后执行大数据量通信(如激活值传输)。 *示例*: ``` 1. 先完成DP的All-Reduce(小数据量梯度) 2. 再执行TP的All-Gather(大数据量激活值) ``` - **通信组隔离**: 为TPPPDP分配独立通信组,避免资源竞争。 *Megatron-LM配置示例*: ```python tp_group = torch.distributed.new_group(ranks=[0,1]) # TP通信组 dp_group = torch.distributed.new_group(ranks=[0,2]) # DP通信组 ``` --- ### 三、**关键优化效果对比** | 优化方法 | 通信量减少比例 | 适用场景 | |------------------|----------------|------------------------------| | TP列切分 | 30%~50% | 隐藏层维度$d$较大时 | | 微批次+梯度累积 | 气泡减少70%+ | 流水线阶段数多 | | 梯度8-bit量化 | 通信量减少50% | 带宽受限环境 | | 分层All-Reduce | 跨节点流量降60%| 多节点训练 | --- ### 四、**实战示例:175B参数模型优化** 以训练GPT-3规模模型为例: 1. **并行策略**: - TP=8(单节点内) - PP=4(跨节点) - DP=16(全局) 2. **通信优化配置**: ```yaml # 优化配置 tensor_parallel: split_dim: "column" # 列切分减少All-Gather量 pipeline_parallel: micro_batch_size: 2 # 微批次填充流水线 gradient_accumulation: 4 # 累积4次梯度后通信 data_parallel: hierarchical_allreduce: true # 分层All-Reduce ``` 3. **性能提升**: - 吞吐量提升:2.3倍 - 通信时间占比:从45%降至18% --- ### 五、**通用优化原则** 1. **计算-通信平衡**:确保单个设备计算时间 ≥ 通信时间 2. **带宽敏感操作优先**:优先优化传输量大的通信(如TP的All-Gather) 3. **硬件感知设计**:根据网络拓扑(NVLink/InfiniBand)调整通信策略 通过上述方法,可显著降低大模型训练的通信开销,实际应用中需结合模型结构和硬件环境灵活调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值