天天看點

利用Docker封裝環境前言正文結束

前言

最近需要将訓練好的模型利用docker封裝成鏡像上傳,之前曾經自學過一段時間docker(沒接觸過swam,compose,原因是沒有那麼多叢集給我去部署),但是在封裝的過程中還是遇到了許多問題,特此記錄一下踩到坑。

注意:本次的系統為ubuntu18.04 LTS

正文

安裝docker

對于docker的安裝其實問題不算很大,隻要遵循官網上的相關教程(前提需要一點英文儲備),就能很輕松的安裝上docker引擎。

安裝nvidia-container-toolkit

一開始我以為安裝完docker引擎之後就可以愉快的拉取鏡像和使用鏡像内的環境進行訓練測試了。但是,實則并不是這樣的,當我們運作

sudo docker run -it --gpus=all dockerID /bin/bash
           

輸完上述指令後往往會報如下錯誤:

docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
           

經過查詢相關資料,原來docker一開始是不支援使用顯示卡的,但是經過一段時間的發展,出現了nvidia-docker進行顯示卡的調用。随着技術不斷發展,在docker 19.03版本開始,docker可以通過安裝相關工具能夠直接原生支援顯示卡調用。隻需要在指令行中分别輸入以下代碼即可:

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
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-container-toolkit
sudo systemctl restart docker
           

撰寫dockerfile

說到撰寫dockerfile,在這裡作者踩到的坑就很多了。一開始拉取的是dockerhub上nvidia官方釋出的隻配置了cuda-11.0.3-cudnn-8.0-ubuntu-18.04的基礎鏡像,即:

FROM nvidia/cuda:11.0.3-cudnn8-devel-ubuntu18.04
           

注意!!!!:涉及到cuda的鏡像,鏡像名往往會有帶有

base/runtime/devel

,如果你的docker後續需要利用nvcc進行編譯操作的話一定下載下傳

devel

版本,該版本内會包含cuda的編譯工具。英偉達官方的解釋如下:

base: Includes the CUDA runtime (cudart)
runtime: Builds on the base and includes the CUDA math libraries, and NCCL. A runtime image that also includes cuDNN is available.
devel: Builds on the runtime and includes headers, development tools for building CUDA images. These images are particularly useful for multi-stage builds.
           

之後就是相關軟體包的安裝,在這裡不得不吐槽一句,鏡像内的python預設安裝版本總是3.6版本。如果隻是在安裝python的時候指定了相關的版本,那麼你會發現當其餘的安裝包安裝完畢時,容器内會出現多個python版本共存的情況,是以如果不是大佬的話,建議不要拉取特别基礎的鏡像。

在dockerfile内撰寫安裝相關依賴包語句:

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake curl ca-certificates \
libjpeg-dev libpng-dev ffmpeg libsm6 libxext6 ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 \
python3 python3-dev python3-pip && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
           

也正因為我拉取的鏡像太小,導緻在安裝自己魔改的mmdetection時各種報錯,很多安裝包都需要自己下載下傳也是以報了很多的錯誤。

比如:

ImportError: No module named setuptools
           
pip install scikit-build
           

對應的隻需要在dockerfile裡添加

RUN pip3 install setuptools
RUN pip3 install scikit-build
           

安裝mmcv不成功,之前在鏡像外,直接利用指令行

pip install mmcv-full
           

但是在容器内,想要mmcv能夠編譯成功且支援cuda加速的話,應當在dockerfile内使用如下指令(花括号内需要自己改版本):

RUN pip3 install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu{version}/torch{version}/index.html
           

編譯mmdet的時候遇到過

nvcc fatal : Unsupported gpu architecture ‘compute_86‘
           

該錯誤的主要是顯示卡的算力已經超出了目前cuda版本的上限,是以需要限制算力:

ENV TORCH_CUDA_ARCH_LIST="3.5 3.7 5.0 5.2 6.0 6.1 7.0 7.5+PTX"
           

各版本cuda所支援的算力如下所示,該清單參考自知乎文章:

#cuda9
export TORCH_CUDA_ARCH_LIST="3.5;5.0;5.2;6.0;6.1;7.0;7.0+PTX"

#cuda10
export TORCH_CUDA_ARCH_LIST="3.5;5.0;5.2;6.0;6.1;7.0;7.5;7.5+PTX"

#cuda11
export TORCH_CUDA_ARCH_LIST="3.5;5.0;5.2;6.0;6.1;7.0;7.5;8.0;8.0+PTX"

#cuda11.1
export TORCH_CUDA_ARCH_LIST="5.0;7.0;8.0;8.6;8.6+PTX"
           

當然在編譯過程中最令我頭疼的是遇到了如下所示的問題:

No CUDA runtime is found, using CUDA_HOME='/usr/local/cuda'
           

編寫好dockerfile檔案之後,有些需要cuda進行編譯的檔案沒法正常進行編譯隻能使用CPU,但是此時顯示卡調用的安裝工具已經全部安裝,搜尋了好久資料無果的情況下,我翻看到了mmdetection官方提供的dockerfile檔案,至此我才恍然大悟,原來在環境變量那裡也要進行必要的設定。除此之外,我覺得當初如果學着示例的寫法,直接拉取pytorch的基礎鏡像可能就沒有太多前面的事情了。

ENV TORCH_NVCC_FLAGS="-Xfatbin -compress-all" # 使用nvcc去編譯pytorch
ENV FORCE_CUDA="1"
           

建構好鏡像,運作容器中具體的程式時候,還遇到過docker的編碼問題:

UnicodeEncodeError: 'ascii' codec can't encode characters in position...
           

python預設使用的是

utf-8

的編碼方式,但是在docker内卻并不是這樣,容器内預設使用的是

POSIX

,在指令行内輸入

locale

就可以觀察到具體的編碼方式,

locale -a

就能看到系統支援的全部編碼方式,本次的鏡像中支援的編碼方式為:

C
C.UTF-8
POSIX
           

是以需要在dockerfile内加上

ENV LANG=C.UTF-8
           

利用基礎鏡像去一點一點搭建環境,目前便遇到了這麼多坑

我發現還是去拉pytorch官方提供的鏡像更為簡單很多,雖然基礎鏡像略大,但是不得不說很多必要的安裝包都已經提前安裝完畢,建構符合要求的鏡像更為簡單。

結束

本以為封裝環境能夠在一兩個效時之内結束,沒想到調bug,查資料,差點就通宵了。不過最後總歸能夠順利完成,對于上述問題如有異議歡迎指正!!!!!