페이지

2020년 11월 30일 월요일

머신러닝 개발 중에 모델을 모니터하고 딥러닝 모델을 개선하는 방법 중 하나 - callback

 

딥러닝 모델을 callback 없이 개발하는 것은 브레이크 없는 차를 운전하는 것과 같다

만약 딥러닝 모델을 개발하고 있다고 해보자. 만약 머리 속에 시간이 많이 소요되는 훈련 중에 프로세스를 조정할 방법에 대해 아무 생각이 없다면 그 프로젝트는 바람직하지 않은 방향으로 끝날 가능성이 높다. 이번 호 에서는 Keras Callback를 통하여 ModelCheckpoint, EarlyStopping 등의 함수들을 사용하여 어떻게 모델을 모니터하고 개선하는지 알아보도록 한다.

Callback 이란?

Callback 이란 훈련 절차의 주어진 단계에서 적용되는 일련의 함수들을 말한다. Callback 을 통하여 훈련 중인 모델의 내부 상태나 통계를 볼 수 있다. 예를 들어, 1000 번의 epoch 가 있는 훈련을 매번 끝날 때까지 시간을 소요하며 돌려보고 그 정확도나 손실을 확인한다면 무척 시간이 아까울것이다. 만약 정확도나 손실이 어떤 단계에 다다르면 훈련을 중단하게 한다면 어떨까? 훈련이 성공적으로 끝난 모델을 저장하는 방법은 없을까? 혹은 learning rate 를 물론 decay 를 설정하고 epoch 마다 조정하는 방법도 있지만 시간에 따라 조절되게 할 순 없을까?

이러한 예들 처럼, 매 단계의 훈련/epoch 과정에 훈련 프로세스를 조정할 수 있게 도와주도록 어떤 자동화된 작업을 정의하고 사용하는 것을 callback 이 맡아서 해준다.

과적합(overfitting)을 방지하는 EarlyStopping

과적합(overfitting)이란 딥러닝 모델이 학습데이터에만 너무 잘 맞아서 일반적인 다른 데이터에 대해서는 제대로 예측하지 못하는 현상을 일컫는다. 너무 많은 epoch는 과적합을 유발하고 너무 적은 epoch는 과소적합(underfitting)을 일으킨다. 한가지 과적합을 방지하는 방법은 훈련 프로세스를 종료전에 일찍 끝내는 것이다. Keras Callbacks API EarlyStopping 은 다양한 지표와 인자를 통하여 언제 훈련 프로세스가 끝나야 하는지를 정할 수 있도록 한다.

우선 Keras EarlyStopping 을 위해 아래와 같은 선언이 필요하다




그 다음, 아래와 같은 인자를 정의해 준다.




위의 정의는 Validated Loss 를 측정하겠다는 것, min_delta = 0 이라는 뜻은 val_loss 변화 값의 최소가 0 일 때 훈련이 중지하는 것, patience = 3 은 성능이 증가하지 않는 상태에서 epoch 3 번 허용한 다는 뜻, restore_best_weights = True 는 훈련이 중지했을 때 최고 성능의 weights 를 보관하라는 뜻이다. verbose = 1로 하면 언제 Keras 에서 훈련을 중지했는 지를 화면에 출력한다.

 최종적으로, model.fit 함수의 callback으로 earlystopping 객체를 넣어주면 early stopping을 적용할 수 있다






Model을 저장해주는 ModelCheckpoint

과적합을 방지하기위해 EarlyStopping을 사용하여 훈련을 중지했을 때, 모델의 validation error 가 더 이상 낮아지지 않도록 조절할 수 있었지만, 중지된 상태가 최고의 모델은 아닐 수 있다. 따라서 가장 validation 성능이 좋은 모델을 저장하는 것이 필요한데, keras 에서는 이를 위해 ModelCheckpoint 라는 객체를 제공한다. 이 객체는 validation_error 를 모니터하면서 이전 epoch 에 비해 validation 성능이 좋으면 무조건 이때의 parameter 들을 저장한다. 이를 통해 훈련이 중지되었을 때, 가장 validation 성능이 높았던 모델을 저장할 수 있다.







ModelCheckpoint 인스턴스와 앞의 EarlyStopping 인스턴스를 Callbacks 파라미터에 넣어 줌으로써 가장 validation 성능이 좋았던 모델을 저장하게 된다.

 






