2016년 12월 15일 목요일

인터넷에 연결되지 않은 Minsky 서버에 CUDA와 PowerAI toolkit 설치하기

기본적으로 CUDA 및 PowerAI toolkit은 local debian package를 제공하므로, internet access 없이도 설치가 가능합니다.  그러나 이들을 설치하기 위해서는 먼저 ubuntu OS에 여러가지 추가적인 package들이 설치되어야 하는데, 그것들은 Ubuntu 16.04.1 LTS의 base OS image에는 들어있지 않고 internet 상의 APT repository에 존재합니다.  따라서 결국 internet access가 필요합니다.

이 문제를 해결하기 위해서, 다소 우악스럽지만 가장 단순한 방법은 internet 상의 ubuntu APT repository를 local disk에 옮겨 놓는 것입니다.  꼭 CUDA와 PowerAI를 위해서 뿐만 아니라, 사용하다보면 몇가지 추가 OS package가 필요한 경우도 있으므로 인터넷 연결이 없는 곳에 서버를 설치하기 위해서는 이를 한번 구성해두는 것이 필요하긴 합니다.



0.  준비물 및 기본 절차 설명

- Ubuntu 16.04.1 LTS 버전이 설치된 Linux on POWER 1대(GPU는 없어도 됨)와, 거기에 연결되는 100GB 이상의 USB 외장 디스크
- 먼저 internet으로부터, 이 laptop에 Ubuntu 16.04.1 LTS의 APT repository로부터 deb file들을 apt-get 명령을 이용해 download 받습니다.
- 이후 그 file들을 USB 외장 디스크에 옮겨담아 datacenter 안에 가지고 들어가서 Minsky 서버에 그 file들을 upload 합니다.
- 그렇게 file을 upload한 뒤, Minsky 서버에서 dpkg-scanpackages 명령을 통해 Minsky 서버의 local disk에 APT repository를 구성합니다.


1.  Ubuntu 16.04.1 LTS의 공식 APT repository로부터 전체 debian package를 laptop 또는 USB disk에 download 받기

$ apt-cache  dumpavail | grep -oP "(?<=Package: ).*" >> packagelist

$ head packagelist
a11y-profile-manager
a11y-profile-manager-doc
a11y-profile-manager-indicator
account-plugin-facebook
account-plugin-flickr
account-plugin-google
accounts-qml-module-doc
acct
acl
acpid

$ cat packagelist | wc -l
52681

--> 총 5만2천개가 넘는 debian package를 download 받아야 하며, 대략 70GB 예상

$ for i in `cat packagelist`
> do
> apt-get download ${i}:ppc64el
> done
...
Fetched 6,490 B in 0s (42.8 kB/s)
Get:1 http://ports.ubuntu.com/ubuntu-ports xenial/main ppc64el libgrail6 ppc64el 3.1.0+16.04.20160125-0ubuntu1 [49.9 kB]
Fetched 49.9 kB in 0s (167 kB/s)
Get:1 http://ports.ubuntu.com/ubuntu-ports xenial/main ppc64el libgraphite2-3 ppc64el 1.3.6-1ubuntu1 [62.9 kB]
Fetched 62.9 kB in 0s (211 kB/s)
Get:1 http://ports.ubuntu.com/ubuntu-ports xenial/main ppc64el libgraphite2-dev ppc64el 1.3.6-1ubuntu1 [14.6 kB]
Fetched 14.6 kB in 0s (65.4 kB/s)
Get:1 http://ports.ubuntu.com/ubuntu-ports xenial/main ppc64el libgraphite2-doc all 1.3.6-1ubuntu1 [567 kB]
Fetched 567 kB in 1s (386 kB/s)
...


2.  이렇게 download 받은 file들을 USB disk를 이용해서 Minsky 서버로 upload

민스키의 앞쪽 USB port에 USB disk를 연결한 뒤, 다음과 같이 인식시키고 mount.

$ sudo fdisk -l
--> USB disk가 /dev/sdc1 등으로 인식된 것을 확인

$ sudo mount /dev/sdc1 /mnt

