티스토리 뷰

개발/Cloud (GCP)

CloudML - 실전 심화

Jaeyeon Baek 2017.12.15 07:22

앞서 CloudML개념기본적인 사용 방법에 대해서 살펴보았고 이번에는 조금 더 실전에 가까운 글을 발행하도록 한다. 기본편에서 로컬 테스트와 클라우드 테스트를 진행했지만 코드의 내용이 단순히 TensorFlow 의 버전을 확인하는 수준이라서 실전에서 사용하려면 막막하거나 여러 장애 요소가 숨어있다. 이번 글에서는 TensorFlow 홈페이지에 있는 샘플 예제 실습을 통해 CloudML 의 울렁증을 극복할 수 있도록 한다.


예제코드 준비


우선 샘플 예제 사용을 위해 TensorFlow 소스코드를 다운로드 받도록 하자. 다운로드 방법은 무엇이든 상관없고 여기서는 GitHub 을 통해 받는 것으로 한다. 소스코드를 받았으면 이제 샘플 예제를 살펴보아야 하는데 예제에 대한 자세한 설명은 홈페이지를 참고하도록 하자. 간단하게 말하자면 미리 준비된 음성 세트를 학습시키고 새로운 음성을 분류해내는 모델이다.


소스코드의 위치는  tensorflow/examples/speech_commands  이다. (아마도) TensorFlow 1.4 에 들어오면서 생긴 예제기 때문에 오래전에 받아놓은 소스코드에서는 해당 경로를 찾지 못할 수도 있으니 최신 코드를 받는 것이 좋겠다. 우리에게 필요한건 TensorFlow 전체코드가 아니라 speech_commands 예제기 때문에 examples 경로로 이동해서 작업을 진행하도록 한다. 혹은 speech_commands 를 다른 작업 디렉터리로 복사해서 사용해도 좋다. 개인적으로는 GitHub 에서 받는 트리가 지저분해지는 것을 좋아하지 않기 때문에 다른 작업 디렉터리로 복사해서 사용하는 것을 선호한다.


이제 본격적인 CloudML 내용을 살펴볼텐데 개념편에서 이야기한 것처럼 CloudML 은 모델을 구글 클라우드에 던지고 클라우드 환경에서 학습이 되도록 지원을 한다. 또한 학습된 내용을 기반으로 product 형태로 사용도 가능하다. 자, 모델을 올바른 형태로 잘 던져주기만 하면 내 로컬환경과 상관없는 클라우드에서 작업이 된다는 의미인데 클라우드의 무한한 자원을 사용할 수 있게 되므로 고통받던 로컬 PC 는 모델을 던지고 정상적으로 동작하는 것이 확인되면 잠시 꺼두셔도 좋다. 


Local 테스트


우선 로컬 환경에서 모델이 정상적으로 수행되는지 확인을 해야 한다. (실제 예제가 돌아가게 하려면 약간의 수정이 필요하다. 우선 speech_commands 디렉터리에 __init__.py 를 생성해서 모듈로 인식될 수 있도록 하고, train.py 내부에 input_datamodelsimport 하는 부분을 speech_commands 하위에 있는 개념으로 수정해줘야 한다. import speech_commands.input_data as input_data 처럼 말이다)

$ gcloud ml-engine local train \
--module-name speech_commands.train \
--package-path speech_commands

앞서 기본편에서 언급된 내용이지만 Local 테스트는 로컬에 있는 TensorFlow 를 이용하기 때문에 TensorFlow 가 정상적으로 import 되어 사용될 수 있는 환경이 보장되어야 한다. 아래는 실제 수행되는 과정을 담은 예제 스크린샷이다.

Cloud 테스트


CloudML 에 모델을 던지는 방법은 이전 기본편에서 살펴본 것과 동일하게 진행한다. 우선 아래처럼 필요한 환경변수를 설정하도록 하자.

$ BUCKET_NAME=jybaek_cloudml_test
$ JOB_NAME=tf_ex_1
$ REGION=us-central1
$ OUTPUT_PATH=gs://$BUCKET_NAME/$JOB_NAME

