레이블이 Deep Learning인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Deep Learning인 게시물을 표시합니다. 모든 게시물 표시

2020년 7월 2일 목요일

Auto Scalable 한 Deep Learning Production 을 위한 AI Serving Infra 구성 및 AI DevOps Cycle

벌써 7개월 전 이군요.
지난 겨울 Tenosrflow-KR Offline 세미나에서 발표했던 내용을 슬라이드쉐어 에 공유 합니다.

Auto Scalable 한 Deep Learning Production 을 위한 AI Serving Infra 구성 방법론 및 AI DevOps Cycle에 대하여 경험을 공유 했던 자료 입니다.

uvicorn + gunicorn + FastAPI + Tensorflow 의 구성으로, 저렴한 Auto Scale Out CPU Docker Serving 환경을 구성하고, 1만 TPS (초당 1만 Transaction Inference Serving by 10 CPU Docker) 까지, 500ms 이내 에러없이 inference 하는 AI Serving 환경을 구성하는 내용을 포함하고 있습니다. (해당 내용은 Azure App Service for linux Docker 환경에서 4 v-CPU 표준 Ubuntu 이미지 Docker 로 실험되었습니다.)

기타, 이를 Production 운영하고 관리하기 위한 DevOps 구축 사례를 공유 하였습니다.( DevOps 부분은 같은 팀의 Patrick(박찬엽님)께서 정리를 해주셨습니다. )



ps. (그로부터 7개월 후)

7개월이 지난 지금, 이 모든 것 또한, 많이 바뀌어 있네요. 새로운 2020년 버전의 New 경험에 대하여는 전혀 새로운 서술을 해 나아가야 할 듯 합니다. 작년에 경험한 것의 몇배 더 큰 경험을 해 나아가고 있습니다.

DevOps 및 MLOps 를 포함한 Production AI 를 Cloud 위에서, 특히 Kubernetes 환경하에서, 서비스하고 운영하는 데에는 기술도 중요하지만, 그에 걸맞는 DevOps/MLOps 문화와 개발조직의 성숙하고 합일된 서비스/개발 철학이 매우 중요하다는 것을 새삼 경험하고 있습니다.

이를 서비스 하기 위한, 극 난이도의 기술들은, 그 기술을 받아들이고 서비스 운영하기 위한, 프로세스와 성숙한 개발 문화가 조직에 보급되어 있지 않으면, 심한 내상으로 되돌아 올 수 있습니다. (기존 전통적인 Water Fall 의 실패 케이스 보다, 더 크게 실패할 수 있습니다.)

반대로, 이를 받아 들이기 위한 난이도 높은 경험을 견디고, 인고의 서비스 정착 경험을 견뎌 낸 경우, 그 기술적인 성숙 외에도, 개발 문화적인 성숙을 통해 얻어지는 잠재력은 훨씬 크지 않나 여겨집니다.

에니메이션 나루토가 막강한 9미의 힘을 내 뿜을때가 이와 유사한 순간인 듯 합니다.
자칫 폭주할 수 있고, 기술에 매몰될 수도 있습니다. 기술이 서비스로 안정적으로 표출되는 순간은 그 크고 파워풀한 힘과 가능성을 받아들일 성숙한 개발 문화와 프로세스가 정착 된 이후 비로서 가능합니다. 그 순간, 비로서 정상적으로 힘의 통제 및 운영이 가능해 집니다.

그 큰 힘의 가능성을 받아들일 준비가 된 개발조직은 나루토가 9미의 힘을 통제 할 수 있게 된 시점 처럼, 무한의 가능성을 갖은 시점으로 비로서 완성될 것 입니다. 그렇게 오픈 된 서비스는, 시작이 미약할 지라도, 유연하게, Continuous 하게 개선하고(DevOps), 실험하고(AB Test), 적용하며(CI/CD), 결국, 시장에서 차별화 된 서비스로 빛을 발할 것 입니다.

인고의 시간을 겪으며 조직이 성숙되고 있는 것이 느껴져서, 저희의 조직이 많이 자랑스러워 지기 시작했습니다. 많이 움츠리고, 많이 고생했던 만큼, 그 내공을 발판 삼아 빠르게 도약할 준비를 얼른 마무리 해야 되겠습니다.

나루토 질풍 전 - 우즈 마키 나루토, 쿠라마의 HD 벽지 다운로드

2019년 3월 31일 일요일

추천(Recommendation) 시스템 - 알고리즘 Trend 정리

추천 알고리즘의 트랜드를 시계열로 정리해 보았습니다.
여기에서 언급된 년도는 논문 년도라기 보다는 산업계에서 주로 유행했던 시점에 대한 개인적인 추정치 년도 입니다.

언급하고 있는 알고리즘 또한 학계에서 유명한 알고리즘 보다는 산업계에서 주로 Production 에서 많이 사용되었던 알고리즘을 나열하고 있습니다. 예를들어, Netflix 는 Competition 에서 우승한 Accuracy 가 높은 복잡한 알고리즘이나, 가장 최신의 학계 SOTA 알고리즘을 사용하는 것이 아닌, 개인화와 최신성, 그리고, 100ms 이하의 빠른 서빙이 가능한, 그로부터 Accuracy 보다는 ABTest 에서 더 효율이 좋은, 기민한 알고리즘을 사용하고 있습니다. 그리고 무엇보다, 그날 그날 시시각각 User 의 미묘한 반응의 변화에 Model 이 즉각적으로 개인화 진화 가능하도록 하는 Realtime Lambda 아키텍처 + 원순환 Continuous 진화 Serving 이 가능한 Simple 한 Model 을 이용하여 추천을 하고 있습니다. ( 2018년 Spark + AI Summit at Sanfrancisco 발표 내용 참고 )

본 글에서 소개 드리는 추천 알고리즘은 모든 도메인에 사용 가능한 범용적인 추천 알고리즘은 아닐 수도 있습니다. 하지만, 다양한 추천 알고리즘 접근 방식 및 각각의 장단점을 이해하여, 사고의 넓이를 키우자는 입장에서 전반적인 Trend 를 나열해 보았습니다. 혹시 제가 언급하지 못한 중요 Approach 가 있거나, 제가 잘못 이해하고 있었던 부분이 발견된다면, 언제든 컴멘트 부탁드립니다.

(1) 10년 ~ 15년 전에는 Apriori 알고리즘. 대표적인 연관 상품 추천 알고리즘.

-> 현재는 현업에서 거의 쓰이고 있지 않지만, Confidence , Support , Coverage , Lift 등의 추천 관련 용어를 이해함에 있어, 교과서적인 지식을 주는 알고리즘.

(2) 5~10년 전에는 Apriori 다음으로 Collaboration Filtering

-> 2010년도 이후, 상당기간 거의 추천의 표준으로 자리 메김.
-> 손쉬운 구현체 많음.
-> User Base , Item Base , Contents Base, 혹은 복수개의 결합. etc…
-> T-Store 추천 시스템 관련 이야기가 있는 아래 Blog 추천. 좀 오래된 블로그인데, 그만큼 옛 방식이기 때문 임.
-> 아래는 CF on Spark 에 관한 spotify 의 Approach
-> spotify 는 이후 song2vec 등 다양한 시도로 좀더 진화 함. (item2vec 항목에서 재 언급)

(3) 4 ~7년 전에는 FPGroth . Apriori 의 BigData  버전

-> Spark ML 라이브러리에 구현되어 있으며, Apriori 와 거의 동일한 Input 과 Output 을 보이지만, 계산 속도 및 BigData Scale 병렬처리에 있어 훨씬 더 효과적인 알고리즘.
-> 이로부터 Output 이 Apriori 와 거의 동일하지만, 대용량 Data 를 통한 커버리지 개선 및 최신성이 개선 되어 결과론적으로 ABTest Score 를 향상 시키는 것이 가능해짐.

(3.5) 4 ~ 5년 전에는 Collaboration Filltering + Deep Learning  혹은 유사 Approach

-> 모두의 연구소에서 정리한 버전. 크게 성공한 방식은 별로 없음.

(4) 3~5년 전에는 Matrix Factorization

-> ALS, SGD 가 많이 쓰이며, 모두 Spark ML 에 구현되어 있어, BigData Scale Approach 에서도 많이 사용 되었음.
-> 나온지는 좀더 오래되었지만, Mahout 과 Spark ML 에 구현되면서 BigData 와 결합 가능한 알고리즘으로서 3~5년 전에 더 유행 하였음. (개인적인 경험으로, 정말 Big한 Data 에서는 Spark ML 보다 Mahout Hadoop 버전이 좀더 안정적 이었음.)
-> 특히 Netflix 추천 Competition 에서 가장 우수한 알고리즘으로 알려지면서 유명세를 탓던 알고리즘이기도 하다. ( ps. 뒤에 Factorization Machine 이 나오는데, MF에 비하여 좀더 Sparse 한 Matrix 에서 유용하다.)

(5) 2~4년 전에는 Item2Vec + CF

-> Doc2Vec , User2Vec , Item2Vec 등을 CF 에 결합하면, Un Seen Feature 에 대하여 좀더 강건해 짐.
-> Doc2Vec 은 상품상세 Text 나 댓글, Search Engine Tag 등을 이용하여 구성 가능. 이후 Doc => Item 으로 치환하고, 카테고리, 제목, 이미지Search Simillarity Score 등을 동원하여, Item2Vec 을 만들어 낼 수 있음.
-> Microsoft 사의 Market 상품 추천에 사용된 바 있음.
-> MS의 원 논문에서 파생되어 다양하게 응용되어 사용되고 있음.
-> [관련 블로그] https://brunch.co.kr/@goodvc78/16
-> 예, item2vec : 아프리카TV에서 Live 방송을 벡터화.
-> song2vec : Spotify(음원 스트리밍)에서 플레이리스트로 노래를 벡터화. ( <- 개인적으로 드는 생각. 추천되는 목록에서 사용자가 Skip 또는 Listen 행위를 할 때. Vector 공간에서 방향성을 + 혹은 - 함으로써, 더 원하는 취향의 노래를(실시간으로 지금 딱 이순간에 맞게) 찾아 들어가는 취지에서…. 음원 서비스 추천에 매우 적합할 듯한 느낌. Word2Vec 이 그러하듯이 Song2Vec 또한 수백차원의 방향성 벡터 공간일 수 있으므로...) 
( word2vec 이 그러하듯, 복수의 차원에서 공간적으로 +, - 연산을 통해 수백차원의 공간 내부를 특정하여, 해당 위치 근처의 음원들에 대하여, cosign similarity 순 정렬을 빠르게 해 올 수 있음. )
(가수와 장르, 남성, 여성, 혼성, 듀오, 년도 등등이 모두 공간 차원 요소일 수 있음.)

