下载
中文
注册

启动模型训练

通过配置文件设置资源信息(rank table方案),启动训练任务(单机单卡和单机多卡)

  1. 使用以下命令查看NPU芯片信息,其中{ASCEND_DRIVER_PATH}代表驱动安装路径,{device_id}代表查看NPU加速卡ID,在单机单卡任务中通常使用0号卡,在单机多卡任务中需要依次执行查看NPU的ip地址,命令参考如下。
    {ASCEND_DRIVER_PATH}/tools/hccn_tool -i {device_id} -ip -g

    查询命令返回结果中“ipaddr”即为NPU卡对应的ip地址{device_ip}

  2. 编写“hccl_json_8p.json”文件,根据上一步骤中获取的{device_ip}“hccl_json_8p.json”文件进行配置,并保存。
    单机多卡配置样例参考如下,其中{device_ip}{host_ip}需要根据真实环境配置进行替换,若执行单机单卡则只需在“device”中配置一项。
    {
        "server_count":"1",
        "server_list":[
            {
                "device":[
                    { "device_id":"0", "device_ip":"{device_0_ip}", "rank_id":"0" },
                    { "device_id":"1", "device_ip":"{device_1_ip}", "rank_id":"1" },
                    { "device_id":"2", "device_ip":"{device_2_ip}", "rank_id":"2" },
                    { "device_id":"3", "device_ip":"{device_3_ip}", "rank_id":"3" },
                    { "device_id":"4", "device_ip":"{device_4_ip}", "rank_id":"4" },
                    { "device_id":"5", "device_ip":"{device_5_ip}", "rank_id":"5" },
                    { "device_id":"6", "device_ip":"{device_6_ip}", "rank_id":"6" },
                    { "device_id":"7", "device_ip":"{device_7_ip}", "rank_id":"7" }
                ],
                "server_id":"{host_ip}"
            }
        ],
        "status":"completed",
        "version":"1.0"
    }

    单机单卡配置样例参考如下。

    {
        "server_count":"1",
        "server_list":[
            {
                "device":[
                    { "device_id":"0", "device_ip":"{device_0_ip}", "rank_id":"0" }
                ],
                "server_id":"{host_ip}"
            }
        ],
        "status":"completed",
        "version":"1.0"
    }
  3. 执行如下命令,启动训练任务。
    bash run.sh main.py

    正常开始执行,打印信息参考如下。

    The ranktable solution
    RANK_TABLE_FILE=“/xxx/example/little_demo/hccl_json_8p.json”
    py is main.py
    use horovod to start tasks
    ...

    执行完成,日志信息显示参考如下。

    ASC manager has been destroyed.
    MPI has been destroyed.
    Demo done!

通过环境变量设置资源信息(去rank table方案),启动训练任务(单机单卡和单机多卡)

使用该方案启动训练任务,需要设置如下环境变量。关于环境变量的说明可参见配置环境变量

