本人也是自学docker,需要创建具有cuda加速的镜像跑一下深度学习,也参考了一些资料,如:跳转,遇到过一些坑,下面做一个总结并准备一个详细的创建步骤,希望对大家有所参考价值,如有不正之处,请指出。
简要说一下我认为的坑在哪几个方面:
- 对于我来说,合适的cuda及nvidia安装包比较难找(个人问题)
- 镜像的nvidia驱动版本要与宿主机一致
- 另外一个就是网不好的话,伟大的墙
若是有参考我博客的打算,最好先全文浏览一下,因为我是按照顺序来解决我遇到的坑,或许你并不需要其中一些步骤。
注:本文没有讲解docker的安装,加速器, 工作组的设置等基础知识。
nvidia-smi
我的版本号是375.66(我在ubuntu中使用的sudo apt-get install nvidia-375安装的,375是我电脑需要的版本,可使用 ubuntu-drivers devices 查看版本号,在我的经验来看,使用cuda自带的驱动安装最好),这是我遇到的第一个坑,因为我后面在Dockerfile 中使用cuda_xxx.run做的镜像,而里面自带的驱动版本是375.26,这样做完镜像后因为和宿主机驱动版本不匹配,无法调起驱动,后面讲述解决办法。
这个的目的是可以多次尝试做ubuntu_cuda镜像,而不需要因为网速太慢,每次都去执行更新和下载一些包。下面是我自己做过的一个ubuntu_apt:16.04镜像,可以直接拉取(推荐),或者按我下面步骤自己做也可以。
sudo docker pull registry.cn-hangzhou.aliyuncs.com/gx_test/ubuntu_apt:16.04
或者按照下面这个Dockerfile来自己做,当然你需要有一个ubuntu:16.04的基础镜像。
注:因为后面需要,我没有最简镜像,没有执行rm -rf /var/lib/apt/lists/*
sudo mkdir myubuntu_apt
cd myubuntu_apt
touch Dockerfile
在此目录下打开Dockerfile,写入下面内容:
FROM ubuntu:16.04
MAINTAINER gx 163.com> #yourname
RUN apt-get update && apt-get install -q -y \
build-essential \
module-init-tools\
# rm -rf /var/lib/apt/lists/*
继续在上面终端里,执行命令(注意 .):
sudo docker build -t ubuntu_apt:16.04 .
成功之后,执行;
docker images
假如你前面一切顺利,坑最大最多最费心的一步到来了!
在这儿就需要针对自己的电脑显卡来配置了,鉴于每个人的驱动版本都不同,此处在镜像制作过程中就没有使用wget来下载cuda_xxx.run(而且制作期间下载也慢),大家肯定都已经配置了宿主机的cuda,所以假定cuda_xxx.run的安装包还存在,Dockferile 中会把它复制到镜像中。
此处又分两种情况:
-宿主机已经安装的cuda版本号和nvidia版本号完全相同,恭喜你
-cuda和nvidia版本号不同
很不幸,我的是第二种,cuda为 cuda_8.0.61_375.26_linux.run,而nvidia通过终端命令安装的为375.66
下面讲解安装方法,我是基于上面已经建立的ubuntu_apt:16.04镜像,否则你需要自行更改Dockerfile,也很简单,两个综合一下即可。
毫无疑问先建立工作目录和Dockerfile文档
sudo mkdir ubunru_cuda
cd ubuntu_cuda
touch Dockerfile
把你现在已经有的cuda_xxx.run复制到ubuntu_cuda目录下,如我的为cuda_8.0.61_375.26_linux.run
在Dockerfile中写入制作命令(注意有些地方更换成你的设置,建议先看一下本段代码后面的详细解释,后面环境变量也需要修改,可能你的不是cuda-8.0,可以参考宿主机现有的):
FROM ubuntu_apt:16.04
MAINTAINER gx @163.com>
COPY ./cuda_8.0.61_375.26_linux.run /opt
RUN cd /opt && \
chmod +x *.run && \
mkdir nvidia_installers && \
./cuda_8.0.61_375.26_linux.run -extract='pwd'/nvidia_installers && \
cd nvidia_installers && \
./NVIDIA-Linux-x86_64-375.26.run -s -N --no-kernel-module
RUN cd /opt/nvidia_installers && \
./cuda-linux64-rel-8.0.61-21551265.run -noprompt && \
./cuda-samples-linux-8.0.61-21551265.run -noprompt -cudaprefix=/usr/local/cuda-8.0/ && \
rm /opt/cuda_8.0.61_375.26_linux.run && \
rm -rf /opt/nvidia_installers
ENV LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-8.0/lib64
ENV PATH=$PATH:/usr/local/cuda-8.0/bin
详细解释:有关NVIDIA-Linux-x86_64-375.26.run、cuda-linux64-rel-8.0.61-21551265.run的由来,这是由于执行了上面cuda-linux64-rel-8.0.61-21551265.run -extract=’pwd’/nvidia_installers 后,解压出来的,所以你可以在另外目录下复制进cuda_xxx.run后执行本条命令,解压后看一下,然后逐个替换代码里面的名称,注意若‘pwd’(当前路径)执行不通过可换成此时你目录的绝对路径。
然后制作镜像,注意是在Dockerfile的目录下执行下面命令(注意 .):
sudo docker build -t ubuntu_cuda:16.04 .
制作成功后,启动容器测试,此处设置了宿主机与容器的共享文件夹(-v /home/yourname/share_data:/share_data),建议设置
sudo docker run -ti -v /home/yourname/share_data:/share_data –device /dev/nvidia0:/dev/nvidia0 –device /dev/nvidiactl:/dev/nvidiactl –device /dev/nvidia-uvm:/dev/nvidia-uvm ubuntu_cuda:16.04 /bin/bash
利用cuda样例测试
cd /usr/local/cuda/samples/1_Utilities/deviceQuery
make
./deviceQuery
若一切顺利,最后会出现类似下面的
deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 6.5, CUDA Runtime Version = 6.5, NumDevs = 1, Device0 = GRID K520
Result = PASS
执行nvidia-smi也可同样测试
这个时候你需要去找一个和你nvidia驱动相同版本号的NVIDIAxxxxxxxxxxxxxx.run,看个人本事啦,一般都有,比如我的375.66,去这儿下载的
解压出来后有一个NVIDIA-Linux-x86_64-375.66-no-compat32.run文件,后面要用到
两种方法
然后把上述的NVIDIA-Linux-x86_64-375.66-no-compat32.run复制到宿主机的共享文件share_data,此时可在容器的share_data查找到,然后(下面在容器执行):
cd share_data
cp ./NVIDIA-Linux-x86_64-375.66-no-compat32.run /usr/local/cuda
cd /usr/local/cuda
chmod 777 ./NVIDIA-Linux-x86_64-375.66-no-compat32.run
./NVIDIA-Linux-x86_64-375.66-no-compat32.run -s -N --no-kernel-module
然后同样按照上面测试
把cudaxxxxxxxxxxxxxx.run和NVIDIAxxxxxxxxxxxxxxx.run复制到Dockerfile同目录下。
把Dockerfile内容替换为:
FROM ubuntu_apt:16.04
MAINTAINER gx <gao_x2015@163.com>
COPY ./cuda_8.0.61_375.26_linux.run /opt
COPY ./NVIDIA-Linux-x86_64-375.66-no-compat32.run /opt
RUN cd /opt && \
chmod +x *.run && \
mkdir nvidia_installers && \
./cuda_8.0.61_375.26_linux.run -extract=/opt/nvidia_installers && \
./NVIDIA-Linux-x86_64-375.66-no-compat32.run -s -N --no-kernel-module
RUN cd /opt/nvidia_installers && \
./cuda-linux64-rel-8.0.61-21551265.run -noprompt && \
./cuda-samples-linux-8.0.61-21551265.run -noprompt -cudaprefix=/usr/local/cuda-8.0/ && \
rm /opt/cuda_8.0.61_375.26_linux.run && \
rm /opt/NVIDIA-Linux-x86_64-375.66-no-compat32.run && \
rm -rf /opt/nvidia_installers
ENV LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-8.0/lib64
ENV PATH=$PATH:/usr/local/cuda-8.0/bin
按照上面测试。
经过不断的尝试,算是解决了问题,并熟练啦docker的操作,上面亲测可行,如有哪儿疏忽或者有问题,请与我联系,感谢阅读!