본 글은 Coursera의 Machine Learning Engineering for Production (MLOps) 특화 과정의 일부인 Introduction to Machine Learning in Production 강좌의 내용을 개인적인 의견과 함께 정리한 글이다. 원 강좌 내용에 관심이 생긴다면 한번 수강해 보도록 하자!
Introduction
당신은 실제 세계의 문제를 풀기 위해 어떤 ML 모델을 개발했다. 그런데 이렇게 개발한 모델을 어떻게 배포하고 운영해야 할까? 또한 배포한 모델의 성능을 어떻게 모니터링하고, 어떻게 다시 개선시켜 배포할 수 있을까? ML 모델의 실제 배포와 운영은 모델 개발 단계에서와는 다른 직관과 스킬을 요구하며, 모델 개발 단계에서는 전혀 생각하지 못 했던 새로운 문제들을 마주하게 된다.
한번 공장 라인에서의 결함 검사 예시를 통해 간략하게 느낌을 알아보자.
컴퓨터 비전 알고리즘을 이용해 휴대폰 제품 사진에서 결함 영역을 bounding box 형태로 찾아내고, 이 결함이 acceptable한 수준인지 판단을 해야 하는 상황을 생각해 보자.
먼저 실제 공장에 놓여져 카메라로 제품 사진을 수집하고, 생산 라인을 컨트롤 할 수 있는 edge device가 필요할 것이다. 그리고 edge device가 API 호출의 형태로 데이터를 쏘아 주면, 이를 받아 실질적인 추론을 내릴 수 있는 prediction 서버도 필요하다. 우리가 학습한 모델은 이곳에 들어가게 된다. 추론 결과를 다시 edge device로 반환해 주면, edge device는 prediction 결과에 따라 라인을 멈춘다던지의 적절한 제어 명령을 수행하게 된다.
여기서 prediction 서버는 edge device의 형태로 공장에 물리적으로 놓여져 있을 수도 있으며, 클라우드 서버의 형태로 공장 외부에서 추론 결과만을 반환해 줄 수도 있다. 전자의 경우 가용 연산량에 (CPU, GPU) 한계가 뚜렷하지만 보안 등의 문제로 인해 공장 내부에서 외부망 접속이 힘든 경우에 유용하며, 통신 환경에 비교적 덜 취약하다는 장점이 있다. 후자의 경우 반대로 통신 문제에 취약하다는 단점이 있지만, 사용 가능한 연산 리소스의 제한이 덜하다는 장점이 있다.
우리가 위와 같은 edge device와 prediction 서버로 이루어진 결함 검사 시스템을 전부 구축했다고 해 보자. 이제 끝난 걸까? 학습해 놓은 모델을 올려 놓고 손을 떼면 되는 걸까? 슬프게도 모델 개발 과정에서 테스트 셋에서 최상의 성능을 보이던 모델을 적용했을 때 실제 추론 결과는 실망스러울 수 있다.
예를 들어 휴대폰 생산 공장의 조명 상태가 변화해, 이전의 학습 데이터와 비교해 사진이 전체적으로 어둡게 찍혔다고 가정해 보자. 위의 사진을 기준으로 왼쪽 사진을 OK, 중간 사진처럼 하얀 스크래치가 나 있는 경우를 NG 클래스로 판정하도록 학습해 놓았을 때, 오른쪽 사진과 같이 어두운 환경에서 촬영된 스크래치 이미지를 제대로 NG 클래스로 판정하지 못 할 가능성이 크다. 이런 식으로 수집되는 데이터의 분포가 학습 분포에서 멀어지는 현상을 Data drift라 칭한다.
이런 류의 문제는 물론 모델 개발을 하는 입장에서는 굉장히 억울한 상황일 것이다. 아무 언질 없이 학습 셋에서 완전히 동떨어진 데이터를 인퍼런스 데이터로 넣고, 성능과 관련한 컴플레인이 쌓이니 억울할 수 밖에 없다. 하지만 프로젝트를 맡은 입장에서는 이런 문제가 생겼을 때 상황을 탓하는 것도 좋지만 어떻게든 문제를 해결해 내야만 한다..
위의 deployment system 에서도 봤듯이, 실제 라인에서의 제품 인퍼런스 시스템에서 실질적으로 모델 추론이 차지하는 부분은 크지 않다. 코드 분량으로 따진다면, 전체 분량에서 ML 모델의 코드가 차지하는 분량은 고작 5~10% 정도밖에 되지 않는다. 이를 'POC to Production Gap' 이라 부른다.
이만큼, 실제 배포와 운영까지 포함된 ML 프로젝트에서는 ML 알고리즘 자체도 물론 빼놓을 수 없는 부분인 것도 사실이지만, 알고리즘만을 잘 개발해 놓는다고 끝이 아니라 모델을 원활하게 이용할 수 있게 해 주는 다른 구성요소들이 다같이 필요하며 이 부분들을 잘 구축해 놓는 것 또한 중요하다는 것이 핵심이다.
Steps of an ML Project
그렇다면 일반적인 ML 프로젝트의 흐름은 어떤 식으로 구성되어 있길래 저렇게나 많은 부수적인 requirements가 있는 지 한번 알아보자.
일반적인 ML 프로젝트의 라이프사이클은 위와 같이 Scoping - Data - Modeling - Deployment 로 이루어져 있다. Scoping은 문제를 정의내리는 단계로, 어떤 데이터로부터 어떤 결과를 도출해야 하는 지를 결정하는 단계라 보면 된다. Data는 필요한 데이터를 특정짓고 (feature 등), 베이스라인을 선정과 데이터 라벨링, 데이터셋 구축을 포함하는 단계이다. Modeling은 모델을 학습시키고 벤치마킹하며, 결과를 분석해 최적의 모델을 선정하는 단계이다. 최종 단계로 들어가기에 앞서, 최종적인 모델 성능을 측정하는 단계도 여기에 포함된다. 만약 모델 개발에 추가적인 데이터가 필요하다고 판단되면, 다시 Data 단계로 돌아가 필요한 데이터나 feature를 추가로 수집할 수 있다. 마지막 Deployment 단계까지 오면 절반 정도는 끝난 것이다! 나머지 절반의 노력은 실제 현장에 모델을 적용해 가며, 일어날 수 있는 문제를 점진적으로 파악해 가며 원하는 성능 수준을 현상 유지 시키는 데에 들여야 한다. 모델의 실제 현장 적용 시엔 분명히 소프트웨어적으로나 알고리즘적으로나 문제가 발생하기 마련이기 때문에, Deployment 단계에 들어선 이후 많은 시간을 시스템 유지보수에 소비해야 한다. 이 단계에서는 앞서 언급한 Data drift와 같은 문제들도 함께 고려해야 하며, 필요하다면 Data 단계로 들어가 drift에 대응하거나, Modeling 쪽으로 돌아가 업데이트 된 데이터셋에서 더욱 적합한 모델을 탐색하게 될 수 있다.
여기서 중요한 점은, ML 프로젝트 라이프사이클은 Scoping - Data - Modeling - Deployment 의 네 단계를 순차적으로, 반복 없이 거쳐가는 것이 아닌, 언제든지 단계 진행 중 문제가 발생하면 이전의 단계로 되돌아가 과정을 반복할 수 있는 Directed Acyclic Graph 와 같은 형태라는 것이다. 모델 개발에 필요한 데이터셋을 한번 구축하고 나서, 해당 셋에서 최상의 모델을 찾아내고 배포한 후 끝나는 것이 아니라 언제든 모델 배포 후 새로운 데이터를 수집할 수 있으며, 그에 따라 배포할 모델 또한 유동적으로 바뀔 수 있다는 것을 프로젝트 진행 시 염두에 두어야 한다.
Case study: Speech Recognition
마지막 Speech Recognition 예시를 통해 위에서 언급한 라이프사이클 단계들을 디테일하게 살펴보고 끝내자.
음성 검색을 위한 speech recognition 프로젝트를 진행한다고 해 보자. Scoping 단계에서는 time series 형태의 음성 데이터를 받아 텍스트 시퀀스 형태의 recognition 결과를 추론해 내는 문제를 정의내릴 것이며, 결과 평가를 위한 메트릭을 여러 사항을 고려해 선정하게 될 것이다. 결과 자체의 정확도 (accuracy)가 평가 지표에 들어가고, 데이터를 전송했을 때 얼마나 짧은 시간 안에 추론 결과를 얻을 수 있는 지 (latency) 또한 상황에 따라 고려할 수 있다. 또한 많은 수의 사용자가 예상된다면, 시스템이 동시에 얼마나 많은 요청을 처리할 수 있는 지 (throughput)도 평가 지표에 포함될 수 있다. 그리고 프로젝트의 대략적인 타임라인을 설정하고, 이 과정에서 얼마나 많은 비용이 들어갈 지 산정해 놓는 작업도 포함시킬 수 있다.
Data 단계에서는 데이터를 정의하고, 베이스라인을 선정하며 데이터 라벨링을 진행하게 된다. 이 과정에서 가장 크게 문제가 되는 것은 데이터 일관성이다. Speech recognition 케이스를 예시로 들자면 문장 사이에 잠시 멈추는 구간을 어떤 형태로 라벨링 할 지 ( , 혹은 ... 등), 음성 데이터 앞뒤로 얼마나 많은 공백 구간을 포함시킬 것인지, 또는 음성 데이터를 어떤 식으로 normalize 할 것인지가 데이터 수집 시 합의가 되어 있어야 한다. 비일관적인 데이터 혹은 라벨로 인한 문제 자체의 ill-posedness는 모델 성능에 큰 영향을 미치기 때문이다. 학계에서는 사용 가능한 데이터셋이 완전히 고정되어 있다고 가정하고 프로젝트를 진행하지만, 실제 ML 프로젝트에서는 언제든지 데이터를 추가/삭제하고 데이터셋 구성을 필요에 따라 변화시켜 모델 성능을 올릴 수 있다는 것을 알아두어야 한다. 데이터셋의 퀄리티를 체계적으로 유지하기 위해 데이터 관리 툴을 도입하는 것도 고려해 볼 수 있다.
Modeling 단계에서는 ML 모델을 개발하고, 결과를 분석하게 된다. ML 모델은 크게 알고리즘 자체와 관련된 하이퍼파라미터들, 그리고 학습에 쓰이는 데이터 이렇게 세 가지 구성요소의 조합으로 최종 성능을 내게 되는데, 앞서 언급했듯이 데이터 쪽을 고정시키고 알고리즘 자체와 하이퍼파라미터만을 튜닝하는 학계의 프레임워크와 달리 (Model centric), ML 프로젝트에서는 학습을 위한 데이터 쪽도 유동적으로 수정할 수 있다. 따라서 모델은 단순히 SOTA 알고리즘 중 적합한 것을 빠르게 도입하고, 학습 데이터 쪽을 지속적으로 개선해 최적의 성능을 이끌어 내는 것도 (Data centric) 매우 효율적인 Modeling 방향이 될 수 있다.
학습 데이터를 보완할 때에는 단순히 수집되는 데이터를 몽땅 데이터셋에 이어붙이는 것이 아니라, 모델의 결과로부터 error analysis를 진행해 어떤 데이터가 추가로 필요한지, 어떤 feature가 유의미하게 작동하며 어떤 feature가 추가적으로 필요할 것인지를 분석한 후 그에 맞는 데이터를 보완하는 것이 효율적인 방향이다.
마지막 deployment 스텝에서는 모델을 배포하고 모델 성능을 모니터링 하게 된다. 이 때 edge device에서 실제 음성 데이터를 수집하고 prediction 서버로 API를 통해 쏘아주기 위해, 마이크와 함께 Voice Activity Detection (VAD) 모듈과 같은 추가적인 모듈이 필요할 수 있으며 이들을 통합하기 위한 프론트엔드 코드도 작성되어야 할 것이다. 그리고 이 단계에서 기존 모델 개발 과정에서 생각지 못 했던 data drift와 같은 문제가 생길 수 있으며, 모델을 크게 바꾸지 않으면서도 성능을 유지할 수 있도록 배포 과정에서 데이터를 수집하고, 다시 Data 스텝으로 넘어가 모델을 개선하는 과정을 반복할 수 있다. 이 과정을 최대한 자동화하는 것이 효율적인 ML 시스템 운영의 핵심이 될 것이다.
이번에는 실제 문제를 풀기 위해 ML 알고리즘을 적용할 때 고려해야 할 사항들과, 일반적인 ML 프로젝트 라이프사이클이 어떻게 진행되는지에 대해 (정말) 개괄적으로 알아봤다. 앞으로는 라이프사이클의 세부 스텝들을 하나씩 설명할 것이며, 첫 시작은 Deployment가 될 것이다.
- Class 1: Production ML 시스템의 전체적인 라이프사이클 ← 현재 강좌
- Class 2: Data 파이프라인
- Class 3: ML modeling 파이프라인
- Class 4: Deployment 파이프라인
References
Machine Learning Engineering for Production (MLOps) 강좌 링크
https://www.coursera.org/specializations/machine-learning-engineering-for-production-mlops