在ubuntu16.04下创建cuda加速的docker镜像

来源:互联网 发布:office2016 for mac 编辑:程序博客网 时间:2024/06/06 01:15

在ubuntu16.04下创建cuda加速的docker镜像

本人也是自学docker,需要创建具有cuda加速的镜像跑一下深度学习,也参考了一些资料,如:跳转,遇到过一些坑,下面做一个总结并准备一个详细的创建步骤,希望对大家有所参考价值,如有不正之处,请指出。

简要说一下我认为的坑在哪几个方面:
- 对于我来说,合适的cuda及nvidia安装包比较难找(个人问题)
- 镜像的nvidia驱动版本要与宿主机一致
- 另外一个就是网不好的话,伟大的墙

若是有参考我博客的打算,最好先全文浏览一下,因为我是按照顺序来解决我遇到的坑,或许你并不需要其中一些步骤。
注:本文没有讲解docker的安装,加速器, 工作组的设置等基础知识。


准备工作

1.在宿主机下确认自己已经安装好的nvidia驱动版本

nvidia-smi

这里写图片描述

我的版本号是375.66(我在ubuntu中使用的sudo apt-get install nvidia-375安装的,375是我电脑需要的版本,可使用 ubuntu-drivers devices 查看版本号,在我的经验来看,使用cuda自带的驱动安装最好),这是我遇到的第一个坑,因为我后面在Dockerfile 中使用cuda_xxx.run做的镜像,而里面自带的驱动版本是375.26,这样做完镜像后因为和宿主机驱动版本不匹配,无法调起驱动,后面讲述解决办法。

2.做一个apt update后的ubuntu镜像

这个的目的是可以多次尝试做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.04MAINTAINER  gx <gao_x2015@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

这里写图片描述


制作ubuntu_cuda镜像

假如你前面一切顺利,坑最大最多最费心的一步到来了!

在这儿就需要针对自己的电脑显卡来配置了,鉴于每个人的驱动版本都不同,此处在镜像制作过程中就没有使用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,也很简单,两个综合一下即可。

1.宿主机cuda与nvidia版本号相同的

毫无疑问先建立工作目录和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.04MAINTAINER  gx <gao_x2015@163.com>COPY ./cuda_8.0.61_375.26_linux.run /optRUN 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-moduleRUN 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_installersENV LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-8.0/lib64ENV 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/deviceQuerymake./deviceQuery 

若一切顺利,最后会出现类似下面的
deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 6.5, CUDA Runtime Version = 6.5, NumDevs = 1, Device0 = GRID K520
Result = PASS

执行nvidia-smi也可同样测试

1.宿主机cuda与nvidia版本号不同的

这个时候你需要去找一个和你nvidia驱动相同版本号的NVIDIAxxxxxxxxxxxxxx.run,看个人本事啦,一般都有,比如我的375.66,去这儿下载的

解压出来后有一个NVIDIA-Linux-x86_64-375.66-no-compat32.run文件,后面要用到
两种方法

1)按照前面的版本号相同做完镜像并创建容器

然后把上述的NVIDIA-Linux-x86_64-375.66-no-compat32.run复制到宿主机的共享文件share_data,此时可在容器的share_data查找到,然后(下面在容器执行):

cd share_datacp ./NVIDIA-Linux-x86_64-375.66-no-compat32.run /usr/local/cudacd /usr/local/cudachmod 777 ./NVIDIA-Linux-x86_64-375.66-no-compat32.run./NVIDIA-Linux-x86_64-375.66-no-compat32.run -s -N --no-kernel-module

然后同样按照上面测试

2)使用Dockerfile直接制作

把cudaxxxxxxxxxxxxxx.run和NVIDIAxxxxxxxxxxxxxxx.run复制到Dockerfile同目录下。
把Dockerfile内容替换为:

FROM ubuntu_apt:16.04MAINTAINER  gx <gao_x2015@163.com>COPY ./cuda_8.0.61_375.26_linux.run /optCOPY ./NVIDIA-Linux-x86_64-375.66-no-compat32.run /optRUN 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-moduleRUN 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_installersENV LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-8.0/lib64ENV PATH=$PATH:/usr/local/cuda-8.0/bin

按照上面测试。

这里写图片描述
成功!

总结

经过不断的尝试,算是解决了问题,并熟练啦docker的操作,上面亲测可行,如有哪儿疏忽或者有问题,请与我联系,感谢阅读!