-> meta-pro2vec : Criteo(개인화 광고)에서 상품을 벡터화.

(6) 2~3년 전에는 You-tube Recommendation 스타일 Deep Learning Approach

-> 사실 딥러닝 보다도 You-tube 는 머문시간으로 Measure 를 바꾼 것 자체가 보다 큰 성공 요인이었음.
-> 딥러닝으로 추천을 바라보는 Bible 격 논문.
-> 시간없으신 분들은 이거라도…
-> 유튜브 알고리즘에 대한 다양한 인문학적 고찰 https://www.bloter.net/archives/301890

(7) 1~3년 전부터 Wide & Deep Model

-> 구글 Play스토어의 추천에 사용되면서 높은 효율 개선 이력을 보인 알고리즘으로 알려지면서, 유명세를 탔음.
-> 추천이 아닌 예측 문제에서도 유용함. (마치 Factorization Machine 처럼...)
-> Cold Start Problem 에 대하여 좀더 능동적으로 대처하고, Memorization (wide)에 의존성을 덜 받기 위한 Generalized 가 가미된 방식(deep).
-> 여기서 시사점. 단건 단건 접근하여 Merged 된 Model 을 Wide Model 이라고 할때, 좀더 Generalized 된 Deep Model 은, User 의 Minimal 한 정보만으로도 다양하게 추천이 되는, 그로부터 Sparse 한 부분까지를 유추해 내는 효과를 주지는 않을 런지… ( 이런 효과는 뒤에서 언급되는 Factorization Machine 에서도 언급 됨.)
-> [조대협님이 정리한 코드가 있는 블로그] https://bcho.tistory.com/tag/wide%20and%20deep%20model

(8) 1~2년 전부터 개인화 추천이 뜨면서 다시 각광 받는 Factorization Machine. (논문은 사실 좀 오래 되었음.)

-> 특히 Big Sparse Matrix 일때 유리.  
-> 특히, (6),(7)의 모델이 Inference 및 Serving 에서 극한의 Engineering 작업을 필요로 하고, BigData Lambda 아키텍처 + Deep Learning Continuous Training 을 통하여 실시간성을 부여하는데 Engineering 복잡도 크게 증가하는 단점을 보여, 단순한 Approach 로 개인화를 구현함에 있어서 상대적으로 Factorization Machine 이  다시금 각광을 받음.
-> 기존 스타일의 추천 Legacy Approach 및 Legacy Search Engine 과 결합하여, 뒷 Layer 로서, 개인화 랭킹을 추가하는 용도로도 많이 쓰임.
-> 기존 검색엔진의 Output에 Factorization Machine 을 적용하면, 개인화 re-Ranking 을 할 수 있음.
-> 복수의 모델의 Output 을 Mash-Up 함에 있어, 모델(영역)을 Factorization Machine 과 결합하면, 개인화된 담벼락을 얻을 수 있음. ( amazon 첫페이지나 You-tube 첫페이지 처럼)
-> 룰엔진의 결과에 적용 시 Rule Engine + 개인화 Re-Ranking 형태로 손쉽게 개인화 추천 적용 가능.
-> 모델별 개별 접근의 결과가 개인별로 있는 경우, 특정 이력이 전혀없어 Sparse 한 부분을 Factorization Machine 으로 보완하는 경우, 개별 모델로 부터 General 모델을 파생하는데 도움이 될 수 있음.
-> Factorization Machine 은 다양한 구현체가 있음. 특히, AWS 에는 SageMaker 안에 PaaS 위에서 돌아가는 손쉬운 Library 수준의 Service 구현체가 있어( Code Snippet 이라 SaaS 라고 하기에는 무리가 있음) 빠르게 자사의 데이터로 Training 및 Serving 할 수 있음.
-> 개인적으로 가지고 있는 Jupyter Notebook 소스코드가 있으므로, 필요하신 분은 요청 주세요.
-> 아래는 정리가 잘 되어있는 Hands On Lab 예제.
-> [HOL] https://cloud.hosting.kr/techblog_180709_movie-recommender-with-factorization-machines/

(8.5) Matrix Factorization 과 Factorization Machine 과의 차이점.

-> MF와 FM의 차이점을 간단하게 써 놓은 글.

Key 내용은 아래와 같다.

So compared to Matrix Factorization, here are key differences:
  1. In recommended systems, where Matrix Factorization is generally used, we cannot use side-features. Ex for a movie recommendation system, we cannot use the movie genres, its language etc in Matrix Factorization. The factorization itself has to learn these from the existing interactions. But we can pass this info in Factorization Machines
MF는 유저-상품 데이터만 가지고, 숨겨진 정보들(side-features, latent feature -> 상품카테고리, 검색어, 이전에 본 상품 등등등) 을 표현(학습) 하는 알고리즘이라,입력 데이터로 유저-상품(클릭 여부) 만 사용 가능. 하지만 FM에서는 이러한 side-feature들을 직접 입력으로 넣어서 학습이 가능하다.
  1. Factorization Machines can also be used for other prediction tasks such as Regression and Binary Classification. This is usually not the case with Matrix Factorization
FM은 MF보다 더 일반적이고 확장된 모델이여서, 추천 뿐만 아니라 회귀나 이진분류 와 같은 다양한 ML에서도 사용 가능하다.(MF는 불가능)

Just some extension to Dileep's answer.
If the only features involved are two categorical variables (e.g. users and items) then FM is equivalent to the matrix factorization model. But FM can be easily applied to more than two and real valued features.

FM의 가장 큰 장점은 이렇듯 기존 user,item 외에 2개이상의 feature들을 실제로 사용 할 수 있다는 부분.

(9) 최근. 개인화 추천. ( 2017 re-invent By Amazon )

-> Amazon 이 사용하였으나, 크게 알려지진 않은 Deep Learning Base 개인화 추천 알고리즘.
-> 그 이전에 Amazon 도 Factorization Machine 을 썼다는 이야기가 나옴.
-> 어떻게 추천이 Deep Learning 으로 진화 되었는지 시계열적인 설명을 하고 있음.
-> 최종 DSSM 버전은 Google 의 You-tube Recommendation 과도 유사. 다양한 Feature 의 Embedding Vector 를 Concat 하여 Neurual Network 에 넣었다는 것이 핵심. 그래서 사실 You-Tube 의 그것보다 그다지 새롭지는 않음.

-> 최종 버전의 소스코드 및 PaaS/SaaS 서비스가 Open 되지는 않았으나, 일부는 github 에 spark + mxnet + gluon 버전의 코드가 부분 공개되어 있음.

(10) 최근. 개인화 추천. Hierarchical RNN ( 2018 re-invent By Amazon )

-> 2018 re-invent 행사에서 Amazon 이 알파버전을 PaaS/SaaS 개인화 추천 서비스로 공개하여, 주목받음. 
-> 아직 알파버전이라 당장 사용해볼 수는 없으나, github 에 위 논문 저자가 올린 공개 버전 코드가 있음.
-> [구현체] 저자의 구현체 공개버전 : https://github.com/mquad/hgru4rec

(11) 최근. 개인화 Re-Ranking. (개인화 Reinforcement Learning Re-Ranking By 알리바바)

-> 개인화 re-Ranking 에 Reinforcement Learning 이용.
-> 아카데믹하게 알려진 논문은 아니지만, 타오바오와 알리바바의 사례를 담고있는 논문이라, 매우 현실적인 접근이며, 의미있는 새로운 Approach 임.
-> Factorization Machine 과 마찬가지로, 기존 Legacy 추천 시스템 뒤에서, 혹은 복수개의 모델의 개인화 노출 순서를 정하는 부분, 혹은 Search 엔진 뒤에서 개인화를 구현하는데, 적합.

(12) Deep Learning 기반 최신 추천시스템 동향 관련 Survey 논문

2018년 8월 29일 수요일

Production Deep Learning 서비스 Pain Point 에 대한 단상 - E-Commerce Product Overview 기능을 통한 분석

요즘 해외 배송이 빨라지고 저렴해 지면서, 전자 제품 및 노트북 액서서리 등등 은 거의 Amazon 및 Alibaba 를 이용하고 있다. 특히 고가의 IT기기의 경우 국내가격대비 20% 이상 저렴한 것을 감안하면, 가격 Save 도 큰 역할을 한다. 하지만 그 무엇보다, Amazon 및 Alibaba 의 IT 기기 Search와 상품상세 view에 있어서의 site 의 편리함과 Data Driven Overview 기능의 사용성은 그 모든것을 능가하는 쐐기를 박는 요소가 아닐 수 없다.
우선 alibaba 는 IT 기기들의 경우 카테고리별로 사용자들이 주로 보는 속성들을 Quick Details 라는 메뉴로 요약해서 보여준다. 사실 이 부분만 보면 거의 98%에 가까운 확인 사항을 모두 확인 할 수 있어서, 상품상세를 모두 봐야 할 필요가 없다.

우리나라 e-commerce 의 경우 무겁고 어마어마한 크기의 카탈로그 scan 이미지를 모두 봐야 제품 상세 정보를 알수 있는 경우가 많고, 요약 속성을 제공하는 경우에도, 업자가 자체적으로 제공하여, 상품마다, 노출 위치나 항목, 요약 정보의 제공 패턴이 모두 제각각이다. 불리한 속성은 일부러 언급하지 않는 경우도 있고, 그 경우에는 어마어마한 크기의 카달로그를 죄다 뒤져야 한다.
Amazon 은 한단계 더 진화 했다. 최근 보았던 2개를 포함하여 총 3개를 비교하여 한눈에 difference 의 요약 정보를 일목 요연 하게 보여 준다.