각 요소에 대해서 살펴보면 BUCKET_NAME 은 결과를 저장하거나 실행 중간에 파생되는 내용을 저장하는 용도로 사용될 것이다. JOB_NAMECloudML 로 지금 던진 모델을 구분할 수 있도록 설정하면 된다. 내 프로젝트 안에서 동일한 JOB 이름을 갖지 않아야 하므로 뒤쪽에 인덱스 등을 넣어주면 좋다 (JOB 이름이 충돌나면 어차피 에러가 난다). REGION 은 모델이 training  될 지역을 선택하는 부분이다. CloudML 은 사용하는 Scale Tier 에 따라 가격이 책정되는데 그 가격이 REGION 별로 또 다르다. 참고로 asia 가 제일 비싼데 설정하지 않으면 REGION 은 asia-east1 로 지정된다 (현재 IP 지역 기준일 듯). 마지막으로 OUTPUT_PATH 는 앞에 생성한 BUCKET_NAMEJOB_NAME 을 조합해서 Google Storage 를 지정해주는 부분이다 ( gsGoogle Storage 를 의미하며 이처럼 터미널에서 바로 접근할 수 있는 형태로 제공된다). 우리의 소스코드(아래쪽에서 package 로 지정되는)와 기타 저장공간으로 사용될 예정이다.


환경설정 이후에는 바로 테스트가 가능하다.

$ gcloud ml-engine jobs submit training $JOB_NAME \
--job-dir $OUTPUT_PATH \
--module-name speech_commands.train \
--package-path speech_commands \
--region $REGION \
--runtime-version 1.4

여기서 주의깊게 살펴보아야 할 부분은 --runtime-version 이다. CloudML 은 내부적으로 다양한 환경을 제공하는데 뒤에 숫자(1.4)는 기본적으로 TensorFlow 의 버전과 동일하다. 각 버전에 따른 기타 모듈의 상세 버전은 아래 링크에서 확인하면 되겠다

https://cloud.google.com/ml-engine/docs/runtime-version-list


 지금까지 CloudML 은 python2 만 제공을 해왔는데 2018.12.11 드디어 python 3.5 를 지원한다. 여러 사람이 무척 애타게 기다렸던 부분이다. 각 모듈에 대한 버전을 별도로 설정하는 방법도 있지만 본 글에서는 다루지 않는다.


아래는 실제 수행되는 과정을 담은 예제 스크린샷이다. 

이 명령이 실행되면 우선 package 로 지정된 디렉터리가 tar 형태로 묶여서 storage 로 전송된다. 물론 여기서 storage--job-dir 로 지정된 Google Storage 이다. 그후 클라우드 어딘가에 우리의 모델을 작업할 공간(인스턴스따위)이 할당이 되고 storage 로 부터 package 를 다운로드 받는다. 그리고 나서 module-name 으로 지정된 speech_commnands.train 모듈을 실행한다.


명령어를 입력하면 바로 prompt 로 떨어지고 모든 작업은 클라우드에서 진행된다. 중간에 보이는 것처럼 실행시킨 모델에 대한 실시간 로그는 아래처럼 확인할 수 있다. 

$ gcloud ml-engine jobs stream-logs tf_ex_1

여러개의 모델을 연속해서 던질 수 있기 때문에 JOB_NAME 을 구분해서 로그를 확인하면 되겠다. 여기서는 tf_ex_1 은 우리가 앞서 설정 했던 JOB_NAME 이다.


클라우드 콘솔에서도 작업 내용을 확인할 수 있는데 아래처럼 완료된 작업, 중지된 작업, 실패한 작업, 그리고 방금 던져져서 실행중인 작업을 한눈에 볼 수 있다. 


각 항목을 선택해서 보면 작업에 대해 조금 더 상세한 정보를 볼 수 있는데, 작업 ID 부분 (여기서는 tf_ex_1) 을 클릭해보자. 환경설정 했던 내용들과 함께 작업에 대한 내용을 확인할 수 있다.


여기서 더 상세한 전체 로그(실시간 현황)를 보고 싶다면 로그 보기 링크를 선택하면 된다. 조금전 터미널에서 확인하는 명령어보다 더 상세한 로그를 확인할 수 있는데 이 로그는 stackdriver 를 통해 제공된다. 무료티어에서 기본 저장일이 7일이라는 점을 감안해서 사용하면 되겠다.


지금 돌린 모델의 경우 클라우드에서 24시간 이상 걸릴 수 있는 예제다. 클라우든데 뭐가 이렇게 오래 걸려? 할 필요 없다. 로컬 PC 에서 이 모델을 돌려볼 수 있는 환경이 된다면 돌려보시라. 뚝딱 결과가 나오는 만만한 예제가 아니다. 뭐 아무리 그래도 CloudMLGCP 의 특장점인데 실망했다고? 당연히 여기서 끝이 아니다. 위에서 잠깐 언급한 것처럼 작업을 던질때 우리는 Scale Tier 를 선택할 수 있다. 이것은 우리 작업의 처리 속도, 처리량, 그리고 비용 (...) 까지 모두 몇 단계 상승시켜준다. 바로 사용방법을 알아보도록 하자.


http://www.fmkorea.com/best/834940553



Scale Tier


위에서 모델이 동작한 Cloud 의 환경은 가장 낮은 등급이다. 각 등급은 아래와 같이 정의된다.

