モデル管理プラットフォームMLflowの設定

環境構築
Author

Ryo Nakagami

Published

2025-07-17

Modified

2025-07-18

MLflowサーバーアクセスイメージ

セキュリティを保ちつつローカルからリモート操作
  • クライアント視点では,自分の localhost:5000 にアクセスしている体感
  • 実際には ssh -L によってサーバの MLflow にトンネル転送されている

sequenceDiagram
    participant ClientPC as クライアントPC<br>(Python)
    participant SSH as SSHトンネル<br>(ポートフォワーディング)
    participant MLflowServer as Docker上のMLflow Server<br>(mlflow server 起動中)

    ClientPC -->> SSH: HTTPリクエスト<br>(localhost:5000 → SSHトンネル)
    SSH -->> MLflowServer: HTTPリクエスト<br>(サーバlocalhost:5000)
    MLflowServer -->> SSH: HTTPレスポンス
    SSH -->> ClientPC: HTTPレスポンス

Figure 1

スコープについて

  • Artifact StoreやBackend Storeはサーバーのストーレージ領域を使用することにします

MLflowサーバーの保存領域

ログやメタデータ,ファイル成果物を保存・管理する保存領域として,Artifact store と Backend storeの2種類があります.

graph TB
    A[MLflow Tracking<br>mlflow server] --> B[Backend Store<br>メタデータ保存]
    A --> C[Artifact Store<br>成果物ファイル保存]

Figure 2
保存領域 役割
Artifact Store 実験で生成された Artifacts = 成果物(モデル,画像,ログファイルなど) を保存する領域
Backend Store モデルや実験やRunのメタデータ(パラメータ,Metricsなどを含む)を格納する領域

Artifact Store

保存オブジェクト例

基本的には以下のような大容量になりがちなものを保存します

  • 学習済みモデル(model.pkl)
  • 学習に出力した画像やプロット(ts-plot.png)
  • 学習時に利用したデータ(train.parquet)

