AWS로 GPU기반의 딥러닝 학습환경 구축하기

Aws GPU 인스턴스를 이용해 딥러닝 환경 구축하기

안녕하세요. 오늘은 아마존 웹 서비스(이하 AWS)를 이용하여 GPU 인스턴스를 이용한 딥러닝 학습환경 만들기에 대해 알아봅시다.

딥러닝이란 최근 핫해진 뉴럴넷 기반의 기계학습 기법을 말하는데요.
학습 시 굉장히 많은 연산을 필요로 하여 학습에 소요되는 시간이 많이 필요합니다.
단순한 연산을 많이 하기 때문에 병렬처리에 특화된 GPU를 사용하여 학습시간을 단축시킬 수 있는데요.
당연히 좋은 GPU를 사용할수록 짧은 학습시간이 필요하겠지요.
하지만 문제는 이 GPU 가격이 개인이 사서 사용하기엔 너무나도 비싸다고 느낄 수 있습니다.

Tesla V100 가격

Tesla K80 가격

위 사진은 GPU 연산에 특화되어 나온 모델들입니다.
저희가 사용할 AWS EC2 P2, P3 인스턴스에 제공되는 GPU 모델들입니다.

포스팅 날짜를 기준으로 최소 200만원 이상의 가격을 보여주고 있는데요.
개인이라도 사지 못할 가격은 아닙니다만, 딥러닝이 무엇인지 이제 알아가는 시점에 입문자가 구매하기엔 굉장히 벅찬 금액이죠.
하지만 AWS에서 제공해주는 GPU인스턴스를 빌려서 시간제로 비용을 낼 수 있다면, 비싼 GPU를 구매하지 않고도 필요할 때에만 성능이 좋은 GPU를 이용할 수 있겠죠 ?

Aws EC2

EC2에 관한 설명은 생략하도록 하고, 여기에서 자세하게 확인 가능합니다.

인스턴스 종류 및 가격

저희는 GPU 인스턴스를 사용할 예정이기 때문에 P, G 두가지 계열을 확인하면 됩니다.
인스턴스 스펙으로 이동하여 자세한 스펙을 확인 가능합니다.
각 인스턴스의 가격은 시간에 비례하여 비용이 청구되는 방식이며, 각 리전마다 사용가격의 편차가 있습니다.

서울리전은 해외리전보다 비싼편이니 (약 2배가량 비쌈), 연구목적으로 사용하실 때에는 해외리전을 이용하시는걸 추천드립니다.

오하이오 리전의 가격
서울 리전의 가격

위 사진은 오하이오 리전의 가격이며, 아래 사진은 서울리전의 가격입니다.
같은 p2.xlarge의 가격을 보더라도 오하이오 리전은 시간당 \$0.9, 서울리전은 시간당 \$1.465의 가격을 보여줍니다.
그리고, 서울리전은 g3계열의 인스턴스가 제공되지 않고 있습니다.

오하이오 리전의 p2.xlarge 가격을 보면 대략 시간당 1,000원 정도의 가격을 보여줍니다.
요새 PC방 가격도 시간당 1,000원이 넘는걸 생각하면 그리 비싸다고 생각하진 않을 수 있습니다.

스팟 인스턴스

하지만 위의 가격은 온디맨드 계약의 가격이며, AWS에서 더 할인을 받을 수 있는 방법이 존재합니다.
그건 바로 R.I(예약 인스턴스) 혹은 Spot인스턴스를 이용하는 방법입니다.
R.I의 경우는 최소 계약단위가 1년 단위이기 때문에 개인이 하기엔 부담스럽고, 오히려 서비스를 운영중인 회사에서 GPU인스턴스가 필요할 때 사용할 수 있겠습니다.

스팟 인스턴스의 경우는 인스턴스를 경매입찰방식으로 할당받는 개념인데, 최대 90%까지 가격이 할인될 수 있습니다.

오하이오 리전의 스팟 인스턴스 가격
서울 리전의 스팟 인스턴스 가격

온디맨드의 가격보다 더 저렴한 가격을 확인할 수 있습니다.
이 스팟 인스턴스를 이용해보도록 하겠습니다.

스팟 인스턴스 생성

스팟인스턴스 생성 - 1

  1. AWS 관리 콘솔에서 스팟 요청을 눌러줍니다.

스팟인스턴스 생성 - 2

  1. 자주 쓰이는 형태의 패턴들이 이미 만들어져 있으나, 명시한 시간동안 인스턴스를 사용할 수 있도록 시간을 지정하여 사용합니다.

    (최소 1시간에서 최대 6시간까지 사용 가능합니다.)