Enums
BASICA single worker instance. This tier is suitable for learning how to use Cloud ML, and for experimenting with new models using small datasets.
STANDARD_1Many workers and a few parameter servers.
PREMIUM_1A large number of workers with many parameter servers.
BASIC_GPUA single worker instance with a GPU.
BASIC_TPUA single worker instance with a Cloud TPU
CUSTOM

The CUSTOM tier is not a set tier, but rather enables you to use your own cluster specification. When you use this tier, set values to configure your processing cluster according to these guidelines:

  • You must set TrainingInput.masterType to specify the type of machine to use for your master node. This is the only required setting.

  • You may set TrainingInput.workerCount to specify the number of workers to use. If you specify one or more workers, you must also set TrainingInput.workerType to specify the type of machine to use for your worker nodes.

  • You may set TrainingInput.parameterServerCount to specify the number of parameter servers to use. If you specify one or more parameter servers, you must also set TrainingInput.parameterServerType to specify the type of machine to use for your parameter servers.

Note that all of your workers must use the same machine type, which can be different from your parameter server type and master type. Your parameter servers must likewise use the same machine type, which can be different from your worker type and master type.

https://cloud.google.com/ml-engine/reference/rest/v1/projects.jobs?hl=ko#scaletier


default 로 사용되는 BASIC 은 작은 데이터셋이나 CloudML 맛보기 용으로 적합하다. 이후 STANDARD_1, PREMIUM_1 은 10배씩 더 큰 리소스를 사용할 수 있게된다. 그러니까 STANDARD_1BASIC 의 10배, PREMIUM_1BASIC 의 100배에 해당한다 (가격도 마찬가지다). 여기까지가 CPU 에 해당되는 단계이다. 이후 BASIC_GPU, BASIC_TPU 는 각각 GPUTPU 를 사용할 수 있도록 지원한다. 하지만 아쉽게도 GPUTPU 는 무료티어에서 사용할 수 없다. quota 제한 때문인데, 무료티어에서는 사용할 수 있는 GPU 의 개수를 늘릴 수가 없다. 사용해보고 싶다면 과감히 계정 업그레이드를 진행해야 할 것이다. quota 정책이 더 궁금하다면 아래 링크를 참고하도록 하자.

https://cloud.google.com/ml-engine/quotas


앞서 살펴본 것들이 프리셋 같은 개념이고 입맛에 맞게 사용할 수 있는 고급단계가 CUSTOM 에 해당된다. 우선 CUSTOM 을 보기 전에 위에서 가격부터 살펴보고 가도록 하자. (가로 화면이 약간 짤릴 수 있는데 스크롤이 존재하므로 우측 끝까지 확인할 수 있다)

US

EUROPE

ASIA PACIFIC

Training (US)

The cost of a training job is $0.49 per hour, per training unit. The number of training units is determined by the machine configuration you choose to run your job. You can choose a predefined scale tier or a custom configuration of selected machine types. See the following tables for details.

Predefined scale tiers - price per hour (and training units)
BASIC

$0.2774 (0.5661)

STANDARD_1

$2.9025 (5.9234)

PREMIUM_1

$24.1683 (49.323)

BASIC_GPU

$1.2118 (2.4731)

CUSTOM

If you select CUSTOM as your scale tier, you have control over the number and type of virtual machines used for your training job. See the table of machine types.

Machine types - price per hour (and training units)
standard

$0.2774 (0.5661)

large_model

$0.6915 (1.4111)

complex_model_s

$0.4141 (0.845)

complex_model_m

$0.8281 (1.69)

complex_model_l

$1.6562 (3.38)

standard_gpu

$1.2118 (2.4731)

complex_model_m_gpu

$3.7376 (7.6278)

complex_model_l_gpu

$7.4752 (15.2555)

standard_p100 (Beta)

$2.6864 (5.4824)

complex_model_m_p100 (Beta)

$9.636 (19.6653)

Batch prediction (US)$0.09262 per node hour.3
Online prediction (US)$0.3 per node hour.3

https://cloud.google.com/ml-engine/pricing


링크로 접속해서 USEUROPE, ASIA region 별로 각각 가격을 확인해보면 US 가 확실히 저렴한 것을 알 수 있다. 이제 정말 BASIC 이 아닌 다른 Scale Tier 를 사용해보도록 하자. gcloud ml-engine 명령어는 기존 테스트와 모두 동일하고 뒤에 --scale-tier 옵션 하나만 추가해주면 된다.

$ gcloud ml-engine jobs submit training $JOB_NAME \
--job-dir $OUTPUT_PATH \
--module-name speech_commands.train \
--package-path speech_commands \
--region $REGION \
--runtime-version 1.4 \
--scale-tier STANDARD_1

