# 使用Ubuntu 20.04系统安装CUDA相关软件（PyTorch+CPU/GPU）
在ModelArts中使用自定义镜像前，需在ECS服务器上以ModelArts官方镜像或第三方镜像为基础编写Dockerfile，构建镜像、推送到容器镜像服务SWR、注册到ModelArts，最后创建Notebook验证。
本文以Ubuntu 20.04系统的ECS为例，介绍安装CUDA相关软件（PyTorch+CPU/GPU）并构建Notebook自定义镜像的完整流程。
#### 前提条件
在使用ModelArts前，需完成华为云账号注册、实名认证及相关权限授权。具体操作，请参见[一、前置准备：账号与权限](https://support.huaweicloud.com/qs-modelarts/modelarts_06_0006.html)。
#### 计费说明
本操作涉及ECS、SWR和Notebook费用，完成后请及时释放资源以避免持续计费。计费详情请参见[ECS计费](https://support.huaweicloud.com/price-ecs/ecs_billing_3000.html)、[SWR计费](https://support.huaweicloud.com/productdesc-swr/swr_03_0001.html#section3)和[Notebook计费](https://support.huaweicloud.com/price-modelarts/price-modelarts-0010.html)。
#### Notebook自定义镜像规范约束
制作自定义镜像时，基础镜像需满足如下规范：
- 基于NVIDIA官网、Docker Hub官网等官方开源镜像制作，开源镜像需满足如下操作系统约束： X86：Ubuntu 22.04、Ubuntu 20.04
  
- CUDA包建议安装12.0及以上版本，本文以ubuntu20.04-cuda12.4版本为例，详情请参见[NVIDIA官网](https://developer.download.nvidia.cn/compute/cuda/repos/ubuntu2004)。
- Dockerfile中需包含ma-user相关配置和ipykernel依赖包，否则无法使用Notebook相关功能。
  ![](https://support.huaweicloud.com/docker-modelarts/public_sys-resources/note_3.0-zh-cn.png)
  ma-user是ModelArts Notebook运行时的系统用户，镜像中需预置该用户及目录权限。
  
- 如果镜像内存在Jupyter静态文件，可能导致Notebook页面打开异常，请执行jupyter --path命令查看相关目录，并清理列出的目录中的静态文件。
- 训练调试模式场景：需保证curl命令存在。
 
#### 自定义镜像构建流程
![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002763296817.png)
1. 准备一台Linux服务器，本文以ECS服务器为例。
2. 在ECS中构建自定义镜像（本文提供Dockerfile样例文件）。
3. 将构建的镜像推送到SWR。
4. 注册SWR镜像到ModelArts。
5. 创建Notebook并验证新镜像。
 
#### 步骤一：准备ECS服务器并配置环境信息
在弹性云服务器（ECS）控制台购买一台X86架构的Ubuntu系统服务器，并配置弹性公网IP。
1. 登录[ECS控制台](https://console.huaweicloud.com/ecm/)，在"弹性云服务器"页面右上角，单击"购买弹性云服务器"。
   本文以自定义购买为例，"CPU架构"选择"x86计算"，"操作系统"选择Ubuntu 20.04或22.04版本，其他参数按需配置。具体操作，请参见[自定义购买ECS](https://support.huaweicloud.com/usermanual-ecs/ecs_03_7002.html)。
   
2. 通过CloudShell或VNC登录ECS。具体操作，请参见[登录Linux ECS](https://support.huaweicloud.com/usermanual-ecs/ecs_03_0134.html)。
3. 在ECS中，执行以下命令，安装Docker并设置开机自启动。
   ```
   wget https://cnnorth4-modelarts-sdk.obs.cn-north-4.myhuaweicloud.com/modelarts/custom-image-build/install_docker_on_ubuntu.sh
   bash install_docker_on_ubuntu.sh
   source /etc/profile
   ```
   安装完成后，执行以下命令，查看Docker运行状态。
   ```
   systemctl status docker
   ```
   如果回显中显示"active (running)"，表示Docker正常运行。
   图1查看Docker运行状态   
   ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002744015053.png "点击放大") 
4. （可选）执行以下命令，查看Docker Engine版本。
   ```
   docker version | grep -A 1 Engine
   ```
   如果回显中显示版本号，表示Docker Engine安装成功。
   图2查看Docker Engine版本   
   ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002714500372.png "点击放大") 
 
#### 步骤二：制作自定义镜像
本节介绍如何通过Dockerfile安装必需软件包，并构建新的Notebook镜像。
- 基础安装包：torchvision、torchaudio、ipykernel、numpy。
- CUDA相关安装包：Miniconda3、CUDA Toolkit。
1. 查询基础镜像，用于编写Dockerfile文件（第三方镜像可跳过此步骤）。 获取ModelArts官方镜像地址，请参见[ModelArts官方镜像](https://support.huaweicloud.com/docker-modelarts/docker-modelarts_6030.html)。
   
2. 连接容器镜像服务。
   1. 登录[容器镜像服务控制台](https://console.huaweicloud.com/swr/)，选择左侧导航栏的"总览"，单击页面右上角的"登录指令"，在弹出的页面中单击复制登录指令。
      登录指令用于完成Docker客户端与SWR之间的鉴权，后续才能push镜像。
      图3获取登录指令   
      ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002743985275.png "点击放大")
      
      ![](https://support.huaweicloud.com/docker-modelarts/public_sys-resources/note_3.0-zh-cn.png)
      按需选择有效时长。如果需要长期有效的登录指令，请参见[获取长期有效登录指令](https://support.huaweicloud.com/usermanual-swr/swr_01_1000.html)。获取了长期有效的登录指令后，在有效期内的临时登录指令仍然可以使用。
      
   
   2. 在安装Docker的服务器中执行上一步复制的登录指令。登录成功会显示"Login Succeeded"。
    
3. 编写容器镜像Dockerfile文件。
   Dockerfile是一个文本文件，包含一系列指令，用于自动构建Docker镜像。通过Dockerfile定义镜像的构建过程，包括基础镜像、安装的软件包、配置文件的复制、环境变量的设置等。
   - ModelArts官方镜像的Dockerfile文件示例（Ubuntu系统）：
     ```
     # ModelArts官方镜像地址，可按需替换
     FROM swr.cn-north-4.myhuaweicloud.com/atelier/pytorch_cuda:pytorch_1.12.1-cuda_10.2-py_3.9.11-ubuntu_20.04-x86_64-20260425154604-d9a1f9f
     ENV DEBIAN_FRONTEND=noninteractive
     USER root
     # section1: 使用标准focal源（x86_64架构）+ 安装系统依赖 + 添加NVIDIA CUDA仓库
     RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
         printf "deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse\n\
         deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted universe multiverse\n\
         deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse\n\
         deb http://security.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse\n" > /etc/apt/sources.list && \
         apt-get update && \
         apt-get install -y zip wget ca-certificates vim python3 python3-pip tzdata gnupg && \
         ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
         dpkg-reconfigure --frontend noninteractive tzdata && \
         apt update && echo Y | apt install openssh-server && \
         wget https://developer.download.nvidia.cn/compute/cuda/repos/ubuntu2004/x86_64/cuda-keyring_1.1-1_all.deb && \
         dpkg -i cuda-keyring_1.1-1_all.deb && \
         rm -f cuda-keyring_1.1-1_all.deb && \
         apt-get update
     RUN rm /bin/sh && ln -s /bin/bash /bin/sh
     # section2: 安装 CUDA toolkit 12.4
     RUN apt-get install -y cuda-toolkit-12-4
     # section3: 设置 CUDA 环境变量
     ENV CUDA_HOME=/usr/local/cuda-12.4
     ENV PATH=${CUDA_HOME}/bin:$PATH
     ENV LD_LIBRARY_PATH=${CUDA_HOME}/lib64:$LD_LIBRARY_PATH
     # section4: 配置 conda、pip 清华镜像源 + 初始化 conda
     RUN mkdir -p /home/ma-user/.pip && \
         echo -e "channels:\nshow_channel_urls: true\ndefault_channels:\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2\nremote_read_timeout: 120" > /home/ma-user/.condarc && \
         echo -e "[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple\n[install]\ntrusted-host = pypi.tuna.tsinghua.edu.cn" > /home/ma-user/.pip/pip.conf && \
         /home/ma-user/anaconda3/bin/conda init bash && \
         source /home/ma-user/anaconda3/bin/activate base && \
         conda config --remove-key channels || true && \
         conda config --append channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main && \
         conda config --append channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r && \
         conda config --append channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
     # section5: 创建 PyTorch 2.6.0 专属 conda 虚拟环境（Python 3.9）+ 安装 CUDA 版 PyTorch
     RUN /bin/bash -c '\
         source /home/ma-user/anaconda3/bin/activate base && \
         conda create -y --override-channels \
         -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main \
         -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r \
         -n pytorch_2_6 python=3.9.18 && \
         conda run -n pytorch_2_6 \
         pip install --index-url https://download.pytorch.org/whl/cu124 \
         torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 && \
         conda run -n pytorch_2_6 \
         pip install --index-url https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn \
         ipykernel==6.7.0 numpy==1.26.4 \
     '
     USER ma-user
     WORKDIR /home/ma-user
     ```
     
   
   - 非ModelArts官方镜像的Dockerfile文件示例：
     ![](https://support.huaweicloud.com/docker-modelarts/public_sys-resources/note_3.0-zh-cn.png)
     如果拉取非ModelArts官方镜像，访问https://registry-1.docker.io/v2/出现"connection refused"或者"Client.Timeout exceeded"错误，需要配置Docker代理。
     1. 执行以下命令，编辑配置文件。
        ```
        vi /etc/docker/daemon.json
        ```
        
     
     2. 添加以下配置。
        ```
        {
        "registry-mirrors":[
        "https://docker.m.daocloud.io",
        "https://docker.jianmuhub.com",
        "https://huecker.io",
        "https://dockerhub.timeweb.cloud",
        "https://dockerhub1.beget.com",
        "https://noohub.ru"]
        }
        ```
        
     
     3. 依次执行以下命令使配置生效。
        ```
        systemctl daemon-reload
        ```
        ```
        systemctl restart docker
        ```
        
      
     ```
     FROM ubuntu:20.04
     ENV DEBIAN_FRONTEND=noninteractive
     # section1: 创建ma-user用户组与用户
     USER root
     RUN default_user=$(getent passwd 1000 | awk -F ':' '{print $1}') || echo "uid: 1000 does not exist" && \
         default_group=$(getent group 100 | awk -F ':' '{print $1}') || echo "gid: 100 does not exist" && \
         if [ ! -z "${default_user}" ] && [ "${default_user}" != "ma-user" ]; then \
             userdel -r ${default_user}; \
         fi && \
         if [ ! -z "${default_group}" ] && [ "${default_group}" != "ma-group" ]; then \
             groupdel -f ${default_group}; \
         fi && \
         if ! getent group 100 > /dev/null; then \
             groupadd -g 100 ma-group; \
         fi && \
         useradd -d /home/ma-user -m -u 1000 -g 100 -s /bin/bash ma-user && \
         chmod -R 750 /home/ma-user
     # section2: 使用标准focal源（x86_64架构）+ 安装系统依赖 + 添加NVIDIA CUDA仓库
     RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
         printf "deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse\n\
         deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted universe multiverse\n\
         deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse\n\
         deb http://security.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse\n" > /etc/apt/sources.list && \
         apt-get update && \
         apt-get install -y zip wget ca-certificates vim python3 python3-pip tzdata gnupg && \
         ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
         dpkg-reconfigure --frontend noninteractive tzdata && \
         apt update && echo Y | apt install openssh-server && \
         wget https://developer.download.nvidia.cn/compute/cuda/repos/ubuntu2004/x86_64/cuda-keyring_1.1-1_all.deb && \
         dpkg -i cuda-keyring_1.1-1_all.deb && \
         rm -f cuda-keyring_1.1-1_all.deb && \
         apt-get update
     RUN rm /bin/sh && ln -s /bin/bash /bin/sh
     # section3: 安装 CUDA toolkit 12.4
     RUN apt-get install -y cuda-toolkit-12-4
     # section4: 设置 CUDA 环境变量
     ENV CUDA_HOME=/usr/local/cuda-12.4
     ENV PATH=${CUDA_HOME}/bin:$PATH
     ENV LD_LIBRARY_PATH=${CUDA_HOME}/lib64:$LD_LIBRARY_PATH
     # section5: 以 ma-user 身份安装 Miniconda3（x86_64版本）
     USER ma-user
     RUN cd /home/ma-user/ && \
         wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
         bash Miniconda3-latest-Linux-x86_64.sh -b -p /home/ma-user/anaconda3 && \
         rm -rf Miniconda3-latest-Linux-x86_64.sh
     # section6: 配置 conda、pip 清华镜像源 + 初始化 conda
     RUN mkdir -p /home/ma-user/.pip && \
         echo -e "channels:\nshow_channel_urls: true\ndefault_channels:\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r\n  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2\nremote_read_timeout: 120" > /home/ma-user/.condarc && \
         echo -e "[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple\n[install]\ntrusted-host = pypi.tuna.tsinghua.edu.cn" > /home/ma-user/.pip/pip.conf && \
         /home/ma-user/anaconda3/bin/conda init bash && \
         source /home/ma-user/anaconda3/bin/activate base && \
         conda config --remove-key channels || true && \
         conda config --append channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main && \
         conda config --append channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r && \
         conda config --append channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 && \
         conda tos accept --override-channels -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main && \
         conda tos accept --override-channels -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r && \
         conda tos accept --override-channels -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
     # section7: 创建 PyTorch 2.6.0 专属 conda 虚拟环境（Python 3.9）+ 安装 CUDA 版 PyTorch
     RUN /bin/bash -c '\
         source /home/ma-user/anaconda3/bin/activate base && \
         conda create -y --override-channels \
         -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main \
         -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r \
         -n pytorch_2_6 python=3.9.18 && \
         conda run -n pytorch_2_6 \
         pip install --index-url https://download.pytorch.org/whl/cu124 \
         torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 && \
         conda run -n pytorch_2_6 \
         pip install --index-url https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn \
         ipykernel==6.7.0 numpy==1.26.4 \
     '
     USER ma-user
     WORKDIR /home/ma-user
     ```
     
     
4. 构建容器镜像。 在Dockerfile文件目录中，执行以下命令，构建容器镜像。命令中的SWR镜像地址请按需修改。构建时间取决于网络带宽和镜像大小，大约30分钟。
   ```
   docker build -t swr.cn-north-4.myhuaweicloud.com/dev-custom/pytorch2_6-cuda12.4.0:v1 -f Dockerfile .
   ```
   如果回显中显示"Successfully built"和"Successfully tagged"，表示镜像构建成功。
   图4容器镜像构建成功   
   ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002714134548.png) 
 
 #### 步骤三：将镜像推送到SWR
1. 执行以下命令，将本地构建的镜像上传到SWR。
   ```
   docker push swr.cn-north-4.myhuaweicloud.com/dev-custom/pytorch2_6-cuda12.4.0:v1
   ```
   如果回显中显示"digest"和SHA256哈希值，表示镜像已成功上传到SWR。
   图5镜像推送成功   
   ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002714298030.png) 
2. 在[SWR控制台](https://console.huaweicloud.com/swr/#/swr/dashboard)左侧导航栏，单击"我的镜像"，执行刷新操作后显示新增的镜像，单击镜像名称，可查看镜像详情。
 
 #### 步骤四：在ModelArts注册新镜像
将新镜像注册到ModelArts镜像管理服务中，以便在ModelArts中使用该镜像。具体操作，请参见[镜像注册与管理](https://support.huaweicloud.com/docker-modelarts/modelarts_23_0219.html)。
镜像源即为[步骤三]推送到SWR中的镜像。上述安装包均在X86架构镜像下完成，因此架构类型选择X86，类型选择GPU/CPU。
图6注册镜像   
![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002744068895.png "点击放大")
#### 步骤五：创建Notebook并验证新镜像
1. 创建Notebook实例（请确保当前区域有相应的GPU机器资源）。
   1. 在[ModelArts管理控制台](https://console.huaweicloud.com/modelarts/)左侧导航栏，按需选择以下操作，进入Notebook管理页面。
      - 新版控制台：选择"模型开发与训练 \> Notebook"，进入"Notebook"页面。
      
      - 旧版控制台：选择"开发空间 \> Notebook"，进入"Notebook"页面。
       
   
   2. 在"Notebook"页面右上角，单击"创建"。 在"资源配置"区域，实例规格选择GPU/CPU；在"环境配置"区域，选择"自定义镜像"，单击![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002743985125.png)图标，选择[步骤四]注册的镜像及版本，WebIDE选择JupyterLab。
      关于创建Notebook的参数说明，请参见[创建Notebook实例](https://support.huaweicloud.com/devtool-modelarts/devtool-modelarts_3495.html)。
      图7创建Notebook   
      ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002714226442.png)
      
      当Notebook实例的"状态"显示为"运行中"，表示Notebook实例创建成功。
      
    
2. 在"Notebook"页面，单击操作列的"接入环境"，在"接入方式"对话框，单击JupyterLab接入右侧的"接入"。
3. 在"ModelArts Launcher"页面的Notebook区域，单击pytorch_2_6，创建一个ipynb文件。
   图8打开pytorch_2_6   
   ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002714066376.png "点击放大") 
4. 执行以下命令，导入PyTorch库，查看PyTorch版本号。
   ```
   import torch
   print(torch.__version__)
   ```
   显示版本如下，表示PyTorch安装成功。
   图9查看PyTorch版本号   
   ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002744076123.png "点击放大") 
5. 查看CUDA是否安装成功。
   1. 在左侧目录区域右键，单击"New File"，新建一个脚本文件test.py。
      图10新建文件   
      ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002714333082.png) 
   
   2. 在test.py文件中输入以下内容。
      ```
      import torch
      # 检查 CUDA 是否可用
      print(f"PyTorch version: {torch.__version__}")
      print(f"CUDA available: {torch.cuda.is_available()}")
      if torch.cuda.is_available():
      print(f"GPU device: {torch.cuda.get_device_name(0)}")
      # 创建张量并转移到 GPU
      x = torch.randn(2, 2).cuda()
      y = torch.randn(2, 2).cuda()
      z = x.mm(y)
      print(z)
      ```
      
   
   3. 在左侧导航栏，单击![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002714330968.png)图标，选择Terminal。
      图11打开Terminal   
      ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002743929781.png) 
   
   4. 在Terminal中执行以下命令，运行test.py文件。
      ```
      python test.py
      ```
      输出结果如下，表示CUDA安装成功。
      图12CUDA安装成功   
      ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002714332932.png "点击放大") 
    
 