내장된 fit() loop 를 통한 callback 사용법

Callbacks 라는 키워드 인자를 사용하여 여러 개의 callbacks 을 모델의 .fit() 메소드에 전달할 수 있다, EarlyStopping, ModelCheckpoint 그리고 TensorBoard callbacks 들을 my_callbacks 으로 정의하고 이를 model.fit 메소드에 callbacks=my_callbacks 인자로 넘겨줌으로써 3가지 callbacks 함수를 한꺼번에 사용할 수 있다.


텐서보드(TensorBoard)는 모델을 이해하고 디버깅 및 최적화를 돕기 위한 시각화도구로 아래와 같은 화면을 제공함으로써 epoch 가 진행되면 서의 정확도와 손실을 손쉽게 파악하게 도와준다.



텐서플로우 와 텐서플로우 callbacks에 대한 내용은 뉴스레터 2호 에서 다루었다. 보다 자세한 사항은 뉴스레터를 클릭하여 살펴보기 바란다.


결언

이상 살펴본 바와 같이, Keras callbacks 을 통해서 과적합을 방지하기위한 EarlyStopping 함수를 사용하면 validation loss 의 성능이 더 이상 증가하지 않는 시점에서 몇 번의 epoch 수를 기다리게 할 것인가를 정함으로써 과적합이 일어나기 전의 최고 성능의 weight를 저장하게 된다. 하지만 EarlyStopping 을 사용하여 훈련을 중지할 수 있지만, 이때가 최고의 모델을 아닐 수 있다

이때, ModelCheckPoint 함수를 사용하여 validation error를 모니터 하면서 이전 epoch에 비하면 성능이 좋으면 무조건 parameter를 저장하는 기능을 사용할 수 있다. 그리고 tensorboard callback을 통하여 디버깅 및 최적화를 돕기 위한 시각화도구를 제공받는 것을 살펴보았다. 그리고 여러 개의 callbacks 를 모델의 .fit() 메소드를 통하여 전달하여 한꺼번에 사용하는 방법을 살펴보았다.

이러한 Keras 기능들을 사용하여 훈련과정을 모니터하고, 최고의 모델의 상태를 저장하며, 훈련의 디버깅 및 최적화를 위한 시각화도구를 제공하는 callback 을 적극 사용해보자.

2020년 10월 7일 수요일

훈련이 끝난 머신러닝 모델을 어떻게 사용자들에게 서비스할 수 있을까?

 

머신러닝 모델 개발은 사용자들에게 서비스하기 위한 것임을 잊지 말자

  생각해보자. 데이터 수집 및 전처리도 어렵게 끝나고 훈련, 검증, 테스트 세트의 데이터를 대상으로 훈련 및 테스트가 끝났다. 축하한다. 그러나 연구용이나 실험용으로 모델을 한번 만들어 본 것이 아니고 머신러닝을 실제 현장에서 사용자에게 서비스 할 계획이라면 모델 서비스라는 결코 쉽지 않은 과정이 남아있다. 머신러닝 파이프라인이란 머신러닝을 통하여 데이터수집부터 모델 훈련, 모델 서비스, 성능 모니터링까지의 반복적 사이클을 진행하는 것을 일컫는다.

연구에 의하면 머신러닝 모델은 전체 파이프라인 과정의 5% 밖에 차지하지 않는다고 한다. 훈련이 20%를 차지하고 아마 상당부분 기간이 소요되는 부분이 데이터 수집 및 정제 그리고 모델 서비스 부분이 아닐까 싶다. 아래 그림1.은 파이프라인 순서도이다.

 (그림1. 머신러닝 파이프라인)
  

모델 서비스(model deployment)는 모델 훈련이 끝난 머신러닝 모델을 실제 서비스 환경에서 의사결정에 사용될 수 있도록 배치하는 것이다. 예를 들어 아래 그림2.와 같이 머신러닝에서 자주 사용되는 MNIST 데이터 학습, 즉 손글씨 0에서 9까지의 28X28 픽셀의 이미지들을 분류하는 모델을 대상으로 한다면, 외부(스마트폰)에서 아래와 같이 8 이라는 손글씨 이미지가 머신러닝이 학습된 서버(혹은 클라우드)HTTP 를 통해 보내지면 서버의 훈련된 모델이 분류를 수행한 후 ‘8’ 이라는 결과를 다시 스마트폰으로 보내주는 것이다.


