2017년 10월 16일 월요일

Minsky 서버에서 Tensorflow r1.3을 source로부터 build하기


2017년 10월 현재 최신 PowerAI 버전은 4.0으로서, 이 속에 포함된 tensorflow는 버전 r1.1입니다.

root@ubuntu:/tmp/kkk# dpkg -l | grep mldl
ii  mldl-repo-local                        4.0.0                                      ppc64el      IBM repository for Deep Learning tools for POWER linux
ii  power-mldl                             4.0.0                                      ppc64el      Meta-package for Deep Learning frameworks for POWER


root@ubuntu:/tmp/kkk# dpkg -l | grep tensor
ii  ddl-tensorflow                         0.9.0-4ibm1                                ppc64el      TensorFlow operator for IBM PowerAI Distributed Deep Learning
ii  tensorflow                             1.1.0-4ibm1                                ppc64el      Open source software library for numerical computation

현재 github에 올라온 tensorflow 최신 버전은 r1.4이며, 몇몇 최신 버전을 사용하시는 고객께서는 r1.3을 테스트하시고자 합니다.  PowerAI는 대략 3개월 단위로 최신 ML/DL framework 버전을 갱신하니까, 다음 버전의 PowerAI는 아마도 11월 경에 나올 가능성이 많습니다.  그렇다면 tensorflow나 기타 framework의 최신 버전을 쓰려면 그때까지 참고 기다려야 할까요 ?

일단 기다려주십사 하는 것이 IBM의 공식 입장입니다만, 사실 꼭 그러실 필요는 없습니다.  오픈 소스니까요.  그냥 tensorflow r1.3을 직접 소스로부터 빌드하셔서 사용하실 수도 있습니다.  여기서는 그 방법을 살펴보시고, r1.3이 포함된 site-packages.tar도 올려놓겠습니다.

먼저, 여기서 제가 빌드를 위해 사용한 환경은 Ubuntu 16.04.2 LTS ppc64le입니다.  CUDA는 8.0.61, libcudnn은 6.0.21, 그리고 gcc는 5.4 입니다.

u0017649@sys-89490:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.2 LTS
Release:        16.04
Codename:       xenial


u0017649@sys-89490:~$ dpkg -l | grep cuda
ii  cuda                                                     8.0.61-1                                   ppc64el      CUDA meta-package
ii  cuda-8-0                                                 8.0.61-1                                   ppc64el      CUDA 8.0 meta-package
...
ii  libcudnn6                                                6.0.21-1+cuda8.0                           ppc64el      cuDNN runtime libraries
ii  libcudnn6-dev                                            6.0.21-1+cuda8.0                           ppc64el      cuDNN development libraries and headers

u0017649@sys-89490:~$ /usr/bin/gcc --version
gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

여기서는 아래의 tensorflow 공식 홈페이지에 나온 source로부터의 빌드 방법을 거의 그대로 따라가겠습니다. 

https://www.tensorflow.org/install/install_sources#ConfigureInstallation

Tensorflow 홈페이지에서는 아래의 libcupti-dev 외에 python 관련 패키지를 잔뜩 설치해야 하라고 나오는데, 실제로는 그냥 anaconda만 설치하고 진행해도 괜찮은 것 같습니다.

u0017649@sys-89490:~$ sudo apt-get install libcupti-dev

아래는 ananconda3 설치 절차입니다.

u0017649@sys-89490:~$ wget wget https://repo.continuum.io/archive/Anaconda3-4.4.0.1-Linux-ppc64le.sh

u0017649@sys-89490:~$ chmod u+x Anaconda*

u0017649@sys-89490:~$ sudo ./Anaconda3-4.4.0.1-Linux-ppc64le.sh
...
[/home/u0017649/anaconda3] >>> /usr/local/anaconda3

u0017649@sys-89490:~$ export PATH="/usr/local/anaconda3/bin:$PATH"

여기서는 주로 u0017649 userid를 사용하므로, 그 userid로 anaconda root directory(/usr/local/anaconda3)를 자유롭게 쓸 수 있도록 그 directory의 ownership을 바꿔줍니다.

u0017649@sys-89490:~$ sudo chown -R u0017649:u0017649 /usr/local/anaconda3

이제 conda 명령을 이용해서 bazel과 numpy를 설치합니다.

u0017649@sys-89490:~$ conda install bazel numpy
Fetching package metadata .........
Solving package specifications: .

Package plan for installation in environment /usr/local/anaconda3:

The following NEW packages will be INSTALLED:

    bazel:    0.4.5-0

The following packages will be UPDATED:

    anaconda: 4.4.0-np112py36_0 --> 4.4.0-np112py36_1
    conda:    4.3.21-py36_0     --> 4.3.27-py36_0

Proceed ([y]/n)? y

bazel-0.4.5-0. 100% |####################################################| Time: 0:00:09  14.58 MB/s
conda-4.3.27-p 100% |####################################################| Time: 0:00:00  10.31 MB/s
anaconda-4.4.0 100% |####################################################| Time: 0:00:00   6.57 MB/s

u0017649@sys-89490:~$ which bazel
/usr/local/anaconda3/bin/bazel

이제 tensorflow의 source를 git clone 명령으로 download 받습니다.

u0017649@sys-89490:~$ git clone --recursive https://github.com/tensorflow/tensorflow.git
Cloning into 'tensorflow'...
remote: Counting objects: 246390, done.
remote: Total 246390 (delta 0), reused 0 (delta 0), pack-reused 246390
Receiving objects: 100% (246390/246390), 125.14 MiB | 6.34 MiB/s, done.
Resolving deltas: 100% (192026/192026), done.
Checking connectivity... done.

우리가 빌드하려는 것은 r1.3으로 그 branch로 switch합니다.

u0017649@sys-89490:~$ cd tensorflow

u0017649@sys-89490:~/tensorflow$ git checkout r1.3
Checking out files: 100% (3934/3934), done.
Branch r1.3 set up to track remote branch r1.3 from origin.
Switched to a new branch 'r1.3'

이제 build 준비가 끝났습니다.  Build 절차는 기본적으로, configure --> bazel로 pip package build --> wheel file build  --> pip 명령으로 wheel file 설치입니다.

Configure하실 때 대부분은 default를 선택하시되, 몇몇 부분에서는 별도로 지정하셔야 합니다.  ppc64le 특성에 맞춰야 하는 부분은 딱 한군데, cuDNN 6 library가 위치한 directory를 지정하는 부분 뿐입니다.

u0017649@sys-89490:~/tensorflow$ ./configure
Extracting Bazel installation...
..................
You have bazel 0.4.5- installed.
Please specify the location of python. [Default is /usr/local/anaconda3/bin/python]:
Found possible Python library paths:
  /usr/local/anaconda3/lib/python3.6/site-packages
Please input the desired Python library path to use.  Default is [/usr/local/anaconda3/lib/python3.6/site-packages]
Do you wish to build TensorFlow with MKL support? [y/N] n
...
Do you wish to build TensorFlow with CUDA support? [y/N] y
...
Please specify which gcc should be used by nvcc as the host compiler. [Default is /opt/at10.0/bin/gcc]: /usr/bin/gcc
...
Please specify the location where cuDNN 6 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]: /usr/lib/powerpc64le-linux-gnu
...
You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus.
Please note that each additional compute capability significantly increases your build time and binary size.
[Default is: "3.5,5.2"]: "3.7,6.0"       # 3.7은 K80, 6.0은 P100을 위한 compute capability입니다.
...

Configure가 끝나면 bazel로 TensorFlow with GPU support를 위한 pip package를 build합니다.  이 과정 중에, 아래 예시한 것과 같이 인터넷으로부터 일부 tar.gz 파일들을 download 받는 부분이 관측됩니다.  즉, 이 과정을 위해서는 인터넷 연결이 필요합니다.

u0017649@sys-89490:~/tensorflow$ bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
...
INFO: Downloading http://mirror.bazel.build/github.com/google/boringssl/archive/bbcaa15b0647816b9a\
1a9b9e0d209cd6712f0105.tar.gz: 3,244,032 bytes
...
INFO: Downloading http://mirror.bazel.build/github.com/google/boringssl/archive/bbcaa15b0647816b9a\
1a9b9e0d209cd6712f0105.tar.gz: 4,032,059 bytes
...
INFO: From Compiling tensorflow/python/pywrap_tensorflow_internal.cc:
bazel-out/local_linux-py3-opt/bin/tensorflow/python/pywrap_tensorflow_internal.cc: In function 'PyObject* _wrap_PyRecordReader_New(PyObject*, PyObject*)':
bazel-out/local_linux-py3-opt/bin/tensorflow/python/pywrap_tensorflow_internal.cc:5173:138: warning: 'arg2' may be used uninitialized in this function [-Wmaybe-uninitialized]
     result = (tensorflow::io::PyRecordReader *)tensorflow::io::PyRecordReader::New((string const &)*arg1,arg2,(string const &)*arg3,arg4);
                                                                                                                                          ^
