백엔드 N년차 MLOps 1일차 — MLOps 아키텍쳐 설계

Sunwoo Park
13 min readJun 23, 2024

--

지난시간 TODO였던 드론영상 EDA 결과에 대해 팀원들이 돌아가면서 공유하기 시작하였다. 각자에게 할당된 드론영상을 확인하고 엣지 또는 코너 케이스 발생이 예상되는 부분에 대해 정리한 내용들을 이야기했다.

  • 빛반사가 심해 윤슬과 돌고래가 만드는 물보라가 구분되지 않는 경우
  • 오히려 빛 반사와 반대로 어두운 경우
  • 돌고래와 바다의 돌을 혼동하거나 바다이다보니 해녀와 부표가 등장하는 경우
  • 돌고래가 바다속에 들어가는 경우 돌고래 그룹 전체 모양이 크게 흔들릴수도 있을 것 같음

이러한 부분들이 제대로 해결되지 않는다면 사용자의 신뢰도를 잃을수도 있어 문제 요소들을 완화할수 있는 방법과 서비스시 주의할 사항에 대해서 논의가 진행되었다.

돌고래 떼가 있는 경우에 선박과의 거리를 어떠한 기준으로 측정할 수 있을까?
선박과 가장 가까이 있는 돌고래를 기준으로 한다면
돌고래의 움직임에 따라 각각의 개별 거리를 계산해야해서 계산량이 많아질 것이다.
따라서 돌고래를 그룹화하고 돌고래 그룹의 중심과 선박과의 거리를 측정하는 것으로 진행한다.

엣지케이스를 미리 구분해 정리할 수 있다면 기획을 통해
사용자 선에서 제약이 필요한 부분과 엔지니어링으로 해결할 부분을 정리할 수 있을 것이다.
전자라면 사용자에게 미리 안내하여 신뢰도를 높이는 방향으로 진행할 수 있다.

또한 검출 모델의 인풋을 사전에 제한하여 (바다/ 바다X) 결과물의 신뢰도를 높이는 것도 하나의 방법이 될 것이다.

서비스에서 사용하는 데이터셋을 직접 들여다보고 확인해봄으로써
MLOps 역할이나 시스템 아키텍쳐를 구성할때에 이해도를 높이고 좀 더 디테일한 부분을 고려해야겠다고 생각했다.

Photo by Lachlan Dempsey on Unsplash

다음으로 현재 구현되어 있는 MVP 버전의 모듈별 소요시간 분석과 모델경량화에 대한 이야기가 이어졌다.

모듈별 소요시간을 측정했을때 2274s 가 소요되었으며
그중에서 가장 시간이 많이 소요되는 모듈은 Detection(YOLOv8.pt) 로
1383s 가 소요되어 전체시간의 60% 정도를 차지하고 있었다.

Frame Parsing : 90.18s
Log Sync : 3.18s
Detection(YOLOv8.pt) : 1383.42s
Detection(YOLOv8.trt) : 793s
Tracking : 1.34s
BEV (user input frame) : 3s

모델 경량화 방법 중에는 양자화가 있으며 양자화된 모델은 원본 모델과 거의 같은 정확도를 내면서, 사이즈가 줄어들고 추론 속도가 빨라진다.
양자화 작업은 서버 모델과 모바일 모델 배포에 모두 적용될 수 있지만,
모바일 환경에서 특히 중요하고 매우 필요하다.

그 이유는 양자화를 적용하지 않은 모델의 크기가 iOS나 Android 앱이 허용하는 크기 한도를 초과하고, 그로 인해 모델의 배포나 OTA 업데이트가 너무 오래 걸리며, 또한 추론 속도가 너무 느려 사용자의 쾌적함을 방해하기 때문이다.

