배민 앱에도 AI 서비스가? AI 서비스와 MLOps 도입기
ChatGPT의 등장으로 전 세계적으로 AI 서비스에 대한 관심이 높아졌습니다. 과연 ChatGPT와 유사한 AI 서비스가 우아한형제들에서도 있을까요? 없을까요? 🤔 (생각할 시간 3초 …) 정답은 있습니다!! 😎
우아한형제들 서비스 이곳저곳에 ‘누가 허위로 리뷰를 작성을 하는지 예측’, ‘음식이 언제 도착하는지 예측’ 등 수십 개의 AI 서비스가 이미 적용되어 있습니다.
[그림 1] 배민 앱에 적용된 AI 서비스 ‘음식이 언제 도착하는지 예측(배달 예상시간/고객 안내시간)’
배민 앱 곳곳에서 사용 중인 AI 서비스 개발 과정은 다음과 같이 크게 3단계로 나눌 수 있습니다.
- 데이터 준비
- AI 생성
- 서비스에 AI 적용
AI 서비스를 개발하는 과정은 크게 3단계로 나눌 수 있지만, 세부적으로 필요한 단계를 내부에서 정의해 보면 50단계 이상이나 됩니다. 많은 단계를 수동으로 처리하면 매우 비효율적이고 서비스 적용까지 많은 시간이 소요됩니다.
이 글에서는 어떻게 비효율적인 단계를 줄여 나갔는지, 그리고 효율적으로 AI 서비스를 개발할 수 있게 고민한 결과는 무엇인지 AI 엔지니어 관점에서 살펴보겠습니다.
먼저 AI 서비스의 주요 개념과 MLOps의 필요성을 설명하고, 두 번째로 AI 서비스 개발 과정을 함께 살펴보면서 이해를 높이고자 합니다. 세 번째로는 MLOps를 도입하면서 고민한 내용을 공유하고, 마지막으로는 우리가 구성한 MLOps를 소개합니다.
1. AI 서비스 개념과 MLOps 도입 배경
AI 서비스를 이해하려면 모델에 대한 이해가 필요합니다. 머신러닝 모델의 정의는 조직마다 다양하지만, Microsoft에서 작성한 이해하기 쉬운 정의는 다음과 같습니다.
"Machine Learning model is a file that has been trained to recognize certain types of patterns.”
이처럼 모델은 데이터를 통해 특정 유형의 패턴을 인식하도록 학습된 파일을 의미하고, 이렇게 생성된 모델 파일을 서비스에 적용하고 있습니다.
그럼 모델은 누가 만들고 서비스에는 누가 적용할까요? 데이터 과학자는 모델 생성을 담당하고, 엔지니어는 데이터 과학자가 품질 좋은 모델을 빠르게 만들 수 있게 필요한 기능을 제공하고 만든 모델 서비스에 적용하고 있습니다.
높은 품질의 모델을 신속하게 개발하고, 지속적으로 운영 가능한 AI 서비스를 구축하려면 MLOps(Machine Learning Operations)가 필요합니다. MLOps는 머신러닝 엔지니어링 문화와 방식으로, 머신러닝 시스템 개발(Dev)과 시스템 운영(Ops)을 통합하여 안정적이고 효율적인 머신러닝 모델 배포와 유지 관리가 목표입니다.
MLOps는 아래 [그림 2] 처럼 Machine Learning, DevOps, 그리고 Data Engineering의 교차점에 있습니다.
각 분야에 대한 대략적인 설명은 아래와 같습니다.
Machine Learning
: 데이터를 분석하고 학습하여 AI 모델을 생성하는 분야Data Engineering
: 데이터를 수집, 저장, 처리 및 분석하는 기술을 개발하는 분야DevOps
: 소프트웨어 개발에서 자동화, CI/CD(지속적인 통합 및 지속적인 배포)와 같은 개발 프로세스를 자동화하고 팀 간 협력을 강화하여 개발 프로세스를 효율화하는 분야
[그림 2] MLOps는 Machine Learning, DevOps 및 Data Engineering 교차점에 위치
출처: MLOps, Wikipedia
세 가지 분야의 교차점에 있는 MLOps는 머신러닝 모델의 개발, 테스트, 배포, 그리고 관리 전 과정을 자동화하고 최적화하여 더욱 빠르고 효율적인 머신러닝 솔루션을 만드는 것을 목표로 합니다.
MLOps는 소프트웨어 개발의 DevOps와 유사한 방식으로 모델을 관리하며, 데이터 엔지니어링 기술을 이용해 데이터를 처리하고 저장합니다. 이를 통해 머신러닝 모델을 운영환경에서 안정적으로 운영할 수 있으며 더 나은 비즈니스 결과를 달성할 수 있습니다.
MLOps 필요성에 대한 논문으로 2015년 NIPS 학회에서 발표된 Hidden Technical Debt in Machine Learning Systems과 2023년 IEEE에서 발행된 Machine Learning Operations (MLOps): Overview, Definition and Architecture를 예로 들 수 있습니다.
첫 번째 논문에서는 기업과 조직이 머신러닝 알고리즘을 적용할 때 발생할 수 있는 숨겨진 기술 부채에 대해 언급합니다. 아래 [그림 3]에서는 머신러닝 코드는 중요하지만 머신러닝 전체 시스템을 고려하면 매우 작은 부분을 차지하고 있으며 주변 인프라의 복잡성에 대해서 설명하고 있습니다.
[그림 3] 머신러닝 시스템의 구성 요소
출처: Hidden Technical Debt in Machine Learning System, Figure 1
머신러닝 모델을 개발하고 배포하는 것은 비교적 빠르고 저렴하지만, 시간이 지남에 따라 유지보수하는 것이 어렵고 비용이 많이 드는 경향이 있습니다. 또한 머신러닝 시스템의 부채는 대부분 코드 레벨보다 시스템 레벨에서 존재합니다. 두 번째 논문에서는 머신러닝 워크플로를 수동으로 수행할 때 발생하는 문제와 실제 운영환경에서의 ML PoC(Proof of Concept) 실패에 대해 다루고 있으며, 이러한 어려움을 MLOps를 통해 극복할 수 있다고 언급합니다. 머신러닝 시스템 부채, 수동으로 할 때 발생하는 문제, 그리고 ML PoC 실패를 해결하기 위해 우아한형제들도 MLOps를 도입해 이를 해결하고 있습니다.
MLOps를 도입한 과정을 설명하기 전에 먼저 AI 서비스와 MLOps를 이해할 수 있게 AI 서비스를 간단히 만들어 보겠습니다.
2. AI 서비스 함께 만들어보기
여러분이 서비스를 기획하고 관리하는 PM(Product Manager)이나 PO(Project Owner)라고 생각하고 ‘음식 배달이 언제 도착할까?’를 주제로 서비스를 만들어 보겠습니다. 모델을 만드는 방법론은 다루지 않고, 모델이 서비스까지 적용되는 과정을 중심으로 설명하겠습니다.
서비스를 만드는 과정은 아래와 같습니다.
데이터 준비
: 배달 관련 데이터를 서비스팀에 요청하고 가져오기모델을 생성
: 배달 소요 시간을 예측하는 모델을 개발하고 테스트서비스에 모델을 적용
: 모델을 배포하고 배달 서비스팀과 협의하여 서비스에 적용하고 모니터링
위 과정을 거쳐 음식 도착 예측 서비스를 완성했지만, 서비스를 운영하다 보면 다양한 문제가 발생할 수 있습니다. 그중에서도 모델의 품질과 재현성 문제가 있을 수 있는데, 이 문제는 어떻게 해결할 수 있는지 알아보겠습니다.
첫 번째 문제는 모델의 품질입니다. 모델을 서비스에 적용한 후 점차 시간이 지나면 모델은 최신 데이터를 예측할 능력이 부족하기 때문에 품질이 낮아지게 됩니다. 따라서 주기적으로 최신 데이터를 이용하여 모델을 재학습하고, 모델의 품질을 유지해야 합니다. 품질을 유지하려면 데이터 준비부터 모델 서비스에 적용 작업까지인 위 1~3번 과정을 지속적으로 수행하여, 새로운 데이터를 기반으로 주기적인 모델 재학습을 수행해야 합니다. 지속적인 학습을 수행하기 위해서는 워크플로를 관리하는 플랫폼을 도입하고 파이프라인(데이터 전처리, 모델링, 평가 등 머신러닝 모델을 만들기 위한 과정을 순서대로 연결하여 자동화하는 프로세스)을 구축하여 머신러닝 라이프 사이클을 관리해야 합니다.
두 번째 문제는 모델의 재현성과 추적성입니다. 서비스가 원활하게 진행되다가도 갑자기 모델이 예상대로 동작하지 않는 경우가 발생할 수 있습니다. 이런 경우에는 모델 내부 동작을 분석하여 문제를 해결해야 합니다. 소스 코드, 데이터, 파라미터 등을 확인해야 하고, 확인을 위해서는 개발과 운영 환경에서 모델을 재현하고 추적하는 기능이 필요합니다.
재현성과 추적성의 개념은 아래와 같습니다.
🧪 재현성(reproducibility)
: 같은 데이터와 환경에서 모델을 재현할 수 있는 능력을 의미🔎 추적성(traceability)
: 모델이 생성된 후에도 모든 버전과 그에 대한 메타데이터를 추적할 수 있는 능력을 의미
모델의 신뢰성을 보장하기 위해서는 모델의 재현성과 추적성이 중요합니다. 이를 위해서는 모델을 만들기 위한 정보(예: 데이터, 아키텍처, 하이퍼파라미터 등)를 기록하고, 이를 위해 실험 추적 기술을 도입해야 합니다.
실험 추적은 머신러닝 모델 개발 과정에서 모든 버전과 그에 대한 메타데이터를 기록하는 기술을 의미합니다. 이를 통해 모델의 재현성과 추적성을 보장할 수 있습니다.
지금까지 ‘음식이 언제 도착할까?’ 모델을 기반으로 AI 서비스를 구현하면서 다양한 문제들을 해결해 보았습니다.
초기에 모델을 개발하고 적용하는 것으로 끝날 줄 알았으나, 서비스를 운영하면서 발생하는 문제들에 직면하였습니다.
모델/데이터 드리프트, 머신러닝 프레임워크, 모델 배포 방식, 데이터 사용 등의 요구사항에 따라 다른 문제들도 발생할 수 있습니다. 이러한 문제들을 모든 서비스마다 개발자들이 각자 해결한다면 중복되는 일이 생겨 비효율적입니다.
그래서 MLOps 플랫폼을 도입하여 공통적인 업무를 효율적으로 처리하고자 하였습니다. 우리의 미션은 ‘AI 서비스 개발자가 기술 기반으로 더 효율적으로 일할 수 있는 플랫폼을 구성해 AI 서비스 생산성과 품질을 향상시킨다’입니다.
지금부터 우리가 구성한 MLOps 이야기를 시작하겠습니다.
3. MLOps를 도입할 때 고민한 흔적들
저는 과거에 데이터 과학자로 일한 경험을 바탕으로 ‘지금 개발자들이 모델을 개발하고 서비스에 적용하기 위해서는 다양한 플랫폼이 필요할 것 같으니 하나씩 도입하자’라는 생각으로 문제를 정의하고 설계를 시작했습니다.
그러나 실제로는 플랫폼 지원보다 엔지니어링에 어려움을 느낀다는 것을 알게 되었습니다. 다행히 프로젝트 초기였기 때문에 개발자들의 요구사항을 다시 듣고 우선순위를 조정하였고, 지금은 미팅을 통해 지속적으로 목표를 맞추고 있습니다. 초기에 이런 미팅이 없었다면 아무도 사용하지 않는 플랫폼을 만들 뻔했네요.
MLOps 도입 및 구성 전 고려할 사항은 다음과 같습니다.
- 🎯 먼저 문제를 명확히 정의해야 합니다.
- 어떤 문제를 해결하고자 하는지 문제를 명확하게 하는 게 좋습니다. 예를 들어, 모델을 개발 환경과 동일하게 운영 환경으로 배포하기, 파이프라인 테스트 자동화를 위해 CI/CD 파이프라인을 구축하기가 있습니다.
- 🤝 협업을 통해 도움을 받아야 합니다.
- 이미 데이터 관련된 플랫폼이 구축된 상황에서는 데이터 플랫폼 관련 팀의 도움을 받는 것이 좋습니다.
- AI 서비스 개발을 하는 엔지니어나 과학자들의 문제를 듣고 함께 구성하세요. 문제 정의와 방향성 잡을 때 많은 도움이 됩니다.
- 📄 운영 정책을 정해야 합니다.
- AI 서비스 개발자가 모든 개발을 진행하고, 어려운 부분은 엔지니어가 지원하는 방향으로 진행하면서, MLOps 컴포넌트 개발에 집중할 수 있도록 운영 정책을 설정하는 것이 좋습니다.
- 서비스에서 모델을 적용할 때 엔지니어의 도움이 필요할 수 있으며, 이때 MLOps 컴포넌트 개발에 집중하기가 어려울 수 있습니다. 따라서 개발자들이 스스로 진행할 수 있도록 개발 환경, 교육, 가이드 문서 및 API 문서를 만들고 개선하는 노력이 필요합니다.
4. 우리가 구성한 MLOps 소개
MLOps를 구성하는 과정에서는 각 컴포넌트 및 플랫폼을 도입할 때 사용자가 더 쉽게 사용할 수 있도록 가이드 문서나 사용성을 고려하였습니다. 또한, AI 서비스 개발은 여러 팀 간의 협업과 전달이 필요한데, 이를 동기화하고 협력하는 상태를 유지하기 위해 운영 원칙이 필요했습니다. 따라서 AI 서비스 개발자들은 비즈니스 로직에 집중하고, 엔지니어는 플랫폼 개발에 집중할 수 있도록 플랫폼 구성 및 운영 정책을 만들어가고 있습니다.
초기 MLOps 도입 시, 서비스 개발자들의 의견 수렴뿐 아니라 참고할 자료가 필요해 MLOps: Continuous delivery and automation pipelines in machine learning와 Machine Learning Operations (MLOps): Overview, Definition, and Architecture를 참고했습니다. 이들 자료에서는 머신러닝 모델 개발 및 배포를 위한 MLOps의 개념, 구성요소, 그리고 MLOps의 레벨 3단계와 각 레벨의 특징에 대해 설명하고 있습니다. 참고 자료를 토대로 아래와 같은 작업을 초기 MLOps 도입 시 진행했습니다.
- MLOps 각 레벨별로 필요한 기능들을 나열
- 문제를 명확하게 정의
- 각 작업의 우선순위를 결정
MLOps는 레벨 0부터 시작되며, 레벨 0은 수동 프로세스를 의미합니다. 레벨 0에서는 데이터 과학자가 모델을 빌드하고 배포하는 과정이 완전히 수동으로 이루어지며, 이는 환경의 동적인 변화나 데이터의 변화에 대응하기 어려울 수 있습니다.
레벨 1은 머신러닝 파이프라인 자동화를 통해 지속적으로 모델을 학습하고 서비스에 제공하여 모델의 품질을 유지하는 것을 목표로 합니다.
마지막으로, 레벨 2는 CI/CD 파이프라인 자동화를 통해 데이터 과학자가 아이디어를 구현하고 파이프라인 구성 요소를 대상 환경에 자동으로 빌드, 테스트, 배포할 수 있도록 지원합니다. 이를 통해 데이터 과학자는 특성 추출, 모델 아키텍처, 하이퍼파라미터 등에 대한 새로운 아이디어를 빠르게 검증할 수 있습니다.
MLOps의 레벨이 높아질수록, 모델 생성부터 서비스 제공까지의 과정에서 소요되는 시간과 단계를 효율적으로 줄일 수 있어 많은 실험을 빠르게 진행할 수 있습니다. 이는 기술 기반으로 더 효율적으로 일할 수 있는 환경을 제공하여 AI 서비스 개발자의 생산성과 서비스 품질을 향상시킬 수 있습니다.
우리는 MLOps 레벨 2를 달성하기 위해 현재의 환경에서 문제를 정의하고, 이를 해결함으로써 AI 서비스 개발에 어떤 효과가 있을지 확인해야 했습니다. 따라서 다음과 같이 문제를 정의했습니다.
- 개발 환경과 운영 환경의 차이로 인해 문제가 발생할 수 있습니다.
- 파이프라인 구성이 복잡하고 어려워서 제대로 관리하지 못할 가능성이 있습니다.
- 모델링 코드 외에 다른 코드 작성 비용이 많이 들어갑니다.
- 운영 정책 및 가이드라인이 부족합니다.
먼저 개발에서 서비스 적용까지 소요되는 시간 중 가장 큰 부분을 차지하는 문제를 해결하는 데 중점을 두었습니다. 다음은 해결 방법을 설명합니다.
4.1 개발 환경과 운영 환경의 갭 줄이기
개발 환경과 운영 환경이 일치하지 않으면 운영 환경에 서비스를 배포하기 전에 환경을 일치시키는 작업이 필요합니다. 예를 들어, 개발 환경에서 사용했던 파이썬 버전과 의존성 패키지들을 운영 환경에서도 동일하게 설치해야 합니다.
프로젝트를 한 번만 배포한다면 환경을 동일하게 만드는 작업이 번거롭지 않을 수 있습니다. 그러나 여러 개의 프로젝트를 여러 번 반복해 배포해야 한다면 실제 개발보다 배포에 더 많은 시간이 소요됩니다. 서비스를 개발하는 개발 환경과 운영 환경을 일치시키기 위해서 아래와 같은 방법으로 문제를 해결하였습니다.
- AI 관련 소스 코드 저장소 ML Projects 도입
- 클라이언트 Docker 이미지 개발
- 프로젝트별 개발 환경 구성
결과적으로 모델을 개발하고 서비스까지 릴리스하는 프로세스를 간소화하는 효과를 얻을 수 있었습니다.
4.1.1 AI 관련 소스 코드 저장소 ML Projects 도입
AI 관련 소스 코드 저장소인 ML Projects를 도입했습니다. ML Projects는 AI 서비스 개발의 시작으로 AI 관련한 데이터 전처리, 모델 학습/예측, 결과 내보내기, 실험, 데모, 서빙 등 코드를 저장하는 곳입니다.
아래는 ML Projects의 디렉터리 구조와 각각의 역할에 대한 설명입니다.
# ML Projects 📁 구조
├── .gitlab-ci.yml # CI/CD를 위한 파일
└── 📁 projects
├── 📁 anomaly_detection # 1. 이상 탐지 프로젝트
│ ├── MLproject # entrypoint가 정의된 설정 파일
│ ├── 📁 config # 설정 값
│ │ └── python_env.yaml # python 환경에 대한 설정 파일
│ ├── 📁 notebook # Jupyter Notebook 파일
│ ├── 📁 demo # 데모 페이지 구성을 위한 코드
│ ├── 📁 serving # 서빙을 위한 코드
│ └── 📁 src # 전처리/학습/예측을 위한 코드
├── 📁 click_prediction # 2. 클릭 예측을 위한 프로젝트
│ ├── MLproject
│ ├── 📁 config
│ │ └── python_env.yaml
│ ├── 📁 notebook
│ ├── 📁 demo
│ ├── 📁 serving
│ └── 📁 src
└── 📁 time_estimation # 3. 시간 예측을 위한 프로젝트
├── MLproject
├── 📁 config
│ └── python_env.yaml
├── 📁 notebook
├── 📁 demo
├── 📁 serving
└── 📁 src
Rules of Machine Learning: Best Practices for ML Engineering Rules # 32 에서는 “Re-use code between your training pipeline and your serving pipeline whenever possible”이라는 규칙을 제시합니다. 가능한 학습 파이프라인과 서빙 파이프라인에서 코드를 재사용하라는 의미인데요. 이렇게 코드를 재사용하려면 모든 코드를 하나의 저장소에서 관리해야 한다고 생각했습니다.
예를 들어, 학습에 사용되는 전처리 코드는 서빙이나 데모에서 재사용됩니다. 만약 학습과 서빙에서 다른 전처리 코드를 사용하면 학습-서빙 편항(skew)이 발생하여 서비스 품질이 저하될 수 있으며, 원인 파악이 어려울 수 있습니다. 또한, 각 프로젝트마다 머신러닝 프로젝트의 코드와 환경을 하나의 묶음으로 관리함으로써, 다른 개발자나 다른 환경에서도 일관된 실행을 보장할 수 있습니다.
ML Projects는 모노리포 방식으로 모든 프로젝트를 통합하여 관리하고 있습니다. 모노리포 방식으로 관리하면 모든 프로젝트가 하나의 저장소에서 관리되기 때문에 통합 CI/CD 구성이 가능해집니다. CI/CD 컴포넌트를 이용하여 개발 및 운영에서 발생할 수 있는 공통 테스트, 빌드 및 배포 단계의 자동화와 특정 단계의 성공/실패 여부에 대한 빠른 피드백으로 제공함으로써 전체 프로세스의 생산성을 향상시킬 수 있었습니다. 또한, 현재 각 프로젝트별로 AI 서비스 개발자들이 자신의 코드를 커밋하고 머지를 통해 소스 코드를 공유하고 있습니다. 소스 코드를 공유하면 협업 및 지식 공유를 실현하면서 코드 품질 개선 및 코드 재사용성의 효과를 부수적으로 얻을 수 있습니다.
4.1.2. 클라이언트 Docker 이미지 개발
클라이언트 Docker 이미지는 모델을 개발할 때 필요한 여러 기능을 제공합니다. 현재는 프로젝트 실행, Jupyter Notebook, 그리고 데이터 조회 기능 등을 포함하고 있습니다.
프로젝트 실행 시에 개발한 소스 코드는 로컬 개발 환경이 아닌 컨테이너 환경에서 실행되며, 개발 환경에서 실행되는 컨테이너는 운영에서 실행되는 컨테이너와 동일한 환경을 보장합니다. 개발 환경과 운영 환경을 일치시켜 운영 배포를 위한 추가 작업이 없어졌습니다. 모든 코드가 컨테이너 환경에서 실행되기 때문에 확장성과 유연성 측면에서도 이점을 가집니다.
데이터 수요에 맞는 리소스 추정이 어려운 경우, 확장성 있는 학습 인프라가 필요합니다. 우리는 데이터플랫폼팀에서 구성한 EKS-A가 확장성 측면에서 장점이 있다고 판단했고, EKS-A 환경에서 CPU 또는 GPU 리소스를 유연하게 할당받아 컨테이너 내에서 학습을 진행하고 있습니다. 또한, 소스 코드를 변경하지 않고 컨테이너를 여러 개 띄우는 방식으로 하이퍼파라미터 튜닝도 가능해졌습니다.
4.1.3. 프로젝트별 개발 환경 구성
각 프로젝트는 파이썬 버전, 빌드 의존성, 패키지 의존성을 요구하기 때문에 각각의 프로젝트에서 별도로 환경을 관리할 필요가 있었습니다. 현재는 각 프로젝트에서 사용할 파이썬 버전, 빌드 의존성, 패키지 의존성을 명시하고, 이를 코드 실행 시에 사용하고 있습니다. 이를 통해 개발 환경에서 사용한 환경을 운영 환경에서 그대로 사용할 수 있으며, 하나의 클라이언트 Docker 이미지로 실행할 수 있게 되었습니다.
4.2. 파이프라인 구성을 효율적으로
모델을 만들고 서비스로 출시하기 위해서는 여러 프로세스로 구성된 파이프라인 필요합니다. 파이프라인이란 여러 단계의 작업을 순차적으로 연결하여 자동화하는 프로세스를 의미하는 것으로, 일반적으로 데이터 수집, 전처리, 특성 추출, 모델 훈련, 평가 및 모델 배포 단계로 구성됩니다. 이러한 파이프라이닝은 코드를 모듈화하고 재사용성을 높이며, 실험과 최적화를 쉽게 수행할 수 있습니다. 또한, 파이프라인을 자동화하고 확장할 수 있게 구현함으로써 프로세스를 더욱 효율적으로 관리할 수 있습니다.
# YAML로 작성한 파이프라인
dag:
description: Time Estimation Service
schedule_interval: 0 6 * * *
tasks:
generate_dataset: # 학습 데이터를 만들기 위한 태스크
operator: Spark # 수행하는 오퍼레이터
query: INSERT OVERWRITE ... AS SELECT ...
preprocess: # 전처리를 위한 태스크
args: # 파라미터
category_features:
- id
- shop_id
numeric_features:
- distance
dependencies: [generate_dataset] # 의존성 추가
train_model: # 학습을 위한 태스크
args:
learning_rate: 0.001
epoch: 3
dependencies: [preprocess]
eval_model: # 검증을 위한 태스크
args:
metric: accuracy
dependencies: [train_model]
deploy_model: # 모델을 배포하기 위한 태스크
dependencies: [eval_model]
파이프라인은 배포하는 단위가 되며, 배포된 파이프라인은 지속적으로 설정된 스케줄로 실행됩니다. 우아한형제들에서는 파이프라인을 생성하고 관리를 효율적으로 구성하기 위해 자체 개발한 Pipeline Builder(이하 PB) 패키지를 사용합니다. PB는 DagFactory와 Kustomize 방법론을 참고하여 YAML 형태로 작성된 파이프라인을 환경에 따라 동적으로 생성합니다.
🦾 PB를 이용해 파이프라인을 구성했을때, 아래와 같은 장점이 있습니다.
코드 재사용성
: 동적으로 생성되는 파이프라인을 재사용할 수 있습니다. 예를 들어, 동일한 작업을 수행하는 파이프라인이 많은 경우 파이프라인 생성 코드를 함수화하고 인자를 조정해 동적으로 파이프라인을 만들 수 있습니다.확장성
: 동적으로 생성되는 파이프라인은 특정 이벤트나 조건에 따라 파이프라인을 추가하거나 제거할 수 있습니다. 이를 통해 시스템의 확장성을 높일 수 있습니다.코드 관리 용이성
: 동적으로 생성되는 파이프라인은 코드 관리를 쉽게 할 수 있습니다. 파이프라인 생성 코드를 수정하면 모든 파이프라인을 동시에 변경할 수 있으며 파이프라인 코드를 한곳에서 관리할 수 있습니다.코드 유연성
: 파이프라인 생성 코드에서 변수나 조건 등을 수정하여 파이프라인의 동작을 변경할 수 있습니다. 이를 통해 파이프라인을 더욱 유연하게 제어할 수 있습니다.자동화 가능성
: 새로운 파이프라인을 생성할 수 있습니다. 이를 통해 자동화된 프로세스를 구현할 수 있으며 더욱 효율적으로 작업이 가능합니다.
4.3. 데이터 과학자는 모델 개발에 집중하게
실제 AI 서비스를 개발하기 위해 작성해야 하는 코드는 데이터 로드, 모델 빌드, 모델 학습, 결과 저장 등 다양한 과정을 포함합니다. 이러한 코드에는 공통으로 개발하는 기능들이 있습니다.
우리는 SDK를 통해 공통 기능들을 제공하여 데이터 과학자가 모델의 핵심 알고리즘에 집중할 수 있는 환경을 만들기 위해 노력하고 있습니다. SDK를 제공함으로써 코드 재사용성을 극대화하고 모델 생성 및 서비스 적용에 필요한 시간을 단축할 수 있습니다. 그럼 공통 기능에는 무엇이 있을까요?
- 데이터를 업로드/다운로드 기능
- 실험 설정 및 기록
- 전처리(데이터 정제/변환/스케일링 등)
- 대규모 데이터 입력 파이프라인
- 피쳐 스토어(Feature Store) 연동
- 각종 환경별 설정값 관리
데이터 과학자에게 설문조사를 진행한 결과, 데이터 업로드/다운로드 기능이 번거로운 과정 중 하나였습니다. 데이터 과학자가 직접 구현하지 않아도 학습에 필요한 데이터를 다운로드하고, 결과를 업로드하는 기능을 SDK로 제공했습니다.
데이터 과학자는 반복적인 실험을 통해 최종 모델을 선택합니다. 이 과정에서도 SDK가 사용되며, 데이터 과학자는 SDK를 통해 실험을 생성하고, 생성된 실험 이력은 SDK를 통해 DB에 저장하고 있습니다. 반복적인 실험을 수행한 이후에는 웹 페이지에서 실험 정보와 결과를 확인할 수 있습니다. 실험 설정 및 로깅을 통해 모델의 재현성과 추적성을 보장할 수 있으며, 실험을 통해 생성된 아티팩트(예: 모델, 환경 정보 등) 또한, 관리할 수 있습니다.
SDK를 설계하고 개발할 때 가장 중요하다고 생각하는 것은 데이터 과학자와 엔지니어의 기여라고 생각했습니다. 초반에는 소수의 MLOps 개발자가 기능을 구현했지만, 이제는 과학자와 엔지니어가 함께 구현하고 있습니다. 또한, 외부 플랫폼을 도입할 때도 SDK를 통해 쉽게 개발할 수 있도록 기능을 제공하고 있습니다.
현재도 AI 서비스를 개발하면서 필요한 공통 기능들을 추가 및 사용하고 있고, 주기적으로 데이터 과학자들에게 필요한 기능이 무엇인지, 작업 중에 가장 번거로운 부분을 파악하여 새로운 기능을 추가하고 있습니다.
4.4. 간결한 가이드
“간단하게 설명할 수 없다면 충분히 이해하지 못한 것이다" – 알베르트 아인슈타인
우리의 목표는 쉽고 간결하게 설명할 수 있는 플랫폼을 만드는 것입니다.
[그림 4] MLOps 플랫폼 가이드 문서
가이드 문서를 작성해 보면서 우리 플랫폼의 사용성에 대해서도 부족한 점을 고민해 보고 그 고민들이 과제로 이어지고 있습니다.
개발자들이 플랫폼을 쉽게 사용할 수 있도록 작성된 운영 정책, 컴포넌트에 대한 설명, 예제 및 FAQ 등을 제공하고 있습니다. 잘 작성한 가이드를 제공해 운영 리소스를 줄이면서 MLOps 핵심 기능 개발에 집중할 수 있는 환경을 만들고 있습니다.
5. 마치며
지금까지 AI 서비스가 개발되는 과정, MLOps의 필요성, 그리고 우아한형제들이 구성한 MLOps에 대해서 설명했는데요. 이 글이 AI 서비스를 만드는 데 많은 도움이 되었으면 좋겠습니다.
우아한형제들의 궁극적인 목표는 데이터 과학자 뿐만 아니라 우아한형제들 구성원들도 쉽고 빠르게 AI 서비스를 개발하고 서비스하는 환경을 만드는 것입니다. 현재 목표 달성을 위해 플랫폼 성능과 사용자 경험/생산성 향상
과 플랫폼의 새로운 기능과 서비스 개발 및 확장
에 집중하고 있습니다.
마지막으로, MLOps 플랫폼을 통해 AI 서비스 생산성과 우아한형제들의 모든 서비스 품질이 올라가는 모습을 상상하며 앞으로 더 흥미로운 주제로 찾아뵙겠습니다. 🎈