You need to enable JavaScript to run this app.
导航

HPC-制作RDMA容器镜像

最近更新时间2024.01.26 18:11:07

首次发布时间2023.01.09 19:30:33

搭建训练环境时,可能需要使用容器镜像,本文介绍如何在高性能计算GPU实例(即HPC实例)搭建容器镜像。您也可以参考本文检查您现有的容器镜像是否符合要求。

前提条件

  • 本文HPC实例的镜像以 Ubuntu 20.04 64位(RDMA) 为例,您也可以任选其他RDMA镜像。
  • 您已购买 高性能计算GPU型hpcpni2实例 且绑定了公网IP,具体操作请参见购买高性能计算GPU型实例

第一步:安装Docker

  1. 登录HPC GPU实例,具体操作请参见登录Linux实例

  2. 添加docker源。

    1. 执行vim docker.list命令,创建docker.list文件。
    2. 在文件中添加docker源。
      echo "deb [arch=amd64] http://mirrors.ivolces.com/docker/linux/debian `lsb_release -cs` stable" | sudo tee /etc/apt/sources.list.d/docker.list
      
    3. Esc退出编辑模式,输入:wq并按下Enter键,保存并退出文件。
  3. 依次执行以下命令,安装docker源的公钥。

    curl -fsSL http://mirrors.ivolces.com/docker/linux/debian/gpg | sudo apt-key add -
    apt-get update
    apt-get install -y docker-ce docker-ce-cli containerd.io
    
  4. 执行以下命令,查看docker版本。
    docker -v

  5. 依次执行以下命令,安装docker-ce与NVIDIA Container Toolkit。

    apt update && apt install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
    curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
    distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
    curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
    apt update
    apt install -y nvidia-docker2 #安装nvidia-docker2容器
    systemctl daemon-reload
    systemctl restart docker #重启docker容器
    
  6. 执行nvidia-docker -v命令,检查docker是否安装成功,回显如下,表示安装成功。

    Docker version 20.10.12, build 20.10.12-0ubuntu2~20.04.1
    

第二步:容器环境配置

制作新镜像通常以原有镜像或容器为基础,此处以“Nvidia在NGC提供的CUDA基础镜像生成的容器”为例,展示在此容器的基础上,如何增加RDMA相关环境。

  1. 在HPC实例上,依次执行以下命令,下载CUDA镜像,启动并进入容器。

    说明

    执行第二步命令启动容器时,需要将HPC实例上的virtualTopology.xml文件挂载至容器中。

    docker pull nvcr.io/nvidia/cuda:12.0.0-devel-ubuntu20.04
    nvidia-docker run --gpus all -it -v /run/nvidia-topologyd/virtualTopology.xml:/run/nvidia-topologyd/virtualTopology.xml:ro nvcr.io/nvidia/cuda:12.0.0-devel-ubuntu20.04 bash
    
  2. 在容器中,执行以下命令安装所需软件包。
    apt update && apt install -y infiniband-diags openssh-server locate wget vim
    回显如下时,输入“6”。
    alt
    回显如下时,输入“19”,等待执行完成。
    alt

  3. 在容器中,执行ibstatus 命令查看网卡速率,回显如下,本例中网卡速率为200Gb/s。
    alt

  4. 在容器中,执行以下命令,安装RDMA相关库。
    apt update && apt install -y perftest ibverbs-providers libibumad3 libibverbs1 libnl-3-200 libnl-route-3-200 librdmacm1

  5. 在容器中,执行以下命令,检查RDMA相关库安装情况。
    dpkg -l perftest ibverbs-providers libibumad3 libibverbs1 libnl-3-200 libnl-route-3-200 librdmacm1
    回显如下,表示安装成功。
    alt

  6. 在容器中,执行以下命令,检查RDMA网卡是否可以正常在容器中使用。
    ib_write_bw
    回显如下,表示可以正常使用。
    alt

  7. 在容器中,执行以下命令,检查CUDA是否安装。
    nvcc -V
    回显如下,说明CUDA正常安装,版本为12.0。
    alt

  8. 选择NCCL版本并安装。如果您的容器中已包含NCCL,可以跳过本步骤。

    1. 访问Nvidia官网根据您的需求及容器中CUDA的版本确定NCCL的版本,该网站需要登录您的nvidia开发者账号。
      alt
    2. 单击上图红框部分,展开安装指导详情,查看对应镜像的安装命令。
      alt
    3. 在容器中,执行以下命令安装NCCL,<nccl_version>是确定的NCCL版本号,<cuda_version>是CUDA的版本号
      apt install libnccl2=<nccl_version>+cuda<cuda_version> libnccl-dev=<nccl_version>+cuda<cuda_version>
      本例为:apt install libnccl2=2.16.2-1+cuda12.0 libnccl-dev=2.16.2-1+cuda12.0
    4. 依次执行以下命令,检查NCCL安装是否正常。
      updatedb
      locate nccl| grep "libnccl.so" | tail -n1 | sed -r 's/^.*\.so\.//'
      
      回显如下,表示已正常安装。
      2.16.2
      
  9. 安装OpenMPI。如果您的容器中已包含OpenMPI,可以跳过本步骤。

    1. 在容器中,依次执行以下命令。
      cd ~
      wget https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.4.tar.bz2
      tar xf openmpi-4.1.4.tar.bz2
      cd openmpi-4.1.4
      ./configure --prefix=/usr/local/openmpi 2>&1 | tee config.out
      make -j 80 all 2>&1 | tee make.out
      make install 2>&1 | tee install.out
      sed -i '1i\export PATH=/usr/local/openmpi/bin:$PATH' ~/.bashrc
      source ~/.bashrc
      
    2. 执行以下命令,检查OpenMPI是否正常安装。
      mpiexec --version
      回显如下,表示已正常安装。
      alt
  10. 安装NCCL Tests。

    1. 在容器中,执行以下命令。
      cd ~
      wget https://github.com/NVIDIA/nccl-tests/archive/refs/tags/v2.10.1.tar.gz
      tar -zxvf v2.10.1.tar.gz
      cd nccl-tests-2.10.1
      make -j40 MPI=1  MPI_HOME=/usr/local/openmpi CUDA_HOME=/usr/local/cuda NCCL_HOME=/usr/lib/x86_64-linux-gnu
      sed -i '1i\export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/x86_64-linux-gnu:/usr/local/openmpi/lib:$LD_LIBRARY_PATH' ~/.bashrc
      source ~/.bashrc
      
    2. 执行以下命令,检查NCCL Tests是否安装正常。
      ./build/all_reduce_perf -b 256M -e 8G -f 2 -g 8 -n 100 -w 20
      回显如下,说明已正常安装,本例中单机平均带宽为230GB/s。
      alt

