2019년 5월 16일 목요일

CUDA 9.0 + Python 3.5.3 + Tensorflow 1.12 + Ubuntu 18.04 docker image 최소화하여 만들기



Docker image size를 최소화해서 만들기 위해서는 일단 anaconda를 사용하면 안됩니다.  Anaconda를 설치하는데만도 4GB 정도가 들어가니까요.   또한 anaconda의 python 3.5.2는 gcc 4.8로 build된 것에 비해, Ubuntu 18.04에서 나오는 모든 library는 gcc 7.2로 build된 것이라서 CXX_ABI 문제가 발생할 가능성이 큽니다. 

이런 이유로, python을 anaconda를 이용하여 설치하지 않고, 그냥 source에서 build했습니다.  원래 Python 3.5.2 환경으로 하려고 했으나, python 3.5.2에는 아래 link에 나오는 pip 관련 error가 있습니다.  이 error는 python 3.5.3에서 fix 되었기 때문에 부득이하게 python 3.5.3을 설치하기로 했습니다.

https://stackoverflow.com/questions/50126814/ignoring-ensurepip-failure-pip-requires-ssl-tls-error-in-ubuntu-18-04 

먼저, 지난번에 만들어둔 CUDA 9.0과 Ubuntu 18.04 기반의 docker image를 run 시킵니다.

ibm@uniac922:~/files$ sudo docker run --runtime=nvidia -ti --rm -v ~/files:/mnt bsyu/ubuntu18.04_cuda9-0_ppc64le:v0.3

root@f47afeb949b5:/# cd /mnt

Python 3.5.3의 source를 download 받습니다.

root@75ecf9980173:/mnt# wget https://www.python.org/ftp/python/3.5.3/Python-3.5.3.tgz

root@75ecf9980173:/mnt# ls -l Python-3.5.3.tgz
-rw-rw-r-- 1 1003 1003 20656090 Jan 17  2017 Python-3.5.3.tgz

root@75ecf9980173:/mnt# tar -zxf Python-3.5.3.tgz

root@75ecf9980173:/mnt# cd Python-3.5.3

Python의 build는 간단합니다.  configure-make-make install 순입니다.

root@75ecf9980173:/mnt/Python-3.5.3# ./configure

root@75ecf9980173:/mnt/Python-3.5.3# make -j 32

root@75ecf9980173:/mnt/Python-3.5.3# make install

Build된 python은 /usr/local/bin/python3 으로 설치됩니다.   따라서 PATH에 /usr/local/bin을 추가해줘야 합니다.  물론 pip도  /usr/local/bin/pip3로 설치됩니다.

root@75ecf9980173:/mnt/Python-3.5.3# export PATH=/usr/local/bin:$PATH

root@75ecf9980173:/mnt/Python-3.5.3# echo "export PATH=/usr/local/bin:$PATH" >> ~/.bashrc

root@75ecf9980173:/mnt/Python-3.5.3# which python3
/usr/local/bin/python3

root@75ecf9980173:/mnt/Python-3.5.3# which pip3
/usr/local/bin/pip3

root@75ecf9980173:/mnt/Python-3.5.3# cd ..

이제 지난번에 anaconda의 python 3.5.2 환경에서 build했던 tensorflow의 wheel file을 이용해 pip3 명령으로 설치합니다.   이때 numpy나 keras-applications 등과 같은 prerequisite package들도 함께 자동으로 설치됩니다.

root@75ecf9980173:/mnt# pip3 install tensorflow_pkg3/tensorflow-1.12.0-cp35-cp35m-linux_ppc64le.whl

이제 python3를 구동하여 tensorflow를 import하고 GPU를 제대로 물고 오는지 test해봅니다.   아래와 같이 잘 됩니다.

root@6afae4bd06e3:/mnt# python3
Python 3.5.3 (default, May 16 2019, 11:02:36)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import tensorflow as tf

>>> sess=tf.Session()
2019-05-16 11:48:42.110194: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 0 with properties:
name: Tesla V100-SXM2-16GB major: 7 minor: 0 memoryClockRate(GHz): 1.53
pciBusID: 0004:04:00.0
totalMemory: 15.75GiB freeMemory: 15.45GiB
2019-05-16 11:48:42.260439: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 1 with properties:
...
2019-05-16 11:48:44.235074: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:3 with 14943 MB memory) -> physical GPU (device: 3, name: Tesla V100-SXM2-16GB, pci bus id: 0035:04:00.0, compute capability: 7.0)