CM_CHIEF_IP={host_ip}
CM_CHIEF_PORT=60000
CM_CHIEF_DEVICE=0
CM_WORKER_IP={host_ip}
CM_WORKER_SIZE=8
  1. 可选:如果需要自定义卡的数量,需要修改local_rank_size=自定义卡的数量CM_WORKER_SIZE=local_rank_size * 训练节点数
    • 自定义卡的数量≤容器(或进程)中可见的卡的数量。
    • 若是以特权模式启动的容器,容器中可见卡的数量=环境中卡的总数;若是以非特权模式启动的容器,容器中可见卡的数量 = 启动容器时实际挂卡的数量。
    • 若是要进一步控制训练进程中可见卡的数量,可通过环境变量ASCEND_RT_VISIBLE_DEVICES来指定当前容器中可见的卡哪些对当前进程可见。该环境变量通常可指定参与训练的Device。
    • 若是当前进程可见卡的数量为8,支持的自定义卡数量包括1、2、4、8。

    下面的示例以环境中可见8卡为例,卡逻辑ID列表为[0,1,2,3,4,5,6,7]

    • local_rank_size = 1,则export CM_CHIEF_DEVICES = [0,1,2,3,4,5,6,7]的任一卡号。
    • local_rank_size = 2,取值说明如下:
      • 连续用卡:
        • export CM_CHIEF_DEVICES = 0 (表示0、1卡参与训练)
        • export CM_CHIEF_DEVICES = 4 (表示4、5卡参与训练)
      • 非连续用卡:
        • export ASCEND_RT_VISIBLE_DEVICES=[1,3,5,7],此时环境可见卡的逻辑ID列表[1,3,5,7]
        • export CM_CHIEF_DEVICES = 0 (表示1、3卡参与训练)
    • local_rank_size = 4,取值说明如下:
      • export CM_CHIEF_DEVICES = 0 (表示0、1、2、3卡参与训练)
      • export CM_CHIEF_DEVICES = 4 (表示4、5、6、7卡参与训练)
    • local_rank_size = 8,取值说明如下:

      export CM_CHIEF_DEVICES = 0 (表示0、1、2、3、4、5、6、7、8卡参与训练)

  2. 直接在启动命令后传入配置Master节点的Host侦听IP,命令格式如下。
    bash run.sh main.py {host_ip}  
    • 只有在启动命令后传入合法可用的IP地址,才可通过环境变量设置资源信息的方式启动训练任务。
    • 若环境中同时存在资源配置文件,此时不传IP或者IP错误,则会通过资源配置文件的方式,启动训练任务。
    • 若环境中不存在资源配置文件,此时不传IP或者IP错误,系统会提示“the rank table file does not exit”,此时用户可以通过配置资源文件或者传入符合要求的IP后,重新启动训练任务。

    正常开始执行,打印信息参考如下。

    ip: {host_ip} available.
    The ranktable solution is removed.
    CM_CHIEF_IP={host_ip}  
    CM_CHIEF_PORT=60000
    CM_CHIEF_DEVICE=0
    CM_WORKER_IP={host_ip}  
    CM_WORKER_SIZE=8
    ASCEND_VISIBLE_DEVICES=0-8
    py is main.py
    use horovod to start tasks
    ...

    执行完成,日志信息显示参考如下。

    ASC manager has been destroyed.
    MPI has been destroyed.
    Demo done!

多机多卡训练,以双机(单节点8卡)为示例

多机训练的配置的主要步骤为:下载Rec SDK镜像并创建容器后,修改SSH配置并启动服务,然后配置物理机节点之间的免密登录,最后配置little_demo模型,进而拉起训练进程,实现多机训练。双机时可任选一节点为主节点。

