Monday, March 6, 2017

AWS EC2 - p2 인스턴스에 텐서플로 도입하기 (원제: p2 インスタンスへの TensorFlow 導入)

들어가며

이 글에서는 AWS의 GPU 머신 중 가장 성능이 높은 p2 계열 머신에서의 텐서플로 환경 구성을 다룹니다.
최종적으로는 AWS Step Function과 AWS Lambda를 결합, 여기서 만든 머신을 스팟인스턴스로 시작해 자동으로 머신러닝을 돌리는 것을 목표로 하고 있습니다.
※ p2 인스턴스는 현재 도쿄 리전에서 사용이 불가능합니다. Oregon・Virginia 등의 리전을 사용해주세요.
(역주: 17/04/14 서울 리전에 출시되었습니다. 서울/도쿄 양쪽 모두 사용 가능합니다. https://aws.amazon.com/ko/blogs/korea/now-available-p2-instance-type-in-asia-pacific-seoul-region/ )

이미지(AMI) 선택

텐서플로 공식 문서에 따르면 Linux의 경우 Ubuntu를 베이스로 만들어진 듯 하여 Ubuntu를 선택하였습니다.
Ubuntu Server 16.04 LTS (HVM), SSD Volume Type
미리 CUDA 환경 등이 탑재되어있는 Amazon Linux AMI 등도 있는 듯 하지만 리뷰에 따르면 GPU 실행에 문제가 있다는 글도 있고 그다지 딱 맞는 느낌은 아니었기에 Ubuntu로 처음부터 만들었습니다.
머신러닝은 디폴트로 생성되는 ubuntu 유저로 실행하겠습니다.
(최종적인 머신러닝은 자동화하기에 하나의 인스턴스에 하나의 유저가 좋습니다.)

pyenv, aws 커맨드

(저는 개인적으로 bash가 아니라 zsh를 사용하기에 미리 chsh 명령어를 사용해 디폴트 쉘을 zsh로 변경해두었습니다.)
온디맨드로 p2 인스턴스를 기동해 ubuntu 유저로 로그인, 아래와 같이 설정합니다.
파이썬은 앞으로의 유지보수를 고려해 pyenv를 사용합니다.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install libffi-dev libssl-dev
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
emacs .zshenv
다음과 같이 .zshenv 에 추가합니다.
차후 머신러닝자동화시 .zshrc에 환경변수를 기록하면 로드를 하지 않아 빼두었습니다.
export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PYENV_ROOT/shims:$PATH
eval "$(pyenv init -)"
이어서 다음과 같이 실행합니다.
source .zshrc
pyenv install 3.5.2
pyenv global 3.5.2
which pip3
> /home/ubuntu/.pyenv/shims/pip3 # pyenv에서 제대로 사용되는지 확인
pip3 install --upgrade pip
pip3 install aws

GPU / Cuda

http://qiita.com/S_Shimotori/items/3a10b35cf64d74b6b07e
에 따라 GPU / Cuda 를 설치합니다. 텐서플로에 관해서는 해당 글이 오래되어 다른 방법을 이용해야 합니다.
경로를 사용하는 부분은 .zshenv 에 입력해두도록 합시다.
최신 라이브러리들을 사용하기 위해 아래의 링크를 확인합니다.

텐서플로

https://www.tensorflow.org/install/install_linux
의 공식 페이지에 따라 인스톨. pip3를 사용하는 것이 편리했습니다. 
sudo apt-get install libcupti-dev
sudo pip3 uninstall tensorflow
pip3 install tensorflow-gpu sklearn matplotlib scipy
sklearn 외에 word2vec 등은 이미지생성 등에 필요해 추가하였습니다.

동작 확인

word2vec 의 코드 등을 이용해 동작을 확인합니다.
git clone https://github.com/tensorflow/tensorflow.git
python tensorflow/tensorflow/examples/tutorials/word2vec/word2vec_basic.py
또한, 실행시에 다음과 같은 로그가 출력되는지를 통해 GPU가 사용되고 있는지 여부를 확인할 수 있습니다.
(다음 예시는 p2.8xlarge의 경우입니다. p2.xlarge의 경우에는 GPU가 한 개만 장착되어 있기에 더 적은 로그를 발생시킵니다.)
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcublas.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcudnn.so.5 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcufft.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcurand.so.8.0 locally
...
I tensorflow/core/common_runtime/gpu/gpu_device.cc:906] DMA: 0 1 2 3 4 5 6 7
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 0:   Y Y Y Y Y Y Y Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 1:   Y Y Y Y Y Y Y Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 2:   Y Y Y Y Y Y Y Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 3:   Y Y Y Y Y Y Y Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 4:   Y Y Y Y Y Y Y Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 5:   Y Y Y Y Y Y Y Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 6:   Y Y Y Y Y Y Y Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 7:   Y Y Y Y Y Y Y Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla K80, pci bus id: 0000:00:17.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:1) -> (device: 1, name: Tesla K80, pci bus id: 0000:00:18.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:2) -> (device: 2, name: Tesla K80, pci bus id: 0000:00:19.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:3) -> (device: 3, name: Tesla K80, pci bus id: 0000:00:1a.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:4) -> (device: 4, name: Tesla K80, pci bus id: 0000:00:1b.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:5) -> (device: 5, name: Tesla K80, pci bus id: 0000:00:1c.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:6) -> (device: 6, name: Tesla K80, pci bus id: 0000:00:1d.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:7) -> (device: 7, name: Tesla K80, pci bus id: 0000:00:1e.0)
여기에 더해 nvidia-smi 커맨드를 이용하면 실제 어떤 GPU가 쓰이고 있는지 확인 가능합니다.
nvidia-smi