CUSTOM 의 경우에는 --scale-tier 옵션 대신 --config 옵션을 사용해주면 된다. 이때는 yaml 를 생성하고 --config 에 달아주면 된다. 꼭 yaml 파일을 사용해야 하는 것은 아니고 --scale-tier 처럼 옵션을 풀어서 써도 되지만 정신건강에 그다지 좋지 않다. 아래와 같이 config.yaml 을 생성해서 사용하도록 하자.

trainingInput:
  scaleTier: CUSTOM
  masterType: complex_model_m
  workerType: complex_model_m
  parameterServerType: large_model
  workerCount: 9
  parameterServerCount: 3


--config 옵션은 아래처럼 사용해주면 된다.

$ gcloud ml-engine jobs submit training $JOB_NAME \
--job-dir $OUTPUT_PATH \
--module-name speech_commands.train \
--package-path speech_commands \
--region $REGION \
--runtime-version 1.4 \
--config config.yaml

참고로 여기서 다룬 TensorFlow 예제 코드는 STANDARD_1 로 했을 때 10시간이 걸린다. 위쪽 클라우드 콘솔 스크린샷에서 작업 ID kaggle_2 가 바로 그것이다. 사용 요금은 US region 에 명시된 것처럼 계산되어 $20~ 정도 청구 되었다. (BASIC_GPU 의 경우 2시간 8분 소요. 약 $3~ 청구)


마무리


비싼 그래픽카드로 무장한 장비를 구매해도 시장의 빠른 변화에 대응할 정도의 성능을 발휘하지는 못한다. 학업 목적이나 작은 데이터를 다루는 것이라면 상관없지만 대규모 프로젝트나 product 용도라면 이제 클라우드를 고려하지 않을 수 없는 세상이 되었다. 더욱이 모델을 연속적으로 계속 던질 수 있다는 것은 엄청난 장점이 아닐 수 없겠다. 어떤 클라우드를 사용할지는 사용자가 고민해야 하는 부분이겠다. (일단 Google Cloud 는 계정을 계속 새롭게 생성해서 $300 크레딧을 사실상 무한하게 사용할 수 있다. 공부를 위한 목적이라면 이보다 좋은 클라우드는 없을지도)


Google Cloud Platform 자체가 워낙 급변하고 있는 시장이라 이 글을 쓰여지고 얼마 안되어 터미널 명령이나 옵션등이 변경될 수도 있다. 혹시 예제가 정상적으로 수행되지 않는다면 말씀을 부탁드린다. 함께 고민하고 해결 할 수 있도록 노력하겠다.



'개발 > Cloud (GCP)' 카테고리의 다른 글

CloudML - 분산학습 아키텍처  (0) 2018.01.08
CloudML vs GCE  (0) 2018.01.04
CloudML - 실전 심화  (4) 2017.12.15
datalab 버전 업그레이드  (0) 2017.09.29
speech api 사용해보기  (6) 2017.08.17
Container Engine 종료(중지) 시키기  (2) 2017.08.14
댓글
  • 프로필사진 정현석 여기서의 Quotas 는 VM에서 GPU 몇개를 요청하는것과는 다른 개념인 것이지요?
    3부작 감사히 읽었습니다. 대략 감이 옵니다. @@
    2018.01.06 02:39 신고
  • 프로필사진 BlogIcon Jaeyeon Baek 제가 잘못 이해한 부분이 있었네요. 쿼타 신청시에 Preemptible 이 붙은게 GCE 에 VM instance 를 이야기하는 줄 알고 일반 VM용과 CloudML용 쿼타가 별도로 있다고 했는데요, 그렇지가 않았네요.

    Preemptible NVIDIA 는 그냥 단순히 GCE 인스턴스 생성시에 preemptible 로 설정되는 경우에만 사용할 수 있는 GPU 였습니다.

    결론: 일반 NVIDIA K80, P100 으로 쿼타 신청하면 GCE instance, CloudML 에서 모두 사용 가능합니다. :-)
    2018.01.06 09:03 신고
  • 프로필사진 정현석 감사합니다.
    Preemptible 도 실제 어떻게 쓸 수 있나 궁금했는데 마찬가지로 별도 쿼타 요청이 필요하군요.
    2018.01.06 10:03 신고
  • 프로필사진 BlogIcon Jaeyeon Baek 재밌는건 Preemptible 로 인스턴스 생성시에 Preemptible 로 신청된 GPU가 없으면 일반 GPU 쿼타를 사용합니다. 그럼 애초에 Preemptible gpu는 왜 있는걸까요ㅎㅎ 뭔가 제가 잘못알고 있는 것 같기도 하고..음. 2018.01.06 10:09 신고
댓글쓰기 폼