👌

MLflowをdocker composeで動かす。

2023/10/09に公開

はじめに

以前、Kubeflow と MLflow を microk8s 上で動かす記事を書いた。kubeflow は使いこなせなかったので、MLflow だけを使うようにした。また、自宅の PC はシングルノードなので k8s も不要なので、docker compose で動かすようにした。

この記事では MLflow のリポジトリ内にある、docker compose のサンプルを参考にした。

https://github.com/mlflow/mlflow/tree/master/examples/mlflow_artifacts

最終的にできたものは以下に配置した。

https://github.com/derbuihan/mlflow-docker-compose

MLflow の構成

MLflow の構成には 6 つのシナリオがある。以下のドキュメントに詳しい。

https://mlflow.org/docs/latest/tracking.html

この記事の内容はシナリオ 5 である。

docker compose で動かす

docker-compose.yaml は以下のように作成した。

docker-compose.yml
version: "3"
services:
  minio:
    image: minio/minio:latest
    expose:
      - "9000"
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 1s
      timeout: 10s
      retries: 5
    volumes:
      - minio-data:/data
    command: >
      server /data --console-address ":9001"

  minio-create-bucket:
    image: minio/mc:latest
    depends_on:
      minio:
        condition: service_healthy
    entrypoint: >
      bash -c "
      mc alias set minio http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD} &&
      if ! mc ls minio | grep --quiet bucket; then
        mc mb minio/bucket
      else
        echo 'bucket already exists'
      fi
      "

  artifacts-server:
    build: .
    depends_on:
      - minio-create-bucket
    expose:
      - "5500"
    ports:
      - "5500:5500"
    environment:
      MLFLOW_S3_ENDPOINT_URL: http://minio:9000
      AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
      AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
    command: >
      mlflow server
      --host 0.0.0.0
      --port 5500
      --artifacts-destination s3://bucket
      --gunicorn-opts "--log-level debug"
      --artifacts-only

  postgres:
    image: postgres:latest
    restart: always
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - db-data:/var/lib/postgresql/data

  tracking-server:
    build: .
    depends_on:
      - postgres
      - artifacts-server
    expose:
      - "5000"
    ports:
      - "5000:5000"
    command: >
      mlflow server
      --host 0.0.0.0
      --port 5000
      --backend-store-uri postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
      --default-artifact-root http://artifacts-server:5500/api/2.0/mlflow-artifacts/artifacts/experiments
      --gunicorn-opts "--log-level debug"

volumes:
  minio-data:
  db-data:

順番に解説する。

minio は以下のように構築する。

minio:
  image: minio/minio:latest
  expose:
    - "9000"
  ports:
    - "9000:9000"
    - "9001:9001"
  environment:
    MINIO_ROOT_USER: ${MINIO_ROOT_USER}
    MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
  healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
    interval: 1s
    timeout: 10s
    retries: 5
  volumes:
    - minio-data:/data
  command: >
    server /data --console-address ":9001"

9000 番ポートは S3 のエンドポイントであり、9001 番ポートは管理画面である。

以下の minio-create-bucket は minio に S3 バケットを作成する。

minio-create-bucket:
  image: minio/mc:latest
  depends_on:
    minio:
      condition: service_healthy
  entrypoint: >
    bash -c "
    mc alias set minio http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD} &&
    if ! mc ls minio | grep --quiet bucket; then
      mc mb minio/bucket
    else
      echo 'bucket already exists'
    fi
    "

minio の healthcheck が成功したら、miniocreate-bucket が実行される。bucket という名前のバケットが作成される。このバケットを MLflow のアーティファクトの保存先として利用する。

以下の artifacts-server は、S3 にアーティファクトを保存するためのサーバーである。

artifacts-server:
  build: .
  depends_on:
    - minio-create-bucket
  expose:
    - "5500"
  ports:
    - "5500:5500"
  environment:
    MLFLOW_S3_ENDPOINT_URL: http://minio:9000
    AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
    AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
  command: >
    mlflow server
    --host 0.0.0.0
    --port 5500
    --artifacts-destination s3://bucket
    --gunicorn-opts "--log-level debug"
    --artifacts-only

コンテナは後述の Dockerfile で作成する。

以下の postgres は MLflow のトラッキングサーバーのためのデータベースである。

postgres:
  image: postgres:latest
  restart: always
  environment:
    POSTGRES_DB: ${POSTGRES_DB}
    POSTGRES_USER: ${POSTGRES_USER}
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
  volumes:
    - db-data:/var/lib/postgresql/data

MLflow はデータベースとして SQLite と MySQL と PostgreSQL と MSQL が利用できる。今回は PostgreSQL を利用する。

以下の tracking-server は MLflow のトラッキングサーバーである。

tracking-server:
  build: .
  depends_on:
    - postgres
    - artifacts-server
  expose:
    - "5000"
  ports:
    - "5000:5000"
  command: >
    mlflow server
    --host 0.0.0.0
    --port 5000
    --backend-store-uri postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
    --default-artifact-root http://artifacts-server:5500/api/2.0/mlflow-artifacts/artifacts/experiments
    --gunicorn-opts "--log-level debug"

コンテナは後述の Dockerfile で作成する。

Dockerfile

mlflow の artifacts-server と tracking-server のコンテナは同じ Dockerfile を利用する。

FROM python:3.8
WORKDIR /app
RUN pip install mlflow psycopg2 boto3

Python のイメージをベースにして、mlflow と psycopg2 と boto3 をインストールする。mlflow が公式で提供しているイメージは、mlflow と boto3 しかインストールされていない。そのため今回は独自のイメージを作成した。

環境変数

上記の docker-compose.yaml を動かすためには、以下の環境変数を設定する必要がある。

MINIO_ROOT_USER=user
MINIO_ROOT_PASSWORD=password
POSTGRES_DB=db
POSTGRES_USER=user
POSTGRES_PASSWORD=password

実行

docker-compose.yaml があるディレクトリで以下のコマンドを実行する。

docker-compose up

以下の URL で管理画面にアクセスできる。

MLflow: http://localhost:5000
Minio: http://localhost:9000

参考にした記事

最後に参考にした記事を紹介する。

Charmed MLflow のセットアップ方法。

https://documentation.ubuntu.com/charmed-mlflow/en/latest/tutorial/mlflow/

試してみたが、インストールされる MLflow のバージョンが 2.1 と少し古かった。MLflow はサーバーサイドとクライアントのバージョンが合っていないと動作しないため、クライアント側の Python 環境にも制約ができてしまうため今回は却下。

docker-compose で mlflow を構築している人はたくんいる。

https://zenn.dev/mjun0812/articles/192f4d4c5a14ab

https://qiita.com/k_tomo/items/5787f9bde6be0eb2930b

https://github.com/sachua/mlflow-docker-compose

おわりに

docker compose で MLflow を動かした。次は、ハイパーパラメータのチューニングのアーティファクトを MLflow に保存してみたい。

Discussion