At global scope:
cc1plus: warning: unrecognized command line option '-Wno-self-assign'
Target //tensorflow/tools/pip_package:build_pip_package up-to-date:
  bazel-bin/tensorflow/tools/pip_package/build_pip_package
INFO: Elapsed time: 7106.091s, Critical Path: 4427.34s

이런저런 warning message만 나올 뿐, 잘 끝났습니다.  저는 이 과정을 1-core짜리 cloud 환경에서 돌렸는데, 이렇게 거의 2시간 가까이 걸렸습니다.

이제 여기서 build된 binary를 이용하여 .whl file을 build합니다.  생성될 .whl 파일은 /tmp/tensorflow_pkg directory에 들어가도록 지정합니다.

u0017649@sys-89490:~/tensorflow$ bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
Fri Oct 13 03:40:03 EDT 2017 : === Using tmpdir: /tmp/tmp.UreS6KLhqt
~/tensorflow/bazel-bin/tensorflow/tools/pip_package/build_pip_package.runfiles ~/tensorflow
~/tensorflow
/tmp/tmp.UreS6KLhqt ~/tensorflow
Fri Oct 13 03:40:23 EDT 2017 : === Building wheel
warning: no files found matching '*.dll' under directory '*'
warning: no files found matching '*.lib' under directory '*'
warning: no files found matching '*.h' under directory 'tensorflow/include/tensorflow'
warning: no files found matching '*' under directory 'tensorflow/include/Eigen'
warning: no files found matching '*' under directory 'tensorflow/include/external'
warning: no files found matching '*.h' under directory 'tensorflow/include/google'
warning: no files found matching '*' under directory 'tensorflow/include/third_party'
warning: no files found matching '*' under directory 'tensorflow/include/unsupported'
~/tensorflow
Fri Oct 13 03:44:36 EDT 2017 : === Output wheel file is in: /tmp/tensorflow_pkg


u0017649@sys-89490:~$ ls /tmp/tensorflow_pkg
tensorflow-1.3.1-cp36-cp36m-linux_ppc64le.whl

잘 끝났습니다.  이제 이 wheel 파일을 pip 명령으로 설치합니다.  단, 그 전에 PYTHONPATH 환경변수를 확실히 지정할 것을 권고합니다.  여기서도 tensorflow 설치에 필요한 tensorboard나 protobuf 등을 인터넷으로부터 자동으로 download 받는 것 같습니다.

u0017649@sys-89490:~$ export PYTHONPATH=/usr/local/anaconda3/lib/python3.6/site-packages

u0017649@sys-89490:~$ pip install /tmp/tensorflow_pkg/tensorflow-1.3.1-cp36-cp36m-linux_ppc64le.whl
Processing /tmp/tensorflow_pkg/tensorflow-1.3.1-cp36-cp36m-linux_ppc64le.whl
Requirement already satisfied: six>=1.10.0 in /usr/local/anaconda3/lib/python3.6/site-packages (from tensorflow==1.3.1)
Collecting tensorflow-tensorboard<0.2.0,>=0.1.0 (from tensorflow==1.3.1)
  Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.python.org', port=443): Read timed out. (read timeout=15)",)': /simple/tensorflow-tensorboard/
  Downloading tensorflow_tensorboard-0.1.8-py3-none-any.whl (1.6MB)
    100% |????????????????????????????????| 1.6MB 772kB/s
Requirement already satisfied: wheel>=0.26 in /usr/local/anaconda3/lib/python3.6/site-packages (from tensorflow==1.3.1)
Requirement already satisfied: numpy>=1.11.0 in /usr/local/anaconda3/lib/python3.6/site-packages (from tensorflow==1.3.1)
Collecting protobuf>=3.3.0 (from tensorflow==1.3.1)
  Downloading protobuf-3.4.0-py2.py3-none-any.whl (375kB)
    100% |????????????????????????????????| 378kB 2.5MB/s
Requirement already satisfied: werkzeug>=0.11.10 in /usr/local/anaconda3/lib/python3.6/site-packages (from tensorflow-tensorboard<0.2.0,>=0.1.0->tensorflow==1.3.1)
...
Successfully installed html5lib-0.9999999 markdown-2.6.9 protobuf-3.4.0 tensorflow-1.3.1 tensorflow-tensorboard-0.1.8

자, 이제 설치가 끝났습니다.  conda list 명령으로 tensorflow의 설치를 확인합니다.