(그림2. MNIST 손글씨 인식 머신러닝 모델의 서비스)

치타를 통해 몇 줄의 코드 추가와 클릭을 통해 HTTP gRPC 모델 서빙이 가능

  이러한 모델 서비스가 가능 하려면 치타에서의 다음과 같은 절차가 필요하다

1.    우선 서버(클라우드)에 있는 MNIST 분류 머신러닝 모델이 아래와 같은 코드가 모델을 서비스하도록 추가되어 훈련이 끝나 있어야 한다. 보다 자세한 사항은 텐서플로우 서빙 모델 편을 참고하기 바란다.


2.    치타 플랫폼의 모델관리로 들어가서 모델업로드 버튼을 누르면 아래 그림 3과 같은  모델업로드 화면이 나오고 위 1번에서 서버에 저장된 모델을 끌어다가 모델업로드에 넣는다. (위와 같은 코드가 들어간 모델 훈련이 끝나면 export_path 에 정의한 장소에 모델이 저장된다)

3.  다시 모델관리로 돌아가서 버전정보 보기를 누르면 아래 그림4. 와 같이 서빙될 모델의 버전을 확인할 수 있다. 여기서 saved_model.pb는 직렬화된 텐서플로우의 저장된 모델로 그래프정의와 시그니처와 같은 모델의 메타데이타가 저장된 것. variables는 그래프의 직렬화된 변수를 보유하는 파일이다. 이들을 확인함으로써 모델이 서빙될 준비가 되었음을 확인. 자세한 내용은 텐서플로우의 Tensorflow 모델제공 편을 참고바람.

  

                     (그림 3. 치타의 모델등록 화면)

4.    치타의 모델배포관리 화면으로 들어가서 등록을 누르고 배포할 모델을 선택한 후 모델배포 파라미터에서 instance 유형을 스마트폰에서 제공될 mnist 이미지로 등록하고 저장을 누른다.

                     (그림 4. 모델 버전파일 확인 화면)

5.    그러면 아래 그림 5. 와 같은 모델배포 테스트화면이 나타나고 하단의 생성 버튼을 누르면 배포 테스트를 수행할 수 있는 환경이 좌측 상단에 생성중으로 나타난다. 그림 5. 에서 보듯이 서비스하는 대상에 따라 HTTP gRPC 통신 프로토콜을 선택할 수 있다.  HTTP는 동기방식의 RestAPI , gRPC 는 구글에서 개발한 오픈소스 RPC(원격 절차 호출)프레임워크로 특히 마이크로서비스 아키텍쳐환경에서 다양한 서비스들이 상호간에 통신이 빈번한 상황에서, JSON 을 통한 직렬화는 취약함에 기인하여 개발한 통신 프레임워크다. 특히 이미지처리등의 서비스에서 벤치마트 성능은 gRPC HTTP 대비 5배 이상의 성능을 나타내는 것으로 되어있다.

(그림5. 모델배포 테스트 화면)

6.    모델배포 테스트 상단좌측 화면에 생성중서비스중으로 바뀜에 따라, 이제 모델을 대외적으로 서비스 할 준비가 되었다.

7.    이제 스마트폰에서 28X28 픽셀 규격의 손글씨 이미지를 RestAPI 혹은 gRPC 프로토콜로 머신러닝 서버측에 분류 추론을 의뢰하는 송신 프로그램을 작성해서 보내면 서버(혹은 클라우드)의 모델이 분류를 한 후 결과를 스마트폰으로 ‘8’ 이라고 보내주는 과정의 서비스가 진행된다

현장 데이터를 통한 모델 서빙 품질 개선

  머신러닝 파이프라인에서 모델 배포 다음에 모델 평가가 필요하다. 모델 평가는 기존의 생성된 모델을 새로운 입력 데이터로 테스트하는 과정이다. 지금 서버나 클라우드에 훈련이 끝나 서비스가 되고 있는 모델은 주어진 데이터를 훈련용과 테스트용으로 나누어 훈련한 것의 정확도와 응답속도를 가지고 있다. 스마트폰에서 입력되는 손글씨 이미지도 서버에서 훈련할 때 보여줬던 정확도와 응답속도를 계속 보여줄까?