第三步:制作镜像

本步骤为您提供了以下两种方式制作镜像,您按需任选一种方式即可。

方式一:docker commit

您可以通过容器制作新的镜像。

  1. 在容器中,执行exit退出到HPC实例,在实例中执行docker ps -a命令查询容器ID。
    alt

  2. 在实例中,执行以下命令制作镜像,<CONTAINER ID>为检查到的容器ID,[镜像名称][镜像版本号]可按需配置。
    docker commit <CONTAINER ID> [镜像名称]:[镜像版本号]
    回显如下,表示镜像制作成功。
    alt

  3. 执行以下命令,查询容器镜像ID。
    docker images
    回显如下,请记录镜像ID。
    alt

方式二:docker build

您可以直接编写Dockerfile文件,通过原镜像制作新的镜像。

  1. 在HPC实例中,依次执行以下命令编写Dockerfile。

    cd ~
    mkdir myimage
    vim myimage/Dockerfile
    
  2. i,进入编辑模式,输入以下内容。

    FROM nvcr.io/nvidia/cuda:12.0.0-devel-ubuntu20.04
    
    # install all libs
    RUN apt-get update && apt-get install -y --allow-downgrades --allow-change-held-packages --no-install-recommends infiniband-diags openssh-server wget vim libnccl2=2.16.2-1+cuda12.0 libnccl-dev=2.16.2-1+cuda12.0 perftest ibverbs-providers libibumad3 libibverbs1 libnl-3-200 libnl-route-3-200 librdmacm1
    
    # install openmpi
    RUN wget https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.4.tar.bz2 && tar xf openmpi-4.1.4.tar.bz2 && cd openmpi-4.1.4 && ./configure --prefix=/usr/local/openmpi 2>&1 | tee config.out && make -j 80 all 2>&1 | tee make.out && make install 2>&1 | tee install.out && cd .. && rm -rf openmpi*
    
    # install nccl-tests
    RUN cd ~ && wget https://github.com/NVIDIA/nccl-tests/archive/refs/tags/v2.10.1.tar.gz && tar -zxvf v2.10.1.tar.gz && cd nccl-tests-2.10.1 && make -j40 MPI=1  MPI_HOME=/usr/local/openmpi CUDA_HOME=/usr/local/cuda NCCL_HOME=/usr/lib/x86_64-linux-gnu
    
    # add env
    RUN sed -i '1i\export PATH=/usr/local/openmpi/bin:$PATH' ~/.bashrc && sed -i '1i\export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/x86_64-linux-gnu:/usr/local/openmpi/lib:$LD_LIBRARY_PATH' ~/.bashrc && mkdir /run/nvidia-topologyd && mkdir ~/.ssh
    
  3. Esc退出编辑模式,输入:wq并按下Enter键,保存并退出文件。

  4. 执行以下命令,构建容器镜像。请替换[镜像名称][镜像版本号]为待构建的镜像信息。
    docker build [镜像名称]/ -t [镜像名称]:[镜像版本号]

  5. 执行以下命令,查询容器镜像ID。
    docker images
    回显如下,请记录镜像ID。
    alt