이는 비단, 사용성과 편리함의 문제로 그치지 않는다. 상품 카테고리별로 중요한 속성이 뭔지를 아는것, 그리고 각 상품별로 그 속성의 값이 무엇인지를 아는 것은 e-commerce site 에서 어마어마한 자산일 수 있다.
일반적인 e-commerce site 의 대부분이 상품별로 제목, 상품상세 text, 카테고리, 브랜드 등만을 관리하는 것과 달리, 위 선진 site 들 처럼 각각의 대표속성, 대표 키워드 등을 관리한다는 것은 Semantic Search , 자연어 기반 챗봇 검색, 속성기반 유사도 추천, 품절 대체 추천, 기타 검색 품질 관리에 있어서도 많은 유리함을 가져다 준다. 다차원의 속성이 있으면, 모든 상품을 N차원 공간에 배치할 수도 있다. 그리고, 그런 유사 상품의 공간 백터 상 관리는, 상품별로 가격, 배송,물류 관리 등 다방명의 Data Driven Model 을 만듦에 있어, 매우 큰 기초 Data 역할을 한다. 약간의 Deep Learning NLP 를 가미하면, 상품명을 몰라도 그 상품을 수식하는 형용사 만으로도 상품을 찾아들어갈 수 있다.
최근의 e-commerce Text NLP AI use case 관련 논문들은 자연어 문장에서 단순하게 NER 만 뽑아내는 것이 아닌, NER 을 뽑아냄과 동시에 이러한 중요 속성을 함께 뽑아내는 연구가 이루어지고 있음을 보여준다. 문장중에 언급이 없어도, 성별을 찾고, 어른용을 찾는지 아이들용을 찾는지, 선물용인지 등등의 중요속성 정보를 NER 뽑아내듯, 화자 혹은 검색 사용자의 일부 단서나 나열된 keyword sequence 로부터 뽑아준다는 의미이다.
해당 논문을 몇달 전부터 구현레벨에서 검토하였는데, 역시, 구현보다 어려운것이, 그 데이타의 Training 을 위한 Input Data 가 legacy 에 존재하지 않는 다는 점이다. 요즘 내가 alibaba 나 amazon 의 저런 제품 속성 기반 Generated(or Model Managed) Overview 기능에 관심을 갖는 이유라 하겠다.
그렇다면, 해당 속성 데이타가 없다는 것은 누구의 잘못인가? 의사결정자의 잘못인가? 기획자? 전략부서? 데이타부서? AI부서? 그 누구의 잘못도 아니다. 그걸 100% 수작업으로 만들어 내려는 시도는 10년전에도 많은 기획자들이 고민했던 ROI 답 안나오는(그래서 검색 Tag 정도만 최소로 관리하는) 문제 중 하나이다. 그래서 그런것을 만들어내는 것 또한, 요즘은 Deep Learning Model 로 접근하고 있다. 혹은 Model 이 95% 정도를 자동으로 해주고, 소수의 운영자 및 알바생들이, Accuracy 점수가 낮은 순으로 정렬하여, quick 하게 eye checking 만 하면서, click, drag 가 대부분 작업이도록 하면서 supervised learning 되도록 operation 관리자 페이지를 구성하여 구성하는 사례가 선진사례에서 등장하고 있다. 즉, ROI 안나오던 작업이 AI Assist 로 인하여, ROI 가 나오는 해볼만 한 작업이 된 것이다.
하루에 수천건의 신규 상품이 들어와도 자동 분류 되고, 자동 tagging 되고, 공간상에 자동으로 꼳혀 들어가야 하고, operator 에 의한 정교화 보정 작업은 후처리 사항이며 모든것을 전수 관리할 필요가 없어졌다. 이를 프로세스화 하고 입력시점에 업체들에게 위임 할 수도 있으나, 업체는 낚시성 Tag 를 다는데 더 최적화 되어 있으며, 이는 Noise 에 해당한다. 감지된 데이타에 대한 보정 작업은, Supervised Learning, 좀더 구체적으로는 online learning 의 재료로 쓰이며, 모델 진화에 기여 한다. 그것보다 더 잘 기획된 AI 서비스는 그 과정에서, 모든 training 진화를 Operator가 죄다 하는 것이 아닌, 사용자의 반응 및 행위가 model 의 진화에 기여 하도록 UI 기획을 하는 것이라 할 수 있다.(요즘 기획자들은 그래서 Deep Learning 개념을 좀 알고 있어야 한다.)

결론을 내 보겠다.
Production AI 서비스를 하다보면,
  1. Main Problem 의 model 을 만드는 일이 사실 제일 쉬운 문제이다. 연구도 많이 되어 있고, 논문 혹은 바로 쓸 수 있는 오픈소스나 github 구현체를 찾아서 활용할 수도 있다.
  2. 그보다 어려운 부분이 다수동접처리 및 빠른 서빙, 무중지 배포, Auto Scale Out 등의 문제이다. 여기서부터는 Lab 에서 연구하지 않는 분야이고, 참고 자료가 많지 않기 때문이다. 이를 위한 방법론은 여러차례 블로깅 한 적이 있었다.
  3. 그보다 더 어려운 부분은 만드는 AI Production 서비스에 Freshness 와 personalization 을 추가하는 문제이다. Freshness 는 병렬성이 핵심이며, realtime 인입이 필요하여 kafka, spark streamming 등의 도움이 필요할 수 있으며, 람다 아키텍처가 필요하고, 요즘 스타일로는 Serverless Microservice 기술이 필요하고, kubernetess 및 docker 를 끌여들여야 할 수 있다. Personalizaion 으로 가면, 모델의 차원이 커지고, 사람별로 혹은 상품별로 Training 을 하기 위해 BigData Scale 의 Computing 과 분산 Deep Learning 을 위한 BigData 기술 연계가 동원된다. (개발 생산성과 low level tensorflow 직접 분산처리보다 더 빠른 컴퓨팅을 위해서 이기도 하거니와, 수많은 heavy pre-processing 을 위해서이기도 하다.) 이를 위한 방법론은 여러차례 블로깅 한 적이 있었다.
  4. 그보다 더 어려운 문제는 양질의 Data 를 확보하는 문제이다. 결국은 Production 직전에 혹은 직 후에 이 부분에 직면하게 된다. Garbage in Garbage out 이다. 모델에 집중하면 정확도 3% 올리는데 반년이 걸릴 수 있지만, Input Data 에 집중하면 몇달을 투자하여 정확도가 10%가 올라갈 수도 있다. 국내에 AI Production Service 를 잘하는 곳도 여기까지 와서 주저 앉는 경우가 많다. 일반적인 IT 프로젝트 처럼 오픈 이후 바로 결과를 확인 하는 습관 때문이기도 하다. AI 프로젝트는 여기서부터 시작이라고 해도 과언이 아니다. 반응을 보지 않고, 상상으로 개발한 1차 결과물보다, 실 데이타가 3달 이상 쌓인 후 이를 보면서, 2차 3차 고도화를 통해, 상상 Training Data 와 Real Input Data 간의 괴리를 줄이는 작업이 이후에 지속적으로 투자 되어야 하는데, 이를 기달리지 못하고, 초기 결과를 보고 스폰을 받지 못하여 Operation 과 이와 맞물린 관리적 고도화가 되지 못하는 AI 서비스를 주변에서 많이 보았다.
  5. 그보다 더 어려운 문제는 양질의 Data를 수작업을 통해서가 아닌 자동으로 혹은, 자동80% 수동 20% 정도로 확보하게 만드는 일이다. e-commerce 를 예를 들자면, OCR, 댓글 텍스트, 크롤링 등등 다양한 방식으로 이런한 Data 를 Generation 화 할 수 있으며, 중요속성을 뽑아내는 다양한 알고리즘이 존재한다. 하지만, 이 부분은 경험해 보니, 모델이 어려운게 아니라, 이것 자체가 또하나의 프로젝트가 되어버리는 것이 문제였다. A 프로젝트를 잘하기 위해 B 프로젝트를 또 해야 해요! 가 조직에 잘 설득되지 않는 경우가 많았다. 사실 할일도 많고, 인력도 없는데, A 프로젝트도 겨우 인력 짜내서 하는 형국에 B 는 Minor 로 치부되는 것이, 당연한 현실 일 수 있다.
  6. 그것보다 더 어려운 문제는 양질의 Data 와 이후 Production 중 보정 후 재 Training 이 사용자들에 의하여 원순환으로 알아서 진화되도록 UI를 잘 만드는 일이다. 덧붙여 이에 맞는 원순환 맞춤 관리자 페이지도 나와줘야 한다. 덧붙여 모델 자체도 원순환 training 이 가능하도록, 람다 아키텍처 및 batch training, 그리고, 무중지 online training 이 삼박자가 잘 맞게 개발되어야 한다. 아쉽지만, 이는, R&R 지옥을 뚫고 기획을 개발자가 하거나, 기획자가 개발자가 되거나 하는 정도의 Mix 된 융합 Co-Work 이 필요하며, 딱 그 만큼(정말로 개발자가 기획을 하고, 기획자가 개발하는 것 만큼이나)이나 어렵다.
오늘 언급한 Production Deep Learning 서비스의 Pain Point 에 대한 단상은 결국, 기획과 모델링과 개발의 유기적인 결합이 중요한 Key 라는 결론으로 귀결 되었다.
경험해 보건데, 현실적으로 이를 위해 제일 쉬웠던 방법은....
  1. 끊임없이 개발자나 모델러들이, 기획자를, 윗분들을 설득하고 , 또 말하고, 또 설득하고... 그 과정에서 싸우기도 하고, 장문의 편지도 많이 쓰고.. 설레발도 많이 떨고, 페이스북에 기사같은것도 막 퍼 날라주고....TT 지난한 일이지만, 그래야....느린속도로 라도 둘 간에 혹은 셋간에(경우에 따라서 넷 이상이 될 수도 있는게 현실이다. TT) 바라보는 곳이 같아지고, Over lap 되어 일하는 부분이 늘어나는 것 같다.
  2. 그리고, 그들을 설득하고, 우리들의 가장 큰 약점인 말빨에서 밀리지 않기 위해서는, 우리들도 끊임없이 문과적으로 사고하고, 비지니스도 좀 가중치를 올려주고, 기획적인 사고도 더 연습하고 더 자주해야 한다는 점이다.
  3. 기획자에게 Deep Learning 에 대한 꿈과 밝은 미래를 자주 주입해주고, 공짜 컨퍼런스 티켓도 좀 사비로라도 사서 나 시간없어서 사놓고 못간다고 하면서 좀 던져 주고, 기획자에게 패스트캠퍼스나 모두의 연구소 같은것도 좀 추천해주고.... 이것이 은근히 정말 큰 도움이 된다. 기획자가 50%를 이해하면, 회의시간이 3배 이상 줄어 들고, 서로 딴이야기를 하지 않을 확률이 200% 이상 증가하는 듯 하다. 실제 경험담이다.
  4. 위 6단계를 warter fall 로 한다는 것은 말도 안되는 일이다. 외주에 맞기고, Production 시점부터 즉, 위 6단계의 4부터 외주업체가 나간체로 내부에서 한다는 것도 말이 안되는 일이다. 물론 협력하면서 프로젝트를 한 경우는 가능할 수 있다. 결국 초반엔 첫 프로젝트는 개고생을 감수해야 할지도 모르겠다. 역시 경험담이다. 개고생한만큼 기술도, 그리고 위를 이끌어 낼려는 간절함의 동인으로 부터 야기된 설레발 능력(1에서 많이 활용되는 능력이다)도 성숙해지는 듯 하다.
  5. 성공을 한번 맞보게 하는것이 매우 중요해 보인다. 그런데 매우 초기에 빨리 맛보게 해줘야 한다. 그렇지 못한다면 자멸할 수도 있다. 이후 그것을 발판삼아야 스폰도 받고, 시간도 얻고, 인력도 얻어서, 시간을 Parallel 화 시킬 수 있다.(초기에는 누구도 기달려주는 사람이 없다.) 결국 AI 서비스는 아이에게 말을 가르치듯, 단계를 하나하나 잘 밟고, 시간 투자를 해야 하는데, 그런데 시간을 기달려주지 않는다....그렇다면, 조직에서 스폰서쉽이라도 받아서 Parallel 하게 모델들을 개발 하는게 중요하다.