아마 그렇지 않을 확률이 높다. 일단 스마트폰으로 촬영한 손글씨 이미지는 이미지 조도와 잡음 등으로 인해 독립된 환경에서 데이터가 확보되고 훈련된 MNIST 데이터보다 예측하기 어려운 결과를 보여줄 수 있다. 예를 들어, 피부에 돌출한 종기를 촬영하여 피부암을 판별하는 모델에 전송할 때도 마찬가지다. 스마트폰의 픽셀 크기와 조도, 잡음 등으로 새로운 입력 데이터가 일관된 응답속도와 정확도를 내는지 새로운 현장 데이터로 성능이 만족될 때까지 체크하는 과정이 필요하다.

결언

 치타 플랫폼을 사용하여 실제 훈련된 머신러닝 모델을 대외적으로 실제 환경에서 사용자들에게 서비스하기 위해 준비해야 하는 과정을 설명해보았다. 머신러닝 파이프라인중에 수행하기에 난이도가 높은 모델서빙 부분은 치타가 제공하는 모델배포 자동화 기능으로 무척 손쉽게 서비스가 가능하다. 치타 플랫폼은 복수의 호스트에 돌아가는 마이크로서비스 환경에서 안정적이고 일관성 있는 성능 제공을 위해 컨테이너, GPU 그리고 로드밸런스등의 관리가 쿠버네티스와 함께 서비스메쉬를 담당하는 istio 플랫폼과 NVIDIA 사의 tritron inference server 로 보장된다. 텐서RT, 텐서플로우, Pytorch ONNX 서빙을 손쉽게 제공할 수 있도록 제공된다.




2020년 9월 28일 월요일

A.I가 시(poetry)를 이해할 수 있을까?

최첨단 AI 자연어 처리 모델의 등장

818일자 포춘 지 블로그에 “AI가 시를 이해할 수 있을까라는 기사가 눈에 띈다. 최근에 AI 중에 눈에 띄는 발전을 보이는 분야는 자연어 처리 분야이다. 정확히는 언어 모델이라는 분야인데 이전까지는 불가능하다고 생각되던 부분이 최근 몇 년간에 눈부신 기술의 발전으로 인해, 이제 보다 커다란 그림으로 우리 앞에 성큼 다가오고 있다.

그동안 인공지능(AI) 자연어 처리(NLP)에서 가장 화제가 되고 있는 플랫폼으로는 구글의 양방향 언어모델 버트(Bert), OpenAI의 단방향 언어모델 GPT-2, 기계신경망 번역(Transformer) 모델 등이었는데 올해 528일에 개방형 arXiv 31명의 OpenAI 연구자들이 GPT-3 라는 3세대 언어예측모델을 발표하면서 세간의 주목을 끌기 시작했다. 주변에서 개발자들만 이러한 용어에 익숙해왔는데 GPT-3 라는 용어를 최근 뜻하지 않은 주변 인물들로부터 듣고있다.

OpenAI 2015년 테슬라 CEO 엘론 머스크와 전 Y콤비네이터 대표였던 샘 앨트만이 설립한 비영리 및 영리 기업이다. 엘론머스크는 2018년 이사회에서 탈퇴하고 기증자로 남아있고 2019년에는 마이크로소프트가 1조원을 투자한 바 있다. 구글이 인수한 DeepMind 와 경쟁하고 있다고 볼 수 있다.


새로운 언어 모델의 특징

  GPT-3 Generative Pre-trained Transformer 3 의 약자로 그 근간은 transformer 라는 언어 모델에 근거하고 있다. 이는 지난해 초에 공개한 소설 쓰는 인공지능 GPT-2 보다 훨씬 크고 혁신적인 모델이다. 이 모델은 4990( 499 Billion) 개의 단어(토큰)를 대상으로 웹과 책 등으로부터의 가중치에 따른 선택으로 3000(300 Billion)개 단어를 샘플링하여 사전 훈련을 받았다. 그리고 1750 (175 billion) 개의 매개변수(parameter)가 사용되었다고 한다. 여기서 매개변수는 심층신경망의 층(layer)과 층 속의 뉴론(unit) 사이의 연산에서 생겨나는 매개변수 숫자인데 많을수록 복잡하다는 것을 의미한다. 이는 작년 초 GPT-2 대비 116배의 크기를 나타낸다.

