Setup

MLOps 서버의 세팅 과정을 설명합니다.

본문서에서 적용된 서버 환경은 다음과 같습니다.

  • Ubuntu 20.04.6

  • CUDA 11.8

글 작성 순서대로 설치하는 것을 권장합니다.

1. docker

docker 설치

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
  • docker에 여러 버전이 존재합니다.

    • ubuntu에서 설치할 수 있는 docker 엔진 리스트를 불러와서 확인할 수 있습니다.

    • grep 명령어를 통대 버전대를 찾을 수 있습니다. 원하는 버전의 docker client를 설치합니다.

  • root 권한없이 docker를 사용하려면 권한을 추가해 줍니다.

  • docker에서 nvidia gpu를 사용하고 싶으면 추가로nvidia-docker를 설치합니다.

    • nvidia-docker의 gpg key를 설치합니다.

  • nvidia-docker를 설치합니다.

  • docker 엔진에서 nvidia-docker를 기본 runtime으로 설정을 변경합니다.

    • docker에서는 daemon.json 에서 기본설정을 업데이트 할 수 있습니다.

  • 변경된 daemon.json을 적용하려면 docker 엔진을 재시작해야 합니다.

  • nvidia-docker가 기본 runtime이 되었는지 확인합니다.

  • cuda가 docker에서 정상적으로 돌아가는지 확인합니다.

2. docker compose

docker compose는 여러 개의 컨테이너로 구성된 애플리케이션을 정의하고 실행하기 위한 도구입니다. 복잡한 애플리케이션을 여러로 docker container로 분리하고, 이를 간단하게 관리할 수 있도록 도와줍니다.

주요 기능은 다음과 같습니다.

  • docker-compose.yml 파일을 사용해 애플리케이션의 컨테이너, 네트워크, 볼륨 등을 정의할 수 있습니다.

  • 단일 명령어로 여러 컨테이너를 동시에 실행, 중지, 또는 관리할 수 있습니다.

  • 서로 다른 컨테이너들 간의 의존성 관리가 가능합니다. (예: 웹 서버 컨테이너가 DB 컨테이너에 의존)

예를 들어, 웹 애플리케이션과 데이터베이스가 있는 프로젝트에서, 각각의 서비스(컨테이너)를 정의한 후 docker-compose up 명령어 하나로 모든 관련 컨테이너를 실행할 수 있습니다.

이것을 통해 개발 환경에서 복잡한 다중 컨테이너 애플리케이션을 쉽게 관리할 수 있습니다.

docker compose 명령어는 공식 홈페이지arrow-up-right 참고하면 됩니다.

본 프로젝트는 docker compose를 사용해 애플리케이션을 설치 및 관리합니다.

docker-compose.yaml

본 프로젝트에서 주로 사용하는 docker-compose.yaml 파일의 관리방법입니다.

  • docker compose로 애플리케이션(서비스)를 설치할 때는 해당 디렉토리로 이동후 설치합니다.

  • 서비스가 여러개 있으므로 network 이름을 지정해 줍니다.

  • 외부 포트로 노출하는 경우, port 테이블을 참고합니다.

  • 재시작하는 경우가 있어 restart always 옵션을 항상 추가합니다.

  • healthcheck를 가능한 사용해 줍니다. 빠른 상태확인에 유용합니다.

기본적인 파일 구조는 다음과 같습니다.

네트워크 설정

docker-compose 파일에 정의된 서비스들은 기본적으로 같은 docker 네트워크가 생성되어서 공유됩니다.

예를 들어, service1/docker-compose.yaml을 실행한 네트워크와 service2/docker-compose.yaml을 실행한 네트워크는 각각 다르고, service1/docker-compose.yaml 파일에 정의된 contrainer들은 같은 네트워크를 공유합니다.

위의 docker-compose.yaml을 정의할 때

이렇게 네트워크를 external: true 옵션을 주게 되면, 다른 서비스의 네트워크를 연결할 수 있게 됩니다. 즉 위의 docker-compose.yaml에서는 app-network-1이라는 다른 docker network를 가져와서 연결하게 되는 의미입니다. 이렇게 container에 원하는 docker 외부 네트워크를 연결할 수 있습니다.

docker network를 확인하고 싶으면 다음 명령어를 입력하면 됩니다.

계정 확인

docker-compose.yaml 파일에서 environments을 보면 각 서비스에 로그인 할 수 있는 ID, 패스워드를 확인할 수 있습니다.

예를 들어 MinIO의 경우 다음과 같이 확인 할 수 있습니다.

각 계정 관련 정보에 대한 envrionments 이름은 서비스마다 다르니 필히 확인을 부탁드립니다.

포트 연결

