원활한 학습과 배포를 위한 ML pipeline

Kimin
tesser-team
Published in
8 min readDec 21, 2022

안녕하세요. 테서의 연구개발팀에서 MLops 환경 구성과 의료 영상 모델을 개발하고 있는 박기민입니다.

‘원활한 학습과 배포를 위한 ML pipeline’은 저희가 Ontol3D를 서비스로 오픈하기 전에 ML pipeline을 구축한 이야기입니다. 저희가 해당 시스템을 구축하게 된 배경과 MLflow를 선택한 이유, 이 과정에서 얻게된 인사이트를 공유하려고 합니다.

도입 배경

딥러닝 모델을 개발할 때 가장 중요한 건 무엇일까요? 대부분의 연구원은 모델 학습과 성능 향상에 초점을 맞춥니다. 물론 모델의 성능을 높이는 일은 중요하지만, 개발한 모델을 활용하지 못한다면 모든 노력은 물거품이 됩니다. 그래서 자신이 개발한 모델을 다른 환경에서도 사용할 수 있게 하는 것이 중요합니다.

테서 역시 딥러닝 모델을 서비스에 붙이기 전에 연구원이 서비스 개발자와 긴밀하게 소통하는 과정이 있습니다. 하지만 라이브러리 버전과 시스템적인 이슈 때문에 서비스에 붙이기 힘든 경우가 대부분이었습니다. 코드와 모델은 전달했지만, 버전이 맞지 않아서 오류가 나거나, 기대했던 성능보다 낮게 나오는 어려움이 있었습니다.

Ontol3D 도식도

최근 팀에서 자체적으로 Segmentation 모델을 개발하며 ML pipeline에 대한 필요성이 더욱 절실해졌습니다. 저희가 운영 중인 Ontol3D는 환자가 MRI, CT를 다양한 각도에서 이해하기 쉽게 보여주기 위해 설계된 AI 엔진입니다. Ontol3D는, 의료 영상을 통해 환자가 직접 자신의 상태를 이해할 수 있도록 돕는 서비스입니다. 해석을 위해 전문적인 영상의학(radiology) 지식이 요구되는 CT, MRI 의료영상을, 직관적인 형태의 3D 이미지를 제공하며, 치료 경과에 따른 변화와 주변 장기 및 조직에 어떤 영향을 줄 수 있는지 한눈에 살펴볼 수 있도록 만들어줍니다.

저희는 Ontol3D에 ML pipeline을 도입하기 위해서 아래의 3가지 과정을 중심으로 고려했습니다.

1. 데이터 준비 / 전처리

2. 모델 학습

3. 모델 배포

데이터 준비 / 전처리

다른 도메인에서도 마찬가지지만, 의료 데이터에서 전처리는 정확도와 효율성에 크게 좌우합니다. 특히 내부적으로 구축한 데이터에 의존된 학습을 하다보면 external 데이터에서 성능이 크게 저하되는 경우가 있습니다. 그래서 학습 데이터를 보다 general 하게 만들기 위해서 여러 augmentation 기법을 적용하여 데이터를 변형합니다. 이때 “ 이 모델은 어떤 전처리를 적용한 데이터로 학습을 시켰는가?”에 대한 답을 하기 위해서 데이터 version 관리 혹은 metadata 관리가 미리 되어 있어야합니다.

모델 학습

연구 파트는 문제 해결을 위한 적합한 방법을 리서치합니다. 리서치를 통해 얻은 인사이트로 다양한 실험을 진행하고, 해당 과제에 대한 최적의 결과를 도출합니다. 이제 가장 좋은 모델을 서비스로 배포하기 위한 재료들을 준비합니다.

모델 배포

서비스에 배포하기 위한 개발자의 요구사항은 생각보다 많습니다. 간단하게 시스템 환경 구성을 위한 도커 파일, 모델 inference에 필요한 모델 weight 파일 등이 있습니다. 여기에 추가로 input, output 명세서만 잘 정의해서 주면 배포까지는 큰 문제 없이 이루어지게 됩니다.

하지만 문제는 배포를 한 뒤부터 입니다. 프로덕션 환경에 배포하게 되면 학습데이터와 상이한 데이터가 입력으로 들어오게 됩니다. 이때부터는 데이터의 양상이 바뀔 때마다 모델을 개선 시켜서 성능을 향상시키는 지속적 학습(Continuous Training)과정이 필수적입니다.

지금까지는 서비스보단 리서치에 집중했기 때문에 지속적인 학습 환경을 구성하지 않았습니다. 효율적인 모델 관리와 배포를 위한 인프라를 구축하고, 프로세스를 자동화하는 Machine Learning LifeCycle의 필요성이 점점 커졌습니다. 또한 모델이 실험 환경에 종속되는 Only me 패턴을 주의하기 위해서 데이터, 개발, 운영 환경을 유기적으로 통합해 안정적인 개발 환경을 위한 프로젝트를 계획했습니다.

MLflow

이에 테서가 Ontol3D에 들어갈 모델을 서빙하기 위해 최우선으로 고려한 사항은 다음과 같았습니다.

1. 해당 모델의 학습과 추론 로그를 기록할 수 있는가?