스팟인스턴스 생성 - 3

  1. 인스턴스 타입 변경을 눌러 사용할 인스턴스의 타입을 지정합니다.

    저는 GPU compute에서 p2.xlarge를 이용하겠습니다.
    GPU instance에서 조금 더 저렴한 G3 계열의 인스턴스도 사용 가능합니다.

스팟인스턴스 생성 - 4

  1. AMI 검색을 눌러 사용할 기본 AMI를 지정합니다.

    딥러닝 프레임워크를 사용하여 GPU를 사용하기 위해선 GPU 설정이 많이 필요한데, 이러한 사전 작업을 마친 템플릿을 AWS에서 공식 AMI로 제공합니다.
    꼭 소유자를 확인하여 아마존 공식 이미지가 맞는지 확인합니다.
    (일반 유저도 AMI를 만들어 배포할 수 있어 마이닝 프로그램을 설치해둔 템플릿들이 다수 존재하니 주의합시다.)

스팟인스턴스 생성 - 5

  1. Additional configurations를 눌러 시큐리티 그룹 등 인스턴스에 필요한 설정을 마쳐줍시다.

스팟인스턴스 생성 - 6

  1. 스팟 인스턴스가 정상적으로 생성되었습니다.

    간혹 해외리전의 스팟 인스턴스 제한이 걸려있어 생성되지 않는 경우가 존재합니다.
    이때는 AWS에 케이스를 오픈하여 리밋제한을 상향요청 할 수 있습니다.

스팟인스턴스 생성 - 7

  1. 생성된 인스턴스 확인

    생성된 인스턴스의 유형과 최대 가격을 볼 수 있습니다.
    최대가격이란 명시된 시간동안 다른 인스턴스들이 높은 입찰가를 제시할 때 인스턴스가 종료 될 수 있으니 최대 가격이 온디맨드 가격으로 자동적으로 조절됩니다.

영구적으로 사용할 볼륨 생성하기

스팟 인스턴스가 종료될 시 75GB로 할당된 AMI 볼륨이 자동적으로 삭제됩니다.
인스턴스 생성 시 해당 볼륨을 삭제하지 않을 수 있으나, 75GB의 볼륨을 갖고 있기는 부담스럽기 때문에 우리가 필요한 데이터들만 저장할 수 있는 작은 크기의 볼륨을 따로 생성하여 인스턴스의 종료와 무관하게 사용할 수 있도록 새로운 볼륨을 만들어 추가해봅시다.

스팟인스턴스 생성 - 8

  1. 데이터 영구보존 볼륨 생성하기

    좌측의 볼륨 메뉴를 눌러 현재 인스턴스의 가용영역을 확인 한 이후,
    볼륨 생성을 눌러줍니다.

스팟인스턴스 생성 - 9

  1. 바로 이전에 확인한 가용영역을 맞춰 새로운 볼륨을 생성합니다.

    가용영역이 다르다면 볼륨이 인스턴스에 사용할 수 없으니 꼭 가용영역을 맞춰 생성합니다.

스팟인스턴스 생성 - 10

  1. 생성된 볼륨을 확인할 수 있습니다.

스팟인스턴스 생성 - 11

  1. 우클릭을 이용해 볼륨 연결을 눌러줍니다.

스팟인스턴스 생성 - 12

  1. 볼륨을 연결합니다.

    인스턴스를 눌러주면 자동적으로 같은 가용영역에 있는 사용중인 인스턴스 목록이 나옵니다.
    디바이스는 해당 인스턴스에 사용될 디바이스명입니다.

여기까지가 콘솔에서 설정 가능한 스팟 인스턴스에 대한 인스턴스 생성과 설정입니다.

이후는 AWS 인스턴스에 ssh접속을 한 이후 설정하는 부분입니다.

SSH 접속

SSH 로 생성한 스팟 인스턴스에 접근하면 초기 화면이 이렇게 보이는걸 확인할 수 있습니다.
각각의 가상환경에 진입할 수 있는 명령어와 사용가능한 환경에 대한 설명이 보입니다.

