[源码解析] 模型并行分布式训练 Megatron (4) --- 如何设置各种并行

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475

[源码解析] 模型并行分布式训练 Megatron (4) — 如何设置各种并行

目录* [源码解析] 模型并行分布式训练 Megatron (4) — 如何设置各种并行
+ 0x00 摘要
+ 0x01 前文回顾
+ 0x02 初始化
- 2.1 全局变量
- 2.2 初始化代码
+ 0x03 切分样例
- 3.1 注释
- 3.2 切分情况
- 3.3 切分策略
- 3.4 实验
+ 0x04 起始状态
- 4.1 GPU 状况
- 4.2 符号说明
- 4.3 初始分组
+ 0x05 Tensor model-parallel
- 5.1 分组
- 5.2 使用
+ 0x06 Pipe-parallel
- 6.1 分组
- 6.2 使用
* 6.2.1 上下游rank
* 6.2.2 world size
+ 0x07 Data-parallel
- 7.1 分组
- 7.2 如何使用
+ 0x08 模型组
+ 0x09 如何把模型分到GPU
+ 0xFF 参考

0x00 摘要

NVIDIA Megatron 是一个基于 PyTorch 的分布式训练框架,用来训练超大Transformer语言模型,其通过综合应用了数据并行,Tensor并行和Pipeline并行来复现 GPT3,值得我们深入分析其背后机理。

本系列大概有 5 篇文章,通过论文和源码和大家一起学习研究。本文将看看 Megatron 如何处理设置并行。

本系列其他文章为:

[源码解析] 模型并行分布式训练Megatron (1) — 论文 & 基础

[源码解析] 模型并行分布式训练Megatron (2) — 整体架构

[源码解析] 模型并行分布式训练 Megatron (3) —模型并行实现

0x01 前文回顾

前文我们对模型并行的原理和代码进行了分析,对于给定的模型,现在还需要解决几个问题:

  • 如何把模型切分给节点,比如哪个节点负责哪些层。
  • 数据并行,模型并行,流水线并行这几种并行之中,每个节点分别属于哪个部分?
  • 如何避免流水线带来的问题。

我们接下来就仔细分析一下。

0x02 初始化

initialize_model_parallel 方法用来设置模型并行,所以我们接下来就具体分析。

2.1 全局变量

因为前文_initialize_distributed之中调用了torch.distributed.init_process_group 初始化分布式环境,所以我们知道,每个进程都有自己的 gloabl rank 和 local rank,都有自己的全局变量。

主要变量如下(具体例子可以结合 initialize_model_parallel 之中的注释来看):

  • _TENSOR_MODEL_PARALLEL_GROUP :当前 rank 所属于的Intra-layer model parallel group,就是tensor 并行进程组。
    • 假如每一层分为两个tensor,则 _TENSOR_MODEL_PARALLEL_GROUP 例子为:[g0, g1], [g2, g3], [g4, g5], [g6, g7], [g8, g9], [g10, g11], [g12, g13], [g14, g15]。
  • _PIPELINE_MODEL_PARALLEL_GROUP :当前 rank 所属于的Intra-layer model parallel group,就是流水线进程组。
    • 假如流水线深度为4,则例子为 [g0, g4, g8, g12], [g1, g5, g9, g13], [g2, g6, g10, g14], [g3, g7, g11, g15]。
  • _MODEL_PARALLEL_GROUP :当前 rank 所属于的模型并行进程组,包括了以上两组。
    • 针对我们例子,就是完整模型被复制了两份,其 GPU 节点具体是[0, 1, 4, 5, 8, 9, 12, 13],[2, 3, 6, 7, 10, 11, 14, 15]
  • _EMBEDDING_GROUP : 嵌入对应的进程组。
  • _DATA_PARALLEL_GROUP :当前 rank 所属于的Data parallel group。
    • 假如数据并行度数为2,则例子为[g0, g2], [g1, g3], [g4, g6], [g5, g7], [g8, g10], [g9, g11], [g12, g14], [g13, g15]。

具体如下:

# Intra-layer model parallel group that the current rank belongs to.
_TENSOR_MODEL_PARALLEL_GROUP = None
# Inter-layer model parallel group that the current rank belongs to.
_PIPELINE_MODEL_PARALLEL_GROUP = None
# Model parallel group (both intra- and pipeline) that the current rank belongs to.
_MODEL_PARALLEL_GROUP = None
# Embedding group.
_EMBEDDING_GROUP = None
# Data parallel group that the current rank belongs to.
_DATA_PARALLEL_GROUP = None

_VIRTUAL_PIPELINE_MODEL_PARALLEL_RANK = None
_VIRTUAL_PIPELINE_MODEL_PARALLEL_WORLD_SIZE = None
_PIPELINE_MODEL_PARALLEL_SPLIT_RANK = None

# These values enable us to change the mpu sizes on the fly.
_MPU_TENSOR_MODEL_PARALLEL_WORLD_SIZE = None
_MPU_PIPELINE_MODEL_PARALLEL_WORLD_SIZE = None
_MPU_TENSOR_MODEL_PARALLEL_RANK = None
_MPU_PIPELINE_MODEL_PARALLEL_RANK = None

# A list of ranks that have a copy of the embedding.
_EMBEDDING_GLOBAL_RANKS = None