2. 학습한 모델이 프로덕션 환경에서 정상적으로 가동이 되는가?

3. 실시간으로 모델에 들어오는 입력값이 학습 데이터와 비슷한 양상인가?

모델, 서비스 전 과정에 걸쳐 모두 만족하는 ML 파이프라인을 설계하려면 꽤 오랜 시간이 걸리게 됩니다. 또한, 확장성까지 고려하기 위해서 쿠버네티스와 같은 오케스트레이션 혹은 SageMaker와 같은 완전관리형 서비스를 사용하는건 비용과 시간 측면에서 부담스러운 것이 사실입니다.

이에 원활한 학습과 배포를 위한 자동화 방안을 찾아보게 되었고, MLflow를 이용하여 모델 버전 관리, 학습 내용 기록, 재현성을 위한 컨벤션 관리등 모델 실험에서 운영까지하는 시스템을 구축하기 위한 프로젝트가 시작되었습니다.

MLflow란?

위와 같은 고려 사항과 요구 사항을 만족시키기 위한 다양한 ML 파이프라인 프레임워크를 비교했습니다. 그중 저희는 프로젝트 전반을 효율적으로 관리할 수 있는 MLflow를 선택하였습니다. MLflow는 다음 4가지의 기능을 가지고 있습니다.

  1. Tracking — Experiment tracking (학습 내용 기록)
  2. Projects — Reproducible runs (convention 설정)
  3. Models — Packaging models (model을 기록후 저장)
  4. Registry — Central repository for store, annotate, discover and manage.

MLflow의 주요 장점은 다음과 같습니다.

  • Hyper parameter tuning을 할 수 있다.
  • Model serving 단계로 확장 가능성이 있다.
  • 모델의 기록이 체계적이다.
  • 무료로 이용할 수 있는 Open source tool이다.
  • conda와 도커를 이용해서 환경을 동일하게 세팅할 수 있다.

위와 같이 정의로만 보면 확 와닿지 않을 것 같아서 코드를 통해 살펴보겠습니다.

MLflow를 사용하지 않았을때

# github clone 
https://github.com/mlflow/mlflow-example

# os 환경 세팅
docker build
docker run

# 패키지 설치
pip install -r requirements.txt

# 학습 실행
python train.py

MLflow를 사용했을때

mlflow run git@github.com:mlflow/mlflow-example.git -P alpha=0.5 --no-conda

위의 예시에서 볼 수 있듯이, github repo를 바로 실행 시킬 때 MLflow는 코드 한줄이면 가능합니다. 이는 MLflow의 강력한 Project packaging 기능 덕분입니다. 이외에도 저희가 프로젝트에 적용한 MLflow의 기능을 살펴보겠습니다.

1) 쉽고 간단한 모델 학습 로그

  • 머신러닝 관련 실험들을 정리하고 각 실험들의 내용들을 기록 가능하도록 설계(여러 사람이 하나의 MLflow 서버 위에서 각자 자기 실험을 만들고 공유 가능)
  • 실험을 정의하고 실행할 수 있다. 각 실행에 사용된 코드, 파라미터, Metric 등을 저장
  • Wandb도 같이 사용하여 실험 비교 가능

2) 재현성을 위한 프로젝트 패키징

  • 머신러닝 프로젝트 코드를 패키징하기 위한 표준
  • MLflow 프로젝트는 코드(code)와 entrypoints 그리고 라이브러리를 packaging하여 실행
  • MLflow 형식에 맞는 컨벤션이 만들어짐.

3) 별도의 Tracking Server를 이용한 Artifact 저장

  • mlflow UI로 누구나 언제든지 상시 확인 가능
  • 모델은 AWS S3에 자동으로 전송

ML pipeline 적용 결과

Ontol3D 파이프라인 도식도

MLflow를 적용한 결과, 모델 학습, 로그 관리, 도커 이미지 관리를 유기적으로 관리할 수 있었습니다. MLflow를 활용하여 모델 패키징을 하고, 도커로패키징된 모델을 experiments ID를 활용하여 쉽게 가져올 수 있었습니다. experiments 단위로 실험을 관리하기 때문에 conda version 혹은 python version의 종속성 문제에서 벗어날 수 있었습니다.

또한 코드 몇줄만 추가하면 학습 로그를 기록할 수 있기 때문에 학습 log를 run ID 단위로 관리할 수 있었습니다. 현재 배포되어 있는 모델의 experiments ID만 알면 해당 모델의 score를 쉽게 확인할 수 있습니다. 이로 인해 불필요한 시간 낭비를 최소화할 수 있었습니다.

마무리

테서의 연구팀에서 ML 파이프라인을 개발하는 과정에 대해 알아보았습니다. UI나 API 등은 백엔드 엔지니어가 개발할 수 있지만, 모델의 성능을 보장하기 위해선 연구원의 개발과 지원이 꼭 필요합니다.

딥러닝 모델은 한번 개발되면 여러 사용자를 대상으로 추론하므로 실험할 때 항상 “실제 서비스”를 중점으로 두고 생각했습니다. AI 프로젝트에 적용할 때 연구원과 개발자 사이의 병목현상이 줄어드는 것만으로도 목표를 잘 달성했다는 생각이 듭니다.

--

--