알려진 양자화 구현방법과 간단한 소개는 다음과 같다.

  • PyTorch Quantization:
    PyTorch는 일반적인 FP32 모델에 비해 INT8 양자화를 지원하므로 모델 크기를 4배 줄이고 메모리 대역폭 요구량을 4배 줄일수 있다.
    INT8 연산을 위한 하드웨어 지원은 일반적으로 FP32연산에 비해 2~4배 빠르다. 양자화는 주로 추론 속도를 높이기 위한 기술이며 양자화된 연산자에는 포워드 패스만 지원된다.
  • TensorRT Quantization/Pruning:
    NVIDIA에서 개발한 딥러닝 추론 최적화 라이브러리, NVIDIA GPU에서만 사용가능하다.
  • NAS
    Once for all은 Neural Architecture Search (NAS) 기법 중 하나로, 모델 경량화를 위해 사용된다. Once for all 은 특정 하드웨어에 종속되지 않는다.

이어서 MLOps 아키텍쳐 설계를 위한 논의가 시작되었다.

아키텍쳐를 설계한다는 것은 무엇일까?

모든 서빙 아키텍처의 목표는 최소한의 기능을 구현하는 것.
가장 복잡하지 않고 가장 저렴한 솔루션을 구축하면서도
모델 결과물의 활용에 필요한 요구 사항을 충족하는 것이 되지않을까

프로젝트 요구사항을 정리해보고 아키텍쳐의 큰 흐름을 작성해본다.

  • 드론 영상이 업로드되면 데이터 수집 및 전처리 단계를 거침
  • 전처리된 데이터는 레이블링되고 버전 관리
  • 레이블링된 데이터를 사용하여 MLOps 파이프라인에서 모델을 학습하고 평가
  • 학습된 모델은 모델 서빙 컴포넌트를 통해 배포
  • 모델 성능과 시스템 지표는 모니터링되며, 이상 징후 발생 시 알람이 전송
  • CI/CD 파이프라인은 MLOps 파이프라인과 모델 서빙 컴포넌트의 자동화된 빌드, 테스트, 배포를 담당

업로드부터 시작해서 데이터 수집 및 전처리, MLOps 파이프라인, 모델서빙까지의 일련의 작업을 우선순위를 높여 먼저 진행하고 이후 CI/CD 구성 및 모니터링/알람 구축을 그 다음으로 이어서 진행하려고 한다.

상세 아키텍쳐를 구성하기 전 고려해야할 사항들을 나열해본다.

  1. 모델 아티팩트(Artifact)를 어떻게 관리할 것인가?
    - MLflow 의 모델 레지스트리를 사용하거나
    - Wandb 를 활용하거나
  2. 피쳐 스토어, 데이터 레이블링 및 버전관리 구성을 어떻게 할 것인가?
    - 데이터 레이블링 오픈소스에는 CVAT, Label Studio 등이 있고
    - 데이터 버전관리에는 DVC가 있음
  3. 서빙 아키텍쳐를 구성할때에 SLA, 비용, 최신성 요소를 고려한다면
  • SLA 및 예측 볼륨 고려 사항
예측 사용 패턴 | 예측 볼륨 | SLA 및 볼륨에 대한 일반적인 아키텍처 권장 사항
-----------------------------------------------------------
시간/일/주 단위 | 낮음 (시간당 1~100) | CRON 예약 배치
시간/일/주 단위 | 보통 (시간당 1K~100K) | CRON 예약 배치
시간/일/주 단위 | 높음 (시간당 100K 초과) | 스트리밍 마이크로배치
즉시 | 낮음 (시간당 1~100) | REST API 마이크로 서비스
즉시 | 보통 (시간당 1K~100K) | REST API 마이크로 서비스
즉시 | 높음 (시간당 100K 초과) | 탄력적 REST API

표 기준으로 예측 사용 패턴은 “즉시”에 해당하며
예측 볼륨은 사용자 업로드 수에 따라 다르겠지만 예상하건데
“낮음 또는 보통” 정도일 것이다.
따라서 SLA 및 볼륨에 대한 일반적인 아키텍쳐 권장사항은
REST API 마이크로 서비스” 에 해당한다.

  • 데이터 최신성 및 사용 패턴 고려 사항