이제 docker image의 크기를 줄이기 위해 아래와 같이 불필요한 file들과 package들을 삭제합니다.

root@6afae4bd06e3:~# rm -rf /var/lib/apt/lists/*  ~/.cache/*

root@6afae4bd06e3:~# apt remove curl fontconfig fontconfig-config fonts-dejavu-core fonts-dejavu-extra git git-man keyboard-configuration less lsb-release make manpages manpages-dev wget cuda-cublas-dev-9-0 cuda-npp-dev-9-0


다른 ssh session을 열어서 parent OS에서 위의 docker container를 image로 commit합니다.

ibm@uniac922:~$ sudo docker commit 6afae4bd06e3 bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le:v0.2
sha256:93a146481e72fbc8714ddbb1adfb596c7f20a094bf5788fbd856fc5e2a489b71

Image 크기를 보면 거의 7GB 정도 되는 것을 보실 수 있습니다.

ibm@uniac922:~$ sudo docker images | grep py353
bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le             v0.2                               93a146481e72        3 seconds ago       6.99GB

이제 이것의 size를 줄이기 위해, 아래와 같이 export 합니다.

ibm@uniac922:~$ sudo docker export 6afae4bd06e3 > ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le_v0.2.tar

여러가지 file들을 지웠기 때문에, export된 tar file의 크기는 4.2GB 정도에 불과합니다.

ibm@uniac922:~$ ls -l ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le_v0.2.tar
-rw-rw-r-- 1 ibm ibm 4204572160 May 16 11:58 ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le_v0.2.tar

이제 이것을 import 합니다.  이때 nvidia driver volume 등을 제대로 가져오기 위해 --change 옵션을 넣어야 하는 것을 잊지 마십시요.

ibm@uniac922:~$ cat ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le_v0.2.tar | sudo docker import  --change "ENV NVIDIA_VISIBLE_DEVICES=all" --change "ENV NVIDIA_DRIVER_CAPABILITIES compute,utility" --change "ENV LD_LIBRARY_PATH /usr/local/nvidia/lib64:/usr/local/nvidia/lib:/usr/local/cuda/lib64:/usr/lib:/usr/lib64:/lib:/lib64:/usr/local/lib:/usr/local/lib64" - bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le:v0.3

이렇게 import된 docker image의 크기는 4.2GB 정도입니다.  원래보다 거의 3GB 정도 줄었습니다.

ibm@uniac922:~$ sudo docker images | grep py353
bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le             v0.3                               be956177f42a        6 seconds ago       4.16GB
bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le             v0.2                               93a146481e72        10 minutes ago      6.99GB

이 새로운 이미지에서 tensorflow가 잘 동작하는지 확인합니다.  아래와 같이 잘 됩니다.

ibm@uniac922:~$ sudo docker run --runtime=nvidia -ti --rm -v ~/files:/mnt bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le:v0.3 bash

root@a8d890e2a25a:/# python3
Python 3.5.3 (default, May 16 2019, 11:02:36)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import tensorflow as tf

>>> sess=tf.Session()
2019-05-16 03:07:31.017607: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 0 with properties:
name: Tesla V100-SXM2-16GB major: 7 minor: 0 memoryClockRate(GHz): 1.53
pciBusID: 0004:04:00.0
totalMemory: 15.75GiB freeMemory: 15.44GiB
...
2019-05-16 03:07:33.042540: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 14938 MB memory) -> physical GPU (device: 0, name: Tesla V100-SXM2-16GB, pci bus id: 0004:04:00.0, compute capability: 7.0)


이제 이 v0.3 image를 latest라는 tag로 tagging하고, docker hub로 push 합니다.

ibm@uniac922:~$ sudo docker images | grep py353
bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le             latest                             be956177f42a        2 minutes ago       4.16GB
bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le             v0.3                               be956177f42a        2 minutes ago       4.16GB

ibm@uniac922:~$ sudo docker push bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le:v0.3

이것을 사용하시기 위해서는 아래 명령으로 pull 하시면 됩니다.


$ sudo docker pull bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le:v0.3

또는

$ sudo docker pull bsyu/ubuntu18.04_cuda9-0_py353_tf1.12_ppc64le:latest

댓글 없음:

댓글 쓰기