GPT-3의 특징은 사람이 한 두 줄 정도의 문장을 던져주면, 사람이 적은 것인지 분간이 안 될 정도의 논리 정연한 장문을 만들어 낸다는 점이다.

사전 학습된 변역 (Pre-trained Transformer), 이게 무슨 말인고 하니, 예전에는 입력되는 순차적인 언어들을 차례로 훈련시켜 어떤 단어가 신경망에 입력되었을 때, 그 다음에 어떤 단어가 올 것인가 등등을 예측했다면, 번역(transformer)모델이라는 것은 통째로 책이나 웹에 있는 초대형의 문장 세트를 엄청난 컴퓨터용량에 한꺼번에 훈련시켜서 사전에 만들어 놓은 것을 말한다. 이 모델 에다가 API(응용 프로그램 인터페이스)를 제공하여 사용자들이 거의 모든 영어와 관련된 작업을 범용적으로 문자를 입력하면 이 훈련된 모델의 성능을 그대로 사용한 결과를 얻을 수 있게 만들었다는 것을 뜻한다. 뒤에 몇가지 예제를 살펴보겠다.


전이 학습 (Transfer Learning)

  전이 학습이란 심층신경망의 최고 성능이 입증된 모델의 가중치(weight) 모델을 그대로 가져와 비교적 작은 데이터세트에 적용하여 사용하는 것을 말한다. 예들 들어 2014년 이미지넷 인식대회에서 옥스포드대학 연구팀VGG 가 개발한 모델로서 16개의 심층신경망 층(layer)이 사용된 VGG16 사전 훈련 모델을 사용한다고 하자. VGG16 사전 훈련 모델을 사용하면 2014년 이미지넷 인식대회에서 준우승을 차지한 성능의 가중치가 그대로 소규모 데이터세트를 다루는 심층신경망에 적용되어 VGG16 에서의 장점을 누릴 수 있다.

우선 Keras from keras.applications.vgg16 import VGG16 문을 선언해 줌으로써 VGG16 모델이 로드 되고 아래 그림 1과 같이 입력 shape 를 맞춰주고 모델을 로드하면 된다.


(그림 1. Keras 를 이용한 Pre-trained 모델 사용 예)


그동안 이미지 분류 분야는 이러한 전이 학습이 고성능으로 사전 훈련된 모델의 가중치모델을 가져다가 적용하여 발전할 수 있는 계기가 되어왔지만 자연어처리분야는 이러한 사전 훈련 모델이 부진했는데 이제 이런 사전 훈련 모델을 통해 상용화를 가속화할 수 있는 단계로 접어들었음을 의미한다.

AI 자연어처리의 발전

  자연어처리를 이해하는데 기초적으로 알아야하는 워드임베딩, skip gram 등의 기본적 지식을 30분을 투자해서 참을성 있게 들어 보실 분은 여기 를 눌러 50분 분량의 유튜브 초기 30분을 들어보자. 초보자들은 조금 어려울 수 있지만 더 알고 싶으면 이러한 단어들을 유튜브나 구글에 검색하면 적지 않은 정보를 얻을 수 있다.

AI를 이용한 자연어처리를 이해하기 위해 Word2vec, Skip Gram, RNN, Bi-LSTM, GRU 같은 선행 기술들을 알고 있으면 좋지만, 빠르게 진화하고 있는 기술은 어쩌면 과거와의 단절을 통해 패러다임을 변화하는 지도 모른다. 그 변화의 신호탄이 이 논문 이었고 이전의 recurrent neural network모델을 쓰지 않고 encoder-decoder 기반의 attention 만으로 이전의 문제점들을 극복해 낸다는 논문을 발표한다. 아래 그림2Transformer 의 구조이고 Bert Transformer 의 인코더-디코더 모델 중에 인코더 만을 사용한다

(그림2. Transformer 구조)


GPT-3 적용 예

  아래는 GPT-3 가 코로나19에 대해서 상대방과 대화를 나누는 내용이다. 신기한 것은 GPT-3 의 데이터세트가 201910월이어서 코로나를 모른다. 그러나 상황을 설명해주고 대화를 이어가면 할 수 있다. 아래 굵은 글씨가 GPT-3 가 생성한 결과이다