서비스마다 docker images에 있는 내부 포트가 정해져있습니다. 각 서비스를 외부에서 사용하기 위해서는 외부포트에 먼저 연결해야 합니다. docker-compose.yaml 파일에서 ports 부분을 확인하면 알 수 있습니다.

docker에서 설치된 서비스를 외부 접근하기 위해서는 다음과 같은 단계를 따르면 됩니다.

  1. (클라우드 사용시) 클라우드에서 서비스의 외부 port에 대해서 인바운드/아웃바운드 규칙을 설정합니다.

  2. http://{host IP}:{외부 port}를 브라우저에 입력해서 접속합니다.

3. Git Clone

각 기능들을 설치하기 전에 dva-mlops 깃 repo를 로컬에 저장합니다.

서비스를 설치하려면 README.mdarrow-up-right 단계를 따르면 됩니다.

  1. 실행할 디렉토리로 이동합니다.

  1. Docker Compose를 실행하여 모든 서비스를 백그라운드에서 시작합니다.

MLflow는 머신러닝 모델의 실험 추적, 모델 관리 및 배포를 위한 오픈소스 플랫폼입니다. 머신러닝 실험에서 생성된 데이터, 메트릭, 모델 등을 체계적으로 관리하고 추적하는데 유용합니다.

  • MLflow Backend Store

    • MLflow의 Backend Store는 실험 및 아티팩트를 관리하는 데이터베이스로, 실험의 결과와 모델 관련 정보를 저장합니다.

    • mlflow에서는 postgres:16.3을 사용합니다.

  • MLflow Server

    • MLflow Server는 MinIO와 같은 오브젝트 스토리지와 연결되어, MLflow 레지스트리로 저장되는 데이터를 관리합니다.

mlflow가 설치되어 있는 docker를 빌드 후 적용합니다.

MLflow 서비스

MLflow 서비스에서 사용하는 주요 정보는 다음과 같습니다:

  • experiments: 머신러닝 실험의 결과를 추적하고 비교할 수 있는 공간으로, 실험에서 사용된 매개변수, 메트릭, 아티팩트를 기록하는데 사용됩니다.

  • models: 훈련된 머신러닝 모델을 저장하고 관리하며, 다양한 환경에서 재사용 및 배포가 가능하도록 지원합니다.

위와 같은 형식의 docker compose 파일이 있는 폴더에서

MLflow를 Docker 환경에서 실행하기 위해서는 미리 MinIO가 설치되어 있어야 합니다. MinIO가 설치된 상태에서 MLflow 서비스를 시작하려면 다음 명령어를 사용하세요:

MinIO는 고성능 객체 스토리지 시스템으로, Amazon S3와 호환되는 API를 제공하며 클라우드 네이티브 애플리케이션에서 사용됩니다. mlops에서는 mlflow 모델 저장, pipeline 중간 결과물 저장, BE-MLOps 결과물 공유에 사용됩니다.

bucket

사용중인 minio의 bucket은 다음과 같습니다.

  • mlflow : mlflow aritifacts 저장소

  • pipelines : job 실행에 따른 중간 결과물 저장

    • {user_id}/{dataset_id}에 실행 artifacts 저장

    • 최종으로 final_result.json 생성

버켓 생성은 UI 화면에서 생성할 수 있습니다.

  1. 화면 왼쪽의 [Administrator] - [Buckets]를 클릭합니다.

  2. Bucket Name에 버켓 이름을 입력합니다.

  3. Capacity를 정합니다. 현재 dva-mlops에서 MLFlow는 512GiB, pipelines는 1TiB를 사용하고 있습니다.

circle-info

포트 관련 주의사항 minio에서는 기본 서버 포트(9000)와 웹 서비스 포트(9001)가 있습니다. 내부에서 연결할 때는 기본 서버 포트를, 웹에서 다운로드 받거나 오브젝트를 확인할 때는 웹 서비스 포트를 사용합니다.

위와 같은 형식의 docker compose 파일이 있는 폴더에서

minio를 Docker 환경에서 실행하려면 다음 명령어를 사용하세요:

Redis는 인메모리 기반의 key:value 저장소로, 캐싱메시지 브로커로 자주 사용됩니다. MLOps 파이프라인에서는 중간 결과 저장과 모델 모니터링을 위한 비동기 추론 등에 활용됩니다.

redis 설정

redis는설정 옵션이 다양하기 때문에 docker compose에서 environments에 직접 작성하기 보다, 설정파일에 필요한 옵션을 작성하는 것이 편리합니다.

