본문으로 건너뛰기

1) MLflow Setup

Chapter Preview


목표

  1. Docker Compose 를 이용하여 실제 서비스 환경과 비슷한 형태로 MLflow 서버를 띄워봅니다.
  2. 서비스 상황을 가정하여 MLflow 의 구성 요소들을 이해합니다.

스펙 명세서

  1. Docker Compose 파일에 MLflow 의 운영 정보, 모델 결과 등을 저장할 물리적인 PostgreSQL DB 서버 스펙을 정의합니다.

    • POSTGRES_USER : mlflowuser
    • POSTGRES_PASSWORD : mlflowpassword
    • POSTGRES_DB : mlflowdatabase
  2. Docker Compose 파일에 학습된 모델을 저장할 물리적인 저장 공간인 MinIO 서버 스펙을 정의합니다.

    • MINIO_ROOT_USER : minio
    • MINO_ROOT_PASSWORD : miniostorage
    • Port forwarding :
      • api: 9000:9000
      • console: 9001:9001
  3. Docker Compose 파일에 모델과 모델의 결과들을 관리할 MLFlow 서버를 정의합니다.

    • 환경 변수를 이용하여 MLflow 서버에서 앞서 띄워둔 PostgreSQL DB 와 MinIO 두 가지 서버에 접근이 가능하도록 연결합니다.

    • Dockerfile

      • MLflow 에 관련된 패키지가 설치된 이미지를 생성하기 위한 Dockerfile 을 정의합니다.
      • MinIO 에 모델 저장을 위한 초기 버켓을 생성 하기 위해 MinIO Client 도 함께 설치되도록 합니다.
    • Docker Compose

      • MinIO 의 접속 정보를 AWS_ACCESS_KEY_ID , AWS_SECRET_ACCESS_KEY 환경 변수를 통해 적절하게 설정합니다.

      • MinIO Client 를 설치하고, MinIO 의 초기 버켓을 생성하도록 명령어를 작성합니다.

      • MLflow 서버를 띄우는 명령어를 작성합니다.

      • Port forwarding : 5001:5000
        • MLflow 에서는 기본값으로 5000 포트를 사용합니다.
        • 하지만 실습에서 MacOS 를 사용하는 경우 AirPlay 기능이 5000번 포트를 사용하기 때문에 중복을 피하기 위해 5001번 포트를 사용합니다.
        • 일반적인 경우 5000번 포트를 사용하면 됩니다.
  4. 정의된 스펙에 따라 서비스들을 띄웁니다.

    • localhost:9001 에 접속하여 MinIO 로그인 페이지가 잘 동작하는지 확인합니다.
    • localhost:5001 에 접속하여 MLflow 페이지가 잘 동작하는지 확인합니다.
https://github.com/mlops-for-mle/mlops-for-mle/tree/main/part3

해당 파트의 전체 코드는 mlops-for-mle/part3/ 에서 확인할 수 있습니다.

part3
├── Dockerfile
├── Makefile
├── README.md
├── docker-compose.yaml
├── load_model_from_registry.py
└── save_model_to_registry.py
[그림 3-2] MLflow Setup Diagram

1. MLflow Backend Store

1.1 Backend Store

Backend Store 란 수치 데이터와 MLflow 서버의 정보들을 체계적으로 관리하기 위한 DB 입니다. Backend Store 에는 모델의 학습 결과인 accuracy, f1-score, 모델이 학습되면서 생기는 loss, 모델 자체의 정보인 hyperparmameters 등의 수치 데이터와 run_id, run_name, experiment_name 등의 MLflow 의 메타 데이터가 저장됩니다.

이번 파트에서는 Backend Store 로 사용하기 위해 01. Database 파트에서 사용되었던 PostgreSQL DB 를 새롭게 생성하겠습니다.

1.2 PostgreSQL DB Server

PostgreSQL DB 서버의 스펙을 Docker Compose 파일에 서비스 이름, 유저 이름, 비밀번호, DB 이름을 환경변수로 설정합니다.

docker-compose.yaml
version: "3"

services:
mlflow-backend-store:
image: postgres:14.0
container_name: mlflow-backend-store
environment:
POSTGRES_USER: mlflowuser
POSTGRES_PASSWORD: mlflowpassword
POSTGRES_DB: mlflowdatabase
healthcheck:
test: ["CMD", "pg_isready", "-q", "-U", "mlflowuser", "-d", "mlflowdatabase"]
interval: 10s
timeout: 5s
retries: 5
  • image :
    • DB 서버에서 사용할 이미지는 postgres:14.0 입니다.
  • environment :
    • POSTGRES_USER : DB 에 접근하기 위한 사용자 이름입니다. 여기서는 mlflowuser 를 사용하겠습니다.
    • POSTGRES_PASSWORD : DB 에 접근하기 위한 비밀번호입니다. 여기서는 mlflowpassword 를 사용하겠습니다.
    • POSTGRES_DB : DB 이름을 설정합니다. 여기서는 mlflowdatabase 를 사용하겠습니다.
  • healthcheck :
    • DB 서버가 잘 띄워졌는지 상태를 확인하기 위해 상태를 체크합니다.

