目錄
爲避免docker操作必須要sudo,將當前用戶加入docker用戶組(${YOUR_NAME_HERE}處填當前用戶名)
前言
docker一詞的原意爲“碼頭的裝卸工”,其開發的目的是爲解決廣大程序員在開發、測試、部署維護等不同場景不可避免的場景不同問題,即提供抽象的“鏡像、容器“等概念,爲windows、linux、macos等不同操作系統運行環境提供一站式解決方案。
鏡像image是靜態文件,容器container是動態運行,同一個鏡像的不同運行可以產生多個不同容器。
但docker比正常環境更喫配置,建議不同時使用的深度學習框架儘量分成不同的鏡像製作、安裝部署、使用,否則內存爆炸。
一、Docker安裝
備份sources.list並新建
sudo mv /etc/apt/sources.list /etc/apt/sources.list.old
sudo vim /etc/apt/sources.list
阿里源鏡像填入(最近清華源好像有問題)
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
更新源使之生效
sudo apt-get update
二、NVIDIA GPU 驅動安裝
驅動安裝
sudo ubuntu-drivers autoinstall
檢查安裝結果
watch nvidia-smi
三、Docker安裝
docker安裝
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce
檢查安裝結果
docker -v
爲避免docker操作必須要sudo,將當前用戶加入docker用戶組(${YOUR_NAME_HERE}處填當前用戶名)
sudo usermod -aG docker ${YOUR_NAME_HERE}
四、Nvidia-docker安裝
安裝
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd
上述最後一步會重啓docker,並載入nvidia-docker的配置
檢查安裝結果
docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi
五、Docker基本使用
Docker啓動
sudo service docker start
或
sudo systemctl start docker
Dokcer關閉
sudo service docker stop
或
sudo systemctl stop docker
Docker倉庫國內源修改,以加速鏡像獲取
打開/etc/default/docker
文件(需要sudo
權限),在文件的底部加上一行。
DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com"
然後,重啓 Docker 服務。
sudo service docker restart
拉取鏡像
docker image pull [倉庫名]/[鏡像名][:版本號](版本號可選,默認爲最新)
docker image pull library/hello-world
查看鏡像
docker image ls
運行鏡像,即生成新容器
docker container run --runtime=nvidia -it --rm -p 8000:3000 dockername /bin/bash
其中
--runtime=nvidia 表示選擇NVIDIA驅動作爲運行時環境
-it 交互式運行 與之對應的是-d代表後臺運行
–rm 代表退出容器後就刪除容器
-p 8000:3000 容器端口與本地端口映射,前爲本地端口,後爲容器端口。這裏的例子是將容器的3000端口映射到 8000端口
tf-gpu 爲之前創立的鏡像名稱
/bin/bash 代表進入容器後選擇bash的方式
另外
-d 後臺運行容器,並返回容器ID
--name 給容器命名,沒有這個參數會隨機生成一個名字
查看容器
docker container ls
六、Docker守護進程修改
問題:Cannot connect to the Docker daemon at tcp://localhost:4243. Is the docker daemon running?
修改配置文件/etc/systemd/system/multi-user.target.wants/docker.service爲:
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
即修改ExecStart改成上述值,即爲docker指定啓動的本地端口。
然後,systemctl daemon-reload/ systemctl restart docker.service /
分別運行上述命令進行docker重啓,重啓成功!
七、深度學習框架生成
Dockerfile編寫
FROM nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04
MAINTAINER zjhao666
# install basic dependencies
RUN apt-get update
RUN apt-get install -y wget \
vim \
cmake
# install Anaconda3
RUN wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.2.0-Linux-x86_64.sh -O ~/anaconda3.sh
RUN bash ~/anaconda3.sh -b -p /home/anaconda3 \
&& rm ~/anaconda3.sh
ENV PATH /home/anaconda3/bin:$PATH
# change mirror
RUN mkdir ~/.pip \
&& cd ~/.pip
RUN echo -e "[global]\nindex-url = https://pypi.mirrors.ustc.edu.cn/simple/" >> ~/pip.conf
RUN /home/anaconda3/bin/pip install --upgrade pip
RUN /home/anaconda3/bin/pip install numpy==1.16.0
RUN /home/anaconda3/bin/pip install matplotlib
RUN /home/anaconda3/bin/pip install scipy
RUN /home/anaconda3/bin/pip install sklearn
RUN /home/anaconda3/bin/pip install echarts
RUN /home/anaconda3/bin/pip install tensorflow-gpu==1.9.0
RUN /home/anaconda3/bin/pip install torch===1.2.0 torchvision===0.4.0 -f https://download.pytorch.org/whl/torch_stable.html
末尾即爲衆框架。
根據之前的建議,torch\tensorflow這種大框架,一個鏡像最好只有一個。
鏡像起名
docker build -t my_image .
-t 後面跟鏡像的名字
運行生成容器
docker run --runtime=nvidia -it --rm my_image /bin/bash
八、pycharm配置
file,settings,build-execution-deployment,docker,如圖,配置URL爲tcp://localhost:4243即可。
隨後,在file,settings,project,interprter,選擇reset下的三個點,選add,docker,如下
image name對應正確的docker鏡像名+版本號,點擊ok,可見已加載tensorflow2gpu版的docker鏡像成功。
找一段測試tensorflow2gpu的代碼,放進test.py裏。代碼如下:
import tensorflow as tf
import timeit
print(tf.test.is_gpu_available())
with tf.device('/cpu:0'):
cpu_a = tf.random.normal([10000, 1000])
cpu_b = tf.random.normal([1000, 2000])
print(cpu_a.device, cpu_b.device)
with tf.device('/gpu:0'):
gpu_a = tf.random.normal([10000, 1000])
gpu_b = tf.random.normal([1000, 2000])
print(gpu_a.device, gpu_b.device)
def cpu_run():
with tf.device('/cpu:0'):
c = tf.matmul(cpu_a, cpu_b)
return c
def gpu_run():
with tf.device('/gpu:0'):
c = tf.matmul(gpu_a, gpu_b)
return c
# warm up
cpu_time = timeit.timeit(cpu_run, number=10)
gpu_time = timeit.timeit(gpu_run, number=10)
print('warmup:', cpu_time, gpu_time)
cpu_time = timeit.timeit(cpu_run, number=10)
gpu_time = timeit.timeit(gpu_run, number=10)
print('run time:', cpu_time, gpu_time)
特別的,ubuntu機器上的pycharm設置運行無法輸出,要右鍵python文件,點run 'test'纔行。
後面要改,也可以繼續照常修改設置。
運行結果如圖:
可見,無論是bool判斷,還是運行時間,均證明tensorflow2gpu的docker版環境已經成功部署。
九、命令行執行
在不使用pycharm的情況下,可以將文件目錄掛載到docker環境中執行。例如,
docker run -v /home/zjhao/Desktop/pycharm_test:/home -it --rm tensorflow/tensorflow:2.0.0-gpu-py3 /bin/bash
這樣,就把本機的/home/zjhao/Desktop/pycharm_test目錄故在到了冒號之後的/home目錄下。原始目錄下有上文提到的測試tensorflow是否安裝成功的代碼。正常命令行執行即可。
root@95b391468605:/# cd /home/
root@95b391468605:/home# ls
test.py
root@95b391468605:/home# python test.py
結果依然符合要求。
然後ctrl d退出即可。
此外,特別提醒,-v可重複使用,即可以一次運行時掛載多個本地文件目錄到docker容器中——從而有效解決非父子目錄的不同路徑下,本地執行文件對數據文件、及本地執行文件之間的文件依賴報錯,即依賴文件不存在的問題。
十、額外福利
使用正常框架安裝tensorflow gpu版時,可能會出現ImportError: libcublas.so.9.0: cannot open shared object file: No such file or directory這類錯誤,可在每次開機後,第一次運行前使用如下命令解決:
sudo ldconfig /usr/local/cuda-9.0/lib64
當然,這是cudnn正常安裝的解決方案。cudnn的正常安裝步驟如下:
首先去官網下載cuDNN
cuDNN官網 https://developer.nvidia.com/rdp/cudnn-download,需要註冊一個賬號才能下載(免費的)。下載cuDNN時也一定要注意與CUDA版本的適配性。
cuDNN在持續更新中,只要對應(我們這裏是CUDA9.0)就好了,因此不一定要最新的。如cudnn-9.0-linux-x64-v7.4.2.24.solitairetheme8,即7.4.2版本,不是最新的,但可用即可。
進入cuDNN目錄後進行解壓
sudo tar -xzvf cudnn-9.0-linux-x64-v7.4.2.24.solitairetheme8
得到cuda文件夾
進入解壓後的文件夾下的include目錄
cd cuda/include
sudo cp cudnn.h /usr/local/cuda/include
進入lib64目錄下,對動態文件進行復制和軟鏈接
cd ..
cd lib64
sudo cp lib* /usr/local/cuda/lib64/
cd /usr/local/cuda/lib64/
sudo rm -rf libcudnn.so libcudnn.so.7
sudo ln -s libcudnn.so.7.4.2 libcudnn.so.7
sudo ln -s libcudnn.so.7 libcudnn.so