Redis의 설정 파일(redis.conf)에서 중요한 항목들은 다음과 같습니다:

  • port : Redis가 사용하는 연결 포트 (기본: 6379)

  • bind : 연결할 네트워크 인터페이스 (0.0.0.0으로 설정하면 모든 IP에서 접근 가능)

  • requirepass : Redis 접속 시 요구되는 패스워드

  • maxmemory : Redis가 사용할 최대 메모리 크기 (예: 4g)

  • maxmemory-policy : 메모리 초과 시의 키 삭제 정책

    • allkeys-lru : 가장 오래 사용되지 않은 키부터 삭제하는 LRU(Least Recently Used) 방식

  • appendonly : 변경된 데이터를 디스크에 영구 저장하는 AOF(Append-Only File) 기능. no로 설정 시 메모리에만 데이터 저장.

자세한 Redis 설정 파일에 대한 설명은 Redis 공식 문서arrow-up-right를 참고하세요.

위와 같은 형식의 docker compose 파일이 있는 폴더에서

Redis를 Docker 환경에서 실행하려면 다음 명령어를 사용하세요:

RabbitMQ는 메시지 큐를 관리하는 메시지 브로커로, 주로 비동기 메시지 전달과 작업 분산에 사용됩니다. AMQP 프로토콜을 기반으로 하며, 프로듀서(메시지를 보내는 측)와 컨슈머(메시지를 받는 측) 간의 통신을 중개해, 작업을 비동기적으로 처리하고 시스템의 부하를 줄입니다.

본 프로젝트에서는 celery에 사용하고 있습니다.

주요 특징은 다음과 같습니다.

  • 큐잉: 메시지를 대기열에 저장하고 순차적으로 처리.

  • 비동기 처리: 작업을 비동기적으로 처리하여 성능 향상.

  • 확장성: 여러 소비자에게 작업을 분배하여 부하 분산 가능.

RabbitMQ는 분산 시스템, MLOps, 마이크로서비스 아키텍처 등에서 자주 사용됩니다.

circle-info

포트관련 주의사항

rabbitmq는 broker 포트 (5672)와 웹 UI 포트(15672)가 있습니다. 내부에서 연결 사용에는 broker 포트를, UI로 큐 상태를 확인하고 싶을 때는 UI 포트를 사용합니다.

기본 설정

큐 구조 및 작업 흐름

작업 처리 순서

  1. MinIO에서 데이터 다운로드 (q1)

  2. 필요시 조명 제거 처리 (q6)

  3. 객체 감지 수행 (q2)

  4. 객체 추적 실행 (q3)

  5. 필요시 FP 제거 (q7)

  6. 결과 MinIO 업로드 (q5)

  7. 완료/에러 처리 (q8, q9)

작업 설정 상세

현재 track_job(), minio_upload_job() 에만 적용됩니다.

작업 설정 설명

  • max_retries: 실패 시 최대 3번 재시도

  • retry_backoff: 지수 백오프로 재시도 간격 증가

  • soft_time_limit: 작업 타임아웃 경고

  • time_limit: 강제 종료 시간 제한

BentoML은 머신러닝 모델을 프로덕션 환경에 효율적으로 배포하고 운영하기 위한 오픈소스 플랫폼입니다. 복잡한 ML 모델을 쉽게 API로 변환하고, 확장 가능한 서비스로 배포할 수 있게 해주는 엔드-투-엔드 솔루션을 제공합니다.

1. 폴더 구조

2. 환경 설정 및 의존성 설치

2.1 기본 설치

2.2 가상 환경 설정

2.3 환경 변수 설정

3. 신규 모델 추가 절차

YOLOv8-OBB 모델 BentoML 서비스 구현 예시

1. 프로젝트 구조 설정

프로젝트의 구조는 BentoML의 표준 구조를 따르며, 각 파일은 다음과 같은 역할을 합니다:

2. 의존성 설정

의존성 관리는 세 가지 레벨에서 이루어집니다.

2.1 bentofile.yaml

이 설정은 BentoML이 서비스를 컨테이너화할 때 필요한 모든 구성요소를 정의합니다.

2.2 environment.yml

Conda 환경 설정은 재현 가능한 환경을 보장하며, 특히 GPU 지원과 관련된 패키지 버전을 명확히 지정합니다.

3. 서비스 구현 (service.py)

3.1 입력/출력 모델 정의

Pydantic 모델을 사용하여 입력과 출력의 스키마를 정의하고 자동 검증을 수행합니다.

3.2 메트릭 정의

Prometheus 스타일의 메트릭을 정의하여 서비스 모니터링을 가능하게 합니다.

3.3 서비스 클래스 구현

서비스 클래스는 모델 로딩, 리소스 관리, 모니터링 등 핵심 기능을 초기화합니다.

3.4 모델 로드 구현

MLflow에서 학습된 모델을 안전하게 로드하고 예외 처리를 수행합니다.

3.5 추론 API 구현

API 엔드포인트는 비동기 처리, 입력 검증, 에러 처리, 메트릭 수집 등을 포함합니다.