(그림 3. GPT-3의 코로나 관련 대화)


  미 버클리 대학생 리암 포어가 GPT-3를 사용해 작성한 블로그 게시물이 IT뉴스 큐레이팅 플랫폼인 해커뉴스에서 1위를 차지했다고 한다. 819일 뉴스.

(그림 4. GPT-3 가 생성한 뉴스)


Casetext 라는 법률회사는 소송이 있을 때, 미국의 관습법 전체를 훈련 받은 GPT-3 가 일반 문장으로 질의를 던졌을 때, 예를 들어, 같은 개념에 대하여 다른 언급이 있었던 결과를 찾고자 할 때 사용한다고 한다

(그림 5. Casetext 사의 GPT-3을 이용한 검색 창)


꽤 전문적인 의학 지식도 답을 할 수 있다. 아래 굵은 글씨가 GPT-3 가 생성한 결과이다

 (그림 6. GPT-3의 의학 관련 문제의 답)


  자 이제 GPT-3 가 시를 작성한 예를 보자. AI 로 시를 생성하는 결과를 실험을 하는 사이트에 있는 T.S. Eliot Hollow Man 이라는 시에 대한 GPT-3 가 생성한 시 에 대한 평가는 다음과 같다.

원작의 변형에 불과하다. 원작의 서정성과 음률이 없어 이 시의 영혼을 잃어버렸다. 아름다움은 비논리적인 영역으로 정보로서 코딩 될 수 없다. 대상에 대한 지향성의 경험은 컴퓨터 정보에는 획득될 수 없지만, 우리의 마음은 완벽하게 우리 자신들을 위해 코딩할 수 있다.

아래는 T.S Eliot 의 원작과 GPT-3 가 생성한 시를 비교해서 표시하였다. 오른쪽의 GPT-3 의 경우, 굵은 글씨로 표시한 원작의 4줄 정도를 GPT-3 에 알려주면 나머지 시를 GPT-3 가 생성하는 것을 볼 수 있다. 
      ( 1. T.S 엘리옷의 Hollow Man 원작 과 GPT-3 생성 본 비교)


결언


앞의 예에서 살펴본 데로, 무엇보다도 GPT-3의 장점은 영어로 되는 모든 작업에 적용할 수 있고 인공지능 전문 지식이 없어도 문자를 인공지능에 입력할 수만 있다면 처리 결과를 받아 볼 수 있다는 놀라운 범용성이다, 다양한 작업에 GPT-3 모델을 사용하기 위해 경사도 / 매개 변수 업데이트를 수행 할 필요가 없다고 한다. 무슨 말인가 하면, 작업 별 모델 아키텍처가 필요하지 않을 뿐만 아니라 대규모 사용자 지정 작업 별 데이터 집합 이 필요하지 않다는 개념이다. 이점은 최첨단 NLP 로 나아가는 큰 단계로 생각된다.

그러나 전작 GPT-2 가 소설 작성과 더불어 가짜 뉴스 생성의 이슈로 인해 모든 사람에게 개방하는 것에 조심스러운 입장인 OpenAI 의 입장을 생각하면, 누구나가 쉽게 접근할 수 있을지는 아직 모르겠다. OpenAI는 비영리법인인 OpenAI inc 와 영리법인인 OpenAI LP를 따로 가지고 있다. 아마도 영리법인을 통해 기업 고객들에게 서비스하지 않을 까 하는 관측이 나오고 있다.

한글이 전세계가 사용하는 영어에 비해 규모의 경제에서 열세인 상황에서 GPT-3 에 필적할 성능을 구가하는 언어 모델의 탄생을 기대할 수 있을까 하는 생각이 들었다. 점점 AI가 국가별 패권주의로 치닫는 환경에서 우리도 대비를 해야겠다.

복수의 GPU가 있다면 분산 훈련을 실행해보자

 4개의 GPU로 분산 훈련(Distributed Training)을 시행하면 1개의 GPU로 훈련하는 것보다 4배로 성능이 빨라질까?

  결론부터 이야기하면, 4배로 빨라진다. 물론 복수 기계 간의 네트워크 속도나 어떤 병렬 학습 전략을 채택 하느냐에 따라 차이가 있겠지만, 자체 테스트결과는 GPU 증가에 따라 이미지 분류의 경우 선형적으로 초당 이미지 처리 성능이 증가했다. 이 설명은 뒷부분에서 다루겠다.