2. MLflow Artifact Store

2.1 Artifact Store

Artifact Store 란 MLflow 에서 학습된 모델을 저장하는 Model Registry 로써 이용하기 위한 스토리지 (storage) 서버입니다. Artifact Store 를 이용하면 기본적인 파일 시스템 보다 체계적으로 관리 할 수 있으며 외부에 있는 스토리지 서버도 사용 할 수 있다는 장점이 있습니다.

2.2 Why MinIO?

이번 파트에서는 Artifact Store 로 MinIO 서버를 사용하는데 그 이유는 다음과 같습니다.

  • MinIO 는 S3 를 대체할 수 있는 오픈 소스 고성능 개체 스토리지입니다.
  • AWS S3 의 API 와도 호환되어 SDK 도 동일하게 사용 할 수 있습니다.
  • MLflow 에서는 AWS S3 를 모델을 저장하기 위한 스토리지로 사용하도록 권장하고 있기 때문에 MinIO 를 사용합니다.
  • 실습에서 AWS credential 을 통해 MinIO 대신 AWS S3 를 사용해도 같은 결과를 얻을 수 있습니다.

2.3 MinIO Server

MinIO의 스펙을 Compose 파일에 서비스 이름, 유저 이름, 비밀번호를 환경변수로 정의하고 호스트와 연결되는 포트 또한 정의합니다.

docker-compose.yaml
version: "3"

services:
mlflow-artifact-store:
image: minio/minio:RELEASE.2024-01-18T22-51-28Z
container_name: mlflow-artifact-store
ports:
- 9000:9000
- 9001:9001
environment:
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: miniostorage
command: server /data/minio --console-address :9001
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 5s
timeout: 5s
retries: 5
  • image :
    • MinIO 서버에서 사용할 이미지는 minio/minio:RELEASE.2024-01-18T22-51-28Z 입니다.
  • ports :
    • 호스트와 컨테이너의 포트를 설정합니다.
    • MinIO 의 API 포트를 9000으로 포트 포워딩합니다.
    • MinIO 의 Console 포트를 9001으로 포트 포워딩합니다.
  • environment :
    • MINIO_ROOT_USER : MinIO 에 접근하기 위한 사용자 이름입니다. 여기서는 minio 를 사용하겠습니다.
    • MINIO_ROOT_PASSWORD : MinIO 에 접근하기 위한 비밀번호입니다. 여기서는 miniostorage 를 사용하겠습니다.
  • command :
    • MinIO 서버를 실행시키는 명령어를 추가합니다.
    • --console-address 를 통해 컨테이너의 9001 포트로 MinIO 에 접근할 수 있도록 주소를 열어줍니다.
  • healthcheck :
    • MinIO 서버가 잘 띄워졌는지 상태를 확인하기 위해 상태를 체크하는 구문을 추가합니다.

3. MLflow Server

앞서 만든 Backend Store 와 Artifact Store 에 접근 가능한 MLflow 서버를 생성합니다.

3.1 Dockerfile

MLflow 서버에 필요한 패키지가 설치된 이미지를 build 할 Dockerfile 을 작성합니다.
서버를 띄울 때, MinIO 에 초기 bucket 을 생성하기 위해 MinIO Client 도 함께 설치합니다.

Dockerfile
FROM amd64/python:3.9-slim

