在 POWER 上使用 nvidia-docker 部署 CUDA 环境

前言

nvidia-docker 是用来做什么的?

由于 Docker 并不支持 GPU,如果想使用的话就需要在启动容器时进行挂载,而容器中要保证安装了宿主机上使用的 GPU 驱动,可以说这很不「优雅」,宿主机的显卡驱动需要明确地匹配容器里所安装的驱动版本。

nvidia-docker 可以实现与 NVIDA 驱动无关(driver-agnostic)的容器化操作,只需要在容器启动时挂载需要的设备字符和驱动文件就可以了,这就使我们构建的镜像可以更加的「便携」和「通用」。

Docker Engine Utility for NVIDIA GPUs

Docker Engine Utility for NVIDIA GPUs


前期准备

在宿主机上安装好对应的显卡驱动以及 Docker,这里就不过多介绍了。


安装 nvidia-docker

获取 nvidia-docker 源码

1
2
3
git clone https://github.com/NVIDIA/nvidia-docker.git && git fetch –all && cd nvidia-docker
git checkout ppc64le

以上操作将获取到 ppc64le 分支上的 nvidia-docker 源码,其它平台可以查看对应分支情况。

构建 nvidia-docker plugin deb 安装包

如果网络没有问题的话,通常执行完 make deb 之后就可以在 dist 目录下获取到安装包,但由于众所周知的原因在构建 nvidia-docker 镜像时,可能会出现 unrecognized import path 报错,即无法从 golang.org 获取到 cryptosys 等依赖包的情况,解决办法之一是修改 Dockerfile,选择手动从 GitHub 上 clone。

ppc64le 对应的是 Dockerfile.build.ppc64le,在 RUN go get -v ./... 这行之前添加:

1
2
3
4
5
6
7
8
# 切换工作目录到 $GOPATH 下并创建对应的包路径
WORKDIR /go/src/golang.org/x
RUN git clone https://github.com/golang/crypto.git && \
git clone https://github.com/golang/sys.git
# 切换回原来的工作目录
WORKDIR /go/src/github.com/NVIDIA/nvidia-docker/src

以上顺利的话,用于构建安装包的镜像就会构建好,脚本会基于此镜像创建容器,并进行安装包的构建。

安装 deb 包

进入到 dist 目录下:

1
sudo dpkg -i nvidia-docker_1.0.1-1_ppc64el.deb

安装成功之后就可以通过 nvidia-docker images 命令查看镜像,通过 service nvidia-docker status 可以查看服务的运行情况。


获取 CUDA 镜像

NVIDIA 提供 ppc64le 对应的 CUDA 镜像:

1
docker pull nvidia/cuda-ppc64le

如果拉取不下来可以尝试从中国官方镜像加速地址拉取:

1
docker pull registry.docker-cn.com/nvidia/cuda-ppc64le

不过这会修改镜像的标签,所以需要创建一个「简洁」的镜像标签:

1
2
# tag <源镜像ID> <标签名>
docker tag 4fa1fc125f9b nvidia/cuda-ppc64le

这里即使不修改也没什么太大的问题,但如果在构建 deb 安装包的步骤时,就需要修改镜像标签了。在 Dockerfile.deb.ppc64le 中,会基于 ppc64le/ubuntu:14.04 构建新的镜像,所以要把拉取下来的镜像修改为相同的标签:

1
docker tag ebcd9d4fca80 ppc64le/ubuntu:14.04

实际上只是为源镜像创建了一个「别名」,之前的镜像标签还是存在的,当然你也可以把之前有长长标签名的镜像删除。


运行容器

在运行之前,要确保 nvidia-docker-plugin 处于运行状态:

1
sudo nvidia-docker-plugin &

或者尝试重启系统。

在所有准备工作都完成之后,就可以通过 nvidia-docker 命令运行容器了:

1
nvidia-docker run -it --rm nvidia/cuda-ppc64le nvidia-smi

输出类似于以下信息就说明运行成功了:
nvidia-smi output


后记

简单地说,nvidia-docker 实际上是调用了 docker,但在这过程依赖 NVIDIA Docker plugin 来发现驱动文件和 GPU 设备,因此 nvidia-docker 命令也只有在容器的创建(create)运行(run)时参与,其余情况也只是调用 Docker 的接口而已,与使用 docker 命令并无二致。

参考