前提条件:

  • 双机节点little_demo模型代码路径和配置IP的网卡名称需要保持一致。
  • 已完成集群内的组网配置。详细方法可参见Ascend Training Solution 23.0.0 组网指南》的“组网介绍”章节
  • 已经根据制作Rec SDK训练镜像,制作Rec SDK的训练镜像。
  • 已完成基础集群环境的网络配置检查,例如确认多机节点的NPU device ip能互相ping通,多机节点的NPU device的TLS配置相同等。如果集群通信失败,可参考HCCL集群通信失败解决。
  • 启动容器时需映射宿主机的.ssh文件容器内,使后续配置的免密登录能在容器内生效。文件映射示例:-v /root/.ssh:/root/.ssh
  1. 双机节点创建并配置容器。
    1. 确定节点需要使用的端口号。所有节点都需要用同一未被占用的端口号。可在物理机上执行以下命令,查询端口是否使用。以端口12345为例。
      ss -tuln | grep 12345

      若ss指令不存在需安装iproute软件包。

      • 结果为空,表示端口未使用 => 继续执行1.b
      • 结果不为空,表示端口已使用 => 重复查询其他端口号
    2. 在容器内修改sshd_config文件。
      vi /etc/ssh/sshd_config
      1. 取消“#Port 22”所在行的注释,并将端口号修改为未使用的端口号(如“12345”),便于mpi通过指定端口进入其他节点容器。同时,Host侧防火墙策略中需允许访问该端口。
      2. 可选:取消“#ListenAddress 0.0.0.0”的注释,并将“0.0.0.0”修改为当前节点IP。如果采用导出最新容器镜像并复制到其他环境的方式部署集群环境,在其他节点启动并进入容器后,需手动修改容器内SSH服务侦听IP为对应节点IP。

        如果不执行该步骤,不会影响集群训练,但是会侦听宿主机全零IP的对应端口。出于安全考虑,建议进行修改。

    3. 在容器内执行以下命令,生成SSH host keys启动SSH服务。
      cd /etc/ssh/ && ssh-keygen -A
      /usr/sbin/sshd

      可执行ss -tuln | grep 12345查看侦听端口是否为配置的端口。

      如需停止容器内SSH服务,可在容器内执行:

      kill -9 `ps -ef | grep sshd | grep -v grep | awk '{print $2}'` > /dev/null 2>&1
    4. 设置容器内环境变量。

      将启动训练前需要配置的环境变量设置到容器内的 ~/.bashrc 文件,便于主节点免密登录到其他节点容器内时能直接使用,无需配置环境变量。

      示例如下,按需配置:

      1. 打开“~/.bashrc”文件。
        vi ~/.bashrc
      2. 在文件末尾添加以下内容。
        source /etc/profile
        source /usr/local/Ascend/ascend-toolkit/set_env.sh
        source /usr/local/Ascend/driver/bin/setenv.bash
        source /usr/local/Ascend/tfplugin/set_env.sh
        export PATH=/usr/local/openmpi/bin:$PATH
        export PATH=/usr/local/python3.7.5/bin:$PATH
        export PATH=/usr/local/gcc7.3.0/bin:$PATH
        export LD_LIBRARY_PATH=/usr/local/python3.7.5/lib:$LD_LIBRARY_PATH
        export LD_LIBRARY_PATH=/usr/local/gcc7.3.0/lib64:$LD_LIBRARY_PATH
        export LD_LIBRARY_PATH=/usr/local/openmpi/lib:$LD_LIBRARY_PATH
      3. 按“Esc”键,输入:wq!,按“Enter”保存并退出编辑。
      4. 执行source ~/.bashrc使环境变量配置生效。
  2. 配置little_demo模型。
    1. 使用以下命令查看8卡芯片的device IP,命令参考如下。
      for i in {0..7}; do hccn_tool -i $i -ip -g ; done
    2. 配置资源信息。
      • ranktable方式启动时,所有节点中均需要“hccl_json_16p_2_host.json”配置文件,且文件内容一样。“hccl_json_16p_2_host.json”文件配置样例参考如下。

        示例为双机节点“hccl_json_16p_2_host.json”配置,主节点的device信息需配置在第一个device中。{device_ip}和{host_ip}需要根据真实环境配置进行替换,rank_id需要一直升序。

        {
            "server_count":"2",
            "server_list":[
                {
                    "device":[
                        { "device_id":"0", "device_ip":"{device_0_ip}", "rank_id":"0" },
                        { "device_id":"1", "device_ip":"{device_1_ip}", "rank_id":"1" },
                        { "device_id":"2", "device_ip":"{device_2_ip}", "rank_id":"2" },
                        { "device_id":"3", "device_ip":"{device_3_ip}", "rank_id":"3" },
                        { "device_id":"4", "device_ip":"{device_4_ip}", "rank_id":"4" },
                        { "device_id":"5", "device_ip":"{device_5_ip}", "rank_id":"5" },
                        { "device_id":"6", "device_ip":"{device_6_ip}", "rank_id":"6" },
                        { "device_id":"7", "device_ip":"{device_7_ip}", "rank_id":"7" }
                    ],
                    "server_id":"{host_1_ip}"
                },
                {
                    "device":[
                        { "device_id":"0", "device_ip":"{device_8_ip}", "rank_id":"8" },
                        { "device_id":"1", "device_ip":"{device_9_ip}", "rank_id":"9" },
                        { "device_id":"2", "device_ip":"{device_10_ip}", "rank_id":"10" },
                        { "device_id":"3", "device_ip":"{device_11_ip}", "rank_id":"11" },
                        { "device_id":"4", "device_ip":"{device_12_ip}", "rank_id":"12" },
                        { "device_id":"5", "device_ip":"{device_13_ip}", "rank_id":"13" },
                        { "device_id":"6", "device_ip":"{device_14_ip}", "rank_id":"14" },
                        { "device_id":"7", "device_ip":"{device_15_ip}", "rank_id":"15" }
                    ],
                    "server_id":"{host_2_ip}"
                }
            ],
            "status":"completed",
            "version":"1.0"
        }
      • no ranktable启动时,不需要配置hccl json文件,但需要在所有备节点little_demo模型代码的main.py中手动设置环境变量,修改如下:
        在main.py顶部import os的下一行添加如下代码:
        # no ranktable时设置CM_WORKER_IP环境变量为当前节点ip,{host_ip}为当前节点ip。
        if not os.getenv("RANK_TABLE_FILE", ""):
            os.environ['CM_WORKER_IP'] = "{host_ip}"
    3. 修改run.sh脚本(仅需修改主节点)。
      1. num_server修改为实际节点数(比如2)。
      2. 删除mpi_args变量值中的“-mca btl_tcp_if_exclude docker0”字符串。
      3. “interface”的值修改为配置当前host ip的网卡名。可通过ip addr进行查询。
      4. 使用ranktable启动方案时,还需修改export RANK_TABLE_FILE变量值中的json文件名称,使其与•ranktable方式启动时,所有节点中均需要...中配置的双机的hccl json文件名一致,例如:
        export RANK_TABLE_FILE="${cur_path}/hccl_json_${local_rank_size}p.json"

        修改为:

        export RANK_TABLE_FILE="${cur_path}/hccl_json_16p_2_host.json"  
      5. 通过horovodrun启动指令指定端口号并修改host参数,修改如下内容:

        在run.sh脚本末尾,将

        xxx --mpi-args "${mpi_args}" --mpi -H localhost:${local_rank_size} 

        修改为:

        xxx --mpi-args "${mpi_args}" -p 12345 --mpi -H {host_1_ip}:8,{host_2_ip}:8
        • -p 12345:容器内ssh server侦听端口号。
        • 8 : 单节点参与训练的device数。
  3. 在每个节点上互相设置免密登录。
    1. 在每个节点执行以下命令,设置免密登录。其中{target_host_user}为对端节点的用户名,{target_host_ip}为对端节点的IP。
      ssh-copy-id -i ~/.ssh/id_rsa.pub {target_host_user}@{target_host_ip}

      若提示没有id_rsa.pub,可使用如下命令生成:

      ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
    2. 检查免密登录是否设置成功。
      ssh-keygen -R {target_host_ip}  # 删除当前节点中目标ip的host key缓存
      ssh-keygen -R "[{target_host_ip}]:12345"  # 删除当前host上保存的目标ip对应端口的host key缓存
      ssh {target_host_user}@{target_host_ip}   # 验证免密登录目标ip
      ssh {target_host_user}@{target_host_ip} -p 12345  # 验证免密登录目标ip指定端口
  4. 在主节点执行以下命令,拉起模型。只需要在主节点拉起即可,备节点不需要手动拉起训练任务,mpi会自动跳转过去拉起训练任务。
    • rank table模式:
      bash run.sh main.py
    • 去rank table模式,其中{host_1_ip}为主节点IP。
      bash run.sh main.py {host_1_ip}