AI, ML의 최종목적은 지속적으로 학습하는 모델을 서비스에 배포하여 새로운 데이터에 대한 예측을 런타임에 하기 위함일텐데요. 그러다보니 시스템 설계에 관심이 많은 저의 개인적인 관점에서는 학습된 모델을 서비스에 배포하는 이 “모델서빙”이야말로 AI기반 서비스의 핵심이 아닐까하는 생각을 갖고 있습니다. (모든 영역 하나하나가 다 중요하지만 아무래도 AI 기반 서비스의 대부분을 담당하기에 자연스럽게 스며든 화룡점정의 스탠스가 아닐까 싶네요 🙂
이 영역이 연구의 단계(ML)에서 개발/운영의 단계(DevOps)로 넘어가는 경계이기도 하여서 이 부분을 원활하게 운영하기 위한 개념 및 조직인 MLOps를 구성한다거나 이 과정을 쉽게 처리하기 위해 AutoML이라는 개념을 각 CSP에서 자신만의 방법으로 도입하는 식의 흐름이 이어지고 있는 것으로 보아 제 생각이 완전 틀리지는 않는 것 같습니다.
물론 이렇게 중요하니! 이러한 흐름에 편승하여 클라우드 엔지니어링, 데이터 엔지니어링, 데이터 사이언스 조직을 다 갖춰놓고 충분한 리소스를 기반으로 AI 서비스 환경을 “robust하게” 구축할 수도 있겠지만 필드에서는 언제나 넉넉한 것은 없고 우리에게는 항상 “Product 같은 MVP를 ASAP으로” 만들어야 하는 미션만 주어지다보니 점점 폴리스택 혹은 풀스택 엔지니어가 되어가는 것 같습니다. (그러니 어 이래도 되네? 더 안뽑아도…)
잠시 감정의 흐름이 다른 곳으로 갔었는데요. 다시 돌아와서…
부족한 자원인데 제대로 차근차근 과제를 수행하기도 그렇고 Open Source의 힘을 빌리고자해도 우리가 원하는 스펙은 여러 OSS를 붙여도 완벽하게 충족되지 않고 붙일수록 운영의 난이도가 올라가기에 초기에 무턱대고 도입하기에 어려운 점이 많습니다.
조직에서 다음으로 수행해야하는 모델서빙 부분에서도 역시 이러한 고민에 빠졌는데요. 많이 들어보셨을 법한 Kubeflow, MLFlow, BentoML 등을 고려하고 있지만 다른 한편으로는 “k8s를 써야하나?”, “PoC 단계에서 서빙레이어가 너무 거창하지 않나?”라는 생각이 먼저 들더라구요..
(물론 나쁘다는 것이 아닌 아직 서비스로 런칭하지 않았는데 이렇게까지 가는 것에 대한 부담이 ^^;;;;;)
그래서 별다른 노력없이 학습한 모델을 다른 곳으로 전이하기 위해 제가 선행해본 방법 몇 가지를 소개 해보겠습니다.
1. KERAS의 model.save를 활용하기
학습 후 mae가 2.37정도 나오는 간단한 모델을 만든 후 boston_model_20220624에 저장을 해봤는데요.
로컬에 다음과 같은 형태로 저장이 됩니다.
이 파일들을 다른 곳에 배포하여 불러온 후 다시 evaluation 해보면
똑같은 mae가 나오는 것을 확인할 수 있습니다.
모델이 저장된 disk를 docker에 마운트 시키거나 CDN 등을 통해 배포하면 생각보다 간단하게 운영이 가능합니다.
그럼 모델의 크기가 크거나 제한된 통신망 사정으로 쉽게 배포할 수 없다면 어떤 접근이 가능할까요?
2. 노드의 가중치만 전달하기
각 레이어의 노드의 가중치만 저장하고 이를 전달하면 용량을 크게 줄일 수 있습니다.
#학습이 완료된(fit 이후) 모델의 가중치 저장
weights = model.get_weights()
#전달받은 가중치를 서비스에서 로드
model3 = build_model() #제가 만든 network build 함수
model3.set_weights(dist_weight)
아래 그림을 보면 제대로 가중치가 설정되지 않은 모델(model2)에 비해 가중치가 적용된 모델(model3)는 앞선 mae와 같음을 확인할 수 있습니다.
네트워크를 빌드하는 코드(layer 구성~comple 까지)가 별도로 배포되어야 한다는 단점이 있지만 학습이 자주일어나고 무중단으로 빠르게 서빙되어야 하는 상황에서 좋은 성능을 보여 주었습니다.
weight를 DB에 저장하는 형태로 운영하면 배포에 대한 부담이 없어지기도 하겠지요.
여기에서 고민을 좀 더 확장해봤는데요,
위의 1, 2번 case는 서비스에서도 keras가 셋팅되어야 하는데 서비스부서가 외부 혹은 물리적으로 떨어져 있어 컨트롤에 제약이 있는 경우를 고려해야 한다면 어떤 방법이 있을까요?
3. 모델의 object를 저장하여 배포
python에서 dataframe을 파일로 저장-로드 할 때 자주 사용하는 pickle을 이용하여 문제를 접근해 봤습니다.
모델을 pickle 파일로 저장한 후 외부에서 배포받아 로딩 및 실행해보면
역시 학습된 모델과 같은 mae가 나오고 있습니다.
특이한 점은 keras관련 아무것도 import하지 않았는데 잘 작동 되네요. import 없이 evaluation 및 predict가 잘 작동하고 있어 서비스 레이어에서 충분히 활용 가능할 것으로 보입니다.
배포용량은 좀 크지만 서비스 부분이 가벼워지는 장점이 있어 쉬운 HA 혹은 scale-out이 필요할 때 유용할 것 같습니다.
조직에서 필요한 시나리오에 맞춰 간단하게 모델을 서빙할 수 있는 방법을 정리해 봤는데요.
아마도 많은 모델서빙 관련 OSS들도 기본적인 컨셉은 이와 많이 틀리지 않을 것으로 예상됩니다. 물론 여기에 여러 노하우와 아이디어를 녹여 좀 더 좋은 환경을 제공 할테구요. 그러다보니 각각의 특성이 있을텐데 이러한 특성은 우리의 여건에 따라 때때로 장점이 되기도 또 단점이 되기도 하다보니 선택에 어려움이 있는 것 같습니다.
이 때, 당장은 가볍게 운영을 해보면서 우리에게 중요한 feature가 무엇이고 이를 가장 잘 반영할 수 있는 방법이 무엇일까 고민할 시간을 벌 필요가 있을 때 제가 소개드린 방법이 도움이 되었으면 하여 경험을 기록해 봤습니다.
긴~글 읽어주셔서 감사합니다.