RUN apt-get update && apt-get install -y \
git \
wget \
&& rm -rf /var/lib/apt/lists/*

RUN pip install -U pip &&\
pip install mlflow psycopg2-binary boto3

RUN cd /tmp && \
wget https://dl.min.io/client/mc/release/linux-amd64/mc && \
chmod +x mc && \
mv mc /usr/bin/mc
  • FROM :
    • Base 이미지를 Python 3.9가 포함된 이미지로 설정합니다.
  • RUN :
    • git , wget 을 설치합니다.
    • git 은 MLflow 서버 내부 동작에, wget 은 MinIO Client 를 설치하기 위해 사용됩니다.
  • RUN :
    • MLflow 를 비롯해 PostgreSQL DB, AWS S3 에 관련된 Python 패키지를 설치합니다.
  • RUN :
    • 앞서 설치한 wget 을 활용하여 MinIO Client 를 설치합니다.

3.2 Docker Compose

작성된 Dockerfile 을 build 하도록 Compose 파일의 services 탭 밑에 정의합니다.

  1. MinIO 에 접근하기 위한 계정 정보를 환경변수로 설정합니다.
  2. 모델을 저장할 때 사용할 MinIO 초기 버켓을 생성합니다.
  3. MLflow 서버를 띄우는 명령어를 작성합니다.
    • PostgreSQL DB 에 연결하기 위한 keyword argument 를 추가합니다.
    • MinIO 에 연결하기 위한 keyword argument 를 추가합니다.
docker-compose.yaml
version: "3"

services:
mlflow-server:
build:
context: .
dockerfile: Dockerfile
container_name: mlflow-server
depends_on:
mlflow-backend-store:
condition: service_healthy
mlflow-artifact-store:
condition: service_healthy
ports:
- 5001:5000
environment:
AWS_ACCESS_KEY_ID: minio
AWS_SECRET_ACCESS_KEY: miniostorage
MLFLOW_S3_ENDPOINT_URL: http://mlflow-artifact-store:9000
command:
- /bin/sh
- -c
- |
mc config host add mlflowminio http://mlflow-artifact-store:9000 minio miniostorage &&
mc mb --ignore-existing mlflowminio/mlflow
mlflow server \
--backend-store-uri postgresql://mlflowuser:mlflowpassword@mlflow-backend-store/mlflowdatabase \
--default-artifact-root s3://mlflow/ \
--host 0.0.0.0
  • depends_on :
    • MLflow 서버가 띄워지기 전에, PostgreSQL DB 와 MinIO 서버를 먼저 띄우도록 합니다.
  • ports :
    • 5001:5000 포트를 설정합니다.
  • environment
    • AWS_ACCESS_KEY_ID : AWS S3 의 credential 정보입니다. 여기서는 MinIO 의 MINIO_ROOT_USER 와 동일합니다.
    • AWS_SECRET_ACCESS_KEY : AWS S3 의 credential 정보입니다. 여기서는 MinIO 의 MINIO_ROOT_PASSWORD 와 동일합니다.
    • MLFLOW_S3_ENDPOINT_URL : AWS S3 의 주소를 설정합니다. 여기서는 MinIO 의 주소와 같습니다.
  • command : MinIO 초기 버켓을 생성 하고, MLflow 서버를 실행합니다.
    • mc config ~ : MinIO Client 를 활용해 MinIO 서버에 호스트를 등록합니다.
    • mc mb ~ : 등록된 호스트를 통해 초기 버켓을 생성합니다.
    • mlflow server : MLflow 서버를 동작시킵니다.
    • --backend-store-uri : 명시된 정보를 통해 PostgreSQL DB 와 연결합니다.
    • --default-artifact-root : 명시된 버켓을 통해 MinIO 의 초기 버켓과 연결합니다.

4. Docker Compose 를 이용하여 서비스 띄우기

완성된 Dockerfile 과 Compose 파일은 아래와 같습니다.

4.1 Dockerfile

Dockerfile
FROM amd64/python:3.9-slim

RUN apt-get update && apt-get install -y \
git \
wget \
&& rm -rf /var/lib/apt/lists/*

RUN pip install -U pip &&\
pip install boto3==1.26.8 mlflow==1.30.0 psycopg2-binary

RUN cd /tmp && \
wget https://dl.min.io/client/mc/release/linux-amd64/mc && \
chmod +x mc && \
mv mc /usr/bin/mc

4.2 Docker Compose

docker-compose.yaml
version: "3"

services:
mlflow-backend-store:
image: postgres:14.0
container_name: mlflow-backend-store
environment:
POSTGRES_USER: mlflowuser
POSTGRES_PASSWORD: mlflowpassword
POSTGRES_DB: mlflowdatabase
healthcheck:
test: ["CMD", "pg_isready", "-q", "-U", "mlflowuser", "-d", "mlflowdatabase"]
interval: 10s
timeout: 5s
retries: 5

mlflow-artifact-store:
image: minio/minio:RELEASE.2024-01-18T22-51-28Z
container_name: mlflow-artifact-store
ports:
- 9000:9000
- 9001:9001
environment:
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: miniostorage
command: server /data/minio --console-address :9001
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 5s
timeout: 5s
retries: 5

mlflow-server:
build:
context: .
dockerfile: Dockerfile
container_name: mlflow-server
depends_on:
mlflow-backend-store:
condition: service_healthy
mlflow-artifact-store:
condition: service_healthy
ports:
- 5001:5000
environment:
AWS_ACCESS_KEY_ID: minio
AWS_SECRET_ACCESS_KEY: miniostorage
MLFLOW_S3_ENDPOINT_URL: http://mlflow-artifact-store:9000
command:
- /bin/sh
- -c
- |
mc config host add mlflowminio http://mlflow-artifact-store:9000 minio miniostorage &&
mc mb --ignore-existing mlflowminio/mlflow
mlflow server \
--backend-store-uri postgresql://mlflowuser:mlflowpassword@mlflow-backend-store/mlflowdatabase \
--default-artifact-root s3://mlflow/ \
--host 0.0.0.0

4.3 실행

Dockerfile 과 Compose 두 파일이 있는 경로에서 아래 명령어를 활용해 정의된 서비스를 백그라운드 프로세스로 띄웁니다.

docker compose up -d
  1. localhost:5001 에 접속하여 MLflow 서버 동작을 확인합니다.

    MLflow ui [그림 3-3] MLflow UI

  2. localhost:9001 에 접속하여 MinIO 서버 동작을 확인합니다.

    MinIO ui [그림 3-4] MinIO Login 화면

    MinIO 에 로그인할 수 있는 아이디는 위에서 설정한 minio / miniostorage 입니다.
    해당 정보로 로그인하여 아래의 [그림 3-5] 와 같은 화면이 보이는 지 확인합니다.

    MinIO ui [그림 3-5] MinIO 접속 화면