MLflowをローカル環境で実装しよう

はじめまして。
皆さんは **ML Ops** に興味を持ったことはありますか？  
私自身、業務でML Opsの環境構築を担当しており、「これをローカル環境で簡単に再現できないか？」と考え、 **Docker** を使って試してみました。今回は、ML Ops環境の中でも重要な **MLflow** を使ってローカル環境で構築する手順をまとめます。

このブログでは以下の内容をカバーします：

- **MLflowとは何か**  
- **Dockerを使ったローカル環境構築の方法**  
- **サンプルコードの実行手順と結果の確認方法**

# MLflowとは
**MLflow** は、ML Opsの主要なプラットフォームの一つで、実験の記録・モデル管理・デプロイメントを一元管理できるツールです。

以下の機能を提供します：
- **Tracking**：機械学習実験の記録（パラメータ、メトリクス、モデル）
- **Projects**：プロジェクト構成の標準化
- **Models**：モデルの保存と再利用
- **Registry**：モデルのバージョン管理と運用環境へのデプロイ

[公式ドキュメント](https://mlflow.org/#core-concepts) も参照してください。

---


# Docker環境で再現

今回は、MLflowサーバーとPython実行環境を **分離した構成** にします。こうすることで、MLflowとPython環境の管理を柔軟に行えます。

## ディレクトリ構成
```ディレクトリ構成
mlflow-docker-compose/
├── mlruns/                # MLflowの実験記録
├── Dockerfile             # MLflowサーバー用Dockerfile
├── docker-compose.yml     # Docker Compose設定
├── python/                # Python実行環境用ディレクトリ
│   ├── Dockerfile         # Python用のDockerfile
│   ├── train.py           # トレーニングスクリプト
│   └── requirements.txt   # Python依存ライブラリの定義
```

### 解説
+ **mlruns/**: 実験結果が自動的に記録されるディレクトリです。これをDockerコンテナの外にマウントしておくことで、コンテナを削除しても記録が消えません。
+ **docker-compose.yml**: 複数のDockerコンテナを一括で管理するための設定ファイルです。


## MLflowサーバーの構築
### mlflow-docker-compose/Dockerfile

```mlflow-docker-compose/Dockerfile
FROM python:3.9-slim

# 必要なライブラリをインストール
RUN pip install --no-cache-dir mlflow

# ポート5001を公開
EXPOSE 5001

# MLflowサーバーを起動
ENTRYPOINT ["mlflow", "server", "--host", "0.0.0.0", "--port", "5000"]
```

### ポイント：

+ ポート番号は自由に変更可能です。今回は5001を使用します。
+ --host 0.0.0.0 で外部からの接続を許可します。

## Docker Composeによる構成管理
### mlflow-docker-compose/docker-compose.yml 
```mlflow-docker-compose/docker-compose.yml 
version: '3'
services:
  mlflow:
    build:
      context: .
      dockerfile: Dockerfile  # MLflow用のDockerfile
    ports:
      - "5001:5000"
    networks:
      - mlflow-network
    volumes:
      - ./mlruns:/mlflow/mlruns

  python-env:
    build:
      context: ./python
    depends_on:
      - mlflow
    environment:
      - MLFLOW_TRACKING_URI=http://mlflow:5000
    networks:
      - mlflow-network  # 同じネットワークを指定
    volumes:
      - ./data:/app/data
      - ./mlruns:/mlflow/mlruns

networks:
  mlflow-network:
    driver: bridge
```
### 解説：

+ ネットワーク（mlflow-network） を使い、MLflowとPython実行環境が同じネットワーク内で通信できるようにしています。
+ volumes を使用して、実験結果（mlruns）やデータをホストマシンと共有します。

### ※補足
### mlflow-docker-compose/mlruns
mlrunsディレクトリはMLflowのTrackingの情報が格納されます。
MLflowのTrackingは、機械学習プロジェクトの実験管理に使用するモジュールです。モデルの学習や評価の過程で得られるパラメータ、メトリクス、アーティファクト（モデルやログファイルなど）を記録し、後から比較・分析できるようにします。
詳細は[trackingとは](https://mlflow.org/docs/latest/tracking.html)をご参照ください。


## pytho実施環境の構築
### mlflow-docker-compose/python/Dockerfile
```mlflow-docker-compose/python/Dockerfile
FROM python:3.9-slim

# 作業ディレクトリの設定
WORKDIR /app

# 必要なファイルをコンテナにコピー
COPY requirements.txt .
COPY train.py .

# 依存ライブラリのインストール
RUN pip install --no-cache-dir -r requirements.txt

# train.pyを実行するエントリーポイント
ENTRYPOINT ["python", "train.py"]
```


### mlflow-docker-compose/python/requirements.txt
```mlflow-docker-compose/python/requirements.txt
mlflow
scikit-learn
pandas
```
**最低限のライブラリ** だけをインストールし、軽量なコンテナを目指しています。
### トレーニングスクリプト
#### mlflow-docker-compose/python/train.py
```mlflow-docker-compose/python/train.py
import mlflow
import mlflow.sklearn
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# Dockerコンテナ間の通信ではサービス名（mlflow）を使用
mlflow.set_tracking_uri("http://mlflow:5000")

mlflow.set_experiment("Iris Classifier Experiment")

# データの読み込みと分割
iris = load_iris()
X = iris.data
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# モデルの構築と評価
with mlflow.start_run():
    clf = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    acc = accuracy_score(y_test, y_pred)

    # パラメータとメトリクスの記録
    mlflow.log_param("n_estimators", 100)
    mlflow.log_param("max_depth", 5)
    mlflow.log_metric("accuracy", acc)

    # モデルの保存
    mlflow.sklearn.log_model(clf, "model")
```
### 解説：

+ with mlflow.start_run() で実験のトラッキングを開始します。
+ 学習したモデルやメトリクスを MLflow UI から簡単に確認できます。

## 実行手順
1\. Dockerコンテナのビルド：
```
docker-compose up -d --build
```
2\. Pythonコンテナでtrain.pyを実行：
```
docker-compose run python-env
```
3\. MLflow UIの確認：
```
http://localhost:5001
```
### 結果確認：
+ 実験結果が MLflow UI に表示され、パラメータやモデルの詳細を確認できます。

# おわりに
今回は、MLflowを使ったローカルML Ops環境の構築方法を紹介しました。
この手法を使えば、手軽に実験を管理し、モデルのトラッキングやバージョン管理ができます。いずれさらに踏み込んだ内容を行いたいです。