추론 데이터 '최신성' (데이터 생성부터 예측 사용) | 사용 패턴 | 아키텍처 요구 사항 설명
------------------------------------------------------------------------
대량 데이터 전송 (시간/날/일별) | 분석/인과적 모델링 | OLAP로 배치 처리 CRON
대량 데이터 전송 (시간/날/일별) | 자동화된 의사 결정 엔진 | OLAP로 쓰기 람다 DAG 실행
스트리밍 수집 | 대규모 분석 | 마이크로 배치로 OLAP로 스트리밍
즉시 (JSON/Protobuf) | 자동화된 의사 결정 엔진 | OLAP로 쓰기 람다 DAG 실행
즉시 (JSON/Protobuf) | 200ms 이내의 예측 사용 | REST 요청에 대한 실시간 응답
즉시 (데이터 클래스/원시 컬렉션) | 5ms 이내의 예측 사용 | 데이터 클래스 변환 및 인스턴스 사용

표 기준으로 추론 데이터 최신성 요구사항에서는
드론 영상이 업로드되는 즉시 처리할 필요없이 배치처리가 허용될 것이며

영상 분석을 통해 거리 위반 여부를 자동으로 판별하고 결과를 제공하는 것은 “자동화된 의사 결정 엔진”에 해당한다.

따라서 우리가 개발할 시스템은 사용자가 드론 영상을 업로드하면 비동기적으로 분석 큐에 넣고, 우선순위에 따라 순차적으로 OLAP 파이프라인을 통해 영상이 분석되어 거리 위반 여부를 자동 판별하는 아키텍처가 적합할 것이다

4. 이미지 원본파일 및 도커이미지 저장공간

구현할 시스템에서는 사용자가 연구목적에 동의시 업로드한 동영상을 따로 보관할 수 있고 이때에는 영상데이터를 별도의 저장공간에 저장해야한다.
이미지 저장소는 보통 S3를 생각할수있지만 온프레미스 서버에서는 오브젝트 스토리지를 위한 MinIO, Ceph 등의 오픈소스 솔루션을 사용해야한다.

Ceph는 설치 및 운영 복잡성이 높고 러닝커브가 있다.
하지만 드론 영상 데이터의 중요성과 향후 확장 가능성도 생각한다면 선택을 고려해볼만하다.

반면 MinIO는 설치와 운영이 간편하고 S3 API 호환성이 좋은 이점이 있지만, 대규모 데이터 환경에서는 확장성과 데이터 관리 측면에서 Ceph에 비해 제한적일 수 있다.

Private Docker Registry를 구축하기 위한 오픈소스로 Habor를 대안으로 고려할수 있다.

5. 모델 추론 방식

일반적으로는 모델 추론 방식을 결정할때에는 전처리 로직의 특성, 확장성 및 유연성, 개발 및 운영 편의성 등을 고려해야 한다.
현재 진행하는 프로젝트 특성상 양자화된 Yolo 모델 크기와 추론 속도가 어느정도인지 확인하여 적합한 모델 추론방식을 선택해야한다.

만약 추론속도가 중요하다면 Triton Inference Server 를
상대적으로 데이터 처리 과정이 복잡하다면 커스터마이징이 상대적으로 쉬운 FastAPI & Seldon-core 조합을 생각할 수 있다.

이러한 사항들로 볼 때,
Triton Inference Server 또는 BentoML을 추론방식 선택지 후보로 정했다.

Triton Inference Server

  • NVIDIA에서 제공하는 PreprocessingContainer를 활용하여 GPU 기반 전처리 로직을 구현
  • PreprocessingContainer와 추론 컨테이너를 파이프라인으로 연결하여 단일 서비스로 제공
  • NVIDIA GPU 환경에서 최적의 성능을 발휘
  • 하지만 PreprocessingContainer 개발 및 통합에 대한 학습 곡선이 있음

BentoML

  • BentoML의 모듈 개념을 활용하여 전처리 로직과 추론 로직을 분리
  • 전처리 모듈과 추론 모듈을 독립적으로 개발, 배포하고 파이프라인으로 연결
  • Python 기반이므로 개발자 친화적이며, 커뮤니티 지원도 활발
  • 하지만 GPU 가속 전처리 및 추론 성능은 Triton에 비해 다소 제한적

6. 데이터베이스

드론 영상의 메타데이터 정보, 모델 추론 결과 정보를 저장하기 위한 목적.
관계형 또는 NoSQL 데이터베이스 (ex. PostgreSQL, MongoDB 등)

