레이블이 nvidia-docker인 게시물을 표시합니다. 모든 게시물 표시
레이블이 nvidia-docker인 게시물을 표시합니다. 모든 게시물 표시

2018년 8월 28일 화요일

nvidia-docker를 위한 Redhat 7.5 ppc64le docker image의 build


** 이 문서에서 서술하는 방식으로 만든 이미지들의 완성본을 다음의 주소에서 받으실 수 있습니다.   IBM GPU 서버인 AC922이나 Minsky 서버를 위한 Redhat 7.5 ppc64le + CUDA 9.2 + cudnn 7.2.1 + NCCL 2.2 + PowerAI 5.2 + Anaconda 2 (py2) or Anaconda3 (py3) 기반으로 만들어진 이미지들입니다.

https://hub.docker.com/r/bsyu/rhel75_ppc64le_cuda92_all_py2_powerai52/
https://hub.docker.com/r/bsyu/rhel75_ppc64le_cuda92_all_py3_powerai52/

Pull 할 때는 다음과 같이 하시면 됩니다.

# docker pull bsyu/rhel75_ppc64le_cuda92_all_py2_powerai52:v0.4     (python2.7)
# docker pull bsyu/rhel75_ppc64le_cuda92_all_py3_powerai52:v0.3     (python3.6)

아래는 이 docker image들을 만들 때의 과정입니다.

----------------------

먼저, 현재 host 서버의 OS(여기서는 Redhat 7.5 ALT ppc64le)를 기반으로 docker base image를 만듭니다.  아래 github에서 제공되는 mkimage-yum.sh를 사용하면 쉽습니다.

https://github.com/moby/moby/blob/master/contrib/mkimage-yum.sh

[root@ING ~]# cd docker

[root@ING docker]# vi mkimage-yum.sh    #  https://github.com/moby/moby/blob/master/contrib/mkimage-yum.sh의 script를 copy & paste

[root@ING docker]# chmod +x mkimage-yum.sh

[root@ING docker]# ./mkimage-yum.sh baserehel75alt
...
Running transaction
  Installing : libgcc-4.8.5-28.el7_5.1.ppc64le                                                                         1/243
  Installing : redhat-release-server-7.5-7.el7a.ppc64le                                                                2/243
  Installing : setup-2.8.71-9.el7.noarch                                                                               3/243
  Installing : filesystem-3.2-25.el7.ppc64le                                                                           4/243
  Installing : tzdata-2018e-3.el7.noarch                                                                               5/243
  Installing : basesystem-10.0-7.el7.noarch                                                                            6/243
...
  xz-libs.ppc64le 0:5.2.2-1.el7                                       yum-metadata-parser.ppc64le 0:1.1.4-10.el7
  zlib.ppc64le 0:1.2.7-17.el7

Complete!
+ [[ -n '' ]]
+ yum -c /etc/yum.conf --installroot=/tmp/mkimage-yum.sh.Oh71td -y clean all
Loaded plugins: langpacks, product-id, search-disabled-repos, subscription-manager
This system is not registered with an entitlement server. You can use subscription-manager to register.
There are no enabled repos.
 Run "yum repolist all" to see the repos you have.
 To enable Red Hat Subscription Management repositories:
     subscription-manager repos --enable <repo>
 To enable custom repositories:
     yum-config-manager --enable <repo>

Script가 위와 같이 성공적으로 완료된 뒤에 message에 표시된 /tmp 밑의 directory로 가보면 아래와 같이 mini-OS image가 마련되어 있는 것을 보실 수 있습니다. 
이제 이걸 tar로 말아올린 뒤 docker import 명령으로 import 해주면 됩니다.

[root@ING docker]# cd /tmp/mkimage-yum.sh.Oh71td

[root@ING mkimage-yum.sh.Oh71td]# ls -ltr
total 12
dr-xr-xr-x  2 root root    6 Dec 15  2017 sys
drwxr-xr-x  2 root root    6 Dec 15  2017 srv
dr-xr-xr-x  2 root root    6 Dec 15  2017 proc
drwxr-xr-x  2 root root    6 Dec 15  2017 opt
drwxr-xr-x  2 root root    6 Dec 15  2017 mnt
drwxr-xr-x  2 root root    6 Dec 15  2017 media
drwxr-xr-x  2 root root    6 Dec 15  2017 home
drwxr-xr-x  2 root root  180 Dec 15  2017 dev
dr-xr-xr-x  2 root root    6 Dec 15  2017 boot
lrwxrwxrwx  1 root root    7 Aug  9 09:47 bin -> usr/bin
lrwxrwxrwx  1 root root    8 Aug  9 09:47 sbin -> usr/sbin
lrwxrwxrwx  1 root root    9 Aug  9 09:47 lib64 -> usr/lib64
lrwxrwxrwx  1 root root    7 Aug  9 09:47 lib -> usr/lib
drwxr-xr-x 13 root root  207 Aug  9 09:47 usr
drwxrwxrwt  7 root root  117 Aug  9 09:47 tmp
drwxr-xr-x 19 root root  335 Aug  9 09:47 var
drwxr-xr-x 15 root root  261 Aug  9 09:47 run
drwxr-xr-x 68 root root 8192 Aug  9 09:47 etc
dr-xr-x---  2 root root   91 Aug  9 09:47 root

[root@ING mkimage-yum.sh.Oh71td]# tar -zcf /tmp/rhel7_ppc64le.tar.gz .

[root@ING mkimage-yum.sh.Oh71td]# ls -l /tmp/rhel7_ppc64le.tar.gz
-rw-r--r-- 1 root root 224266718 Aug  9 10:15 /tmp/rhel7_ppc64le.tar.gz

[root@ING mkimage-yum.sh.Oh71td]# docker import /tmp/rhel7_ppc64le.tar.gz bsyu/rhel75_ppc64le:base

[root@ING mkimage-yum.sh.Oh71td]# docker images
REPOSITORY                 TAG                         IMAGE ID            CREATED             SIZE
bsyu/rhel75_ppc64le        base                        3bf1baa60960        4 seconds ago       715 MB

이제 이 base image를 기반으로 dockerfile을 편집해서 CUDA 명령을 쓸 수 있는 nvidia-docker image를 만들면 됩니다.