요즘 박항서가 2002년도 히딩크 만큼이나 베트남에서 축구 감독으로 활약을 하고 있다. 우리나라에서 AI 하기는 우리나라 대표팀으로 월드컵 16강 가기 정도로, 생각할게 많은 듯 하다. AI와 축구는 멀티플레이어가 매우 중요한것도 닮아 있다. 그리고, 골을 넣는것도 중요하다. 결국 골을 못넣으면, 과정이 어찌 되었든 비난 받는다. 수많은 시선과 실시간으로 쏟아지는 매우 short-term 의 비판을 뚫고서도, long term 의 전략을 세우지 않으면, 본질적으로 결코 쉬운일이 아니다. 너무 log term 의 전략은 자칫 Short-term 의 비판에 나가 떨어지거나, 포기하거나, 이직하거나, 인사고과 D 맞기 십상이다. 하지만...본질적으로 우리나라는 16강 가기 위해, Long term 의 전략과 본질적인 기본기 확충을 위한 시간 투자와, 시스템의 개편과, 축구 협회의 성찰과 혁신도 필요하다.

대한민국 AI 개발자 화이팅 합시다.!!!!

2018년 1월 11일 목요일

Deep Learning Multi Host & Multi GPU Architecture #2 - Keras 를 이용한 Scale Up, Horovod 를 이용한 Scale Out 성능 비교

Deep Learning Multi Host, Multi GPU 를 사용하고, BigData Scale 데이타를 처리하며, Auto Scale Out 확장 까지 고려한 아키텍처 구성에 대하여 연재 중이다.