u0017649@sys-89490:~$ conda list | grep tensor
tensorflow                1.3.1                     <pip>
tensorflow-tensorboard    0.1.8                     <pip>

이제 tensorflow가 설치된 PYTHONPATH, 즉 /usr/local/anaconda3/lib/python3.6/site-packages를 통째로 tar로 말아서 K80 GPU가 설치된 제2의 서버에 가져가겠습니다.  물론 그 제2의 서버에는 미리 anaconda3가 설치되어 있어야 합니다.

u0017649@sys-89498:/usr/local/anaconda3/lib/python3.6 $ tar -zcf site-packages.tgz site-packages

u0017649@sys-89498:~$ scp /usr/local/anaconda3/lib/python3.6/site-packages.tgz firestone:~/
site-packages.tgz                             100%  313MB  19.6MB/s   00:16

이제 위에서 firestone이라고 되어 있는 그 서버로 이동해서 작업합니다.  참고로, 이 firestone이라는 서버는 Ubuntu 16.04.3으로서 빌드 서버의 16.04.2보다 약간 버전이 높습니다만, 별 문제 없이 잘 수행되더군요.

먼저 anaconda3가 설치되어 있는지 확인합니다.

root@ubuntu:~# which conda
/root/anaconda3/bin/conda

여기서는 root user로 /root/anaconda3 위치에 anaconda를 설치해놓았네요.  뭐 별로 좋은 위치는 아닙니다만, 여기서는 이걸 그대로 써보겠습니다.  여기서의 PYTHONPATH, 즉, /root/anaconda3/lib/python3.6/site-packages에 저 위의 서버에서 가져온 site-packages.tgz를 그대로 풀어놓겠습니다.  기존의 site-packages 속에 들어있는 package들은 overwrite 됩니다만, 만약 새로 풀리는 site-packages 밑에 없는 패키지들이 있었다면 그것들은 그대로 보존되니까, 그냥 풀어놓으셔도 됩니다.

root@ubuntu:~# cd /root/anaconda3/lib/python3.6

root@ubuntu:~/anaconda3/lib/python3.6# tar -zxf ~/site-packages.tgz

이제 준비 완료입니다.  먼저 conda list로 tensorflow가 설치되어 있는 것으로 나오는지 확인해봅니다.

root@ubuntu:~/anaconda3/lib/python3.6# conda list | grep tensorflow
tensorflow                1.3.1                     <pip>
tensorflow-tensorboard    0.1.8                     <pip>

예, 잘 보이네요.  이제 PYTHONPATH를 다시 한번 확실히 선언하고, 시험 삼아 cifar10을 수행해보겠습니다.

root@ubuntu:~# export PYTHONPATH=/root/anaconda3/lib/python3.6/site-packages

root@ubuntu:~# git clone https://github.com/tensorflow/models.git
Cloning into 'models'...
remote: Counting objects: 7644, done.
remote: Total 7644 (delta 0), reused 0 (delta 0), pack-reused 7644
Receiving objects: 100% (7644/7644), 157.90 MiB | 19.09 MiB/s, done.
Resolving deltas: 100% (4139/4139), done.
Checking connectivity... done.

root@ubuntu:~# cd models/tutorials/image/cifar10

root@ubuntu:~/models/tutorials/image/cifar10# ls
BUILD             cifar10_input_test.py       cifar10_train.py
cifar10_eval.py   cifar10_multi_gpu_train.py  __init__.py
cifar10_input.py  cifar10.py                  README.md

root@ubuntu:~/models/tutorials/image/cifar10# which python
/root/anaconda3/bin/python

Download 받은 example script 중 cifar10_train.py을 수행하면 training dataset의 download부터 training까지 일사천리로 수행됩니다.

root@ubuntu:~/models/tutorials/image/cifar10# python cifar10_train.py
>> Downloading cifar-10-binary.tar.gz 100.0%
Successfully downloaded cifar-10-binary.tar.gz 170052171 bytes.
/root/anaconda3/lib/python3.6/site-packages/numpy/core/machar.py:127: RuntimeWarning: overflow encountered in add
  a = a + a
/root/anaconda3/lib/python3.6/site-packages/numpy/core/machar.py:129: RuntimeWarning: invalid value encountered in subtract
  temp1 = temp - a
/root/anaconda3/lib/python3.6/site-packages/numpy/core/machar.py:138: RuntimeWarning: invalid value encountered in subtract
  itemp = int_conv(temp-a)