# A list of global ranks for each pipeline group to ease calculation of the source
# rank when broadcasting from the first or last pipeline stage.
_PIPELINE_GLOBAL_RANKS = None

2.2 初始化代码

我们首先把 initialize_model_parallel 代码摘录出来。initialize_model_parallel 作用就是对模型进行分组,然后初始化进程组相关的各种全局变量。

def initialize\_model\_parallel(tensor\_model\_parallel\_size\_=1,
 pipeline\_model\_parallel\_size\_=1,
 virtual\_pipeline\_model\_parallel\_size\_=None,
 pipeline\_model\_parallel\_split\_rank\_=None):
    """
 Initialize model data parallel groups.

 Arguments:
 tensor\_model\_parallel\_size: number of GPUs used for tensor model parallelism.
 pipeline\_model\_parallel\_size: number of GPUs used for pipeline model parallelism.
 virtual\_pipeline\_model\_parallel\_size: number of virtual stages (interleaved
 pipeline).
 pipeline\_model\_parallel\_split\_rank: for models with both encoder and decoder,
 rank in pipeline with split point.


 Let's say we have a total of 16 GPUs denoted by g0 ... g15 and we
 use 2 GPUs to parallelize the model tensor, and 4 GPUs to parallelize
 the model pipeline. The present function will
 create 8 tensor model-parallel groups, 4 pipeline model-parallel groups
 and 8 data-parallel groups as:
 8 data\_parallel groups:
 [g0, g2], [g1, g3], [g4, g6], [g5, g7], [g8, g10], [g9, g11], [g12, g14], [g13, g15]
 8 tensor model-parallel groups:
 [g0, g1], [g2, g3], [g4, g5], [g6, g7], [g8, g9], [g10, g11], [g12, g13], [g14, g15]
 4 pipeline model-parallel groups:
 [g0, g4, g8, g12], [g1, g5, g9, g13], [g2, g6, g10, g14], [g3, g7, g11, g15]
 Note that for efficiency, the caller should make sure adjacent ranks
 are on the same DGX box. For example if we are using 2 DGX-1 boxes
 with a total of 16 GPUs, rank 0 to 7 belong to the first box and
 ranks 8 to 15 belong to the second box.
 """
    if torch.distributed.get_rank() == 0:
        print('> initializing tensor model parallel with size {}'.format(
            tensor_model_parallel_size_))
        print('> initializing pipeline model parallel with size {}'.format(
            pipeline_model_parallel_size_))
    # Get world size and rank. Ensure some consistencies.
    world_size = torch.distributed.get_world_size()
    tensor_model_parallel_size = min(tensor_model_parallel_size_, world_size)
    pipeline_model_parallel_size = min(pipeline_model_parallel_size_, world_size)
    ensure_divisibility(world_size,
                        tensor_model_parallel_size * pipeline_model_parallel_size)
    data_parallel_size = world_size // (tensor_model_parallel_size *
                                        pipeline_model_parallel_size)

    num_tensor_model_parallel_groups = world_size // tensor_model_parallel_size
    num_pipeline_model_parallel_groups = world_size // pipeline_model_parallel_size
    num_data_parallel_groups = world_size // data_parallel_size

    if virtual_pipeline_model_parallel_size_ is not None:
        global _VIRTUAL_PIPELINE_MODEL_PARALLEL_RANK
        global _VIRTUAL_PIPELINE_MODEL_PARALLEL_WORLD_SIZE
        _VIRTUAL_PIPELINE_MODEL_PARALLEL_RANK = 0
        _VIRTUAL_PIPELINE_MODEL_PARALLEL_WORLD_SIZE = virtual_pipeline_model_parallel_size_

    if pipeline_model_parallel_split_rank_ is not None:
        global _PIPELINE_MODEL_PARALLEL_SPLIT_RANK
       
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DeepSpeed命令参数是指在启动容器时使用的命令参数,用于配置DeepSpeed库和Megatron-Deepspeed的相关设置。根据引用的内容,以下是DeepSpeed命令参数的解释: - -d: 启用后台模式 (detached mode),容器将在后台运行。 - -t: 分配一个伪终端 (pseudo-TTY),使得用户可以与容器进行交互。 - --network=host: 使用主机网络模式,容器将共享主机的网络命名空间。 - --gpus all: 分配所有可用的GPU给容器使用。 - --privileged: 赋予容器完全的特权,使其可以访问主机的设备。 - --ipc=host: 使用与主机共享的IPC命名空间,用于进程间通信。 - --ulimit memlock=-1: 设置内存锁定的限制为无限制,以防止内存被交换出去。 - --ulimit stack=67108864: 设置栈的限制为67108864字节,用于控制进程的栈空间。 - --name megatron-deepspeed: 为容器指定一个名称。 - -v /etc/localtime:/etc/localtime: 将主机的时区信息挂载到容器内部,以保持时间同步。 - -v /root/.ssh:/root/.ssh: 将主机的SSH配置目录挂载到容器内部,以便容器可以访问SSH密钥。 - nvcr.io/nvidia/pytorch:21.10-py3: 指定使用的Docker镜像,这里使用了nvcr.io/nvidia/pytorch的21.10-py3版本。 综上所述,以上是DeepSpeed命令参数的解释。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [阿里云AIGC- 使用Megatron-Deepspeed训练GPT-2并生成文本](https://blog.csdn.net/qq_39970492/article/details/131090026)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值