7. 현재 서버 스펙

OS: Ubuntu 20.04.6 LTS x86_64
CPU: AMD Ryzen 9 7950X (32) @ 4.500GHz
GPU: AMD ATI 5d:00.0 Raphael
GPU: NVIDIA RTX A5000–24기가바이트(GB)의 GPU 메모리
GPU: NVIDIA RTX A5000–24기가바이트(GB)의 GPU 메모리
Memory: 66.5 GiB
Storage: 약 1TB

아키텍쳐 설계를 위한 주요사항 검토 후에는
MLOps 아키텍쳐와 관련된 툴들을 정리해보았다.

툴들을 표기할때 색으로 구분해보았는데

보라색으로 표시한 부분은 이미 사용중이거나 당장에는 구현 우선순위가 낮은 것을 나타낸다.

또한 칸안에 “/” 으로 2개가 함께 작성되어있는 것은
논의를 통해 한가지를 선택 해야함을 표시한 것이다.

먼저 기본적인 CI 구성은 Github, Github Actions을 사용한다.

도커 이미지 저장소는 private docker registry를 구축해야하고
로컬환경에 도커 레지스트리를 직접 구축하는 방법도 있지만 Harbor를 사용하는 것으로 진행한다.

데이터버전 관리에는 DVC를 사용.
처음에는 DVC 셋업이 우선순위가 낮게 측정되었으나
협업하는 인원이 많고 데이터를 일정한 포맷으로 관리하는 것의 중요성을 인지하여 우선순위를 높여서 진행하기로 정했다.
DVC 셋업이 k8s 환경구축과 무관하게 진행할수 있는지 확인이 필요하다.

기본적으로 서버에 온프레미스 k8s 클러스터를 구축해야한다.

실험관리 및 모델 버저닝에는 W&B 또는 MLflow를 사용한다.
초기 모델탐색 단계에서는 W&B를 사용하다가 어느정도 모델선택이 이뤄진 후에는 MLflow를 사용해 체계적으로 실험기록 및 관리를 하기로 했다.

아티팩트와 Raw 이미지/동영상 저장 공간으로 MinIO 또는 Ceph가 후보.
러닝커브가 높은 Ceph 보다 초기에 빠르게 셋업할수있는 MinIO를 선택하였다. MinIO 는 S3 API 호환성이 좋은 점도 한가지 이점이다.

전처리/분산처리/하이퍼파라미터 튜닝에는 Ray 와 Katib 를 선택지로 고려했다. Ray는 Spark를 대체해 좀 더 쉽게 접근가능한 솔루션이라고 한다.
Katib는 지원해주는 알고리즘이 다양하고 Deep Learning 관련된 NAS 예제가 있어 해당 부분 확인후 프로젝트에서 적용가능할지 확인해봐야한다.

ML 파이프라인은 Kubeflow로 구성.

모델 배포 및 관리를 어떻게 구성할지가 가장 큰 고민이었는데
프로젝트에서는 여러 모델을 사용하고 있고 모델 중 YOLO의 경우 경량화를 생각하고 있었다.

경량화까지 고려한다면 Triton이 성능면에서 이점이나
Triton은 C++ 베이스이고 (Python을 지원하긴 한다)
필요한 기능을 커스터마이즈 하는데 다소 시간이 걸릴수도 있을 것이다.
먼저 빠르게 시도해볼 수 있는 건 상대적으로 설치 및 사용이 용이한 BentoML 이다.

RDB 에는 업로드되는 이미지의 메타정보와 모델 추론 후 결과값이 저장되고
이 정보는 이후 Prometheus & Grafana 와 연동되어 메트릭을 수집하고 대시보드화 하는데도 사용된다.

여기까지 논의한 내용을 바탕으로
1차 정리된 MLOps 아키텍쳐 구성은 다음과 같다.

다음 글에서는 위 아키텍쳐 구성을 바탕으로
모델훈련 중단과 같은 예외 사항 처리와 DVA 시스템의 앞단인 프론트/백엔드 부분과 AI모듈이 연계하는 부분에 대해 이야기해보겠다.

참고자료

--

--