/root/anaconda3/lib/python3.6/site-packages/numpy/core/machar.py:162: RuntimeWarning: overflow encountered in add
  a = a + a
/root/anaconda3/lib/python3.6/site-packages/numpy/core/machar.py:164: RuntimeWarning: invalid value encountered in subtract
  temp1 = temp - a
/root/anaconda3/lib/python3.6/site-packages/numpy/core/machar.py:171: RuntimeWarning: invalid value encountered in subtract
  if any(temp-a != zero):
Filling queue with 20000 CIFAR images before starting to train. This will take a few minutes.
...
2017-10-13 22:18:12.974909: I tensorflow/core/common_runtime/gpu/gpu_device.cc:986] 2:   N N Y Y
2017-10-13 22:18:12.974915: I tensorflow/core/common_runtime/gpu/gpu_device.cc:986] 3:   N N Y Y
2017-10-13 22:18:12.974933: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla K80, pci bus id: 0000:03:00.0)
2017-10-13 22:18:12.974942: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:1) -> (device: 1, name: Tesla K80, pci bus id: 0000:04:00.0)
2017-10-13 22:18:12.974952: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:2) -> (device: 2, name: Tesla K80, pci bus id: 0020:03:00.0)
2017-10-13 22:18:12.974960: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:3) -> (device: 3, name: Tesla K80, pci bus id: 0020:04:00.0)
2017-10-13 22:18:22.502001: step 0, loss = 4.67 (52.2 examples/sec; 2.451 sec/batch)
2017-10-13 22:18:22.917980: step 10, loss = 4.62 (3076.9 examples/sec; 0.042 sec/batch)
2017-10-13 22:18:23.240470: step 20, loss = 4.43 (3969.1 examples/sec; 0.032 sec/batch)
2017-10-13 22:18:23.538250: step 30, loss = 4.41 (4298.5 examples/sec; 0.030 sec/batch)
2017-10-13 22:18:23.837076: step 40, loss = 4.29 (4283.4 examples/sec; 0.030 sec/batch)
2017-10-13 22:18:24.134108: step 50, loss = 4.33 (4309.3 examples/sec; 0.030 sec/batch)
2017-10-13 22:18:24.426799: step 60, loss = 4.30 (4373.2 examples/sec; 0.029 sec/batch)
...
2017-10-14 07:09:50.128824: step 999920, loss = 0.10 (4352.2 examples/sec; 0.029 sec/batch)
2017-10-14 07:09:50.428406: step 999930, loss = 0.11 (4272.7 examples/sec; 0.030 sec/batch)
2017-10-14 07:09:50.722993: step 999940, loss = 0.14 (4345.0 examples/sec; 0.029 sec/batch)
2017-10-14 07:09:51.019963: step 999950, loss = 0.11 (4310.2 examples/sec; 0.030 sec/batch)
2017-10-14 07:09:51.317448: step 999960, loss = 0.13 (4302.7 examples/sec; 0.030 sec/batch)
2017-10-14 07:09:51.617180: step 999970, loss = 0.11 (4270.7 examples/sec; 0.030 sec/batch)
2017-10-14 07:09:51.914633: step 999980, loss = 0.14 (4303.0 examples/sec; 0.030 sec/batch)
2017-10-14 07:09:52.213837: step 999990, loss = 0.13 (4278.1 examples/sec; 0.030 sec/batch)


완벽하게 잘 수행되었습니다.

아래의 제 구글 드라이브에 site-packages.tgz를 올려두었습니다.  사이즈는 330MB 정도인 이 파일은 ppc64le 아키텍처의 Ubuntu 16.04, CUDA 8.0, libcuDNN 6.0 환경의 K80 또는 P100을 활용하실 수 있도록 빌드된 것입니다.  필요하시면 마음대로 가져가 쓰셔도 됩니다.   제가 책임은 질 수 없는 패키지라는 것은 양해 바랍니다.

https://drive.google.com/open?id=0B-F0jEb44gqUZGdYb3A2QUNaenM 

댓글 1개:

  1. 간혹 tensorflow with gpu support 를 위한 pip 생성하는 과정에서 dist quota error 가 발생합니다. bazel --output_base 가 NFS 등으로 잡혀있으면 발생하는 문제 같은데, bazel build 할때 output_base를 변경해주면 잘 진행됩니다.
    (기존) bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
    (변경) bazel --output_base=/gpfs/gpfs_gl4_16mb/b7p284za/bazel/output build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package

    답글삭제