개요는 이곳에서 확인 가능하다. [아키텍처 주안점 및 설계를 위한 고찰 : https://hoondongkim.blogspot.kr/2018/01/deep-learning-multi-host-multi-gpu.html ]

오늘은 두번째로, High Level 딥러닝 프레임워크 인 Keras 를 이용한 GPU Scale Up. 그리고 Horovod 를 이용한 Multi Host GPU Scale Out 의 성능에 대한 비교를 해보도록 하겠다.

우선 Tensorflow 나 pyTorch 나 CNTK , Caffe2 등에서 이미 GPU 나 Host 에 대한 확장을 이미 지원하고 있는데, 이러한 실험이 무슨 의미가 있는지 의아할 듯 하여, 그 의미에 대하여 다시 언급해 보도록 하겠다.
  1. 기존 Deep Learning 프레임워크에서의 Low  Level 병렬 수행 최적화 코드를 별도로 구현해야 하는 수고를 덜 수 있다.
    1. Keras 의 경우 Multi GPU 를 지원하기 시작한지 불과 3달도 체 지나지 않았다. 2017년 10월 경 버전 2.0.9 부터 지원되기 시작했다.
    2. 하지만, Keras는 단 1줄로 Multi GPU Scale Up 이 된다. (Horovod 와 함께 Keras 를 함께 실험한 이유이기도 하다.)
  2. Multi Host 는 훨씬 복잡하다.
    1. Keras 의 경우 Multi Host 는 아직 지원하지 않는 한계가 있다.
    2. Multi GPU Scale Up 은 8 GPU 가 Max 이다. 즉, BigData Scale 확장을 위해서는 Multi Host 도 동원해야 한다.
    3. Keras등은 자체적으로는 Multi Host 를 지원하지 않는데, Multi Host 까지 최소의 노력으로 사용가능 하도록 구성하기 위해서는 tensorflowOnSpark 나 Horovod, elephas 등을 이용해야 한다. 
  3. 개발 생산성 뿐 아니라, 성능 까지 더 좋았으면 한다.
    1. Horovod (made by Uber ) 의 official 페이지에는 Horovod 개발 배경을 다음과 같이 설명하고 있다.
    2. 이런 언급도 있다.
이제 위에서 언급된 (1) 병렬 코딩에 있어서의 개발생산성 , (2) 수행 시간 단축 효과가 어느 정도 인지 확인 해 보자. (맛보기 정도의 예제이기는 하지만, 느낌을 공유 하고자 한다.)

테스트는 아래 환경에서 수행되었다.
1. GPU Scale Up Test
=> Azure DSVM Image NC-Series .
=> K80 GPU.
=> Tensorflow + Keras
2. GPU Scale Out Test
=> Azure Batch AI Cluster with NC-Series vm.
=> K80 GPU.
=> Tensorflow + Keras + Horovod + Azure Batch AI

  1. Keras 를 이용한 Multi GPU Scale Up 코드
    1. 아래 코드 1줄이면 된다.
    2. 위에서 사용한 메소드를 호출하기 위해 필요한 package import 는 아래처럼 해주면 된다.
    3. 여기서 매우매우 유의해야 할 점이 있다.
      1. Keras 는 Multi GPU 사용 시 epoch 가 나눠져서 수행되는 것과 유사하게 동작한다.
      2. 즉, Epoch 를 GPU 갯수로 나누는 코드 적용이 필요하다.
      3. 이론적으로는 이 경우 GPU 갯수가 2배가 되면, Training 속도가 2배 빨라져야 할 것이다. 그러나, 실험을 해보면 그정도 까지 개선되지는 않는다. 그것은 GPU 가 증가 시 GPU 간 Data 의 동기화 Copy 등에 부가적인 Overhead 가 소요되기 때문이다.
  2. Keras 를 이용한 Multi GPU Scale Up 성능 비교
    1. General 한  LSTM 모델이다. 실험을 위해 Training Data Size 는 줄여놓은 모델이다.
    2. GPU 1개 (NC6)
      1. 150초 정도가 소요되었다.
    3. GPU 2개 (NC6)
      1. 127초가 소요되었다.
      2. 그리고 약간 성능도 개선되었다.
      3. 이 시점의 nvidia GPU 사용량은 다음과 같다.
      4. 위 처럼 2번째 GPU 는 보편적으로 Fully 일하지는 못한다. (그러나, 모델 및 알고리즘에 따라 그 양상에는 차이가 있었다.)
    4. GPU 4개 (NC12)
      1. 82초가 소요 되었다.
      2. 성능도 좀더 향상 되었다.
      3. GPU 갯수와 성능과의 관계는 뒤에서 다시 언급 토록 하겠다.
  3. Horovod 를 이용한 Multi GPU Scale Out 코드
    1. Keras 의 Scale Up 코드 만큼 심플하지는 않지만, Horovod 의 경우도 몇줄 코드만으로 Deep Learning 을 Multi Host 로 Scale Out 가능하다. 중요한 것은 Keras와 달리 Scale Up 도 되고, Scale Out 도 된다는데 있다.
    2. import 패키지
      1. import horovod.keras as hvd
    3. horovod init 코드
      1. hvd.init()
    4. Process 당 GPU 하나씩 할당하기 위한 코드
      1. config = tf.ConfigProto()
      2. config.gpu_options.allow_growth = True
      3. config.gpu_options.visible_device_list = str(hvd.local_rank())
      4. K.set_session(tf.Session(config=config))
    5. Epoch 분산 용으로 변경
      1. EPOCH = 200.0
      2. epochs = int(math.ceil(EPOCH / hvd.size()))
    6. Optimizer 분산용으로 변경
      1. opt = optimizers.Adadelta(1.0 * hvd.size())
    7. Callbacks 추가
      1. hvd.callbacks.BroadcastGlobalVariablesCallback(0)
    8. 아래는 위 코드 Example 이다.
      1. epoch 를 본 예에서는 직접 입력하였다. 이후 Optimizer 와 Callbacks 관련 2줄만 각각 model compile 과 model fit 전에 수행해 주면 된다.
  4. Horovod 를 이용한 Multi Host Scale Out 성능비교
    1. Node 1개
      1. Jupyter 를 통해 Azure Batch AI 클러스터 위로 Training Job 을 구동하였다.
      2. Node 1개에서 166초가 소요되었다. 
    2. Node 2개
      1. Node 2개 에서 멀티 Host 모드로 수행하자 아래처럼 로그가 2번씩 찍힌다.
      2. Horovod Cluster Size 가 2가 되자 initial epoch가 200 이었지만, 각 노드별 병렬 epoch 는 100으로 줄었다.
      3. 143초로 수행시간이 단축 되었다.
    3. Node 4개
      1. Horovod 는 계속 NC6 으로도 병렬 확장 테스트가 가능하나, Keras Scale Up 과의 비교를 위해 , 이 시점에 NC12로 바꾸었다. 왜냐하면, Scale Up 의 경우 NC6 은 GPU 2개 까지밖에 지원하지 않아서, GPU 4개를 테스트하는 시점 NC12로 바꾸었었기 때문이다. 
      2. 동일한 테스트를 위해 이시점은 NC12 이미지 4대에서의 테스트 이다. 각 멀티 노드에서 GPU 는 1개씩만 사용하였다.
      3. 즉, 4 Host * 1 GPU = 4GPU 환경이다.
      4. 예상했던 것처럼 로그가 4번씩 나오고 있다.
      5. 수행속도는 89초로 줄어 들었다.
[결론]

Keras 의 Scale Up과 Horovod 의 Scale Out 모두 Epoch 를 나눠가졌다. 이런 양상은 TensorflowOnSpark 와는 조금 다른 양상이다. TensorflowOnSpark 는 Epoch 를 나눠갖지 않고, Multi Node 의 Multi Job 들이 Mini Batch 를 1/N 로 나눠 갖는다. 각 특성이 갖는 양상에 따른 차이도 그 차이점을 고려해볼만 한 주제인듯 하다.(향후 시간이 허락한다면 이 부분도 파 보도록 하겠다.)

우선 오늘 실험해본 내용의 종합 결과는 아래와 같다.


앞에서도 언급 했던 것처럼 Keras 를 사용하면, Tensorflow Backend 의 GPU Scale Up 은 우선 매우 매우 쉽다. 성능 또한, 기본적인 initial time 을 제외 하고는 어느정도 선형적인 증가를 보여 준다. 좀 더 특이한 양상이 발견되었던 점은, (적은 양의 데이타에서 특히) GPU 갯수가 늘어나자 좀더 성능이 빨리 좋아지는 양상이 발견되었다는 점이다. 이는 앙상블 효과 처럼 보인다. 그리고, 마치 가끔 Mini Batch Size 를 키웠더니, 정확도가 오히려 개선되었을 때와 비슷한 양상이다.(일반적으로 그 반대가 더 많지만...) 모든 weight 의 실시간 공유가 꼭 좋은것 만은 아니다. 4개의 독립적인 GPU 가 어느정도는 독자적인 local minigma 를 찾고, 각 GPU 가 1번씩 epoch 가 끝났을때, 지연 동기화를 하게 되면, local minigma 에 빠질 확률이 훨씬 줄어들기 때문에, 분산 지연 weight 동기화가 오히려 training 에 긍정의 효과를 준 것으로 보여진다.

Horovod 를 통한 Scale Out 형태의 GPU 확장은 예상 했던 것 처럼, Scale Up 모드보다는 무거운 연산임이 실험을 통해서도 확인 되었다. 노드 갯수가 작을때에는 Single Node 의 멀티 GPU 보다 더 느린 양상을 보였다. 이는 노드갯수가 4개 정도로 늘어나면 큰 차이가 나지 않는다. (이 곳에 언급하진 않았지만, 노드 갯수가 많아질수록 성능은 역전된다.) 즉, Horovod 시나리오는 좀더 BigData Scale Deep Learning 에 가깝다. 

Production 시스템에서 Training Data 가 쌓이고, 그 크기가 점점 커지기 시작하면, 점점 training 전에 전처리 단계에서 부터, 1대 머신의 물리 Disk 를 모두 동원해도 감당이 안될 정도로 Data가 커지는 경우가 있다. 이 경우 Scale Out 시나리오에서는 해당 노드에 간단하게 Hadoop 정도를 설치해주면, 데이타는 복수 Node 에 펼쳐져 저장되게 되고, Disk IO 는 분산되어, 훨씬 성능도 좋아진다. ( Tensorflow 의 공식 github 에는 이러한 경우를 위해hadoop 에 저장된 Training Data를 핸들링 할 수 있는 Hadoop Connector 유틸리티가 제공되고 있다. Spark Connector 도 있다. TensorflowOnSpark 는 내부적으로 해당 유틸리티를 활용하고 있다.) Data 의 크기는 크지 않지만, Disk IO 를 20~30배 이상 성능적으로 개선해보고자 할때는 Hadoop 대신에 해당 노드에 Spark 나 Tachyon (이름이 바뀌긴 했으나, original 이름으로 더 알려진) 이나, Apache ignite 를 설치하고 수행할 수도 있다.

위 실험에서도 알 수 있는것처럼, 데이타의 크기가 1대의 머신에 담을 수 있는 크기이고, GPU는 8개 미만만 사용해도 되는 수준이라고 한다면, Scale Up 이 더 유리하다. ( Deep Learning Infra 설계시 참고하기 바란다. 작은 데이타는 1Node 4GPU 가 1GPU 4Node 보다 성능이 더 좋음을 위해서 보여 준 바 있다.)

하지만, Scale Up 은 Nvidia 의 dependency 로 대부분의 Deep Learning 프레임워크들이 8개 까지만 지원하는 경우가 많다. 하지만, Scale Out 은 그런 한계를 극복 할 수 있다. Horovod 는 그래서, 1대 Node 에 GPU 를 4개씩 꼳아서 8대를 클러스터로 묶어서 수행하는 경우 Scale Up 과 Scale Out 의 성능을 동시에 활용할 수 있다. 즉, 그 경우 4*8 = 32개 GPU 를 사용할 수 있다. Keras 는 8개가 한계 이지만, Horovod 그리고, Horovod + Cloud PaaS (본 실험에서는 이 부분을 Azure batch AI 를 이용했다.) 를 사용하는 경우 수백대 이상 까지도 Node 및 GPU를 동원하여, 분산 Training 의 장점을 몇번의 클릭으로 수행 해 볼 수 있다.

Keras 는 1줄 코드 수정으로 Scale Up 이 되었지만,  Horovod 는 6~8 줄 정도의 수정이 필요하였다. 하지만, 익숙해지면, 1분안에 적용 가능한 수준이었다. 때문에, 발생산성 향상은 검증되었다고 본다.

Horovod  의 위키에는 다양한 Horovod 성능 수치 비교자료들이 존재한다. 아래는 그중에 어떤 사용자의 경험을 보여주는 성능비교 수치이다. Scale Out 이 아닌 Scale Up 의 경우에도 8개 GPU 이상일때는 Horovod 방식이 성능이 더 잘 나오는 것을 표현해주고 있다. 내가 했던 실험 데이타 또한 처음에는 Horovod 가 느리다가 Node 4개를 기점으로 역전되는 모양을 보여주었었다.

Scale Out 부분에 있어서도, 대부분의 벤치마크 자료나, 대다수의 비교 자료에서 Horovod 는 Tensorlfow 에서 자체적으로 제공하는 Parameter Server 를 활용한 방식 보다, 수행 속도 측면에서 성능이 더 잘 나오는 것을 확인 해 볼 수 있다.

즉, 성능 적인 개선도 검증되었다고 여겨진다.


개발이 훨씬 쉬워지면서 성능이 뒤쳐지지 않는다면... 아키텍처링 입장에서는 마다할 이유가 없다.


2018년 1월 3일 수요일

Deep Learning Multi Host & Multi GPU Architecture #1 - 고찰 및 구성 with tensorflow, cntk, keras, horovod, Azure Batch AI

지난번 Deep Learning Serving Layer 아키텍처 수립을 위한 고찰(http://hoondongkim.blogspot.kr/2017/12/deep-learning-inference-serving.html) 이후 , 이번에는 Deep Learning Training Layer 아키텍처 수립에 대하여도 고찰해 보았다.

아키텍처 수립에서 고려한 주요 주안점은 다음과 같다.

  1. Training 은 Fine Tuning 이 이루어지는 주기적인 Batch Training 이 있을 수 있고, 시시각각 혹은 실시간으로 수행후 바로 반영될 필요가 있는 RealTime & Online Training 이 있을 수 있다. 
    1. Online Training 은 Fine Tuning 을 하는 시나리오는 아니지만, 기존의 Fine Tuning 된 weight 값을 불러 들여, 빠르게 변경분에 대하여 반영하는 로직이다.
    2. 이 경우 부분적으로 해당 Data 로 약간의 overfit 이 발생될 소지는 있다. 하지만, 변경분 Data 는 크기가 매우 작고, 변경 분 Data 의 왜곡을 최소화 하기 위해 일정량의 랜덤 sampling 데이타를 전 class 에 대하여 부분 추출후 섞어 주는 기법을 사용, 왜곡 현상을 줄일 수 있다.
    3. RealTime Training 시나리오를 Production 에 반영하는 경우 가장 중요한 고려 점은 
      1. 긴급한 Training 변경 요건을 빠르게 수행하여 운영중 모델에 적용할 수 있는가? 그리고,
      2. 다수의 Model 관리 Operator 가 실시간적으로 Training Data 를 손보는 경우 이를 받아들일 만큼 시스템이 유연한가? 일 것이다. 
  2. 우리가 구상하는 시스템은 BigData Scale Data 를 포함하고 있다. 1대의 GPU 로는 Disk 에 담기 힘든 규모의 Large Scale Data 로 확장 가능하다.
  3. 주기적으로 수행되는 다수의 Deep Learning 모델이 Pipe Line 을 통해 구성될 수 있으며, 일정 시간안에 모두 완료되어야 한다.
  4. 일시적으로 Deep Learning 모델 프로젝트가 다수개 동시 수행되는 경우 On-Premise GPU 리소스 로는 부족한 경우도 있다. Production Batch Training 을 위해 구성한 GPU 클러스터 시스템은 내부 모델 개발의 유연한 확장에도 활용가능 했으면 한다.
  5. Multi GPU 그리고 Multi Host 를 지원하는 Deep Learning 모델을 만드는 것은 불가능하지 않지만, Tensorflow 에서는 너무 Low level 접근이 필요하고, Keras 에서는 한계가 크다. GPU Cluster 가 그런 부분을 프레임워크 레벨에서 보완해주는 아키텍처가 필요하다. (예, BigDL , TensorlfowOnSpark , Horovod , Azure Batch AI ...) 예를 든 솔루션에 대하여 뒷 부분에서 설명토록 하겠다.)
위 4번, 5번 때문에, 우리는 경험상 On-premise 보다는 Cloud 에 GPU 리소스가 존재하길 원했다. 프로젝트 시작 초기에는 모델개발에 굉장히 많은 GPU 리소스가 필요하다. 운영중에는 오픈 초기 여러번의 on-line Training  이 운영자에 의해 시시각각 수행될 수 있으며, 매 새벽 배치를 통해 fine tuning 배치가 수행될 필요도 있다. 이 경우 GPU 1대 혹은 1대의 single 머신에서 모델이 Training  되는 경우 최고의 성능에 도달하기 까지 매우 많은 시간이 소요 될 수도 있을 것이다.

이러한 이유로 우리는 아래와 같은 환경을 고려하게 되었다.
  1. 운영상의 효율성. 안정성. 모델개발 시점의 시간 및 투자비용 Save 를 위해 Cloud GPU 인프라가 효율적이다.
  2. BigData Scale Data 를 통한 Training 및 빠른 Training 퍼포먼스를 위해 GPU Cluster 구성이 필요하다.
  3. GPU 클러스터는 다양한 Deep Learning 프레임워크를 지원해야 한다.
    1. 우리가 사용하는 Deep Learning 프레임워크는 다음과 같다.
      1. Tensorflow
      2. Keras
      3. CNTK
  4. 다수의 Operator 가 관리자 페이지에서 online Training 을 동시에 여러 Job 을 수행 시킬때, 혹은 다수의 Deep Learning 모델러가 복수의 Job을 수행할때, 유연하게 자사의 GPU 클러스터가 반응할 수 있는 플랫폼이 필요했다.
우리는 이를 위해 최종 적으로 다음과 같은 사전 시스템을 구성 및 테스트 해 본 적이 있다.
  1. Hadoop + Spark + BigDL
    1. Data Pre Processing 에 강점이 크며, 기존 Machine Learning 배치와도 잘 결합 가능하다.
    2. 기존의 Spark Job 과 한몸처럼 구성이 가능하다.
    3. BigDL 이 아직은 구현된 모델이 많지 않다는 가장 큰 단점이 존재한다. 속도도 GPU 클러스터 보다는 떨어진다. 
    4. 내부에 기존 BigData 클러스터가 충분히 많고 Spark 를 중요 Machine Learning 개발 도구로 사용하는 경우 활용할 가치가 있다. (참고로 BigDL 은 Intel 이 주도하는 Open Source 이며, Spark 에 내장 라이브러리 처럼 활용 가능하다.)
    5. 이 시스템은 이미 On Premise 에 구축하여 일부 모델의 검증에 활용하고 있다. 하지만 최종 시스템으로 선정하지는 않았다.
    6. 이 시스템에 대한 경험은 아래에 블로그 했었다.
    7. http://hoondongkim.blogspot.kr/2017/08/deep-learning-text-nlp-with-spark.html
  2. Hadoop + Spark + tensorflowOnSpark
    1. 위 장점을 수용하면서 Tensorflow 를 사용할 수 있다.
    2. BigDL 과 달리 CPU 뿐 아니라 GPU 도 사용 가능하다.
    3. Tensorflow 에서 Multi GPU, Multi Host 병렬 확장을 10줄 미만의 간단한 코드 수정으로 수행할 수 있다.
      1. VGG, inception 등 널리 알려진 모델은 이미 multi gpu 및 multi host 지원이 내장 구현되어 있다. 이런 경우는 tensorflow 만 쓰거나, 혹은 high level api 를 쓰더라도 큰 문제가 되지 않는다.
      2. 그러나, 대부분의 custom 모델이거나, 특히 RNN, LSTM 의 수많은 공개된 변종 알고리즘들은 병렬성이 구현된 구현체들이 거의 존재하지 않는다.
      3. 이를 직접 병렬성 구현해 주는 것은 매우 지난한 작업이다.
      4. 즉, tensorflowOnSpark (made By Yahoo) 는 이런 부분을 보완해 주는 Deep Learning 확장 도구이다.
      5. 이 시스템은 또한 On Premise 에 구축하여 Tensorlfow 모델의 일부 검증에 활용한 바 있다. 하지만 Main Production 시스템으로 선정하지는 않았으며, Dev 및 모델링 시점에 활용하는 용도로만 사용중이다.
        1. 가장 큰 이유는 내부에 CPU 클러스터는 수천 코어 동원이 가능하지만, GPU 클러스터는 리소스가 부족하기 때문이다.
        2. Cloud 에 구성하기에도 Hadoop 및 Spark  디펜던시, 그리고, Legacy 가 Tensorlfow 보다도 훨씬 무거워, 유연한 시스템으로 사용하기에는 다소 Over Spec 인 느낌이 커보였다.
      6. 이 시스템을 아직 Production 으로 사용하지 않는 가장 큰 이유는 Keras 가 아직 완벽하게 지원되지 않고 있다는 점이다. 우리는 많은 모델을 빠르게 실험해보고 적용해 보기 위해 Keras 를 상당한 비중으로 사용중에 있다.
        1. 논문 쓸 목적이 아니라면, 그리고, Agile 한 Deep Learning Approach 를 위해서는 Keras 는 최고의 툴이다.  
      7. 이 시스템에 대한 경험 그리고 세팅 방법은 아래에 블로그 했었다.
      8. http://hoondongkim.blogspot.kr/2017/09/bigdata-distributed-deep-learning.html
  3. Tensorflow + Keras + CNTK + Horovod + Azure Batch AI
    1.  최종 아키텍처로 선정한 시스템이다.
    2. TenosrlflowOnSpark 와 마찬가지로 CPU 와 GPU 모두 사용 가능하다.
    3. Production 용 배치 프레임워크의 아키텍처로 더 적당하다.
      1. 즉, 모델 개발 및 Dev 시스템은 꼭 이 구성일 필요는 없다. 아니, Dev 시스템은 이 구성이 오히려 개발 생산성에 저해가 될 수 있다.
      2. Dev 에서는 위 1,2가 사용될 수 있다.
      3. 모델 개발 시점에는 Cluster 보다 Scale Up된 High End 장비 혹은 GPU VM이 더 편할 수 있다. 
      4. 단, 다양하게 하이퍼 파라미터를 실험 적용해보는 단계에서는 Scale Out 가능한 이 구성이 더 유리하다.
    4. 앞 4개는 Open Source Deep Learning 도구들이며 각각 장단점이 있고, 때로는 보완 도구로서 함께 사용해야 한다.(특히 Keras)
    5. CNTK 는 보완 및 대체제로 경우에 따라 사용이 가능하다. CNTK 는 Keras 환경에서 기존의 Keras Source Code를 거의 수정하지 않고(우리의 Production 코드는 1~2줄 미만의 수정으로, 때로는 0줄 수정으로 가능하였다.) Backend 를 Tensorlfow 에서 CNTK 로 바꾸어 모델마다 선별적으로 선택하여 사용할 수 있다. 그리고, 다음과 같은 장점이 있다.
      1. Keras 와 함께 사용시 기존 코드를 그대로, CNTK 적용이 가능하다.
      2. RNN 계열에서 Tensorflow 보다 빠르다고 알려져 있다.
      3. 대부분의 병렬 Deep Learning 수행에 있어, 훨씬 적은 노력으로 확장이 가능하다.
    6. Horovod 는 Uber 가 만든 Deep Learning 분산 프레임워크로 Tensorflow 와 Keras 를 지원한다.
      1. Tensorflow 및 Keras 의 Low Level 코드 접근 없이 Multi GPU , Multi Host 사용이 가능하다.
      2. 위는 BechMark  자료이다.
    7. Azure Batch AI
      1. Azure 가 제공하는 Deep Learning 프레임워크의 병렬 확장 및 Auto Scale Out 을 지원하는 PaaS 이다.
      2. Tensorflow , keras, cntk , horovod(Manually) 등을 지원한다.
      3. CNTK 를 Backend 로 사용 시 병렬확장성에 대한 Code 접근을 추상화 할 수 있다.
        1. 즉, 이 때문에 tensorflow + keras 코드를 CNTK + keras 코드로 수정한 후, 이를 Azure Batch AI 에 호스팅 하는 경우 Auto Scale Out 의 장점을 극대화 할 수 있다.
        2. 모든 것이 Compute Parallel 이 되지는 않을 수 있다.(Horovod 와는 다른 방식이다.) 모델에 따라 Data Parallel 만 될 수도 있다는 의미이며, 이 부분에 대해서는 추후 좀더 실험을 해볼 예정이다.
      4. Tensorflow + Horovod  + Azure Batch AI 구성 시 native tensorflow 코드를 Low Level 코드 접근 없이 multi Gpu, multi host 확장이 가능할뿐 아니라 Auto Scale Out 이 가능하다.
      5. 비용에 대한 Limit 을 위해 Min Node 수와 Max Node 수 설정이 가능하다.
      6. 하나의 Job 의 확장 뿐 아니라, 복수 GPU 클러스터 Node 에 복수의 Deep Learning  Job 을 분배 및 할당하는 Cluster 로도 활용 가능하다.
      7. 이는 Production 용 Training 시스템 뿐 아니라, 다수의 Deep Learning Model 개발자들이 있는 경우 모델 개발이나 하이퍼파라미터의 빠른 튜닝을 위해서도 활용 가능한 시스템 이다.

여기서부터는 위 최종 선정 시스템을 이용 실제 Production 용 Legacy Deep Learning 모델을 Azure Batch AI 위에서 병렬 구동한 모습이다.

  1. Tensorlfow + Keras 로 작업된 Legacy 코드를 CNTK + Keras + Azure Batch AI 로 포팅하여 Multi Host + Multi GPU 로 수행한 화면.
  2. Tenosrflow + Keras 로 작업된 Legacy 코드를 Tenosorflow + Keras + horovod + Azure Batch AI 로 포팅하여 Multi Host + Multi GPU 로 수행한 화면.
  3. 수행 이후 수행 결과를 PaaS 상에서 확인


    1. 수행결과
    2. 클러스터 모니터링

[결론]



위 처럼 Tensorflow + Keras 로 작성된 Legacy Deep Learning Training 코드는 코드 수정을 거의 하지 않고, Single GPU 에서만 돌던 코드가 Azure Batch AI 위에서 Mulit GPU 와 Multi Host 로 병렬 구동됨을 확인 하였다.

위를 위해서 CNTK + Keras + Azure Batch AI 환경에서는 Legacy 코드를 단 1줄도 수정하지 않고, Backend 설정만 Tensorflow 에서 CNTK 로 변경하여 Azure Batch AI 위에서 병렬 수행됨을 확인 하였다.

하지만, 모든 Legacy 코드가 Keras  코드로만 구성된 것은 아니다. Keras 가 지원하지 않는 최신의 기법을 사용하는 경우. (예를 들어 2017년 여름경 까지 Keras 는 LSTM 에 Attention 을 포함하는 것을 지원하지 않았었다.) Tensorlfow 코드와 Keras 코드가 섞여 사용하는 경우가 실제로 우리의 경우도 존재 한다.

때로는 github 에 구현체가 공개된 잘짜여진 open source  코드가 keras 가 아닌 tensorflow 로만 구성된 코드일 수도 있다.

이를 위해 우리는 Horovod 를 이용한 Multi Host + Multi GPU 구동도 함께 테스트 했었다.
Tensorflow + Keras + Horovod + Azure Batch AI  구성은 그러한 시나리오를 위한 추가 확장 환경 구성이었다.

tensorflow + Keras + Horovod + Azure Batch AI 환경에서는 기존 Legacy 코드를 약 4~5 줄 정도를 추가하고, 2줄 정도를 변경하였으며, 변경을 하는데 들어간 시간은 최초 작업이었을 때에도 3~5분 미만으로 매우 쉬운 편이었다. 익숙해지면, 1~2분 안에 코드 수정이 가능한 수준이다.

단, CNTK + Keras + Azure Batch AI 와는 다르게, tensorflow + Keras + Horovod + Azure Batch AI 는 공식 github 에 example 도 존재하지 않으며, 다소 초기 세팅시 Debug 후 수동 설정 변경 사항이 많이 필요하였다.( 최초에 한번만 수행해주면 된다. ) 이 복잡한 초기 세팅 부분은 별도로 블로깅 예정이다 . 해당 부분을 따라한다면 어렵지 않게 Legacy 코드를 수행할 수 있을 것이다.

이번 블로깅에서는 고찰 및 구성 결론 만 다루었다. 다음 연재에서는 실제로 구성하는 방법과 구성 과정에서 구성을 debug 하는 방법, trouble shutting 하는 방법에 대하여 다루도록 하겠다.

연재 순서는 다음과 같다.

연재 1. 이번글.

연재 2. Deep Learning Multi Host & Multi GPU Architecture #2 - Keras 를 이용한 Scale Up, Horovod 를 이용한 Scale Out 성능 비교

연재 3. CNTK + Keras + Azure Batch AI 구성 방법

연재 4. Tensorlfow + Keras + Horovod + Azure Batch AI. Mnist 간단 버전 구성 설정 방법

연재 5. Tensorlfow + Keras + Horovod + Azure Batch AI. Legacy Code Advanced 버전 구성 설정 방법.

연재 6. Azure Batch AI 를 이용한 Custom Deep Learning 모델 구동 시 Trouble Shutting 을 좀더 쉽게 하는 방법.



2017년 12월 27일 수요일

Deep Learning Inference & Serving Architecture 를 위한 실험 및 고찰 1 - GPU vs CPU

최근 Production을 위한 Deep Learning Serving 레이어의 아키텍처를 구성하기 위해 몇가지 실험을 했던 내용을 정리해 보았다. 몇번에 걸쳐 연재 될 수 있을 듯 한데...

우선 오늘의 주제는 Inference 에 있어서도 정말 GPU 가 CPU보다 유리한가? (결론이 유추 되는가???)


아키텍처를 구성함에 있어, 다양한 Use Case 가 있을 수는 있으나, 정답이 존재하지는 않는다고 생각한다. 다양한 비지니스로직, 데이타의 양이나 성격, 사용하는 기술들, 개발 언어, 목적하는 바, 동시접속자 수, On-premise , Cloud 여부 등에 따라 다양한 조합이 있을 수 있을 것이고, 각각이 장단점이 존재할 것이기 때문이다.

여러 참고 자료로 사전 조사를 해본것은 사실이지만, 우리의 Deep Learning 모델과 우리의 데이타, 우리의 로직으로 후보 아키텍처에서 직접 실험을 하고 아키텍처를 확정하고자 아래와 같은 실험을 진행하였다.

실험에 앞서, 주안점은 다음과 같다.

  1. 우리는 Keras , Tensorflow (일부 CNTK) 등의 Deep Learning Framework 로 만들어진 Deep Neural Network 모델을 이용, 대국민 서비스를 준비하고 있다.
  2. 다수의 동접이 있을 수 있고, 이벤트나 행사 여부, 광고 및 홍보 여부에 따라, 트래픽이 매우 가변적일 수 있고, 다수의 동접 및 다수의 inference 가 일어날 수 있다.
  3. 많은 동접의 경우에도 응답은 1초 이내를 목표로 한다.
  4. Deep Learning 모델은 RNN, LSTM 류와 간단한 류의 CNN 이 주를 이룬다.(우리의 모델은 vgg, inception 류의 heavy CNN  은 아니다.)
  5. 우리의 모델이 특이한 점은 주기적인 Fine Tuning 과 시시 각각의 RealTime on-line Training 이 운영중인 Model 에 시시각각 이루어진다는 점이다. 이는 Serving Layer 설계에 있어 중요 고려 사항 중 하나인데, Serving 되는 모델의 Size 를 줄이고 응답 속도를 빠르게 하기 위한 알려진 기법들을 적용하는데 방해가 되는 요소이기 때문이다. 
  6. Tensorflow 의 Serving 은 써본 사람들은 알겠지만, Web Service 로 만들어 배포하기에는 몇가지 제약이 느껴진다. 이 실험은 Tensorflow Serving 전용 엔진을 통한 실험은 아니며, 보다 High Level 로 접근하여 Inference Layer 를 직접 구현했을 때의 실험이다.
일반적으로 Inference 전용 Model Optimization 을 할 때는 주로 아래의 방법들이 사용된다.

  1. check point 등 training 에서만 사용되는 operation 을 없앤다.
  2. batch normalization ops 도 제거한다.
  3. 도달하지 않는 graph 영역 제거
  4. Check Numeric 제거
  5. 각종 variable 값 들은 constant 로 바꾸어, 크기를 줄이고 속도를 빠르게 하며, Thread Safe 하게 변경한다.
위 기법들은 Model 이 Freezing 된 경우에 한하여서이다. realtime training 과 inference 가 동시에 일어나는 경우는 
  1. training  model 과 inference  model 을 분리하고, 지연 동기화 시키거나
  2. 둘을 하나로 가져가되 constant 화 하고 freezing 하는 것을 포기해야 한다.
위 둘의 중간도 가능할 수는 있다. Node 가 복수개인 경우 Training  중인 Node 가 잠시 Serving Node 에서 빠져 있는 경우가 그 경우에 해당 할 것이다. 후에 우리는 Serving Layer 에 있어, Auto Scale Out 가능한 Docker PaaS나 Microservice Serverless PaaS 를 중요 고려 요소로 낙점하고 추가적인 실험을 하였는데, (아마 이 연재가 좀더 계속되어진다면, 다시 상세하게 다루어 보도록 하겠다. ) 이 시나리오 에서는 Training Layer 와 Serving Layer 를 각각의 장점을 극대화 시키고, Model 파일의 경우만 지연 공유시키는 또다른 시나리오가 나올 수 있다.


우선 오늘 다룰 내용은 위에서 언급된 다양한 방법론의 첫단추로서, 우리 모델이 과연 CPU 에서 더 잘 inference 되는 지, GPU 에서 더 잘 inference 되는지 의 여부에 대하여 실험 해본 결과이다. (ps. 실험에서 사용된 모델은 실험용으로 실제 모델이 다소 단순화된 General Model 임)
다수 동접 Inference 테스트 전 training 퍼포먼스 또한 실험한 결과를 함께 정리 하였다.

[1] 실험에 사용된 딥러닝 모델 및 모델 크기

- 일반적인 Language Model 용 LSTM 모델
- categorical_cross_entropy 사용
- Top 1 분류 모델
- Word Embedding Layer 차원 수 : 300차원
- Total Parameter 수 : 80,656,435 개

- [특이사항] Language Model 특성상 Total Parameter 에서 앞부분이 많은 부분 차지.
- [특이사항] LSTM 이 번역등의 문제가 아닌 Text Classification 문제에 적용된 경우 이므로, 층이 복잡하지는 않음. 층을 복잡하게 하여도 성능 향상 없었음. 그러나, 일반적인 word2vec + cnn 보다는 3% 정도 성능 향상된 모델임.


[2] 실험에 사용된 hyper parameter

- epochs=4 , batch_size=64 , optimizer=adam
- learning Rate=0.001, beta_1=0.9 , beta_2=0.999, epsilon=1e-8

- [특이사항] CPU Training 은 GPU 와 달리 batch size 를 4096등 훨씬 큰 수치를 주어도 memory resource 고갈 에러가 발생하지 않음, drop out 이나 batch bormalize 를 적절히 쓰는 경우 batch size 를 크게 주는 경우, 정확도는 비슷한데, 더 빨리 Training 이 될 수 있음.
- 즉, CPU vs GPU 트레이닝 퍼포먼스는 실무에서는 batch_size 를 달리 주어, CPU가 아래보다 더 빨리 응답하는 것도 가능하나, 동일 hyper parameter 값에 대한 성능 비교를 위해 아래에서는 동일 값으로 수행한 결과 이다.

[3] 실험에 동원된 HW 장비 Spec

- cpu : 12 vcore , 112gb Memory ( On Azure Cloud VM )
- gpu : K80 GPU * 2개 , 12 vcore , 112GB Memory ( On Azure Cloud Data Science GPU VM ) (단, 모델 inference 시에는 1개 GPU 만 사용하여 실험하였음)

[4] Training Data 크기

- training data row 수 : 1,649,415 건

[5] Training 속도 및 성능


  1. CPU Training Performance
    1. epoch1 : 23,790 초
    2. epoch2 : 24,071 초
    3. epoch3 : 24,026 초
    4. epoch4 : 24,100 초
  2. GPU Training Performance

    1. epoch1 : 8,612초
    2. epoch2 : 8,370초
    3. epoch3 : 8,377초
    4. epoch4 : 8,360초
[6] Single Inference 성능

      

예상과 달리 CPU가 Wall Time 이 더 빠르다. Wall Time 은 벽걸이 시계 시간을 의미한다. 즉 실제, 걸린 시간이다. CPU 의 경우 user time 은 150에 육박하는 경우가 있는데, 그래도 wall time 은 일정하게 30에서 40 사이의 값을 보여준다. 여기에서 다음과 같은 가정을 해볼 수 있다. CPU 는 멀티코어를 써서 더 빠른가??

[7] Multiple Sequential Inference 성능

이번에는 1개 Inference 가 아닌 1000번의 inference 를 sequencial  하게 (Not 병렬) 수행해보았다. 그리고, 위 (6)의 가정이 맞는지 cpu 및 gpu 의 usage 상황을 확인해 보았다.

사용된 코드도 아래에 참고로 넣어 보았다.

1000번을 연속하여 serial 하게 수행해보자 위와 같은 속도가 측정되었으며, 평균을 내 보면, CPU는 20ms , GPU는 60 ms 정도가 걸렸다.

특이한점은 , 처음 예상과 비슷하게, CPU는 멀티코어를 쓰고 있고,(코어 전체를 쓰진 않았음, 위 스크린샷 시점에는 420% 정도가 동작하고 있음.), GPU 는 GPU 1번 코어만을 50~70% 정도 사용하고 있으며, CPU 는 1개 CPU만 100% 사용하고 있다는 점 이었다.

여기에서 한가지 의문이 생겼다. 그렇다면 혹시 CPU가 병목인가?
그리고, 그렇다면, 혹시 위 코드에서 사용된 유일한 Pre Processing 인 Tokenizer 가 영향을 주고 있는 것인가?

그래서 위 실험에 사용된 코드에서 Tokenizer 전처리 Pre Processing 부를 1000번의 loop 바깥으로 빼보고 성능 향상 정도를 측정해 보았다.

[8] CPU  에서 Tokenizer 가 주는 영향


위 처럼 CPU 실험에서는 Pre-Processing 영역인 Tokenizer 가 주는 영향은 5% 정도에 지나지 않았다.

[9] GPU에서 Tokenizer 가 주는 영향


GPU에서도 마찬가지로 Pre-Processing 부분이 주는 영향은 2% 정도에 지나지 않았다. %는 줄었고, 절대치는 비슷하다. 즉, CPU에서이든 GPU에서이든 Pre-Processing 은 CPU 를 이용하기 때문에 절대치는 비슷한것이 이치에 맞다.

위 상황에서 CPU와 GPU  의 USAGE 도 확인해 보았다.



여전히 CPU 는 1Core 만 100% Full로 일하고 있고, GPU 는 50%에서 70%를 왔다갔다 하였다. 그러므로, CPU 는 전처리 때문이 아닐까 하는 가정은 False 라고 할 수 있을 것이다. 해당 가정에 대한 의문은 해소 되었다.

[10] 이제 실제 Inference 테스트를 위해 모델을 flask microservice 형태로 배포하였다. 


위 구동은 CPU 전용 머신과 GPU 전용 머신에서 각각 해 주었다.
실제 Production 에서는 성능 극대화를 위해 하나의 머신에 port 를 달리하여 여러 Process 를 띄우고 앞에 웹프록시 등을 두는 것이 일반적이지만, 이 실험은 상대적인 비교를 위함이 목적이므로, 그런 작업을 해주지는 않았다.

[11] 이제 실제 운영 Production 환경과 유사한 환경에서 동시접속수행 Test 를 해보겠다.

이곳에 따로 기재하진 않았으나, 앞선 시점에서의 비교는 Jupyter Notebook 에서 이루어졌다. 모두가 아는 바와 같이 Jupyter Notebook 위에서의 구동은 단일 Python 독립 프로세스보다 훨씬 느리다. 즉, 동일한 실험이 flask 위에서 구동된 경우 Jupyter 위에서 구동된 경우보다 훨씬 빠르다. 그리고, flask 는 경량의 비동기 웹 프레임워크 이기 때문에, 병렬 수행이 위의 경우보다 훨씬 빠르게 일어난다.

위에서는 Serial 하게 한번에 하나씩만 Job 을 수행하였다. 이번 flask 에서의 수행은 다수 User 에서의 Parallel 동접 수행이다. 때문에 Serial 하게 수행했을 때보다 더 많은 병렬 Job 이 수행되었고, 그 결과 Jupyter 에서의 serial 수행보다 성능이 훨씬 더 좋게 나오고 있다.

(1) CPU 에서의 최종 결과

[Run User]      [TPS]   [Time Per Request : millisec]   [Transfer rate: Kbytes/sec]     [Complete Request]      [Failed Request]
1       200.35  4.991   30.13   201     0
11      273.97  3.650   41.20   274     0
21      245.21  4.078   36.88   246     0
31      265.94  3.760   39.99   266     0
41      265.97  3.760   40.00   266     0
51      265.95  3.760   40.00   266     0
61      258.76  3.865   38.92   259     0
71      260.95  3.832   39.24   262     0
81      244.99  4.082   36.84   245     0
91      251.80  3.971   37.87   253     0

[Run User]      [TPS]   [Time Per Request : millisec]   [Transfer rate: Kbytes/sec]     [Complete Request]      [Failed Request]
300     274.39  3.644   41.27   275     0
310     233.33  4.286   35.09   234     0
320     173.71  5.757   26.12   174     0
330     133.75  7.476   20.12   134     0
340     142.73  7.006   21.46   143     0
350     130.86  7.642   19.68   131     0
360     128.93  7.756   19.39   129     0
370     280.45  3.566   42.18   281     0
380     267.97  3.732   40.30   268     0
390     278.43  3.592   41.87   279     0
400     200.84  4.979   30.20   201     0

Apach 오픈소스 부하테스트 도구를 이용하여 동시접속 수행 성능을 측정하였다.
하나의 단일 User 가 비동기로 여러개의 병렬 수행을 요청하며, 그러한 User 또한 1에서 최고 400까지 늘려가며 측정 하였다.

CPU는 TPS 가 270 정도씩 나와 주고 있다. 그 시점 flask  의 로그를 보면, 실제 초단위로 동일한 log 가 270여개 실제로 모두 200 응답으로 존재함을 확인 할 수 있다.




(2) GPU 에서의 최종 결과

[Run User]      [TPS]   [Time Per Request : millisec]   [Transfer rate: Kbytes/sec]     [Complete Request]      [Failed Request]
1       16.47   60.735  2.48    17      0
11      16.24   61.565  2.44    17      0
21      15.69   63.740  2.36    16      0
31      11.60   86.215  1.74    12      0
41      4.98    200.914         0.75    5       0
51                              0       0
61      17.80   56.186  2.68    18      0
71                              0       0
81      17.47   57.242  2.63    18      0
91                              0       0

[Run User]      [TPS]   [Time Per Request : millisec]   [Transfer rate: Kbytes/sec]     [Complete Request]      [Failed Request]
1       15.87   63.014  2.39    16      0
11      17.28   57.886  2.60    18      0
21      15.69   63.744  2.36    16      0
31      12.46   80.263  1.87    13      0
41      5.76    173.748         0.87    6       0
51                              0       0
61      17.33   57.706  2.61    18      0
71                              0       0
81      12.42   80.529  1.87    13      0
91                              0       0



GPU 는 TPS 가 16 정도밖에 되지 않는 저조한 결과를 보여 주었다.

[결론]

(ps. 동시수행 과정에서의 cpu , gpu 사용량은 serial 1000건 수행의 경우와 매우 유사했다.)

CPU 의 경우 특징은 느려질 지언정 400동접까지도 Fail Request 가 하나도 없었다는 점이다.
그리고 Serial 하게 1000개를 수행했을때, 개당 20 ms 이던것이 병렬로 수행했을때에는 약 5배정도 빠른 성능을 보여 주었다. 

하지만 GPU 의 경우는 동접자가 많아지면, Fail Request 가 매우 많아 졌고, TPS 자체도 CPU 에 비하여 매우 느렸다. Serial 수행에서 3배 느렸으나, 동접 수행은 거의 10배 이상 느렸다. CPU 코어가 여러개인것도 그렇지만, 메모리 등도 한몫을 했을 것으로 보여진다. GPU 의 경우는 serial 하게 측정했을때나 parallel 하게 측정했을때 모두 개당 응답 속도가 60ms  정도로 일정하다는 특징도 보여주었다. 즉, 동시 처리가 좀 매우 취약해 보인다. 동시 수행하는 속도 개선 효과가 거의 없었다.(CPU 와는 전혀 다른 양상이다.)

또한 GPU inference 의 경우 단일 CPU 가 GPU 한개와 함께 힘들게 일하고 있었던 양상 또한, 병렬 동시접속 능력을 떨어뜨리는 계기가 된듯 하다.
(이는 Tensorflow 에서의 실험 내용이다. CNTK  로도 동일한 모델을 수행할 수 있는데, 그 비교 결과는 다음 기회에 Posting 해보도록 하겠다.)

일단 CPU Inference 의 경우는, 메모리 사용량, CPU 사용량, 모두 저정도의 traffic 에 대하여는 안정적인 결과를 보여주는 것을 확인 할 수 있었다. GPU 의 경우는 Production 으로 대국민 서비스를 하기에 매우 위험한 수준이었다.

Developer 입장에서, 우리에게 CPU는 사실 GPU에 비하여 상대적으로 너무나 친숙하고 풍족한 리소스 이다. 게다가, 우리는 Docker , Microservice , Spark on Hadoop Yarn, Mesos  등 다양한 CPU + in-Memory 병렬 cluster 솔루션이 있다. 그리고 Public Cloud 에도 Auto Scale Out  이 가능한 Docker PaaS 나 Serverless MicroService PaaS 가 GPU 보다는 훨씬 저렴한 가격으로 구비되어 있다.

AI Serving Layer 는 이렇게 일단 우리의 시나리오와 우리의 모델에 있어서는 GPU 를 제끼고 고려할만 한 실험 결과가 나왔다. ( 물론 VGG, Inception 등 층이 깊은 Deep Learning 모델은 이것과 다른 양상이 나올 지도 모른다. TensorRT 등 Nvidia 는 Inference 전용 솔루션도 내놓은 것으로 알고 있다.) 

지금 담담하게 결론을 적고 있지만, 사실 실험결과가 이렇게 나왔을때 나는 흥분을 감추지 못했다. 하마터면 수억원짜리 GPU가 6~8개씩 꼳 힌 장비를 수대 구매하는 프로세스를 태울 뻔 했기도 했지만.... 무엇보다, 대용량 서비스와 다수 동접자를 위한 아키텍처에, 위 결론에서는 많은 솔루션과 오픈소스 그리고 public cloud 를 쓸 수 있는 풍부한 가능성이 생겼다는 점에서 안도의 한숨을 쉴 수 있었다.

PS. 위 실험 결과와 결론 유추 과정에서 제가 범한 논리적 오류가 있었다면 지적해주시기 바랍니다. 공유 이후 컴멘트는 곧 저에게는 배움이기도 하다는 자세로 공유를 실천 하고 있습니다.