首页 > 解决方案 > 如何在 gitlab-ci docker executor 中使用 cuda

问题描述

我们正在使用 gitlab 持续集成来构建和测试我们的项目。最近,其中一个项目增加了对 CUDA 启用 GPU 加速的要求。我不想改变我们的管道(docker 和 gitlab-ci 对我们来说工作得很好),所以我想以某种方式让 docker 能够与 nvidia GPU 对话。

额外细节:

标签: dockercudagitlab

解决方案


现在--gpugitlab runner 版本 >13.9 上有标志。你应该使用那些 insetad。如果坚持使用旧版本,请继续阅读。


有多个步骤:

  1. 在主机 PC 上安装 nvidia 驱动程序
  2. 安装 nvidia-docker2
  3. 使用 CUDA 构建 docker 镜像
  4. 让它在 gitlab CI 中工作

请注意,如果您只想编译 CUDA 代码而不需要运行它,则无需使用 nvidia-docker2,在主机 PC 上安装 nvidia 驱动程序,并且无需特殊步骤即可使其工作gitlab CI。(即您只需执行第 3 步)

恐怕我对 docker 不太熟悉,所以如果我混合了容器和图像,我深表歉意。如果有更多知识的人想要修复有关 docker 的任何拼写错误,将不胜感激。

步骤 1:在主机 PC 上安装 nvidia 驱动程序

您在这里有两个选择。您可以使用主机操作系统推荐的程序。这很容易,但意味着不同构建服务器的环境可能不同。另一种选择是直接从 nVidia 下载安装程序(即https://www.nvidia.com/object/unix.html),以便您可以将其与 docker 容器一起分发。

第 2 步:安装 nvidia-docker2

我当前的测试 PC 是 archlinux,所以这是从 AUR 使用它的一个案例。nVidia 为多个操作系统提供存储库,因此请参阅nvidia-docker github 页面上的快速入门指南。

您应该按照快速入门指南测试您的 nvidia-docker 安装。从您的主机 PC 运行命令: docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi应该运行并输出如下内容:

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 415.18       Driver Version: 415.18       CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 106...  Off  | 00000000:02:00.0  On |                  N/A |
| 28%   39C    P0    24W / 120W |    350MiB /  6071MiB |      3%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+

请注意,虽然我指定了 9.0-base 映像,但 nvidia-smi 报告 Cuda 10。我认为这是因为 Cuda 10 安装在主机 PC 上。nvidia-docker 文档说它将使用 docker 映像中的 cuda,所以这应该不是问题。

第 3 步:使用 CUDA 构建 docker 映像

您应该直接使用 Nvidia dockerhub docker 映像,除非您有充分的理由不这样做。就我而言,我想使用基于 Debian 的 docker 镜像,但 Nvidia 只为 Ubuntu 和 CentOS 提供镜像。幸运的是,Nvidia 为他们的图像发布了 dockerfile,所以你可以从他们那里复制他们的 dockerfile 的相关部分。我基于https://gitlab.com/nvidia/cuda/blob/ubuntu16.04/9.2/base/Dockerfile

dockerfile 的神奇部分包括:

# Install cuda manually
RUN wget https://developer.nvidia.com/compute/cuda/9.2/Prod2/local_installers/cuda_9.2.148_396.37_linux

COPY install_cuda.exp install_cuda.exp
RUN mv cuda_* cuda_install_bin && \
    chmod +x cuda_install_bin && \
    expect install_cuda.exp && \
    rm cuda_*

# Magic copied from nvidia's cuda9.2 dockerfile at
# https://gitlab.com/nvidia/cuda/blob/ubuntu16.04/9.2/base/Dockerfile
ENV CUDA_VERSION 9.2.148


LABEL com.nvidia.volumes.needed="nvidia_driver"
LABEL com.nvidia.cuda.version="${CUDA_VERSION}"

RUN echo "/usr/local/nvidia/lib" >> /etc/ld.so.conf.d/nvidia.conf && \
    echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf

ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64

# nvidia-container-runtime
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
ENV NVIDIA_REQUIRE_CUDA "cuda>=9.2"

“expect”命令将允许您编写脚本以自动接受许可协议等。发布文件对我来说可能不是一个好主意install_cuda.exp(因为我不能接受你的协议),但就我而言,我接受了 eula,同意将其安装在不受支持的操作系统上,没有安装图形驱动程序,确实安装了 cuda,使用了默认路径,安装了指向 usr/local/cuda 的符号链接并且没有安装示例。有关 expect 的更多信息,请参阅手册页[此处的在线手册页]。检查文件主要由以下行组成expect -- "(y)es/(n)o/(q)uit:" { send "y\r" }

您应该检查是否可以使用您自己的容器为 nvidia-smi 运行 nvidia-smi 测试命令。(即docker run --runtime=nvidia -it your_image_here /bin/sh

第 4 步:让它在 gitlab-ci 中运行。

在网络上进行研究时,大多数消息来源都告诉您,您无法--runtime从 gitlab 运行器配置中提供标志。实际上,根据这个合并请求,您可以。为此,您必须编辑/etc/gitlab-runner/config.toml并添加runtime = "nvidia"到正确的位置。例如,我的运行器配置如下所示:

[[runners]]
  name = "docker-runner-test"
  url = "<<REDACTED>>"
  token = "<<REDACTED>>"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "build_machine"
    privileged = false
    disable_cache = false
    runtime = "nvidia"
    volumes = ["/cache"]
    pull_policy = "never"
    shm_size = 0
  [runners.cache]

推荐阅读