=============================================================================
       __|  __|_  )
       _|  (     /   Deep Learning AMI (Amazon Linux) Version 20.0
      ___|\___|___|
=============================================================================

Please use one of the following commands to start the required environment with the framework of your choice:
for MXNet(+Keras2) with Python3 (CUDA 9.0 and Intel MKL-DNN) _____________________________________ source activate mxnet_p36
for MXNet(+Keras2) with Python2 (CUDA 9.0 and Intel MKL-DNN) _____________________________________ source activate mxnet_p27
for MXNet(+Amazon Elastic Inference) with Python3 _______________________________________ source activate amazonei_mxnet_p36
for MXNet(+Amazon Elastic Inference) with Python2 _______________________________________ source activate amazonei_mxnet_p27
for TensorFlow(+Keras2) with Python3 (CUDA 9.0 and Intel MKL-DNN) ___________________________ source activate tensorflow_p36
for TensorFlow(+Keras2) with Python2 (CUDA 9.0 and Intel MKL-DNN) ___________________________ source activate tensorflow_p27
for Tensorflow(+Amazon Elastic Inference) with Python2 _____________________________ source activate amazonei_tensorflow_p27
for Theano(+Keras2) with Python3 (CUDA 9.0) _____________________________________________________ source activate theano_p36
for Theano(+Keras2) with Python2 (CUDA 9.0) _____________________________________________________ source activate theano_p27
for PyTorch with Python3 (CUDA 10.0 and Intel MKL) _____________________________________________ source activate pytorch_p36
for PyTorch with Python2 (CUDA 10.0 and Intel MKL) _____________________________________________ source activate pytorch_p27
for CNTK(+Keras2) with Python3 (CUDA 9.0 and Intel MKL-DNN) _______________________________________ source activate cntk_p36
for CNTK(+Keras2) with Python2 (CUDA 9.0 and Intel MKL-DNN) _______________________________________ source activate cntk_p27
for Caffe2 with Python2 (CUDA 9.0) ______________________________________________________________ source activate caffe2_p27
for Caffe with Python2 (CUDA 8.0) ________________________________________________________________ source activate caffe_p27
for Caffe with Python3 (CUDA 8.0) ________________________________________________________________ source activate caffe_p35
for Chainer with Python2 (CUDA 9.0 and Intel iDeep) ____________________________________________ source activate chainer_p27
for Chainer with Python3 (CUDA 9.0 and Intel iDeep) ____________________________________________ source activate chainer_p36
for base Python2 (CUDA 9.0) ________________________________________________________________________ source activate python2
for base Python3 (CUDA 9.0) ________________________________________________________________________ source activate python3
Official Conda User Guide: https://conda.io/docs/user-guide/index.html
AWS Deep Learning AMI Homepage: https://aws.amazon.com/machine-learning/amis/
Developer Guide and Release Notes: https://docs.aws.amazon.com/dlami/latest/devguide/what-is-dlami.html
Support: https://forums.aws.amazon.com/forum.jspa?forumID=263
For a fully managed experience, check out Amazon SageMaker at https://aws.amazon.com/sagemaker
=============================================================================

파이썬 가상환경 진입

저희는 Python 3.6기반의 Tensorflow 사용할 수 있는 가상환경으로 진입해보겠습니다.

1
2
3
4
[ec2-user@ip-172-31-15-213 ~]$ source activate tensorflow_p36

# 파이썬 가상환경으로 진입하면 쉘이 아래와 같이 변합니다.
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$

연결한 볼륨 확인

생성하고 나서 연결한 볼륨에 대한 정보를 확인합니다.

1
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  75G  0 disk
└─xvda1 202:1    0  75G  0 part /
xvdf    202:80   0   8G  0 disk

아까 연결한 8GB의 볼륨이 xvdf로 연결되어있는걸 확인할 수 있습니다.

볼륨의 포맷 확인

연결된 xvdf 디바이스를 통해 볼륨의 포맷을 확인합니다.

1
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ sudo file -s /dev/xvdf

/dev/xvdf: data

갓 생성한 볼륨의 경우 data로 나오게 될 것이고, 이 볼륨은 사용하고 있는 os 파일 시스템에 맞춰 파일 포맷을 진행해줘야 합니다.

볼륨 ext4 포맷

볼륨의 파일시스템을 ext4 포맷으로 변경합니다.

1
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ sudo mkfs -t ext4 /dev/xvdf

mke2fs 1.43.5 (04-Aug-2017)
Creating filesystem with 2097152 4k blocks and 524288 inodes
Filesystem UUID: 6ce22348-395a-4ac1-8df7-e180aaadaadf
Superblock backups stored on blocks:
  32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

볼륨 포맷 재확인

파일 시스템 포맷이 완료 된 후 ext4 포맷으로 변경됬는지 확인합니다.

1
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ sudo file -s /dev/xvdf
/dev/xvdf: Linux rev 1.0 ext4 filesystem data, UUID=6ce22348-395a-4ac1-8df7-e180aaadaadf (extents) (64bit) (large files) (huge files)

결과에 나오는 UUID를 잘 기억하세요.

볼륨 마운트

포맷 완료 된 볼륨을 사용하기 위해서는 마운트 과정이 필요합니다.
현재 Home 디렉터리에 새로운 디렉터리를 만들어 마운트를 진행합니다.

1
2
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ mkdir mount_dir
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ sudo mount /dev/xvdf mount_dir/

정상적으로 마운트 되었다면 에러 메세지 없이 완료됩니다.

볼륨 자동 마운트

1
2
cp /home/ubuntu ubutnu
mount /dev/xvdf ~/smount

위와 같이 수동으로 마운트 시켜 사용하는 경우 인스턴스가 재시동 되는 경우 마운트를 다시 해줘야 합니다.
/etc/fstab 이라는 폴더는 부팅 시 마운트 해야할 목록을 가지고 있어 자동으로 마운트가 진행되도록 합니다.
fstab 파일이 잘못 작성 되어 있으면 부팅이 안되는 경우도 발생하니 백업을 만들고, 신중하게 파일을 수정하도록 합시다.

아래 명령어는 복붙하지마시고 본인의 UUID와 마운트 할 디렉터리에 맞춰 변경하여 사용하세요.

1
2
3
4
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ sudo cp /etc/fstab /etc/fstab.orig  
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ echo "UUID=6ce22348-395a-4ac1-8df7-e180aaadaadf /home/ec2-user/mount_dir ext4 defaults,nofail 0 2" | sudo tee --apend /etc/fstab

(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ sudo mount -a

마지막 mount -a 옵션을 꼭 실행해보시고, 정상적이라면 아무 메시지 없이 완료됩니다.
에러 메세지가 발생한 경우 fstab 파일에 문제가 있을 수 있으니 꼭 확인하세요.

Jupyter Notebook 실행

원격에서 접속하기 위해 IP 대역을 전부 풀어줍니다.
Port 번호는 기본적으로 8888 포트를 사용하니 시큐리티 그룹에서 해당 포트를 허용시켜주시고, 다른 포트번호로 사용하셔도 무방합니다.

1
(tensorflow_p36) [ec2-user@ip-172-31-15-213 ~]$ jupyter notebook --ip 0.0.0.0
[I 06:43:24.447 NotebookApp] Using EnvironmentKernelSpecManager...
[I 06:43:24.448 NotebookApp] Started periodic updates of the kernel list (every 3 minutes).
[I 06:43:24.552 NotebookApp] Writing notebook server cookie secret to /home/ec2-user/.local/share/jupyter/runtime/notebook_cookie_secret
[I 06:43:27.661 NotebookApp] Loading IPython parallel extension
[I 06:43:27.784 NotebookApp] JupyterLab beta preview extension loaded from /home/ec2-user/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/jupyterlab
[I 06:43:27.784 NotebookApp] JupyterLab application directory is /home/ec2-user/anaconda3/envs/tensorflow_p36/share/jupyter/lab
[I 06:43:28.405 NotebookApp] [nb_conda] enabled
[I 06:43:28.408 NotebookApp] Serving notebooks from local directory: /home/ec2-user
[I 06:43:28.408 NotebookApp] 0 active kernels
[I 06:43:28.408 NotebookApp] The Jupyter Notebook is running at:
[I 06:43:28.408 NotebookApp] http://ip-172-31-15-213:8888/?token=d591bd615294176a215c3ae4273b1b41ab12db439b7fbb8d
[I 06:43:28.408 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 06:43:28.408 NotebookApp] No web browser found: could not locate runnable browser.
[C 06:43:28.408 NotebookApp]

  Copy/paste this URL into your browser when you connect for the first time,
  to login with a token:
      http://ip-172-31-15-213:8888/?token=d591bd615294176a215c3ae4273b1b41ab12db439b7fbb8d&token=d591bd615294176a215c3ae4273b1b41ab12db439b7fbb8d
[I 06:43:28.409 NotebookApp] Starting initial scan of virtual environments...

ec2 인스턴스의 public ip 주소가 만약 1.10.10.10 이라고 가정하면,
http://1.10.10.10:8888 로 접속하시면 위에 출력된 해당 토큰을 요청합니다.
토큰을 입력해주면 쥬피터 노트북을 사용하실 수 있습니다.

Powered by Hexo and Hexo-theme-hiker

Copyright © 2019 - 2019 Commit once a day All Rights Reserved.

UV : | PV :