처음 머신러닝 모델을 만들고 학습용 데이터로 하나의 서버에서 훈련을 실행할 경우에는 별다른 속도의 병목 현상을 느끼지 못할 수도 있지만, 딥러닝의 특성상 데이터와 모델이 커지면 피할 수 없이 직면하는 문제는 훈련 시간의 증가다. 만약 단일 서버에 4개의 GPU가 있다면, 4개모두의 GPU를 대상으로 병렬 훈련을 실행하면 그렇다, 훈련에 4시간이 소요되던 것이 1시간에 끝난다.  만약 3대의 서버에 각각 4개의 GPU가 장착되어 있다면 이 모두를 연결하여 12개의 GPU에 분산 훈련을 시행할 수 있다. 각각의  경우에, 적용할 수 있는 병렬 학습 전략을 고려해야 한다.


(그림1. 각각의 노드 상의 장치와 GPU)


훈련의 과정은 여러분들이 아시는 바와 같이, 먼저 모델이 학습데이터를 읽어서 1) 초기화한 weight와 모델이 feed forward 를 통해 예측한 값을 내고, 2) 예측 값과 실제 값의 차이로 나타나는 손실 함수, 3)  손실을 weight 로 편미분한 경사도(gradient)를 구하는 과정이 반복되어 결국 weight 가 변경되는 과정이다. 분산 훈련은 각 GPU 1개의 작업 프로세스(worker process)가 위치하여 각 GPU의 경사도 값을 서로 주고 받고 각자의 worker는 모아진 경사도(gradients)들의 평균을 이용하여 모델을 변경한다. 이처럼 worker 는 한번의 반복 마다 경사도를 모두 모아서 변경하므로 모든 worker 는 언제나 같은 파라미터(weight)를 갖는다. 이를 동기(synchronous)방식이라고 하며 비동기 방식도 있으나 설명은 생략한다.

MultiWorkerMirroredStrategy 도 있는데 이는 복수의 노드(서버)에 장착된 GPU를 대상으로 한다. 기본적으로 동기 방식의 MirroredStrategy 와 같은 방식이다. 다만 복수의 노드에 소속된 GPU에 데이터가 배치되고 각 GPU worker 에서 훈련된 경사도(gradient)로부터 계산 된weight all-reduce 방식으로 전체 GPU 가 모두 같은 weight를 갖도록 실행되는 점이 다르다.

(그림2. MultiWorkerMirroedStrategy 작동 방식)