サポートされる保存先

  • ローカルディレクトリ(例: /mlflow/mlruns)
  • Amazon S3(例: s3://<bucket>/<path>)
  • Google Cloud Storage(例: gs://<bucket>/<path>)
  • Azure Blob Storage
  • FTP/SFTP ServerやNFS共有ディレクトリなど

Backend Store

保存オブジェクト例

  • Model ID
  • Run ID
  • Start & end time
  • Parameters
  • Metrics
  • Source file name

サポートされる保存先

  • デフォルトではローカルの ./mlruns ディレクトリに保存
  • configureでデータベースを指定可能

MLflowサーバー構築手順

サーバー側での公式MLflow Docker Imageのインストール

最新版MLflowイメージのPull

docker pull ghcr.io/mlflow/mlflow:latest

MLflowイメージversionの確認

docker run --rm ghcr.io/mlflow/mlflow:latest mlflow --version

MLflowイメージの削除

docker rmi ghcr.io/mlflow/mlflow:latest

DockerベースのMLflow環境の構築

基本手順としては

  • Artifact Storeの作成と指定(./mlruns)
  • Backend Storeの作成と指定(./mlflow.db)

を行います.Dockerベースで行うため,Permissionの指定には注意します.

# MLflowのデータを保存したい任意のディレクトリに移動
cd <target-directory>

# tracking dataを保存するために使用する空のSQLiteデータベースファイルを作成
touch ./mlflow.db

# Artifact(モデル,プロットなど)を保存するためのディレクトリを作成
mkdir -p ./mlruns

# MLflowデータベースファイルに読み書き権限を設定.Dockerコンテナ内でMLflowが正しく動作するために必要
chmod 666 ./mlflow.db

# MLflowの実行(run)ディレクトリに読み書き実行権限を設定.MLflowがArtifactを作成&保存可能にするため必要。
chmod 777 ./mlruns

# MLflowサーバーをDockerコンテナとして起動.--host 0.0.0.0以下はMLflowサーバーに任意のIPアドレスからポート5000でアクセス可能にするため
docker run -d --name mlflow-server -p 5000:5000 \
  -v $(pwd)/mlruns:/mlflow/mlruns \ 
  -v $(pwd)/mlflow.db:/mlflow/mlflow.db \ 
  ghcr.io/mlflow/mlflow:latest mlflow server \ 
  --backend-store-uri sqlite:///mlflow/mlflow.db \ 
  --default-artifact-root /mlflow/mlruns \ 
  --host 0.0.0.0 --port 5000

MLflowコンテナの停止と削除

# 現在実行中のコンテナ mlflow-server を 停止 
docker stop mlflow-server 

# 停止された mlflow-server コンテナを 削除 
docker rm mlflow-server
Note
  • コンテナを削除しても,mlruns/mlflow.db がマウントされていれば中のデータは保持されます

Docker compose fileの作成

  • コンテナの構成・起動・管理を簡潔・再現可能にしたい
  • 毎回 docker runの長いスクリプトを実施したくない

以上の理由から,docker-compose.ymlベースでコンテナの起動を実施します.

docker-compose.ymlの実装

services:
  mlflow-server:
    image: ghcr.io/mlflow/mlflow:latest
    container_name: mlflow-server
    ports:
      - "5000:5000"
    volumes:
      - ./mlruns:/mlflow/mlruns
      - ./mlflow.db:/mlflow/mlflow.db
    command: >
      mlflow server
      --backend-store-uri sqlite:///mlflow/mlflow.db
      --default-artifact-root /mlflow/mlruns
      --host 0.0.0.0
      --port 5000

servicesセクション

services:
  mlflow-server:
  • Compose で起動するサービスの名前を mlflow-server と指定
  • あくまでコンテナ名ではなく,docker composeで管理するサービス名

container_nameの指定

container_name: mlflow-server
  • 起動したコンテナの名前を明示的に mlflow-server に指定

ポートの指定

ports:
  - "5000:5000"
  • host-port:container-portの順番で指定
  • ホストのポート5000 を,コンテナのポート5000 にマッピング
  • http://localhost:5000 でブラウザからアクセスできるようになる

Volumesの指定

volumes:
  - ./mlruns:/mlflow/mlruns
  - ./mlflow.db:/mlflow/mlflow.db
  • artifact(成果物)保存先: ./mlruns:/mlflow/mlruns
  • backend store保存先: ./mlflow.db:/mlflow/mlflow.db

command

  • mlflow server: MLflow Tracking Server を起動
  • --backend-store-uri sqlite:///mlflow/mlflow.db: SQLite を使用
  • --host 0.0.0.0: 外部アクセスを許可

実行方法

# カレントディレクトリに mlflow.db が無いなら作成しておく
touch mlflow.db
chmod 666 mlflow.db  # SQLiteが読み書きできるように

# コンテナ作成
docker compose up -d

# コンテナ起動
docker compose start

# 停止
docker compose stop

# 削除
docker compose down

# 稼動状況の確認
docker ps -f name=mlflow-server
その他の設定例

本記事では紹介しませんが,さらなる設定として以下のような方針が考えられます

  • PostgreSQL や MySQL に backend-store を切り替える
  • S3 や MinIO に artifact-store を変更
  • systemd 経由で自動起動

ssh経由でのMLFlowへのアクセス

ブラウザでlocalhostアクセスするためには,SSH接続時に自動的にポートフォワーディング(ローカルフォワード) する設定が必要です.これは

ssh -L 5000:localhost:5000 user@remote

というコマンドでも実現可能ですが,.ssh/config に以下のように記載したほうが楽に成ると判断しています.

Host mlflowserver
    Hostname mlserver-desktop
    User hoshinokirby
    ForwardAgent yes
    RequestTTY yes 
    LocalForward 5000 localhost:5000

この設定のよって,ssh user@remote だけで,自動的にポートフォワーディングしてくれます.

BackgroundでSSH接続

background接続

MLflowサーバーの ~/mlflow-playgrounddocker-compose.yml があり,それを立ち上がっている状況で,backgroundでssh接続したい場合は以下のコマンドを実行します.

ssh mlflowserver -fN

-fN オプション

オプション 動作
-f SSH接続後,すぐにバックグラウンドに回る(foreground → background)
-N リモートでコマンドを実行せず、シェルも起動しない(トンネル用途向け)
-T 疑似ターミナル(tty)を割り当てない.対話的操作が不要な非対話型コマンドの実行時に使用

接続状況の確認

ssh コマンドがバックグラウンドでまだ動いているか確認したい場合,現在動作中の ssh 関連プロセスを表示することで確かめます.

ps aux | grep "ssh -fN -L 5000:localhost:5000" | grep -v grep
コマンド部分 意味
ps aux 全ユーザー(a)、端末に関係なく(x)、詳細情報(u)付きで すべてのプロセスを一覧表示
grep "ssh" その中から 「ssh」を含む行だけを抽出
grep -v grep さらにそこから grep ssh 自体の行を除外
-vは「除外」を意味)

該当プロセスをkillしたい場合は

# ssh processをkill
kill [PID]

# 強制kill
kill -9 [PID]

となります.または,pkillを用いて

pkill -f "ssh mlflowserver -fT"
部分 意味
pkill 条件に合うプロセスに**終了シグナル(デフォルトは SIGTERM)**を送る
-f プロセス名だけでなくコマンドライン全体を検索対象にする
"ssh mlflowserver -fT" 条件:ssh mlflowserver -fT を含むコマンドを実行しているプロセス

Appendix: Linux File Permission

数値 パーミッション 意味
4 r-- read(読み取り)
2 -w- write(書き込み)
1 --x execute(実行)
0 --- 何も許可しない

Appendix: Docker compose Command

コマンド 何をするか
docker compose up コンテナを作成・起動.構成(Dockerfile, docker-compose.yml)が変われば再構築する
docker compose start すでに存在するコンテナを起動のみする.構成変更は反映されない
docker compose stop コンテナを停止するが,定義やボリュームは残る
docker compose down コンテナを停止・削除し,ネットワークや定義も削除