第四步:上传镜像

本步骤为您提供了以下两种方式上传镜像,您按需任选一种方式即可。

方式一:上传到火山引擎镜像仓库

您可以将镜像上传到火山引擎的镜像仓库,操作步骤请参考推送和拉取镜像

方式二:上传到docker hub

您可以按照如下步骤将镜像上传到docker hub您自己的repo下。

  1. 访问Dockerhub官网,注册或登录您的docker hub账号。
  2. 执行命令docker login在HPC实例上登录您的docker账号,该命令要求输入您的docker hub账号密码。
  3. 执行以下命令对您刚才制作的镜像设置tag,<YOUR_DOCKERHUB_NAME>为您的docker hub用户名,[镜像名称][镜像版本号]为待上传的镜像信息。
    docker tag myimage:1.1 <YOUR_DOCKERHUB_NAME>/[镜像名称]:[镜像版本号]
  4. 执行以下命令,推送镜像文件。
    docker push <YOUR_DOCKERHUB_NAME>/[镜像名称]:[镜像版本号]

第五步:多实例集合通信能力测试

使用两台高性能计算GPU型实例对已制作的容器镜像进行集合通信能力测试。集合通信能力是介于网络带宽和AI训练场景间的一个评价通信能力的指标。

  1. 参考购买高性能计算GPU型实例创建两台hpcpni2实例A和B。

  2. 在A和B实例上参考安装Docker完成docker,并安装制作好的镜像。

    • 如果您在步骤四中将镜像上传到了火山引擎镜像仓库,请参考拉取镜像完成操作。
    • 如果您在步骤四中将镜像上传到了docker hub,请执行以下命令安装。<YOUR_DOCKERHUB_NAME>为您的docker hub用户名,[镜像名称][镜像版本号]为待安装的镜像信息。
      docker pull <YOUR_DOCKERHUB_NAME>/[镜像名称]:[镜像版本号]
  3. 在A和B实例上分别执行如下命令启动容器。<IMAGE ID>为容器镜像ID。

    说明

    如果您的实例为火山引擎自研最新DPU架构,即第三代实例规格,则无需执行以下命令的-v及以后部分。

    nvidia-docker run --gpus all --network host --ipc host --privileged -it -v /run/nvidia-topologyd/virtualTopology.xml:/run/nvidia-topologyd/virtualTopology.xml:ro <IMAGE ID> bash

  4. 在B实例的容器中,执行以下操作:

    1. 执行vim /etc/ssh/sshd_config命令,按“i”修改以下配置后,按Esc退出编辑模式,输入:wq并按下Enter键,保存并退出文件。
      Port 2222
      PermitRootLogin yes
      
    2. 执行/etc/init.d/ssh restart命令重启ssh服务器。
    3. 执行passwd命令设置root登录密码。
  5. 在A和B实例的容器中,分别执行如下命令,启动SSH。

    ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
    chmod 600 ~/.ssh/id_rsa	
    
  6. 在A实例的容器中,执行以下命令,配置向B实例容器的互信登陆,该命令需要您输入刚才为B实例的容器设置的密码。

    scp -P2222 ~/.ssh/id_rsa.pub root@192.XX.XX.205:~/.ssh/authorized_keys #root@后需替换为B实例的私网IP地址
    
  7. 在A实例的容器中,执行以下命令查看集群性能,请确认实例A已放通端口号2222,两个host IP需替换为A和B实例VPC主网卡(eth0)的IP。

    mpirun --oversubscribe --allow-run-as-root -mca plm_rsh_args "-p 2222 -q -o StrictHostKeyChecking=no" \
    	-n 16 -N 8 -H 192.xxx.xxx.111:1,192.xxx.xxx.104:1 \
    	-bind-to socket -map-by slot -mca pml ob1 -mca btl ^openib -mca orte_base_help_aggregate 0 \
    	-mca btl_tcp_if_include eth0 -mca coll_hcoll_enable 0 -x NCCL_DEBUG=INFO -x NCCL_PXN_DISABLE=1 \
    	-x NCCL_SOCKET_IFNAME=eth0 -x NCCL_IB_DISABLE=0 -x NCCL_NET_GDR_LEVEL=1 -x NCCL_IB_HCA=mlx5_1:1,mlx5_2:1,mlx5_3:1,mlx5_4:1 -x NCCL_IB_GID_INDEX=3 \ 
    	~/nccl-tests-2.10.1/build/all_reduce_perf -b 256M -e 1G -f 2 -g 1 -c 1 -n 100
    

    回显如下,A和B实例集合通信Allreduce的带宽为97GB/s,该指标可以代表系统的通信能力。

    alt