텐서플로로 분산 훈련하기

  텐서플로우 가이드(https://www.tensorflow.org/guide/distributed_training)에 명시된 분산 훈련부분에는 tf.distributed.Strategy tf,keras tf.estimator 와 함께 사용할 수 있다고 설명하고 있다. 아울러 지원하는 5가지 분산 훈련 전략도 아래와 같이 설명하고 있다

(1. 분산 훈련 전략)


  TF2.0 베타 버전에서는 케라스와 함께 Mirrored Strategy를 사용할 수 있고 CentralStoreStrategy MultiWorkerMIrroedStrategy는 아직 실험 기능이므로 추후 바뀔 수 있다고 나와있다


동일 서버 내의 복수의 GPU를 통한 분산 훈련

  
이 경우는 텐서플로의 동기화방식인 MirroredStrategy를 사용하기위해 케라스의 경우 몇 줄의 코드를 기존 머신러닝 코드 위에 추가하면 된다.

예를 들면, 모델과 옵티마이저를 만들기 전에 with mirrored_strategy.scope() 를 정의한다 던지, 입력데이터를 각 GPU worker 에 배분하는 부분과  경사도 계산을 위한 정의 등이다. 케라스를 사용한 MNIST 사용 예는 https://www.tensorflow.org/tutorials/distribute/keras 를 참고하면 된다.


복수 서버 내의 복수의 GPU를 통한 분산 훈련

  앞에 살펴본 텐서플로 분산 훈련 tf.distributed.Strategy는 텐서플로 가이드에 따르면, TF2.0 베타 버전에서는 현재 API를 개선 중에 있다고 하지만, 케라스와 함께 MirroredStrategy만 지원하고 있는 상태이다. 복수의 기계에 장착된 복수의 GPU를 통한 분산 훈련을 시행하기 위해서 호로보드 방식을 적용해보았다. 호로보드는 우버(Uber)에서 분산 훈련으로 MPI 모델과 ring-allreduce worker 간 경사도 교환 방식을 사용한 복수 GPU를 장착한 복수 서버 간의 분산 훈련에 탁월하다.

호로보드(Horovod)를 통한 복수 서버 내의 복수의 GPU 분산 훈련

  호로보드는 리눅스재단 산하의 LF AI 재단이 주최하는 머신러닝 표준으로 특히 우버 내부에서는 MPI 모델이 훨씬 간단하고 텐서플로우보다 분산 훈련을 위해 휠씬 적은 코드 변경이 필요하고 속도도 빨라서 호로보드 방식을 사용한다고 한다. 우리 회사 자체적으로 엔디비아사의 고성능 AI연구용 시스템인 DGX-1(V100 8GPU), DGX-2(V100 16 GPU)를 대상으로 tf_cnn_benchmark 수행 시 이미지 처리량을 비교한 결과, 아래와 같이 GPU 노드가 증가함에 따라 이미지 처리 성능도 일정하게 증가하는 결과를 확인하였다. Infinity band 100GPS에서 복수의 노드(서버) 테스트 수행 시, 단일 노드(서버) 수행보다 단지 1.3% 감소한 이미지 처리량을 보였다.

(그림 3. DGX-1. DGX-2를 사용한 복수 노드, DGX-1 단일 노드 수행 시 이미지 처리량)


호로보드를 통하여 복수 서버상의 복수 GPU 대상으로 분산 훈련을 하기 위해서는 기존 프로그램에 import horovod.tensorflow as hvd 를 포함한 7~8 라인 정도의 프로그램의 코드 추가가 필요하다. 이러한 코드 추가에 대해서는 여기를 참조하면 된다

AI플랫폼 치타에서의 분산 훈련 

  치타에서 분산 훈련을 사용하기위해서는 우선 프로젝트관리에서 작업추가를 선택한 후에 분산 트레이닝 타입 선택을 통해 단일노드내의 분산 GPU (Distributed GPU)를 사용할 지, 복수 노드의 분산 GPU(Horovod)를 사용할 지를 선택한다. 당연한 얘기지만, Distributed GPU 를 선택하면 단일 노드에서 사용할 수 있는 최대 GPU 개수까지 할당이 가능하다

(그림 4. 치타의 단일 서버 내의 복수 GPU 분산 훈련 선택 화면)


만약 Horovod 를 선택했다면, 복수 노드에서 사용할 수 있는 최대 GPU 개수까지 할당이 가능하다

(그림 5. 치타의 복수 서버 내의 복수 GPU 분산 훈련 선택 화면)


 이 경우, 팀들이 그룹별로 GPU 를 공유하고 있는 상태에서 한 사용자가 복수 노드의 전체 GPU를 점유하여 분산 훈련을 하려는 시도 일 수 있기 때문에 프로젝트 관리의 스케쥴링 관리로 진입하여 잡스케쥴링을 등록하게 한다. 이를 통하여 전체 관련 팀원들이 언제 얼마만큼의 GPU 작업이 예약되어 있는지 알고 대비하게 한다. 이러한 잡스케쥴링 기능이 분산 훈련이 잘 끝났는지 여부도 모니터링 할 수 있도록 기능을 제공하고 있다.

 

결언

  단일 서버의 GPU 분산 훈련은 현재 시점에서 텐서플로우의 케라스API를 통해 분산 훈련이 가능하며 기존 프로그램에 3~4 라인의 프로그램을 추가 하면 된다. 이 상태에서 치타의 Distributed GPU의 작업관리에서 테스트 버튼을 누르는 것으로 아주 쉽게 실행을 할 수 있다.

복수 서버의 GPU 분산 훈련은 호로보드를 선택하고 위와 똑 같은 경로로 실행하면 된다. 기본 프로그램에 6 라인 정도의 호로보드를 위한 코드 추가만 하면 된다. 나머지는 치타가 알아서 분산 훈련을 처리해 준다.

초보자도 사용설명서를 보고 기존 프로그램에 이러한 코드를 추가하고 치타의 자동 분산 훈련 수행 기능을 사용해보자. 어렵게 느껴졌던 복수 서버의 분산 훈련을 몸소 체험해보자.