글쓴이: 김정주(haje01@gmail.com)
최근 딥러닝 관련 패키지들은 대부분 CPU와 GPU를 함께 지원하고 있습니다. GPU를 사용하면 보다 빠르게 학습 결과를 낼 수 있지만, GPU를 활용하기 위해서는 NVIDIA계열의 그래픽 카드, 드라이버 S/W 그리고 CUDA의 설치를 필요로 합니다.
이 글에서는 AWS의 GPU 인스턴스와 도커를 활용해 딥러닝 패키지(Caffe)를 편리하게 사용하는 방법을 소개합니다.
클라우드 GPU 인스턴스 사용에는 다음과 같은 두가지 걸림돌이 있습니다.
- 높은 가격
- NVIDIA 드라이버 및 CUDA 설치
높은 가격은 Spot Instance를 쓰는 것으로, 드라이버 및 CUDA설치는 AMI를 사용하는 것으로 해결합니다.
현재 ap-northeast 리전에는 다음과 같은 GPU 인스턴스 타입이 있습니다.
- g2.2xlarge (1GPU, 8vCPU, 15GiB)
- g2.8xlarge (4GPU, 32vCPU, 60GiB)
주의점은, GPU 인스턴스의 경우 리전을 아시아 태평양(토쿄)로 사용하면 스팟의 가격도 비쌉니다. 따라서 응답 속도는 느리지만 US East (N. Virginia) 리전에서 합니다.
AZ(Availability Zone)에 따라 다르긴 하지만, g2.2xlarge의 경우 시간당 100원 수준으로 저렴하게 이용할 수 있습니다. (AZ는 비딩 가격에 맞는 것이 자동으로 찾아집니다.)
Spot Request탭에서 Request Spot instance를 선택합니다.
AMI선택 화면에서 기본 Ubuntu를 선택합니다
GPU 인스턴스 g2.2xlarge를 선택합니다.
스토리지는 기본이 8GiB인데 넉넉하게 20정도로 설정합니다. 용량이 부족하면 docker pull
에서 에러가 발생합니다.
$0.1로 비딩을 하겠습니다.
KeyPair 등의 설정을 마치고 인스턴스를 생성합니다. 인스턴스 생성 및 접속 관련 막히는 부분이 있으면 이재홍님의 글을 참고하시기 바랍니다.
잠시 시간이 걸리고 스팟 인스턴스 탭에서 인스턴스가 Active 상태가 되면 인스턴스 탭으로 가서 접속 IP를 확인 합니다.
확인한 IP로 ssh
로그인 하고
ssh ubuntu@{IP 주소} -p22 -i {.pem파일 경로}
GPU 정보를 확인합니다.
$ lspci | grep -i nvidia
00:03.0 VGA compatible controller: NVIDIA Corporation GK104GL [GRID K520] (rev a1)
간단히 GPU 머신이 준비되었습니다! 일단 OS 패키지를 업데이트해둡니다.
$ sudo apt-get update
NVIDIA 드라이버의 설치를 위해 아래의 작업이 필요합니다.
$ sudo -i
$ apt-get -y install linux-image-extra-virtual
마지막에 grub에 관한 질문이 나오면 "install the package maintainer's version"을 선택합니다.
nouveau(누보)는 NVIDIA 그래픽카드를 위한 오픈소스 드라이버입니다. 이것이 NVIDIA 드라이버의 커널 모듈과 충돌하기에 해제해야 합니다.
$ vi /etc/modprobe.d/blacklist-nouveau.conf
후, 다음 행들을 추가합니다.
blacklist nouveau
blacklist lbm-nouveau
options nouveau modeset=0
alias nouveau off
alias lbm-nouveau off
커널에서 nouveau를 비활성화 후
$ echo options nouveau modeset=0 | sudo tee -a /etc/modprobe.d/nouveau-kms.conf
$ update-initramfs -u
$ reboot
리부팅이 끝나면 다시 접속합니다.
빌드에 필요한 패키지를 받고
$ sudo -i
$ apt-get -y install build-essential
커널 소스를 설치합니다.
$ apt-get -y install linux-source
$ apt-get -y install linux-headers-`uname -r`
CUDA 인스톨러를 받습니다.
$ wget http://developer.download.nvidia.com/compute/cuda/6_5/rel/installers/cuda_6.5.14_linux_64.run
압축을 풉니다.
$ chmod +x cuda_6.5.14_linux_64.run
$ mkdir nvidia_installers
$ ./cuda_6.5.14_linux_64.run -extract=`pwd`/nvidia_installers
드라이버를 설치합니다.
$ cd nvidia_installers
$ ./NVIDIA-Linux-x86_64-340.29.run
라이센스에는 Accept 후 나머지는 기본 값을 선택합니다. 설치가 끝나면 NVIDIA 커널 모듈을 로딩 후
$ modprobe nvidia
드라이버 버전을 확인합니다.
$ nvidia-smi
Thu Dec 17 06:01:05 2015
+------------------------------------------------------+
| NVIDIA-SMI 340.29 Driver Version: 340.29 |
이제 CUDA와 샘플을 설치합니다.
$ ./cuda-linux64-rel-6.5.14-18749181.run
$ ./cuda-samples-linux-6.5.14-18745345.run
설치 중 나오는 라이센스는 스페이스키를 눌러 끝까지 스킵 후 accept
를 입력하면 됩니다. 나머지는 기본값을 선택합니다.
CUDA가 동작하는 지 확인합니다.
$ cd /usr/local/cuda/samples/1_Utilities/deviceQuery
$ make
$ ./deviceQuery
./deviceQuery Starting...
CUDA Device Query (Runtime API) version (CUDART static linking)
Detected 1 CUDA Capable device(s)
Device 0: "GRID K520"
CUDA Driver Version / Runtime Version 6.5 / 6.5
CUDA Capability Major/Minor version number: 3.0
Total amount of global memory: 4096 MBytes (4294770688 bytes)
( 8) Multiprocessors, (192) CUDA Cores/MP: 1536 CUDA Cores
GPU Clock rate: 797 MHz (0.80 GHz)
Memory Clock rate: 2500 Mhz
...
호스트 머신에서 CUDA를 사용할 때를 위해 ~/.profile
에 아래를 추가해둡니다.
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
이제 GPU 머신의 준비가 끝났습니다. 여기까지의 작업을 AMI로 만들어 놓으면 필요할 때 바로 생성해 쓰실 수 있습니다.
Caffe는 강력한 딥러닝 툴이지만, 설치가 까다로워 접근하기가 쉽지 않습니다. 이에 도커를 사용하여 설치합니다.
다음과 같이 도커를 설치합니다.
$ wget -qO- https://get.docker.com/ | sh
$ usermod -aG docker ubuntu
계정 설정 적용을 위해 로그아웃 후 로그인 하면 docker를 사용할 수 있습니다.
미리 빌드해서 올린 도커 이미지 파일을 내려 받습니다.
$ docker pull haje01/caffe-gpu
도커 컨테이너 안에서 호스트의 GPU 디바이스를 사용하기 위해서는 컨테이너 생성시 --device
옵션을 사용해야 합니다.
먼저 호스트에서 컨테이너로 전달할 NVIDIA 디바이스를 확인하고,
$ ls -la /dev | grep nvidia
crw-rw-rw- 1 root root 252, 0 12월 16 02:41 nvidia-uvm
crw-rw-rw- 1 root root 195, 0 12월 16 02:41 nvidia0
crw-rw-rw- 1 root root 195, 255 12월 16 02:41 nvidiactl
Caffe 컨테이너를 시작합니다.
$ docker run -dit --device /dev/nvidia-uvm:/dev/nvidia-uvm --device /dev/nvidia0:/dev/nvidia0 --device /dev/nvidiactl:/dev/nvidiactl --name caffe haje01/caffe-gpu
컨테이너의 정보를 살펴봅니다.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4209a9436996 haje01/caffe-gpu "/bin/bash" 2 seconds ago Up 2 seconds caffe
이제 컨테이너 안으로 들어가겠습니다.
$ docker exec -ti caffe bash
컨테이너의 드라이버 버전을 확인합니다.
$ nvidia-smi
Thu Dec 17 06:01:16 2015
+------------------------------------------------------+
| NVIDIA-SMI 340.29 Driver Version: 340.29 |
참고로 드라이버의 버전이 호스트와 다르면 CUDA가 동작하지 않습니다.
Caffe 모듈 import
를 테스트 해봅니다.
$ ipython
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
Type "copyright", "credits" or "license" for more information.
IPython 4.0.0 -- An enhanced Interactive Python.
In [1]: import caffe
libdc1394 error: Failed to initialize libdc1394
libdc1394 에러가 발생할 수 있으나, 무시해도 됩니다.
이제 Caffe를 사용할 수 있는 환경이 되었습니다.
컨테이너 안에서 Caffe가 설치된 폴더로 이동합니다.
cd /opt/caffe
MNIST 데이터를 설치합니다.
$ ./data/mnist/get_mnist.sh
$ ./examples/mnist/create_mnist.sh
마찬가지로 libdc1394 관련 에러는 무시하셔도 됩니다.
학습을 시작합니다.
$ examples/mnist/train_lenet.sh
제 경우, 기본 옵션인 GPU 모드로 3분 40초가 걸렸습니다. 비교를 위해서 다음과 같이 CPU로도 해보겠습니다.
examples/mnist/lenet_solver.prototxt
파일 아래 쪽의 solver_mode: GPU
를 solver_mode: CPU
로 바꾸어 줍니다.
다시 학습을 시작합니다.
$ examples/mnist/train_lenet.sh
CPU 모드로는 19분 30초가 걸렸습니다. 수행 시간에 큰 차이가 나는 것을 확인할 수 있습니다.
CUDA를 도커 컨테이너에서 쓰기 위해서는 호스트와 컨테이너의 NVIDIA드라이버 버전이 같아야 한다는 제약이 있습니다. 따라서 도커의 장점인 환경 분리는 많이 약해진 것 같습니다.
그러나 호스트 환경은 AMI로, 다양한 딥러닝 패키지는 도커 이미지로 만들어 두면 필요에 따라 선택해 활용할 수 있는 장점이 있겠습니다.
다 사용한 스팟 인스턴스는 제거해 비용을 아끼도록 합시다.
감사합니다.
http://tleyden.github.io/blog/2014/10/25/cuda-6-dot-5-on-aws-gpu-instance-running-ubuntu-14-dot-04/
http://tleyden.github.io/blog/2014/10/25/running-caffe-on-aws-gpu-instance-via-docker/
멋지고 자세한 설명 감사합니다!!
gpu 인스턴스가 있었군요!!