$ cp -r /mnt/*  ~/files/apt  
--> ~/files/apt directory로 전체 copy

$ sudo umount /mnt


3.  Minsky 서버에서 아래와 같이 local APT repository를 구성

(~/files/apt directory에 전체 deb file들을 복사해놓은 상황)

u0017496@sys-84793:~/files/apt$ sudo dpkg-scanpackages . /dev/null > Packages

u0017496@sys-84793:~/files/apt$ sudo gzip -9c Packages > Packages.gz

--> debian package file들을 scan하여 Packages.gz file을 만드는 작업입니다.  이 file이 있어야 APT repository로 인식됩니다.

u0017496@sys-84793:~/files/apt$ ls -l Pa*
-rw-rw-r-- 1 u0017496 u0017496 5407830 Dec 14 22:07 Packages.gz

u0017496@sys-84793:~/files/apt$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.org

u0017496@sys-84793:~/files/apt$ sudo vi /etc/apt/sources.list
deb file:///home/u0017496/files/apt ./
--> 원래의 /etc/apt/sources.list에는 인터넷 상의 APT repository 주소들이 있습니다.  그중 맨 윗줄에 이와 같이 1줄을 넣습니다.  물론 file:// 뒤에는 deb file들과 Packages.gz이 들어있는 그 directory를 써야 합니다.

그리고나서 Release file을 다음과 같이 apt-ftparchive 명령어로 만듭니다.

u0017496@sys-84793:~/files/apt$ sudo apt-ftparchive release . > Release

이제 이 file들에 gpg sign을 해야 합니다.  하지 않을 경우 "The repository 'file:/home/apt ./ Release' is not signed"와 같은 error가 나면서 APT repository가 활성화되지 않습니다.

u0017496@sys-84793:~/files/apt$ sudo gpg --gen-key
gpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: XXXX
Email address: XXXX@gmail.com
Comment:
You selected this USER-ID:
    "XXX <XXXX@gmail.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/7A19D61F 2017-03-13
      Key fingerprint = XXXXXXXXXXXXXXXXX7A19D61F
uid                  XXX <XXX@gmail.com>
sub   2048R/XXXXX 2017-03-13



u0017496@sys-84793:~/files/apt$ sudo gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub   2048R/7A19D61F 2017-03-13
uid                  XXX <XXX@gmail.com>
sub   2048R/XXXXX 2017-03-13

u0017496@sys-84793:~/files/apt$ sudo gpg --output /home/pubkey-export-file --armor --export 7A19D61F
u0017496@sys-84793:~/files/apt$ sudo sudo apt-key add /home/pubkey-export-file
OK

u0017496@sys-84793:~/files/apt$ sudo gpg --clearsign -o InRelease Release
u0017496@sys-84793:~/files/apt$ sudo gpg -abs -o Release.gpg Release

이제 준비가 되었습니다.  apt-get update를 수행합니다.

u0017496@sys-84793:~/files/apt$ sudo apt-get update
Get:1 file:/home/apt ./ InRelease
Ign:1 file:/home/apt ./ InRelease
...
Get:8 file:/opt/DL/repo  Release.gpg
Ign:8 file:/opt/DL/repo  Release.gpg
Reading package lists... Done
W: file:///home/apt/./Release.gpg: Signature by key XXXXXXXXXXXXXX uses weak digest algorithm (SHA1)

apt-get 명령을 통해 새로 /etc/apt/sources.list로부터 APT repository를 읽어들이게 합니다.  위와 같이 weak algorithm 관련 warning이 있을 수 있으나 무시.

이제 local APT repository 구성이 끝났습니다.  시험 삼아 telnet을 설치/삭제해보십시요.

u0017496@sys-84799:~$ sudo apt-get install telnet



4.  CUDA 및 PowerAI (power-mldl)의 package들을 Minsky 서버에 USB disk 등을 통해 upload 합니다.

u0017496@sys-84799:~/files$ ls -l
total 2197160
-rw-rw-r--  1 u0017496 u0017496 1318461544 Dec  7 19:58 cuda-repo-ubuntu1604-8-0-local-ga2_8.0.54-1_ppc64el-deb
-rw-r--r--  1 u0017496 u0017496   32904888 Nov 14 09:57 libcudnn5-dev_5.1.5-1+cuda8.0_ppc64el.deb
-rw-r--r--  1 u0017496 u0017496    5189230 Nov 14 09:58 libcudnn5-doc_5.1.5-1+cuda8.0_ppc64el.deb
-rw-r--r--  1 u0017496 u0017496   39605204 Nov 14 09:58 libcudnn5_5.1.5-1+cuda8.0_ppc64el.deb
-rw-rw-r--  1 u0017496 u0017496  196132114 Oct 28 14:53 mldl-repo-local_1-3ibm2_ppc64el.deb

--> cuda 관련 1개, 그리고 cudnn 관련 3개, 그리고 PowerAI (mldl) 관련 1개 총 5개가 필요합니다.  다음과 같은 NVIDIA 및 IBM 홈페이지에서 download 받을 수 있습니다.

https://developer.nvidia.com/compute/cuda/8.0/prod/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.54-1_ppc64el-deb
https://download.boulder.ibm.com/ibmdl/pub/software/server/mldl/mldl-repo-local_1-3ibm2_ppc64el.deb
https://developer.nvidia.com/cudnn


5.  아래와 같이 이 debian package들을 dpkg 명령으로 설치합니다.

u0017496@sys-84799:~/files$ sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.54-1_ppc64el-deb
u0017496@sys-84799:~/files$ sudo dpkg -i mldl-repo-local_1-3ibm2_ppc64el.deb

--> 이 명령들은 실제 CUDA나 PowerAI를 설치하는 것이 아니라, Minsky 서버에 CUDA 및 PowerAI의 local APT repository를 만들어주는 것입니다.

u0017496@sys-84799:~/files$ sudo apt-get update

--> 새로 만들어진 CUDA 및 PowerAI의 local APT repository를 읽어들입니다.  이제 설치 준비가 끝났습니다.


6.  CUDA 및 PowerAI 설치 

u0017496@sys-84799:~/files$ sudo apt-get install cuda

u0017496@sys-84799:~/files$ sudo dpkg -i libcudnn5_5.1.5-1+cuda8.0_ppc64el.deb
u0017496@sys-84799:~/files$ sudo dpkg -i libcudnn5-dev_5.1.5-1+cuda8.0_ppc64el.deb
u0017496@sys-84799:~/files$ sudo dpkg -i libcudnn5-doc_5.1.5-1+cuda8.0_ppc64el.deb

--> 먼저 CUDA를 설치한 뒤 cudnn debian package들을 설치합니다.  이것들은 PowerAI 이전에 설치되어야 합니다.

u0017496@sys-84799:~/files$ sudo apt-get install power-mldl

--> 여러가지 Ubuntu OS의 prereqs을 아까 설치한 local APT repository로부터 끌어오면서 CUDA 및 PowerAI가 설치됩니다.






** Alternative way : 위와 같이 전체 Ubuntu APT repository를 다 download 받는 것은 시간과 공간이 많이 필요한 일입니다.  CUDA와 PowerAI에 필요한 OS prerequites만 download 받는 방법도 있습니다.

먼저 아래와 같이, 인터넷에 연결된 Linux on POWER 서버(Ubuntu 16.04.1 LTS)에서 CUDA와 PowerAI의 repository를 설치합니다.

u0017496@sys-84799:~/files$ sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.54-1_ppc64el-deb
u0017496@sys-84799:~/files$ sudo dpkg -i mldl-repo-local_1-3ibm2_ppc64el.deb

그리고 난 뒤, apt-cache 명령을 이용해서 cuda 및 power-mldl package를 설치하기 위한 prereq file들에 대한 정보를 file로 받아냅니다.

u0017496@sys-84793:~/files$ sudo apt-get update

u0017496@sys-84793:~/files$ apt-cache depends --recurse -i cuda > prereqs
u0017496@sys-84793:~/files$ apt-cache depends --recurse -i power-mldl >>  prereqs
u0017496@sys-84793:~/files$ cat prereqs | sed -e 's/.*Depends://' -e 's/[<>]//g' -e 's/\s//g' | sort -u > prereqs.txt
u0017496@sys-84793:~/files$ wc -l prereqs.txt
544 prereqs.txt

이 file들을 다음과 같이 apt-get download 명령으로 internet 상의 APT repository로부터 download 받습니다.

u0017496@sys-84793:~/files$ mkdir os-prereqs
u0017496@sys-84793:~/files$ cd os-prereqs
u0017496@sys-84793:~/files/os-prereqs$ cp ../prereqs.txt .
u0017496@sys-84793:~/files/os-prereqs$ for i in `cat prereqs.txt`
> do
> apt-get download $i
> done

여기서 받은 file들을 인터넷 접속이 안되는 Minsky에 올린 뒤, 앞서 언급한 3번 step부터 작업을 하면 됩니다.

* 단, 이 방법은 fully test된 것이 아니므로, 시간과 disk 공간이 허락하는 한, 전체 APT repository를 download 받으시길 권장드립니다.