4. 모델 버전 관리 및 배포 프로세스

automate_model_update.pyarrow-up-right 이 스크립트는 MLflow에서 관리되는 모델을 BentoML 서비스로 자동 배포하는 전체 프로세스를 자동화합니다.

1. MLflow에서 BentoML로의 모델 전환 과정

1.1 MLflow 모델 버전 조회

  • MLflow에서 모델의 최신 버전을 조회

  • 현재 Staging 단계의 모델을 우선적으로 선택

  • 버전 번호와 run_id 반환

1.2 BentoML로 모델 저장

  • MLflow에서 모델 파일의 URI를 가져옴

  • BentoML의 모델 저장소로 모델을 임포트

  • 이후 service.py에서 사용할 수 있는 형태로 변환

2. 서비스에서의 모델 사용

2.1 모델 로드 (service.py)

  • BentoML 저장소에서 모델을 로드

  • 서비스 초기화 시점에 모델이 메모리에 로드됨

3. 모델 버전 관리 프로세스

3.1 버전 관리 흐름

  1. MLflow 단계

    • MLflow에서 모델 학습 및 등록

    • Staging/Production 단계로 모델 승격

  2. BentoML 변환

    • MLflow에서 승인된 모델을 BentoML로 임포트

    • 서비스에서 사용 가능한 형태로 변환

  3. 서비스 빌드

    • 새 모델이 포함된 서비스 빌드

    • Docker 이미지 생성

    • 실제 수행되는 명령어는 다음과 같습니다.

  4. 배포 업데이트

    • docker-compose.yml 파일 업데이트

    • 서비스 재시작으로 새 모델 적용

    • 실제 수행되는 명령어는 다음과 같습니다.

3.2 버전 관리 특징

  1. 자동화된 버전 선택

    • Staging 환경의 모델 우선 선택

    • 버전 번호 기반 정렬로 최신 모델 보장

  2. 안전한 롤백 지원

    • 업데이트 실패 시 자동 롤백

    • 실패한 이미지 자동 제거

  3. 환경 분리

    • 서비스별 독립된 가상환경 유지

    • 의존성 충돌 방지

  4. 모니터링 및 로깅

    • 상세한 로그 기록

    • 버전 변경 추적 가능

이러한 프로세스를 통해 MLflow에서 학습/검증된 모델이 자동으로 프로덕션 환경에 배포되며, 각 단계에서의 실패를 안전하게 처리하고 모델의 버전을 효과적으로 관리할 수 있습니다.

9. Monitoring System

1. Prometheusarrow-up-right 메트릭 수집 설정

1.1 기본 설정

1.2 서비스별 스크랩 설정

YOLO 서비스 (고부하 서비스)

기타 BentoML 서비스

1.3 수집 메트릭 종류

1) 요청 메트릭

2) 모델 성능 메트릭

3) 시스템 리소스 메트릭

2. Grafanaarrow-up-right 대시보드 구성

2.1 Grafana 설정

2.2 주요 대시보드

1) 서비스 상태 대시보드

  • API 엔드포인트 상태

  • 요청 성공/실패율

  • 평균 응답 시간

  • 에러율 추이

2) 모델 성능 대시보드

  • 모델별 추론 시간

  • GPU 사용률

  • 처리량(throughput)

3) 리소스 모니터링 대시보드

  • CPU 사용률

  • 메모리 사용량

  • GPU 메모리 상태

  • 디스크 I/O

3. 로그 수집 및 분석

3.1 로그 저장소 구성

3.2 로그 수집 정책

1) 애플리케이션 로그

2) 시스템 로그

  • 컨테이너 상태 로그

  • 리소스 사용량 로그

  • 네트워크 통신 로그

3) 에러 로그

4. 성능 모니터링 지표

4.1 서비스 성능 지표

1) API 성능

  • 요청 처리율 (RPS)

  • 평균 응답 시간

  • 에러율

  • 동시 처리 요청 수

2) 모델 성능

  • 추론 시간 (P95, P99)

  • 배치 처리 효율성

  • GPU 활용률

  • 메모리 사용 패턴

4.2 리소스 사용 제한

4.3 헬스체크 설정

4.4 모니터링 대응 전략

1) 성능 저하 시

  • 자동 스케일링 트리거

  • 배치 크기 조정

  • 캐시 정책 최적화

2) 리소스 부족 시

  • 불필요 프로세스 정리

  • 메모리 캐시 정리

  • 우선순위 기반 작업 조절

3) 장애 발생 시

  • 자동 재시작

  • 백업 서비스 활성화

이러한 모니터링 시스템을 통해 서비스의 안정성을 확보하고, 성능 이슈를 사전에 감지하여 대응할 수 있습니다.

Last updated