Fri Feb 24 07:20:43 2017
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 367.57                 Driver Version: 367.57                    |
|-------------------------------+----------------------+----------------------+
| 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 K80           Off  | 0000:00:17.0     Off |                    0 |
| N/A   56C    P0    59W / 149W |  10915MiB / 11439MiB |     31%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla K80           Off  | 0000:00:18.0     Off |                    0 |
| N/A   44C    P0    71W / 149W |  10877MiB / 11439MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla K80           Off  | 0000:00:19.0     Off |                    0 |
| N/A   55C    P0    58W / 149W |  10877MiB / 11439MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla K80           Off  | 0000:00:1A.0     Off |                    0 |
| N/A   47C    P0    72W / 149W |  10875MiB / 11439MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   4  Tesla K80           Off  | 0000:00:1B.0     Off |                    0 |
| N/A   56C    P0    59W / 149W |  10875MiB / 11439MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   5  Tesla K80           Off  | 0000:00:1C.0     Off |                    0 |
| N/A   49C    P0    70W / 149W |  10875MiB / 11439MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   6  Tesla K80           Off  | 0000:00:1D.0     Off |                    0 |
| N/A   58C    P0    58W / 149W |  10873MiB / 11439MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   7  Tesla K80           Off  | 0000:00:1E.0     Off |                    0 |
| N/A   50C    P0    71W / 149W |  10873MiB / 11439MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
GPU Util 부분이 GPU 사용률입니다. 0번째의 GPU 만이 31% 사용되고 있는 것을 알 수 있습니다.
전체 GPU를 사용하는 경우, 텐서플로의 애플리케이션코드상의 수정이 필요한 듯 합니다.(확실치 않습니다.)

AMI

현 단계까지 완료 되었다면 AMI로 만들어둡니다.

다음 단계로

지금까지 딥러닝이 가능하도록 준비하는 과정을 차례대로 실행하였습니다.
하지만 p2 인스턴스는 비싸기에 사용이 끝나면 자동으로 셧다운 되도록 한다든가 여러 자동화가 필요하겠지요?
그렇다면 AWS 스팟인스턴스에서 텐서플로 러닝 자동화를 참고하세요.

번역된 컨텐츠입니다.
Qiita. by halhorn. http://qiita.com/halhorn/items/361008b19b4fcfd618d6

Translated article.
Qiita. by halhorn. http://qiita.com/halhorn/items/361008b19b4fcfd618d6

No comments:

Post a Comment