그러기 위해서는 먼저 이 docker base image에서도 yum 명령을 써야 하는데, 기본적으로 Redhat에서 제공되는 /etc/yum.repos.d/redhat.repo 파일은 매번 yum을 기동할 때마다 자동으로 blank로 reset 되어버립니다.   따라서 이 파일 이름말고, 다른 이름, 가령 /etc/yum.repos.d/new.repo라는 이름으로 host OS에 있는 /etc/yum.repos.d/redhat.repo 파일을 그대로 저장해두면 host OS에서처럼 외부 YUM repository를 자유롭게 쓸 수 있습니다.   물론 이때 /etc/pki/entitlement/*-key.pem 등의 필요 ceritificate 파일들도 함께 docker image 속의 /etc/pki/entitlement에 copy 해두어야 합니다.   가령 다음과 같이 하면 됩니다.

[bsyu@p57a22 ~]# docker run -ti --rm -v /etc:/mnt bsyu/rhel75_ppc64le:base bash

----inside docker container------

[root@7e3b00f3fac2 ~]# cp /mnt/pki/entitlement/*.pem /etc/pki/entitlement

[root@7e3b00f3fac2 ~]# cp /mnt/yum.repos.d/redhat.repo /etc/yum.repos.d/new.repo    # 절대 redhat.repo라는 이름으로 copy하면 안 됩니다.

[root@7e3b00f3fac2 ~]# rpm -Uvh /mnt/epel-release-7-11.noarch.rpm   # epel-release-7-11.noarch.rpm 파일의 경우 host의 /etc 밑에 미리 copy해둡니다.

[root@7e3b00f3fac2 ~]# yum install wget curl cmake cmake3 make automake autoconf bzip2 zip unzip git gcc gcc-c++ gfortran yum-utils   # 기본적으로 필요한 package들을 미리 설치해둡니다.

----outside docker container------

[bsyu@p57a22 ~]# docker ps
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS              NAMES
7e3b00f3fac2        bsyu/rhel75_ppc64le:base bash   "bash"              23 hours ago        Up 23 hours                  angry_bose

[bsyu@p57a22 ~]# docker commit 7e3b00f3fac2 bsyu/rhel75_ppc64le:base_v6

이제 dockerfile을 이용하여 nvidia-docker 이미지를 만듭니다.  먼저 (다른 이름도 상관없습니다만) docker라는 directory를 만들고, 거기에 docker image 속에 설치할 cuda*.rpm 등을 미리 copy 해둡니다.  그리고나서 dockerfile.cuda92 파일을 다음과 같이 만듭니다.

[bsyu@p57a22 ~]# mkdir /home/docker && cd /home/docker   

[root@p57a22 docker]# vi dockerfile.cuda92
FROM bsyu/rhel75_ppc64le:base_v6

# Update image
# 'local' means rhel local repository
# To use these repos below in building process, you must set up the RHEL subscription and enable these repos on your host system first.
RUN yum-config-manager --enable rhel-7-for-power-9-rpms/7Server/ppc64le
RUN yum-config-manager --enable rhel-7-for-power-9-optional-rpms/7Server/ppc64le
RUN yum-config-manager --enable rhel-7-for-power-9-extras-rpms/7Server/ppc64le
RUN yum-config-manager --enable epel/ppc64le

RUN mkdir /tmp/temp
COPY cuda-repo-rhel7-9-2-local* /tmp/temp/
RUN rpm -Uvh /tmp/temp/cuda-repo-rhel7-9-2-local*
RUN yum install -y cuda

# nvidia-docker 1.0
LABEL com.nvidia.volumes.needed="nvidia_driver"
LABEL com.nvidia.cuda.version="${CUDA_VERSION}"

RUN echo "/usr/local/nvidia/lib" >> /etc/ld.so.conf.d/nvidia.conf && \
    echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf

ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/cuda/lib64/stubs

# nvidia-container-runtime
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
ENV NVIDIA_REQUIRE_CUDA "cuda>=9.2"

RUN yum clean all &&  rm -rf /var/cache/yum/* /tmp/temp
RUN rpm -e cuda-repo-rhel7-9-2-local

이제 위의 dockerfile.cuda92 파일을 이용하여 다음과 같이 bsyu/rhel75_ppc64le_cuda92_all:v0.1라는 이름으로 docker image를 build합니다.

[root@p57a22 docker]# docker build -t bsyu/rhel75_ppc64le_cuda92_all:v0.1 -f dockerfile.cuda92 .
Sending build context to Docker daemon 1.705 GB
Step 1/24 : FROM docker.io/bsyu/rhel75_ppc64le:base_v5
 ---> fc88cbad6b18
....
Cleaning up everything
Maybe you want: rm -rf /var/cache/yum, to also free up space taken by orphaned data from disabled or removed repos
 ---> f26c0a2167a0
Removing intermediate container bb911c868f27
Step 26/26 : RUN rpm -e cuda-repo-rhel7-9-2-local
 ---> Running in 6bceb027f2f1

 ---> deaf06286bf4
Removing intermediate container 6bceb027f2f1
Successfully built deaf06286bf4

다음과 같이 지정한 이름의 docker image가 생성된 것을 확인합니다.

[root@p57a22 docker]# docker images | grep bsyu
bsyu/rhel75_ppc64le_cuda92_all                 v0.1                        deaf06286bf4        45 seconds ago      8.11 GB
bsyu/rhel75_ppc64le                       base_v6                     872374a229f2        8 minutes ago       1.35 GB

이제 nvidia-docker로 이 image를 구동하여 nvidia-smi가 제대로 작동하는지 확인합니다.   그리고 PowerAI나 libcudnn* libnccl2* 등 필요 SW를 더 설치한 뒤 commit 하여 필요한 image를 추가로 만듭니다.

[bsyu@p57a22 data]$ nvidia-docker run -ti --rm -v /home/bsyu/files:/mnt bsyu/rhel75_ppc64le_cuda92_all:v0.1 bash

----inside docker container------

[root@e8a6f36fb132 /]# nvidia-smi
Thu Aug 23 01:28:52 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 396.26                 Driver Version: 396.26                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P100-SXM2...  Off  | 00000002:01:00.0 Off |                    0 |
| N/A   28C    P0    29W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-SXM2...  Off  | 00000003:01:00.0 Off |                    0 |
| N/A   30C    P0    32W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla P100-SXM2...  Off  | 0000000A:01:00.0 Off |                    0 |
| N/A   28C    P0    29W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla P100-SXM2...  Off  | 0000000B:01:00.0 Off |                    0 |
| N/A   31C    P0    29W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+


2018년 5월 16일 수요일

Ubuntu ppc64le 환경에서 nvidia-docker를 source로부터 build하기

최근에 nvidia-docker를 source에서 build 해보니 기존에 있던 ppc64le branch가 없어져서 그냥 하면 error가 납니다.   물론 nvidia-docker는 다음과 같이 apt repository에서 편리하게 설치가 가능합니다.

$ sudo vi /etc/apt/sources.list.d/nvidia-docker.list
deb https://nvidia.github.io/libnvidia-container/ubuntu16.04/$(ARCH) /
deb https://nvidia.github.io/nvidia-container-runtime/ubuntu16.04/$(ARCH) /
deb https://nvidia.github.io/nvidia-docker/ubuntu16.04/$(ARCH) /

$ sudo vi /etc/apt/sources.list.d/docker.list
deb [arch=ppc64el] https://download.docker.com/linux/ubuntu xenial stable


그래도 필요에 의해서 nvidia-docker를 source로부터 build해야 할 경우가 있습니다.   이 경우에도 근성만 있으면 아래와 같이 build가 가능합니다.

minsky_test@minsky:~/files$ git clone https://github.com/NVIDIA/nvidia-docker.git

minsky_test@minsky:~/files$ cd nvidia-docker

minsky_test@minsky:~/files/nvidia-docker$ git fetch --all

minsky_test@minsky:~/files/nvidia-docker$ git checkout tags/v1.0.1

여기서 그냥 make를 하시면 결국 다음과 같은 "exec format error"가 납니다.

minsky_test@minsky:~/files/nvidia-docker$ sudo make
...
http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64 /" > /etc/apt/sources.list.d/cuda.list
 ---> Running in 9bc30333d07a
standard_init_linux.go:178: exec user process caused "exec format error"
...
make: *** [tools] Error 2

이건 기본적으로 이 build를 위해 pull 해오는 golang container image가 ppc64le가 아닌 AMD64 아키텍처의 것이기 때문입니다.

minsky_test@minsky:~/files/nvidia-docker$ sudo docker inspect golang:1.5 | grep Arch
        "Architecture": "amd64",

이 문제와 기타 다른 문제들을 해결하기 위해 아래와 같이 Makefile과 Dockerfile.build을 일부 수정해주면 됩니다.

minsky_test@minsky:~/files/nvidia-docker$ vi Makefile
...
#ifneq ($(MAKECMDGOALS),rpm)
#PKG_ARCH := amd64
#else
#PKG_ARCH := x86_64
#endif
PKG_ARCH := ppc64le
...


minsky_test@minsky:~/files/nvidia-docker$ vi Dockerfile.build
#FROM golang:1.5
FROM ppc64le/golang:1.9
...
#    apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64/7fa2af80.pub && \
    apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/ppc64el/7fa2af80.pub && \
...
#    echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64 /" > /etc/apt/sources.list.d/cuda.list
    echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/ppc64el /" > /etc/apt/sources.list.d/cuda.list
...
#        cuda-cudart-dev-6-5=6.5-14 \
        cuda-cudart-dev-8-0=8.0.61-1 \
#        cuda-misc-headers-6-5=6.5-19 && \
        cuda-misc-headers-8-0=8.0.61-1 && \
...
#RUN objcopy --redefine-sym memcpy=memcpy@GLIBC_2.2.5 /usr/local/cuda-6.5/lib64/libcudart_static.a   #으로 comment-out합니다
...
#ENV CGO_CFLAGS "-I /usr/local/cuda-6.5/include -I /usr/include/nvidia/gdk"
ENV CGO_CFLAGS "-I /usr/local/cuda-8.0/include -I /usr/include/nvidia/gdk"
#ENV CGO_LDFLAGS "-L /usr/local/cuda-6.5/lib64"
ENV CGO_LDFLAGS "-L /usr/local/cuda-8.0/lib64"

이제 build를 하면 됩니다.  make tarball을 수행하면 nvidia-docker와 nvidia-docker-plugin binary를 tar.xz로 묶어 줍니다.  이걸 /usr/local 등 적절한 위치에 풀어주기만 하면 됩니다.

minsky_test@minsky:~/files/nvidia-docker$ sudo make tarball
...
Find tarball at /home/minsky_test/files/nvidia-docker/dist

minsky_test@minsky:~/files/nvidia-docker$ tar -tvf /home/minsky_test/files/nvidia-docker/dist/nvidia-docker_1.0.1_ppc64le.tar.xz
-rwxr-xr-x root/miruware 5247984 2018-05-16 16:57 nvidia-docker/nvidia-docker
-rwxr-xr-x root/miruware 6489232 2018-05-16 16:57 nvidia-docker/nvidia-docker-plugin

물론 이렇게 source에서 build한 nvidia-docker는 service로 등록하기 전엔 아래처럼 손으로 start 해주고 kill로 죽여야 합니다.

minsky_test@minsky:~/files/nvidia-docker/bin$ sudo ./nvidia-docker-plugin &

minsky_test@minsky:~/files/nvidia-docker/bin$ sudo ./nvidia-docker run -ti bsyu/tf1.3-ppc64le:v0.1 bash

root@78d0b67e2c8d:/# nvidia-smi
Wed May 16 08:05:31 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.111                Driver Version: 384.111                   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P100-SXM2...  Off  | 00000002:01:00.0 Off |                    0 |
| N/A   35C    P0    31W / 300W |     10MiB / 16276MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-SXM2...  Off  | 00000003:01:00.0 Off |                    0 |
| N/A   35C    P0    30W / 300W |     10MiB / 16276MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla P100-SXM2...  Off  | 0000000A:01:00.0 Off |                    0 |
| N/A   35C    P0    32W / 300W |     10MiB / 16276MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla P100-SXM2...  Off  | 0000000B:01:00.0 Off |                    0 |
| N/A   30C    P0    31W / 300W |     10MiB / 16276MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

아래에 이렇게 만들어진 nvidia-docker tarball을 google drive에 올려놓았습니다.

https://drive.google.com/open?id=1XoXXgpdsQPKHo-IPx3iNbKuJYHKgpihz

nvidia-driver 올린 뒤 container 속에서의 "Driver/library version mismatch" error

다음과 같이 nvidia-driver가 384.111인 환경에서 docker image bsyu/tf1.3-ppc64le:v0.1를 구동했습니다.

minsky_test@minsky:~/files/nvidia-docker/bin$ sudo ./nvidia-docker run -ti bsyu/tf1.3-ppc64le:v0.1 bash

그 속에 들어가서 nvidia-smi 명령으로 nvidia-driver가 384.111인 것을 확인합니다.

root@78d0b67e2c8d:/# nvidia-smi
Wed May 16 08:05:31 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.111                Driver Version: 384.111                   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P100-SXM2...  Off  | 00000002:01:00.0 Off |                    0 |
| N/A   35C    P0    31W / 300W |     10MiB / 16276MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-SXM2...  Off  | 00000003:01:00.0 Off |                    0 |
| N/A   35C    P0    30W / 300W |     10MiB / 16276MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla P100-SXM2...  Off  | 0000000A:01:00.0 Off |                    0 |
| N/A   35C    P0    32W / 300W |     10MiB / 16276MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla P100-SXM2...  Off  | 0000000B:01:00.0 Off |                    0 |
| N/A   30C    P0    31W / 300W |     10MiB / 16276MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

이 docker container에 변화를 주기 위해 다음과 같이 tensorflow models를 clone 해서 넣습니다.

root@78d0b67e2c8d:/# git clone https://github.com/tensorflow/models.git

root@78d0b67e2c8d:/# cd /models/tutorials/image/cifar10

여기서 cifar10 training을 잠깐 시켜봐도 좋습니다.   도중에 중단시키고 빠져 나갑니다.

root@78d0b67e2c8d:/models/tutorials/image/cifar10# python cifar10_train.py
...
2018-05-16 08:15:25.329494: step 1520, loss = 1.97 (9342.9 examples/sec; 0.014 sec/batch)
2018-05-16 08:15:25.454485: step 1530, loss = 1.86 (10240.0 examples/sec; 0.013 sec/batch)
2018-05-16 08:15:25.580138: step 1540, loss = 2.06 (10186.0 examples/sec; 0.013 sec/batch)
2018-05-16 08:15:25.711379: step 1550, loss = 1.73 (9754.1 examples/sec; 0.013 sec/batch)
^Z
[1]+  Stopped                 python cifar10_train.py
root@78d0b67e2c8d:/models/tutorials/image/cifar10# exit


이제 parent OS로 나왔습니다.  docker ps 명령으로 다음과 같이 78d0b67e2c8d container가 남아 있는 것을 보실 수 있습니다.

minsky_test@minsky:~/files/nvidia-docker/bin$ docker ps -a
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                           PORTS               NAMES
78d0b67e2c8d        bsyu/tf1.3-ppc64le:v0.1   "bash"                   11 minutes ago      Exited (148) 43 seconds ago                          vigilant_jennings
af8e4f0af9d2        9d72ea809195              "/bin/sh -c 'go ge..."   42 minutes ago      Exited (2) 42 minutes ago                            practical_brown
021b52c86fdf        588a60a80ab7              "/bin/sh -c 'go ge..."   About an hour ago   Exited (2) About an hour ago                         nifty_beaver
716660e1b44b        bf2674b6db4a              "/bin/sh -c 'go ge..."   About an hour ago   Exited (1) About an hour ago                         blissful_pasteur
7e0b933581c5        3349633cccc3              "/bin/sh -c 'apt-g..."   About an hour ago   Exited (100) About an hour ago                       unruffled_haibt
53853b98c3f0        958e9eb53afd              "/bin/sh -c 'NVIDI..."   About an hour ago   Exited (2) About an hour ago                         goofy_williams
85afec3a1429        52a84e97014b              "/bin/bash -c 'mak..."   3 weeks ago         Exited (2) 3 weeks ago                               vigilant_curie
5e172a9eb6c0        3426d0bdc1ee              "/bin/sh -c 'cd /p..."   3 weeks ago         Exited (2) 3 weeks ago                               thirsty_wescoff
27725169f8c2        c9cf4b61ab78              "/bin/sh -c 'pip i..."   3 weeks ago         Exited (127) 3 weeks ago 

이제 nvidia driver를 390으로 올립니다.

minsky_test@minsky:~$ sudo apt-get install nvidia-390-dev nvidia-390

당장 nvidia-smi를 해보면 error가 납니다.  원래는 reboot을 해야 하는데, 그러지 않았기 때문인가 봅니다.

minsky_test@minsky:~$ nvidia-smi
Failed to initialize NVML: Driver/library version mismatch

이걸 rebooting하지 않고 하기 위해서는 nvidia-docker-plugin을 죽인 뒤, 현재 load된 nvidia 관련 module들을 rmmod로 제거한 뒤 다시 nvidia-docker-plugin을 살리면 됩니다.

minsky_test@minsky:~$ ps -ef | grep 86949 | grep -v grep
root      86949  86948  0 17:03 pts/7    00:00:03 ./nvidia-docker-plugin

minsky_test@minsky:~$ sudo kill -9 86949

minsky_test@minsky:~$ sudo lsmod | grep nvidia
nvidia_drm             59673  0
nvidia_modeset       1173401  1 nvidia_drm
nvidia_uvm            869865  4
nvidia              16625272  779 nvidia_modeset,nvidia_uvm
drm_kms_helper        182400  2 ast,nvidia_drm
drm                   453521  5 ast,ttm,drm_kms_helper,nvidia_drm

minsky_test@minsky:~$ sudo rmmod nvidia_drm

minsky_test@minsky:~$ sudo rmmod nvidia_uvm

minsky_test@minsky:~$ sudo rmmod nvidia_modeset

minsky_test@minsky:~$ sudo rmmod nvidia

nvidia 관련 모듈이 다 없어진 것을 아래와 같이 확인합니다.

minsky_test@minsky:~$ sudo lsmod | grep nvidia
minsky_test@minsky:~$

이제 다시 nvidia-docker-plugin을 살립니다.  그러면 nvidia 관련 module들이 다시 load 됩니다.

minsky_test@minsky:~/files/nvidia-docker/bin$ sudo ./nvidia-docker-plugin &

이제 nvidia-smi로 보면 driver 버전이 390.31로 올라온 것을 볼 수 있습니다.

minsky_test@minsky:~/files/nvidia-docker/bin$ nvidia-smi
Wed May 16 17:32:17 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.31                 Driver Version: 390.31                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P100-SXM2...  Off  | 00000002:01:00.0 Off |                    0 |
| N/A   37C    P0    31W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-SXM2...  Off  | 00000003:01:00.0 Off |                    0 |
| N/A   36C    P0    30W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla P100-SXM2...  Off  | 0000000A:01:00.0 Off |                    0 |
| N/A   36C    P0    32W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla P100-SXM2...  Off  | 0000000B:01:00.0 Off |                    0 |
| N/A   31C    P0    31W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

이제 아까 exit했던 bsyu/tf1.3-ppc64le:v0.1의 container인 78d0b67e2c8d에 다시 attach 해보겠습니다.

minsky_test@minsky:~/files/nvidia-docker/bin$ sudo ./nvidia-docker start 78d0b67e2c8d
78d0b67e2c8d

minsky_test@minsky:~/files/nvidia-docker/bin$ sudo ./nvidia-docker attach 78d0b67e2c8d
root@78d0b67e2c8d:/#

이 속에서 nvidia-smi 해봐도 다음과 같은 error만 납니다.

root@78d0b67e2c8d:/# nvidia-smi
Failed to initialize NVML: Driver/library version mismatch

이렇게 예전 버전의 384 driver를 가지고 구동된 container는 다시 제대로 작동시킬 방법이 없습니다.  새로 다시 시작해야 하는데, 그러자면 기존에 변경시켜둔 file 내용들이 날라갑니다.  그렇게 변경시켜둔 file들을 보존하려면 docker commit을 하시면 됩니다.  가령 아까 위에서 clone 받아둔 /models의 내용이 그대로 보존될 수 있습니다.

먼저 parent OS에서 다음과 같이 새로운 이름의 image로 해당 container id를 commit 합니다.

minsky_test@minsky:~/files/nvidia-docker/bin$ ./nvidia-docker commit 78d0b67e2c8d bsyu/tf1.3-ppc64le:v0.2
sha256:4e5cf1b9f9672a41d2a71737f32a0d0f2a042d9162ab351433d16a828946d4f4

이제 새로 만들어진 bsyu/tf1.3-ppc64le:v0.2 image를 새로 start 합니다.

minsky_test@minsky:~/files/nvidia-docker/bin$ ./nvidia-docker run -ti bsyu/tf1.3-ppc64le:v0.2 bash

이제 nvidia-smi를 해보시면 새로운 driver version으로 잘 올라오는 것을 보실 수 있습니다.

root@53f8f0993f34:/# nvidia-smi
Wed May 16 08:39:33 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.31                 Driver Version: 390.31                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P100-SXM2...  Off  | 00000002:01:00.0 Off |                    0 |
| N/A   34C    P0    30W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-SXM2...  Off  | 00000003:01:00.0 Off |                    0 |
| N/A   34C    P0    30W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla P100-SXM2...  Off  | 0000000A:01:00.0 Off |                    0 |
| N/A   33C    P0    31W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla P100-SXM2...  Off  | 0000000B:01:00.0 Off |                    0 |
| N/A   29C    P0    31W / 300W |     10MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

물론 /models directory도 그대로 잘 보존되어 있습니다.

root@53f8f0993f34:/# cd /models/tutorials/image/cifar10
root@53f8f0993f34:/models/tutorials/image/cifar10# ls
BUILD      __init__.py  cifar10.py       cifar10_input.py       cifar10_multi_gpu_train.py
README.md  __pycache__  cifar10_eval.py  cifar10_input_test.py  cifar10_train.py

2018년 2월 20일 화요일

ppc64le용 docker 및 nvidia-docker repository 주소 (Redhat과 Ubuntu)

nvidia-docker version2는 아직 ppc64le에서 테스트되지 않았습니다.  현재는 기존 version1을 쓰시면 됩니다.  그 설치는 기존처럼 source에서 빌드하실 필요가 없고, 아래의 repository를 등록해서 YUM(redhat)과 APT(ubuntu)에서 각각 설치하시면 됩니다.


1. Redhat 환경의 경우

[root@ac922 ~]# cat /etc/yum.repos.d/docker.repo
[docker]
name=Docker
baseurl=http://ftp.unicamp.br/pub/ppc64el/rhel/7/docker-ppc64el/
enabled=1
gpgcheck=0

[root@ac922 ~]# cat /etc/yum.repos.d/nvidia-docker.repo
[nvidia-docker]
name=nvidia-docker
baseurl=https://nvidia.github.io/nvidia-docker/centos7/ppc64le
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://nvidia.github.io/nvidia-docker/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt

[root@ac922 ~]# yum list | grep nvidia-docker
Repository 'local' is missing name in configuration, using id
nvidia-docker.ppc64le                     1.0.1-1                  @nvidia-docker



2. Ubuntu 환경의 경우

u0017649@sys-91795:~$ cat /etc/apt/sources.list.d/docker.list
deb http://ftp.unicamp.br/pub/ppc64el/ubuntu/16_04/docker-17.06.1-ce-ppc64el xenial Release

u0017649@sys-91436:~$ cat /etc/apt/sources.list.d/nvidia-docker.list
deb https://nvidia.github.io/nvidia-docker/ubuntu16.04/ppc64el /

u0017649@sys-91436:~$ sudo apt-get update

u0017649@sys-91436:~$ sudo apt-get install docker.io nvidia-docker

2017년 11월 10일 금요일

tensorflow 1.3, caffe2, pytorch의 nvidia-docker를 이용한 테스트

tensorflow 1.3, caffe2, pytorch의 nvidia-docker를 이용한 테스트 방법입니다.

1) tensorflow v1.3

다음과 같이 tensorflow 1.3 docker image를 구동합니다.

root@minsky:~# nvidia-docker run -ti --rm  -v /data:/data bsyu/tf1.3-ppc64le:v0.1 bash

먼저 각종 PATH 환경 변수를 확인합니다.

root@67c0e6901bb2:/# env | grep PATH
LIBRARY_PATH=/usr/local/cuda/lib64/stubs:
LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64
PATH=/opt/anaconda3/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PYTHONPATH=/opt/anaconda3/lib/python3.6/site-packages

cifar10 관련된 example code가 들어있는 directory로 이동합니다.

root@67c0e6901bb2:/# cd /data/imsi/tensorflow/models/tutorials/image/cifar10

수행할 cifar10_multi_gpu_train.py code를 일부 수정합니다.  (원래는 --train_dir 등의 명령어 파라미터로 조정이 가능해야 하는데, 실제로는 직접 source를 수정해야 제대로 수행되는 것 같습니다.)

root@67c0e6901bb2:/data/imsi/tensorflow/models/tutorials/image/cifar10# time python cifar10_multi_gpu_train.py --batch_size 512 --num_gpus 2
usage: cifar10_multi_gpu_train.py [-h] [--batch_size BATCH_SIZE]
                                  [--data_dir DATA_DIR] [--use_fp16 USE_FP16]
cifar10_multi_gpu_train.py: error: unrecognized arguments: --num_gpus 2

위와 같은 error를 막기 위해, 아래와 같이 직접 code를 수정합니다.

root@67c0e6901bb2:/data/imsi/tensorflow/models/tutorials/image/cifar10# vi cifar10_multi_gpu_train.py
...
#parser.add_argument('--train_dir', type=str, default='/tmp/cifar10_train',
parser.add_argument('--train_dir', type=str, default='/data/imsi/test/tf1.3',
                    help='Directory where to write event logs and checkpoint.')

#parser.add_argument('--max_steps', type=int, default=1000000,
parser.add_argument('--max_steps', type=int, default=10000,
                    help='Number of batches to run.')

#parser.add_argument('--num_gpus', type=int, default=1,
parser.add_argument('--num_gpus', type=int, default=4,
                    help='How many GPUs to use.')


이제 다음과 같이 run 하시면 됩니다.  여기서는 batch_size를 512로 했는데, 더 크게 잡아도 될 것 같습니다.

root@67c0e6901bb2:/data/imsi/tensorflow/models/tutorials/image/cifar10# time python cifar10_multi_gpu_train.py --batch_size 512
>> Downloading cifar-10-binary.tar.gz 6.1%
...
2017-11-10 01:20:23.628755: step 9440, loss = 0.63 (15074.6 examples/sec; 0.034 sec/batch)
2017-11-10 01:20:25.052011: step 9450, loss = 0.64 (14615.4 examples/sec; 0.035 sec/batch)
2017-11-10 01:20:26.489564: step 9460, loss = 0.55 (14872.0 examples/sec; 0.034 sec/batch)
2017-11-10 01:20:27.860303: step 9470, loss = 0.61 (14515.9 examples/sec; 0.035 sec/batch)
2017-11-10 01:20:29.289386: step 9480, loss = 0.54 (13690.6 examples/sec; 0.037 sec/batch)
2017-11-10 01:20:30.799570: step 9490, loss = 0.69 (15940.8 examples/sec; 0.032 sec/batch)
2017-11-10 01:20:32.239056: step 9500, loss = 0.54 (12581.4 examples/sec; 0.041 sec/batch)
2017-11-10 01:20:34.219832: step 9510, loss = 0.60 (14077.9 examples/sec; 0.036 sec/batch)
...

다음으로는 전체 CPU, 즉 2개 chip 총 16-core의 절반인 1개 chip 8-core와, 전체 GPU 4개 중 2개의 GPU만 할당한 docker를 수행합니다.   여기서 --cpuset-cpus을 써서 CPU 자원을 control할 때, 저렇게 CPU 번호를 2개씩 그룹으로 줍니다.  이는 IBM POWER8가 SMT(hyperthread)가 core당 8개씩 낼 수 있는 특성 때문에 core 1개당 8개의 logical CPU 번호를 할당하기 때문입니다.  현재는 deep learning의 성능 최적화를 위해 SMT를 8이 아닌 2로 맞추어 놓았습니다.

root@minsky:~# NV_GPU=0,1 nvidia-docker run -ti --rm --cpuset-cpus="0,1,8,9,16,17,24,25,32,33,40,41,48,49" -v /data:/data bsyu/tf1.3-ppc64le:v0.1 bash

root@3b2c2614811d:~# nvidia-smi

Fri Nov 10 02:24:14 2017
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 361.119                Driver Version: 361.119                   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P100-SXM2...  On   | 0002:01:00.0     Off |                    0 |
| N/A   38C    P0    30W / 300W |      0MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-SXM2...  On   | 0003:01:00.0     Off |                    0 |
| N/A   40C    P0    33W / 300W |      0MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+


root@3b2c2614811d:/# cd /data/imsi/tensorflow/models/tutorials/image/cifar10

이제 GPU가 4개가 아니라 2개이므로, cifar10_multi_gpu_train.py도 아래와 같이 수정합니다.

root@3b2c2614811d:/data/imsi/tensorflow/models/tutorials/image/cifar10# vi cifar10_multi_gpu_train.py
...
#parser.add_argument('--num_gpus', type=int, default=1,
parser.add_argument('--num_gpus', type=int, default=2,
                    help='How many GPUs to use.')

수행하면 잘 돌아갑니다.

root@3b2c2614811d:/data/imsi/tensorflow/models/tutorials/image/cifar10# time python cifar10_multi_gpu_train.py --batch_size 512
>> Downloading cifar-10-binary.tar.gz 1.7%
...
2017-11-10 02:35:50.040462: step 120, loss = 4.07 (15941.4 examples/sec; 0.032 sec/batch)
2017-11-10 02:35:50.587970: step 130, loss = 4.14 (19490.7 examples/sec; 0.026 sec/batch)
2017-11-10 02:35:51.119347: step 140, loss = 3.91 (18319.8 examples/sec; 0.028 sec/batch)
2017-11-10 02:35:51.655916: step 150, loss = 3.87 (20087.1 examples/sec; 0.025 sec/batch)
2017-11-10 02:35:52.181703: step 160, loss = 3.90 (19215.5 examples/sec; 0.027 sec/batch)
2017-11-10 02:35:52.721608: step 170, loss = 3.82 (17780.1 examples/sec; 0.029 sec/batch)
2017-11-10 02:35:53.245088: step 180, loss = 3.92 (18888.4 examples/sec; 0.027 sec/batch)
2017-11-10 02:35:53.777146: step 190, loss = 3.80 (19103.7 examples/sec; 0.027 sec/batch)
2017-11-10 02:35:54.308063: step 200, loss = 3.76 (18554.2 examples/sec; 0.028 sec/batch)
...


2) caffe2

여기서는 처음부터 GPU 2개와 CPU core 8개만 가지고 docker를 띄워 보겠습니다.

root@minsky:~# NV_GPU=0,1 nvidia-docker run -ti --rm --cpuset-cpus="0,1,8,9,16,17,24,25,32,33,40,41,48,49" -v /data:/data bsyu/caffe2-ppc64le:v0.3 bash

보시는 바와 같이 GPU가 2개만 올라옵니다.

root@dc853a5495a0:/# nvidia-smi

Fri Nov 10 07:22:21 2017
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 361.119                Driver Version: 361.119                   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P100-SXM2...  On   | 0002:01:00.0     Off |                    0 |
| N/A   32C    P0    29W / 300W |      0MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-SXM2...  On   | 0003:01:00.0     Off |                    0 |
| N/A   35C    P0    32W / 300W |      0MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

환경변수를 확인합니다.  여기서는 caffe2가 /opt/caffe2에 설치되어 있으므로, LD_LIBRARY_PATH나 PYTHONPATH를 거기에 맞춥니다.

root@dc853a5495a0:/# env | grep PATH
LIBRARY_PATH=/usr/local/cuda/lib64/stubs:
LD_LIBRARY_PATH=/opt/caffe2/lib:/opt/DL/nccl/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64
PATH=/opt/caffe2/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PYTHONPATH=/opt/caffe2

caffe2는 아래의 resnet50_trainer.py를 이용해 테스트합니다.  그 전에, 먼저 https://github.com/caffe2/caffe2/issues/517 에 나온 lmdb 생성 문제를 해결하기 위해 이 URL에서 제시하는 대로 아래와 같이 code 일부를 수정합니다.

root@dc853a5495a0:/# cd /data/imsi/caffe2/caffe2/python/examples
root@dc853a5495a0:/data/imsi/caffe2/caffe2/python/examples# vi lmdb_create_example.py
...
            flatten_img = img_data.reshape(np.prod(img_data.shape))
#            img_tensor.float_data.extend(flatten_img)
            img_tensor.float_data.extend(flatten_img.flat)

이어서 다음과 같이 lmdb를 생성합니다.   이미 1번 수행했으므로 다시 할 경우 매우 빨리 수행될 것입니다.

root@dc853a5495a0:/data/imsi/caffe2/caffe2/python/examples# python lmdb_create_example.py --output_file /data/imsi/test/caffe2/lmdb
>>> Write database...
Inserted 0 rows
Inserted 16 rows
Inserted 32 rows
Inserted 48 rows
Inserted 64 rows
Inserted 80 rows
Inserted 96 rows
Inserted 112 rows
Checksum/write: 1744827
>>> Read database...
Checksum/read: 1744827

그 다음에 training을 다음과 같이 수행합니다.  여기서는 GPU가 2개만 보이는 환경이므로, --gpus에 0,1,2,3 대신 0,1만 써야 합니다.

root@dc853a5495a0:/data/imsi/caffe2/caffe2/python/examples# time python resnet50_trainer.py --train_data /data/imsi/test/caffe2/lmdb --gpus 0,1 --batch_size 128 --num_epochs 1

수행하면 다음과 같이 'not a valid file'이라는 경고 메시지가 나옵니다만, github 등을 googling해보면 무시하셔도 되는 메시지입니다.

Ignoring @/caffe2/caffe2/contrib/nccl:nccl_ops as it is not a valid file.
Ignoring @/caffe2/caffe2/contrib/gloo:gloo_ops as it is not a valid file.
Ignoring @/caffe2/caffe2/contrib/gloo:gloo_ops_gpu as it is not a valid file.
Ignoring @/caffe2/caffe2/distributed:file_store_handler_ops as it is not a valid file.
Ignoring @/caffe2/caffe2/distributed:redis_store_handler_ops as it is not a valid file.
INFO:resnet50_trainer:Running on GPUs: [0, 1]
INFO:resnet50_trainer:Using epoch size: 1499904
INFO:data_parallel_model:Parallelizing model for devices: [0, 1]
INFO:data_parallel_model:Create input and model training operators
INFO:data_parallel_model:Model for GPU : 0
INFO:data_parallel_model:Model for GPU : 1
INFO:data_parallel_model:Adding gradient operators
INFO:data_parallel_model:Add gradient all-reduces for SyncSGD
INFO:data_parallel_model:Post-iteration operators for updating params
INFO:data_parallel_model:Calling optimizer builder function
INFO:data_parallel_model:Add initial parameter sync
WARNING:data_parallel_model:------- DEPRECATED API, please use data_parallel_model.OptimizeGradientMemory() -----
WARNING:memonger:NOTE: Executing memonger to optimize gradient memory
INFO:memonger:Memonger memory optimization took 0.252535104752 secs
WARNING:memonger:NOTE: Executing memonger to optimize gradient memory
INFO:memonger:Memonger memory optimization took 0.253523111343 secs
INFO:resnet50_trainer:Starting epoch 0/1
INFO:resnet50_trainer:Finished iteration 1/11718 of epoch 0 (27.70 images/sec)
INFO:resnet50_trainer:Training loss: 7.39205980301, accuracy: 0.0
INFO:resnet50_trainer:Finished iteration 2/11718 of epoch 0 (378.51 images/sec)
INFO:resnet50_trainer:Training loss: 0.0, accuracy: 1.0
INFO:resnet50_trainer:Finished iteration 3/11718 of epoch 0 (387.87 images/sec)
INFO:resnet50_trainer:Training loss: 0.0, accuracy: 1.0
INFO:resnet50_trainer:Finished iteration 4/11718 of epoch 0 (383.28 images/sec)
INFO:resnet50_trainer:Training loss: 0.0, accuracy: 1.0
INFO:resnet50_trainer:Finished iteration 5/11718 of epoch 0 (381.71 images/sec)
...

다만 위와 같이 처음부터 accuracy가 1.0으로 나오는 문제가 있습니다.  이 resnet50_trainer.py 문제에 대해서는 caffe2의 github에 아래와 같이 discussion들이 있었습니다만, 아직 뾰족한 해결책은 없는 상태입니다.  하지만 상대적 시스템 성능 측정에는 별 문제가 없습니다.

https://github.com/caffe2/caffe2/issues/810


3) pytorch

이번에는 pytorch 이미지로 테스트하겠습니다.

root@8ccd72116fee:~# env | grep PATH
LIBRARY_PATH=/usr/local/cuda/lib64/stubs:
LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64
PATH=/opt/anaconda3/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

먼저 docker image를 아래와 같이 구동합니다.  단, 여기서는 --ipc=host 옵션을 씁니다.  이유는 https://discuss.pytorch.org/t/imagenet-example-is-crashing/1363/2 에서 언급된 hang 현상을 피하기 위한 것입니다. 

root@minsky:~# nvidia-docker run -ti --rm --ipc=host -v /data:/data bsyu/pytorch-ppc64le:v0.1 bash

가장 간단한 example인 mnist를 아래와 같이 수행합니다.  10 epochs를 수행하는데 대략 1분 30초 정도가 걸립니다.

root@8ccd72116fee:/data/imsi/examples/mnist# time python main.py --batch-size 512 --epochs 10
...
rain Epoch: 9 [25600/60000 (42%)]      Loss: 0.434816
Train Epoch: 9 [30720/60000 (51%)]      Loss: 0.417652
Train Epoch: 9 [35840/60000 (59%)]      Loss: 0.503125
Train Epoch: 9 [40960/60000 (68%)]      Loss: 0.477776
Train Epoch: 9 [46080/60000 (76%)]      Loss: 0.346416
Train Epoch: 9 [51200/60000 (85%)]      Loss: 0.361492
Train Epoch: 9 [56320/60000 (93%)]      Loss: 0.383941

Test set: Average loss: 0.1722, Accuracy: 9470/10000 (95%)

Train Epoch: 10 [0/60000 (0%)]  Loss: 0.369119
Train Epoch: 10 [5120/60000 (8%)]       Loss: 0.377726
Train Epoch: 10 [10240/60000 (17%)]     Loss: 0.402854
Train Epoch: 10 [15360/60000 (25%)]     Loss: 0.349409
Train Epoch: 10 [20480/60000 (34%)]     Loss: 0.295271
...

다만 이건 single-GPU만 사용하는 example입니다.  Multi-GPU를 사용하기 위해서는 아래의 imagenet example을 수행해야 하는데, 그러자면 ilsvrc2012 dataset을 download 받아 풀어놓아야 합니다.  그 data는 아래와 같이 /data/imagenet_dir/train과 /data/imagenet_dir/val에 각각 JPEG 형태로 풀어놓았습니다.

root@minsky:/data/imagenet_dir/train# while read SYNSET; do
> mkdir -p ${SYNSET}
> tar xf ../../ILSVRC2012_img_train.tar "${SYNSET}.tar"
> tar xf "${SYNSET}.tar" -C "${SYNSET}"
> rm -f "${SYNSET}.tar"
> done < /opt/DL/caffe-nv/data/ilsvrc12/synsets.txt

root@minsky:/data/imagenet_dir/train# ls -1 | wc -l
1000
root@minsky:/data/imagenet_dir/train# du -sm .
142657  .
root@minsky:/data/imagenet_dir/train# find . | wc -l
1282168

root@minsky:/data/imagenet_dir/val# ls -1 | wc -l
50000

이 상태에서 그대로 main.py를 수행하면 다음과 같은 error를 겪게 됩니다.  이유는 이 main.py는 val 디렉토리 밑에도 label별 디렉토리에 JPEG 파일들이 들어가 있기를 기대하는 구조이기 때문입니다.

RuntimeError: Found 0 images in subfolders of: /data/imagenet_dir/val
Supported image extensions are: .jpg,.JPG,.jpeg,.JPEG,.png,.PNG,.ppm,.PPM,.bmp,.BMP

따라서 아래와 같이 inception 디렉토리의 preprocess_imagenet_validation_data.py를 이용하여 label별 디렉토리로 JPEG 파일들을 분산 재배치해야 합니다.

root@minsky:/data/models/research/inception/inception/data# python preprocess_imagenet_validation_data.py /data/imagenet_dir/val imagenet_2012_validation_synset_labels.txt

이제 다시 보면 label별로 재분배된 것을 보실 수 있습니다.

root@minsky:/data/imagenet_dir/val# ls | head -n 3
n01440764
n01443537
n01484850

root@minsky:/data/imagenet_dir/val# ls | wc -l
1000
root@minsky:/data/imagenet_dir/val# find . | wc -l
51001

이제 다음과 같이 main.py를 수행하면 됩니다. 

root@8ccd72116fee:~# cd /data/imsi/examples/imagenet

root@8ccd72116fee:/data/imsi/examples/imagenet# time python main.py -a resnet18 --epochs 1 /data/imagenet_dir
=> creating model 'resnet18'
Epoch: [0][0/5005]      Time 11.237 (11.237)    Data 2.330 (2.330)      Loss 7.0071 (7.0071)    Prec@1 0.391 (0.391)   Prec@5 0.391 (0.391)
Epoch: [0][10/5005]     Time 0.139 (1.239)      Data 0.069 (0.340)      Loss 7.1214 (7.0515)    Prec@1 0.000 (0.284)   Prec@5 0.000 (1.065)
Epoch: [0][20/5005]     Time 0.119 (0.854)      Data 0.056 (0.342)      Loss 7.1925 (7.0798)    Prec@1 0.000 (0.260)   Prec@5 0.781 (0.930)
...




* 위에서 사용된 docker image들은 다음과 같이 backup을 받아두었습니다.

root@minsky:/data/docker_save# docker save --output caffe2-ppc64le.v0.3.tar bsyu/caffe2-ppc64le:v0.3
root@minsky:/data/docker_save# docker save --output pytorch-ppc64le.v0.1.tar bsyu/pytorch-ppc64le:v0.1
root@minsky:/data/docker_save# docker save --output tf1.3-ppc64le.v0.1.tar bsyu/tf1.3-ppc64le:v0.1
root@minsky:/data/docker_save# docker save --output cudnn6-conda2-ppc64le.v0.1.tar bsyu/cudnn6-conda2-ppc64le:v0.1
root@minsky:/data/docker_save# docker save --output cudnn6-conda3-ppc64le.v0.1.tar bsyu/cudnn6-conda3-ppc64le:v0.1

root@minsky:/data/docker_save# ls -l
total 28023280
-rw------- 1 root root 4713168896 Nov 10 16:48 caffe2-ppc64le.v0.3.tar
-rw------- 1 root root 4218520064 Nov 10 17:10 cudnn6-conda2-ppc64le.v0.1.tar
-rw------- 1 root root 5272141312 Nov 10 17:11 cudnn6-conda3-ppc64le.v0.1.tar
-rw------- 1 root root 6921727488 Nov 10 16:51 pytorch-ppc64le.v0.1.tar
-rw------- 1 root root 7570257920 Nov 10 16:55 tf1.3-ppc64le.v0.1.tar

비상시엔 이 이미지들을 docker load 명령으로 load 하시면 됩니다.

(예)  docker load --input caffe2-ppc64le.v0.3.tar

2017년 11월 1일 수요일

caffe2, tensorflow 1.3, pytorch가 설치된 docker image 만들기

docker hub에서 제공되는 nvidia/cuda-ppc64le 이미지를 이용하여, 거기에 이것저것 원하는 package를 설치하고 docker commit 명령을 통해 새로운 이미지를 만드는 방법을 보시겠습니다.

먼저 parent ubuntu OS에서 필요한 file들을 아래처럼 docker라는 directory에 모아둡니다.

root@firestone:~/docker# ls -l
total 2369580
-rwxr-xr-x  1 root root  284629257 Oct 31 22:27 Anaconda2-4.4.0.1-Linux-ppc64le.sh
-rwxr-xr-x  1 root root  299425582 Oct 31 22:28 Anaconda3-4.4.0.1-Linux-ppc64le.sh
-rw-r--r--  1 root root 1321330418 Oct 31 22:35 cuda-repo-ubuntu1604-8-0-local-ga2v2_8.0.61-1_ppc64el.deb
-rwxr-xr-x  1 root root       8788 Oct 31 21:40 debootstrap.sh
-rw-r--r--  1 root root   68444212 Oct 31 22:35 libcudnn6_6.0.21-1+cuda8.0_ppc64el.deb
-rw-r--r--  1 root root   59820704 Oct 31 22:35 libcudnn6-dev_6.0.21-1+cuda8.0_ppc64el.deb
-rw-r--r--  1 root root    6575300 Oct 31 22:35 libcudnn6-doc_6.0.21-1+cuda8.0_ppc64el.deb
-rw-r--r--  1 root root  386170568 Oct 31 22:36 mldl-repo-local_4.0.0_ppc64el.deb
drwxr-xr-x 21 root root       4096 Oct 31 21:55 ubuntu


이미 nvidia/cuda-ppc64le 이미지는 docker pull 명령으로 당겨왔습니다.

root@firestone:~/docker# docker images | grep nvidia
nvidia-docker                                       build                            405ee913a07e        About an hour ago   1.02GB
nvidia/cuda-ppc64le                                 8.0-cudnn6-runtime-ubuntu16.04   bf28cd22ff84        6 weeks ago         974MB
nvidia/cuda-ppc64le                                 latest                           9b0a21e35c66        6 weeks ago         1.72GB


이제 nvidia/cuda-ppc64le:latest를 interactive mode로 구동합니다.  이때 docker directory를 /docker라는 이름으로 마운트합니다.

root@firestone:~/docker# docker run -ti -v ~/docker:/docker nvidia/cuda-ppc64le:latest bash

이제 nvidia/cuda-ppc64le:latest 안에 들어왔습니다.  /docker로 가서 동일한 file들이 보이는지 확인합니다.

root@deeed8ce922f:/# cd /docker
root@deeed8ce922f:/docker# ls
Anaconda2-4.4.0.1-Linux-ppc64le.sh                         libcudnn6-doc_6.0.21-1+cuda8.0_ppc64el.deb
Anaconda3-4.4.0.1-Linux-ppc64le.sh                         libcudnn6_6.0.21-1+cuda8.0_ppc64el.deb
cuda-repo-ubuntu1604-8-0-local-ga2v2_8.0.61-1_ppc64el.deb  mldl-repo-local_4.0.0_ppc64el.deb
debootstrap.sh                                             ubuntu
libcudnn6-dev_6.0.21-1+cuda8.0_ppc64el.deb


이제 libcudnn6을 먼저 설치합니다.  아울러 NCCL 및 bazel 등을 쓸 수도 있으니 PowerAI 4.0 (mldl-repo-local_4.0.0_ppc64el.deb)의 local repo도 설치합니다.

root@deeed8ce922f:/docker# dpkg -i libcudnn6_6.0.21-1+cuda8.0_ppc64el.deb libcudnn6-dev_6.0.21-1+cuda8.0_ppc64el.deb mldl-repo-local_4.0.0_ppc64el.deb

root@deeed8ce922f:/docker# apt-get update


이제 cuda와 nccl, openblas 등을 설치합니다.

root@deeed8ce922f:/docker# apt-get install cuda

root@deeed8ce922f:/docker# apt-get install -y libnccl-dev libnccl1 python-ncclient bazel libopenblas-dev libopenblas libopenblas-base


이번엔 다른 ssh 세션에서, parent OS에서 docker ps 명령어로 현재 우리가 쓰고 있는 container ID를 확인합니다.

root@firestone:~# docker ps | grep -v k8s
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
deeed8ce922f        nvidia/cuda-ppc64le:latest   "bash"                   About an hour ago   Up About an hour                        gracious_bhaskara


저 container ID에 대해 docker commit 명령을 다음과 같이 날립니다.

root@firestone:~# docker commit deeed8ce922f bsyu/libcudnn6-ppc64le:xenial

이제 새로운 docker image가 생성된 것을 볼 수 있습니다.

root@firestone:~# docker images | grep -v ibm
REPOSITORY                                          TAG                              IMAGE ID            CREATED             SIZE
bsyu/libcudnn6-ppc64le                              xenial                           6d621d9d446b        48 seconds ago      7.52GB
nvidia-docker                                       build                            405ee913a07e        2 hours ago         1.02GB
nvidia/cuda-ppc64le                                 8.0-cudnn6-runtime-ubuntu16.04   bf28cd22ff84        6 weeks ago         974MB
nvidia/cuda-ppc64le                                 latest                           9b0a21e35c66        6 weeks ago         1.72GB
ppc64le/golang                                      1.6.3                            6a579d02d32f        14 months ago       705MB


적절히 tagging한 뒤, docker에 login하여 docker hub으로 push 해둡니다.

root@firestone:~# docker tag bsyu/libcudnn6-ppc64le:xenial bsyu/libcudnn6-ppc64le:latest

root@firestone:~# docker login -u bsyu
Password:
Login Succeeded

root@firestone:~# docker push bsyu/libcudnn6-ppc64le:xenial
The push refers to a repository [docker.io/bsyu/libcudnn6-ppc64le]
de3b55a17936: Pushed
9eb05620c635: Mounted from nvidia/cuda-ppc64le
688827f0a03b: Mounted from nvidia/cuda-ppc64le
a36322f4fa68: Mounted from nvidia/cuda-ppc64le
6665818dfb83: Mounted from nvidia/cuda-ppc64le
4cad4acd0601: Mounted from nvidia/cuda-ppc64le
f12b406a6a23: Mounted from nvidia/cuda-ppc64le
bb179c8bb840: Mounted from nvidia/cuda-ppc64le
cd51df595e0c: Mounted from nvidia/cuda-ppc64le
4a7a95d650cf: Mounted from nvidia/cuda-ppc64le
22c3301fbf0b: Mounted from nvidia/cuda-ppc64le
xenial: digest: sha256:3993ac50b857979694cdc41cf12d672cc078583f1babb79f6c25e0688ed603ed size: 2621


이제 여기에 추가로 caffe2를 설치합니다.  이전 포스팅(http://hwengineer.blogspot.kr/2017/10/minsky-caffe2-jupyter-notebook-mnist.html)에서 build 해두었던 /opt/caffe2 directory를 통째로 tar로 말아두었던 것을 여기에 풀겠습니다.


root@deeed8ce922f:/docker# ls
Anaconda2-4.4.0.1-Linux-ppc64le.sh                         libcudnn6-doc_6.0.21-1+cuda8.0_ppc64el.deb
Anaconda3-4.4.0.1-Linux-ppc64le.sh                         libcudnn6_6.0.21-1+cuda8.0_ppc64el.deb
caffe2.tgz                                                 mldl-repo-local_4.0.0_ppc64el.deb
cuda-repo-ubuntu1604-8-0-local-ga2v2_8.0.61-1_ppc64el.deb  site-packages.tgz
debootstrap.sh                                             ubuntu
libcudnn6-dev_6.0.21-1+cuda8.0_ppc64el.deb

root@deeed8ce922f:/docker# cd /opt
root@deeed8ce922f:/opt# tar -zxf /docker/caffe2.tgz

root@deeed8ce922f:/opt# vi ~/.bashrc
...
export LD_LIBRARY_PATH=/opt/DL/nccl/lib:/opt/DL/openblas/lib:/usr/local/cuda-8.0/lib6:/usr/lib:/usr/local/lib:/opt/caffe2/lib:/usr/lib/powerpc64le-linux-gnu
export PATH=/opt/anaconda2/bin:/opt/caffe2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PYTHONPATH=/opt/caffe2

caffe2가 정상 작동하기 위해 필요한 package들을 추가 설치합니다.

root@deeed8ce922f:/opt# conda install protobuf future

root@deeed8ce922f:/opt# apt-get install libprotobuf-dev python-protobuf libgoogle-glog-dev libopenmpi-dev liblmdb-dev python-lmdb libleveldb-dev python-leveldb libopencv-core-dev libopencv-gpu-dev python-opencv libopencv-highgui-dev libopencv-dev


이제 다시 parent OS에서 다른 이름으로 docker commit 합니다.

root@firestone:~# docker commit deeed8ce922f bsyu/caffe2-ppc64le-xenial:v0.1


이제 GPU를 사용하기 위해 nvidia-docker로 구동해봅니다.   그러자면 (혹시 아직 안 하셨다면) 먼저 nvidia-docker-plugin을 background로 구동해야 합니다.

root@firestone:~# nohup nvidia-docker-plugin &

root@firestone:~# nvidia-docker run -ti --rm -v ~/docker:/docker bsyu/caffe2-ppc64le-xenial:v0.1 bash


bsyu/caffe2-ppc64le-xenial:v0.1 컨테이너에서 caffe2가 성공적으로 import 되는 것을 확인합니다.

root@0e58f6f69c44:/# python -c 'from caffe2.python import core' 2>/dev/null && echo "Success" || echo "Failure"
Success


이 이미지를 이용하여 또 tensorflow 1.3 및 pytorch 0.2.0이 들어간 docker image도 만듭니다.

root@firestone:~# docker run -ti --rm -v ~/docker:/docker bsyu/caffe2-ppc64le-xenial:v0.1 bash

root@8cfeaf93f28b:/# cd /opt
root@8cfeaf93f28b:/opt# ls
DL  anaconda2  anaconda3  caffe2
root@8cfeaf93f28b:/opt# rm -rf caffe2

root@8cfeaf93f28b:/opt# vi ~/.bashrc
...
export LD_LIBRARY_PATH=/opt/DL/nccl/lib:/opt/DL/openblas/lib:/usr/local/cuda-8.0/lib6:/usr/lib:/usr/local/lib:/usr/lib/powerpc64le-linux-gnu
export PATH=/opt/anaconda3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PYTHONPATH=/opt/anaconda3/lib/python3.6/site-packages


root@8cfeaf93f28b:~# apt-get install libcupti-dev openjdk-8-jdk openjdk-8-jdk-headless git

root@8cfeaf93f28b:~# conda install bazel numpy

root@8cfeaf93f28b:~# git clone --recursive https://github.com/tensorflow/tensorflow.git

root@8cfeaf93f28b:~# cd tensorflow/
root@8cfeaf93f28b:~/tensorflow# git checkout r1.3

root@8cfeaf93f28b:~/tensorflow# ./configure

root@8cfeaf93f28b:~/tensorflow# bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package

root@8cfeaf93f28b:~/tensorflow# bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg

root@8cfeaf93f28b:~/tensorflow# pip install /tmp/tensorflow_pkg/tensorflow-1.3.1-cp36-cp36m-linux_ppc64le.whl

root@8cfeaf93f28b:~/tensorflow# conda list | grep tensor
tensorflow                1.3.1                     <pip>
tensorflow-tensorboard    0.1.8                     <pip>


이제 tensorflow 1.3이 설치되었으므로 이를 docker commit으로 저장합니다.

root@firestone:~# docker ps | grep -v k8s
CONTAINER ID        IMAGE                             COMMAND                  CREATED             STATUS              PORTS               NAMES
8cfeaf93f28b        bsyu/caffe2-ppc64le-xenial:v0.1   "bash"                   2 hours ago         Up 2 hours                              vigilant_ptolemy

root@firestone:~# docker commit 8cfeaf93f28b bsyu/tf1.3-caffe2-ppc64le-xenial:v0.1


이 이미지에 다시 pytorch를 설치합니다.

root@8cfeaf93f28b:~# git clone --recursive https://github.com/pytorch/pytorch.git

root@8cfeaf93f28b:~# cd /pytorch

root@8cfeaf93f28b:~/pytorch# export CMAKE_PREFIX_PATH=/opt/pytorch

root@8cfeaf93f28b:~/pytorch# conda install numpy pyyaml setuptools cmake cffi openblas

root@8cfeaf93f28b:~/pytorch# python setup.py install

root@8cfeaf93f28b:~# python
Python 3.6.1 |Anaconda custom (64-bit)| (default, May 11 2017, 15:31:35)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import print_function
>>> import torch
>>>

이제 최종적으로 bsyu/pytorch-tf1.3-caffe2-ppc64le-xenial:v0.1 라는 이미지를 commit 합니다.

root@firestone:~# docker commit 8cfeaf93f28b bsyu/pytorch-tf1.3-caffe2-ppc64le-xenial:v0.1

root@firestone:~# docker push bsyu/pytorch-tf1.3-caffe2-ppc64le-xenial:v0.1

2017년 10월 30일 월요일

ppc64le에서의 nvidia-docker의 설치 (2017.10)

전에 nvidia-docker를 ppc64le에서 build하는 방법을 올린 적(http://hwengineer.blogspot.kr/2017/02/minsky-ubuntu-1604-xenial-ppc64le.html)이 있습니다.   그 사이에 설치 방법이 업데이트가 된 것이 있어서, 새로 올립니다.

이 URL(https://developer.ibm.com/linuxonpower/docker-on-power)에 나온 가이드대로, 먼저 docker를 설치합니다.

u0017649@sys-89698:~$ sudo vi /etc/apt/sources.list.d/xenial-docker.list
deb http://ftp.unicamp.br/pub/ppc64el/ubuntu/16_04/docker-17.06.0-ce-ppc64el/ xenial main

u0017649@sys-89698:~$ sudo apt-get update

u0017649@sys-89698:~$ sudo apt-get install docker-ce

그 뒤에 아래와 같이 하시면 됩니다.

u0017649@sys-89698:~$ git clone https://github.com/NVIDIA/nvidia-docker.git

u0017649@sys-89698:~$ cd nvidia-docker/

u0017649@sys-89698:~/nvidia-docker$ sudo make
...
Step 21/22 : ENV VERSION $PKG_VERS
 ---> Using cache
 ---> 39d92843179c
Step 22/22 : CMD go install -v -ldflags="-s -X main.Version=$VERSION" ./...
 ---> Using cache
 ---> a66fd805e845
Successfully built a66fd805e845
Successfully tagged nvidia-docker:build
github.com/NVIDIA/nvidia-docker/src/nvidia-docker-plugin
github.com/NVIDIA/nvidia-docker/src/nvidia-docker


u0017649@sys-89698:~/nvidia-docker$ sudo make install
...
Step 21/22 : ENV VERSION $PKG_VERS
 ---> Using cache
 ---> 39d92843179c
Step 22/22 : CMD go install -v -ldflags="-s -X main.Version=$VERSION" ./...
 ---> Using cache
 ---> a66fd805e845
Successfully built a66fd805e845
Successfully tagged nvidia-docker:build
github.com/NVIDIA/nvidia-docker/src/nvidia-docker
github.com/NVIDIA/nvidia-docker/src/nvidia-docker-plugin
install -D -m 755 -t /usr/local/bin /home/u0017649/nvidia-docker/bin/nvidia-docker
install -D -m 755 -t /usr/local/bin /home/u0017649/nvidia-docker/bin/nvidia-docker-plugin

u0017649@sys-89698:~$ which nvidia-docker
/usr/local/bin/nvidia-docker

그리고 이렇게 설치된 nvidia-docker에서는 nvidia-docker-plugin을 수동으로 살려줘야 합니다.  매번 그러기는 귀찮으니, 아예 /etc/rc.local에 아래와 같이 1줄 넣어주는 것을 권고합니다.  그러면 부팅 때마다 nvidia-docker-plugin이 백그라운드로 떠있게 됩니다.

/usr/local/bin/nvidia-docker-plugin &

그러난 뒤에, 아래와 같이 제가 미리 build 해둔 tensorflow 1.3과 python3용 Anaconda가 설치된 ppc64le용 docker image를 pull 하시면 됩니다.

root@firestone:/home# docker pull bsyu/tf1.3-ppc64le:v0.1
v0.3: Pulling from bsyu/tf1.3-ppc64le
0ad9ca03f1b2: Already exists
7d2491df9494: Already exists
9a961cbb08c0: Already exists
9f38c9e24bdd: Already exists
36070ab6f935: Already exists
dd84cc8c7847: Already exists
4317eeb0f4b7: Already exists
13f482d825bc: Already exists
d221c8d6a86c: Already exists
994d0d1ac151: Already exists
c736e0aba22f: Already exists
e7b4f7096c8f: Already exists
a0aaaa391ef4: Downloading  3.165MB/38.83MB
3c8d454a2390: Download complete
9bdf7a145ee5: Downloading  2.671MB/120.4MB

이왕 하실 때 기타 아래 것들도 받아두시면 해로울 건 없겠습니다.

# docker pull bsyu/cudnn6-conda2-ppc64le:v0.1  (python 2.7의 anaconda image)
# docker pull bsyu/cudnn6-conda3-ppc64le:v0.1  (python 3.6의 anaconda image)


-------- 이하는 그냥 실습 옵션입니다.

이제 여기서 ppc64le/ubuntu:latest를 이용하여 libcudnn 6.0와 anaconda2/3 등이 설치된 docker image를 빌드해보겠습니다.

u0017649@sys-89830:~/docker$ ls
Anaconda2-4.4.0.1-Linux-ppc64le.sh
Anaconda3-4.4.0.1-Linux-ppc64le.sh
cuda-repo-ubuntu1604-8-0-local-cublas-performance-update_8.0.61-1_ppc64el-deb
cuda-repo-ubuntu1604-8-0-local-ga2v2_8.0.61-1_ppc64el-deb
dockerfile.cudnn6
libcudnn6_6.0.21-1+cuda8.0_ppc64el.deb
libcudnn6-dev_6.0.21-1+cuda8.0_ppc64el.deb
mldl-repo-local_4.0.0_ppc64el.deb

관련 file들을 위와 같이 ~/docker 디렉토리 속에 모아놓은 뒤, 아래와 같이 dockerfile을 구성합니다.

u0017649@sys-89830:~/docker$ vi dockerfile.cudnn6
FROM ppc64le/ubuntu:latest

ENV CUDNN_VERSION 6.0.21
LABEL com.nvidia.cudnn.version="${CUDNN_VERSION}"

RUN mkdir /tmp/temp
COPY *deb /tmp/temp/
COPY *.sh /tmp/temp/
RUN dpkg -i /tmp/temp/cuda-repo-ubuntu1604-8-0-local-ga2v2_8.0.61-1_ppc64el-deb && \
   dpkg -i /tmp/temp/cuda-repo-ubuntu1604-8-0-local-cublas-performance-update_8.0.61-1_ppc64el-deb && \
   apt-get update && apt-get install -y --no-install-recommends initramfs-tools && \
   apt-get install -y cuda && \
   dpkg -i /tmp/temp/libcudnn* && \
   dpkg -i /tmp/temp/mldl-repo-local_4.0.0_ppc64el.deb && \
   /tmp/temp/Anaconda3-4.4.0.1-Linux-ppc64le.sh -b -p /opt/anaconda3 && \
   /tmp/temp/Anaconda2-4.4.0.1-Linux-ppc64le.sh -b -p /opt/anaconda2 && \
   apt-get install -y libnccl-dev libnccl1 python-ncclient bazel libopenblas-dev libopenblas libopenblas-base && \
   apt-get remove -y mldl-repo-local && \
   apt-get remove -y cuda-repo-ubuntu1604-8-0-local-ga2v2 cuda-repo-ubuntu1604-8-0-local-cublas-performance-update && \
   ldconfig && \
   rm -rf /tmp/temp && \
   rm -rf /var/lib/apt/lists/*
ENV LD_LIBRARY_PATH="/opt/DL/nccl/lib:/opt/DL/openblas/lib:/usr/local/cuda-8.0/lib6:/usr/lib:/usr/local/lib:/opt/caffe2/lib:/usr/lib/powerpc64le-linux-gnu"
ENV PATH="/opt/anaconda2/bin:/opt/caffe2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

이제 이걸 아래와 같이 build 하면 됩니다.

u0017649@sys-89830:~/docker$ sudo docker build -t bsyu/cudnn6_v0.1:ppc64le-xenial -f dockerfile.cudnn6 .

저는 한창 진행 중에 아래와 같이 disk 공간 부족으로 error가 나네요.  PDP(Power Development Platform) cloud는 disk 공간이 너무 작은 것이 탈입니다...

Preparing to unpack .../libcudnn6_6.0.21-1+cuda8.0_ppc64el.deb ...
Unpacking libcudnn6 (6.0.21-1+cuda8.0) ...
dpkg: error processing archive /tmp/temp/libcudnn6_6.0.21-1+cuda8.0_ppc64el.deb (--install):
 cannot copy extracted data for './usr/lib/powerpc64le-linux-gnu/libcudnn.so.6.0.21' to '/usr/lib/powerpc64le-linux-gnu/libcudnn.so.6.0.21.dpkg-new': failed to write (No space left on device)
dpkg-deb: error: subprocess paste was killed by signal (Broken pipe)

2017년 2월 2일 목요일

Minsky 서버에서 nvidia-docker를 이용하여 Caffe Alexnet training 수행하기

앞선 포스팅에서 말씀드린 바와 같이, nvidia-docker를 이용하면 다양한 환경의 deep learning framework을 사용자 간의 application 충돌 없이 손쉽게 사용 가능합니다.   이번에는 NVIDIA P100 GPU를 탑재한 ppc64le 환경인 Minsky 서버에서 Caffe를 docker image로 build하여 Alexnet training을 수행해 보겠습니다.  

먼저, 다음과 같이 CUDA와 CUDNN, Caffe를 포함한 IBM의 PowerAI toolkit 등을 포함한 docker image를 만들기 위해 dockerfile을 생성합니다.  이때, COPY라는 명령에서 사용되는 directory의 끝에는 반드시 "/"를 붙여야 한다는 점을 유의하십시요.


root@minsky:/data/mydocker# vi dockerfile.caffe
FROM bsyu/p2p:ppc64le-xenial

# RUN executes a shell command
# You can chain multiple commands together with &&
# A \ is used to split long lines to help with readability
# This particular instruction installs the source files
# for deviceQuery by installing the CUDA samples via apt

RUN apt-get update && apt-get install -y cuda

RUN mkdir /tmp/temp
COPY libcudnn5* /tmp/temp/
COPY cuda-repo-* /tmp/temp/
COPY mldl-repo-local_1-3ibm5_ppc64el.deb /tmp/temp/

RUN dpkg -i /tmp/temp/cuda-repo-ubuntu1604-8-0-local_8.0.44-1_ppc64el.deb && \
    dpkg -i /tmp/temp/libcudnn5_5.1.5-1+cuda8.0_ppc64el.deb && \
    dpkg -i /tmp/temp/libcudnn5-dev_5.1.5-1+cuda8.0_ppc64el.deb && \
    dpkg -i /tmp/temp/mldl-repo-local_1-3ibm5_ppc64el.deb && \
    rm -rf /tmp/temp && \
    apt-get update && apt-get install -y caffe-nv libnccl1 && \
    rm -rf /var/lib/apt/lists/*

# set the working directory
WORKDIR /opt/DL/caffe-nv/bin
ENV LD_LIBRARY_PATH="/opt/DL/nccl/lib:/opt/DL/openblas/lib:/opt/DL/nccl/lib:/usr/local/cuda-8.0/lib6:/usr/lib:/usr/local/lib"

# CMD defines the default command to be run in the container
# CMD is overridden by supplying a command + arguments to
# `docker run`, e.g. `nvcc --version` or `bash`
CMD ./caffe


이제, 이 dockerfile로 build를 시작합니다.  물론 현재의 host directory에는 관련 deb file들을 미리 copy해 두어야 합니다.

root@minsky:/data/mydocker# docker build -t bsyu/caffe:ppc64le-xenial -f dockerfile.caffe .
Sending build context to Docker daemon 1.664 GB
Step 1 : FROM bsyu/p2p:ppc64le-xenial
 ---> 2fe1b4ac3b03
Step 2 : RUN apt-get update && apt-get install -y cuda
 ---> Using cache
 ---> ae24f9bb0f23
Step 3 : RUN mkdir /tmp/temp
 ---> Using cache
 ---> 5340f9d1b49c
Step 4 : COPY libcudnn5* /tmp/temp/
 ---> Using cache
 ---> 4d1ff5eed9f0
Step 5 : COPY mldl-repo-local_1-3ibm5_ppc64el.deb /tmp/temp/
 ---> Using cache
 ---> c3e3840d33e5
Step 6 : RUN dpkg -i /tmp/temp/libcudnn5_5.1.5-1+cuda8.0_ppc64el.deb &&     dpkg -i /tmp/temp/libcudnn5-dev_5.1.5-1+cuda8.0_ppc64el.deb &&     dpkg -i /tmp/temp/mldl-repo-local_1-3ibm5_ppc64el.deb &&     rm -rf /tmp/temp &&     apt-get update && apt-get install -y  caffe-nv libnccl1 &&     rm -rf /var/lib/apt/lists/*
 ---> Using cache
 ---> 1868adb5dc10
Step 7 : WORKDIR /opt/DL/caffe-nv/bin
 ---> Running in 875c714591e5
 ---> ec7c68de4d7e
Step 8 : ENV LD_LIBRARY_PATH "/opt/DL/nccl/lib:/opt/DL/openblas/lib:/opt/DL/nccl/lib:/usr/local/cuda-8.0/lib6:/usr/lib:/usr/local/lib"
 ---> Running in e78eaede0f62
 ---> 7450b81fde8d
Removing intermediate container e78eaede0f62
Step 9 : CMD ./caffe
 ---> Running in a95e655fee4f
 ---> be9b92d51239


이제 docker image를 확인합니다.  이것저것 닥치는대로 넣다보니 image size가 4GB가 좀 넘습니다.  원래 필요없는 것은 빼시는 것이 좋습니다.

root@minsky:/data/mydocker# docker images
REPOSITORY                     TAG                  IMAGE ID            CREATED             SIZE
bsyu/caffe                     ppc64le-xenial       2705abb3bbc5        13 seconds ago      4.227 GB
bsyu/p2p                       ppc64le-xenial       2fe1b4ac3b03        17 hours ago        2.775 GB
registry                       latest               781e109ba95f        44 hours ago        612.6 MB
127.0.0.1/ubuntu-xenial        gevent               4ce0e6ba8a69        44 hours ago        282.5 MB
localhost:5000/ubuntu-xenial   gevent               4ce0e6ba8a69        44 hours ago        282.5 MB
ubuntu/xenial                  gevent               4ce0e6ba8a69        44 hours ago        282.5 MB
bsyu/cuda8-cudnn5-devel        cudnn5-devel         d8d0da2fbdf2        46 hours ago        1.895 GB
bsyu/cuda                      8.0-devel            dc3faec17c11        46 hours ago        1.726 GB
bsyu/ppc64le                   cuda8.0-devel        dc3faec17c11        46 hours ago        1.726 GB
cuda                           8.0                  dc3faec17c11        46 hours ago        1.726 GB
cuda                           8.0-devel            dc3faec17c11        46 hours ago        1.726 GB
cuda                           devel                dc3faec17c11        46 hours ago        1.726 GB
cuda                           latest               dc3faec17c11        46 hours ago        1.726 GB
cuda8-cudnn5-runtime           latest               8a3b0a60e741        46 hours ago        942.2 MB
cuda                           8.0-cudnn5-runtime   8a3b0a60e741        46 hours ago        942.2 MB
cuda                           cudnn-runtime        8a3b0a60e741        46 hours ago        942.2 MB
cuda8-runtime                  latest               8e9763b6296f        46 hours ago        844.9 MB
cuda                           8.0-runtime          8e9763b6296f        46 hours ago        844.9 MB
cuda                           runtime              8e9763b6296f        46 hours ago        844.9 MB
ubuntu                         16.04                09621ebd4cfd        6 days ago          234.3 MB
ubuntu                         latest               09621ebd4cfd        6 days ago          234.3 MB
ubuntu                         xenial               09621ebd4cfd        6 days ago          234.3 MB
nvidia-docker                  deb                  332eaa8c9f9d        6 days ago          430.1 MB
nvidia-docker                  build                8cbc22512d15        6 days ago          1.012 GB
ppc64le/ubuntu                 14.04                c040fcd69c12        3 months ago        227.8 MB
ppc64le/ubuntu                 latest               1967d889e07f        3 months ago        168 MB
ppc64le/golang                 1.6.3                6a579d02d32f        5 months ago        704.7 MB


Docker image를 nvidia-docker로 수행해 봅니다.  Caffe 버전을 확인할 수 있습니다.

root@minsky:/data/mydocker# nvidia-docker run --rm bsyu/caffe:ppc64le-xenial ./caffe --version
caffe version 0.15.13

root@minsky:/data/mydocker# nvidia-docker run --rm bsyu/caffe:ppc64le-xenial
caffe: command line brew
usage: caffe <command> <args>

commands:
  train           train or finetune a model
  test            score a model
  device_query    show GPU diagnostic information
  time            benchmark model execution time

  Flags from tools/caffe.cpp:
    -gpu (Optional; run in GPU mode on given device IDs separated by ','.Use
      '-gpu all' to run on all available GPUs. The effective training batch
      size is multiplied by the number of devices.) type: string default: ""
    -iterations (The number of iterations to run.) type: int32 default: 50
    -model (The model definition protocol buffer text file.) type: string
      default: ""
    -sighup_effect (Optional; action to take when a SIGHUP signal is received:
      snapshot, stop or none.) type: string default: "snapshot"
    -sigint_effect (Optional; action to take when a SIGINT signal is received:
      snapshot, stop or none.) type: string default: "stop"
    -snapshot (Optional; the snapshot solver state to resume training.)
      type: string default: ""
    -solver (The solver definition protocol buffer text file.) type: string
      default: ""
    -weights (Optional; the pretrained weights to initialize finetuning,
      separated by ','. Cannot be set simultaneously with snapshot.)
      type: string default: ""


그냥 docker를 수행하면 container 내의 filesystem은 다음과 같습니다.  /nvme라는 host 서버의 filesystem이 mount point조차 없는 것을 보실 수 있습니다.

root@minsky:/data/mydocker# nvidia-docker run --rm -ti bsyu/caffe:ppc64le-xenial bash

root@8f2141cfade6:/opt/DL/caffe-nv/bin# df -h
Filesystem      Size  Used Avail Use% Mounted on
none            845G  184G  619G  23% /
tmpfs           256G     0  256G   0% /dev
tmpfs           256G     0  256G   0% /sys/fs/cgroup
/dev/sda2       845G  184G  619G  23% /etc/hosts
shm              64M     0   64M   0% /dev/shm

root@8f2141cfade6:/opt/DL/caffe-nv/bin# cd /nvme
bash: cd: /nvme: No such file or directory


그러나 다음과 같이 -v (--volume) 옵션을 주면서 수행하면 host 서버의 filesystem도 사용할 수 있습니다.

root@minsky:/data/mydocker# nvidia-docker run --rm -ti -v /nvme:/nvme bsyu/caffe:ppc64le-xenial bash

root@ee2866a65362:/opt/DL/caffe-nv/bin# df -h
Filesystem      Size  Used Avail Use% Mounted on
none            845G  184G  619G  23% /
tmpfs           256G     0  256G   0% /dev
tmpfs           256G     0  256G   0% /sys/fs/cgroup
/dev/nvme0n1    2.9T  290G  2.5T  11% /nvme
/dev/sda2       845G  184G  619G  23% /etc/hosts
shm              64M     0   64M   0% /dev/shm


root@ee2866a65362:/opt/DL/caffe-nv/bin# ls /nvme
caffe_alexnet_train_iter_102000.caffemodel   caffe_alexnet_train_iter_50000.caffemodel   data
caffe_alexnet_train_iter_102000.solverstate  caffe_alexnet_train_iter_50000.solverstate  ilsvrc12_train_lmdb
caffe_alexnet_train_iter_208.caffemodel      caffe_alexnet_train_iter_51000.caffemodel   ilsvrc12_val_lmdb
caffe_alexnet_train_iter_208.solverstate     caffe_alexnet_train_iter_51000.solverstate  imagenet_mean.binaryproto
caffe_alexnet_train_iter_28.caffemodel       caffe_alexnet_train_iter_56250.caffemodel   kkk
caffe_alexnet_train_iter_28.solverstate      caffe_alexnet_train_iter_56250.solverstate  lost+found
caffe_alexnet_train_iter_37500.caffemodel    caffe_alexnet_train_iter_6713.caffemodel    solver.prototxt
caffe_alexnet_train_iter_37500.solverstate   caffe_alexnet_train_iter_6713.solverstate   train_val.prototxt



이제 caffe docker image를 이용하여 Alexnet training을 수행합니다.  아주 잘 되는 것을 보실 수 있습니다.


root@minsky:/data/mydocker# nvidia-docker run --rm -v /nvme:/nvme bsyu/caffe:ppc64le-xenial ./caffe train -gpu 0,1,2,3 --solver=/nvme/solver.prototxt
I0202 02:27:22.200032     1 caffe.cpp:197] Using GPUs 0, 1, 2, 3
I0202 02:27:22.201119     1 caffe.cpp:202] GPU 0: Tesla P100-SXM2-16GB
I0202 02:27:22.201659     1 caffe.cpp:202] GPU 1: Tesla P100-SXM2-16GB
I0202 02:27:22.202191     1 caffe.cpp:202] GPU 2: Tesla P100-SXM2-16GB
I0202 02:27:22.202721     1 caffe.cpp:202] GPU 3: Tesla P100-SXM2-16GB
I0202 02:27:23.986641     1 solver.cpp:48] Initializing solver from parameters:
...
I0202 02:27:28.246285     1 parallel.cpp:334] Starting Optimization
I0202 02:27:28.246449     1 solver.cpp:304] Solving AlexNet
I0202 02:27:28.246492     1 solver.cpp:305] Learning Rate Policy: step
I0202 02:27:28.303807     1 solver.cpp:362] Iteration 0, Testing net (#0)
I0202 02:27:44.866096     1 solver.cpp:429]     Test net output #0: accuracy = 0.000890625
I0202 02:27:44.866148     1 solver.cpp:429]     Test net output #1: loss = 6.91031 (* 1 = 6.91031 loss)
I0202 02:27:45.356459     1 solver.cpp:242] Iteration 0 (0 iter/s, 17.1098s/200 iter), loss = 6.91465
I0202 02:27:45.356503     1 solver.cpp:261]     Train net output #0: loss = 6.91465 (* 1 = 6.91465 loss)
I0202 02:27:45.356540     1 sgd_solver.cpp:106] Iteration 0, lr = 0.01
...


이렇게 docker container를 이용해 training이 수행되는 동안, host 서버에서 nvidia-smi 명령을 통해 GPU 사용량을 모니터링 해봅니다.  GPU를 사용하는 application 이름은 caffe로 나오는 것을 보실 수 있습니다.

Thu Feb  2 11:37:52 2017
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 361.107                Driver Version: 361.107                   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P100-SXM2...  On   | 0002:01:00.0     Off |                    0 |
| N/A   74C    P0   242W / 300W |   9329MiB / 16280MiB |     98%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-SXM2...  On   | 0003:01:00.0     Off |                    0 |
| N/A   69C    P0   256W / 300W |   8337MiB / 16280MiB |     97%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla P100-SXM2...  On   | 0006:01:00.0     Off |                    0 |
| N/A   75C    P0   244W / 300W |   8337MiB / 16280MiB |     95%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla P100-SXM2...  On   | 0007:01:00.0     Off |                    0 |
| N/A   67C    P0   222W / 300W |   8337MiB / 16280MiB |     97%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|    0    121885    C   ./caffe                                       9317MiB |
|    1    121885    C   ./caffe                                       8325MiB |
|    2    121885    C   ./caffe                                       8325MiB |
|    3    121885    C   ./caffe                                       8325MiB |
+-----------------------------------------------------------------------------+


그 pid를 통해 추적해보면 저 caffe라는 process의 parent는 docker-containerd 임을 알 수 있습니다.

root@minsky:/data/mydocker# ps -ef | grep 121885
root     121885 121867 99 11:27 ?        01:30:11 ./caffe train -gpu 0,1,2,3 --solver=/nvme/solver.prototxt
root     121992 116723  0 11:39 pts/0    00:00:00 grep --color=auto 121885

root@minsky:/data/mydocker# ps -ef | grep 121867
root     121867 106109  0 11:27 ?        00:00:00 docker-containerd-shim 61b16f54712439496aec5d04cca0906425a1106a6dda935f47e228e498ddb94c /var/run/docker/libcontainerd/61b16f54712439496aec5d04cca0906425a1106a6dda935f47e228e498ddb94c docker-runc
root     121885 121867 99 11:27 ?        01:34:04 ./caffe train -gpu 0,1,2,3 --solver=/nvme/solver.prototxt
root     121996 116723  0 11:39 pts/0    00:00:00 grep --color=auto 121867


이 docker image는 https://hub.docker.com/r/bsyu/ 에 push되어 있으므로 Minsky 서버를 가지고 계신 분은 자유롭게 pull 받아 사용하실 수 있습니다.