0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DatabricksにおけるMLflow 3.0のサポート - 従来の機械学習編

Last updated at Posted at 2025-04-09

こちらのマニュアルに沿ってサンプルノートブックを動かします。

注意
執筆時点ではベータ版です。

MLflow 3.0

こちらにもまとめていますが、エクスペリメントページにおけるモデルタブの追加、Logged Modelエンティティの追加、モデルレジストリUIの改善などが含まれています。特に大きな変更点は、情報アーキテクチャが見直されたことだと思います。これまでは、MLflowラン(トレーニングの実行単位)にモデルやアーティファクト、メトリクス、パラメータなどが紐づけられていました。生成AIのように一つのモデルに繰り返し評価が行われる場合や、ディープラーニングのように複数のモデルチェックポイントができる場合には、この情報アーキテクチャでは困難さが生じていたため、今回の変更でモデルに複数のメトリクス、アーティファクトが紐づけられるようになっています。

有効化

ワークスペースのプレビューメニューにアクセスし、MLflow 3を有効化します。

Screenshot 2025-04-09 at 21.15.18.png

従来のMLのワークフロー

こちらのサンプルを動かします。

このノートブックは最初にモデルのトレーニングジョブを実行し、MLflow Runとして追跡され、トレーニングされたモデルを生成します。モデルはMLflow Logged Modelとして追跡されます。

%pip install mlflow  --upgrade --pre
dbutils.library.restartPython()
import pandas as pd
from sklearn.linear_model import ElasticNet
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

import mlflow
import mlflow.sklearn
from mlflow.entities import Dataset

# メトリクスを計算するためのヘルパー関数
def compute_metrics(actual, predicted):
    rmse = mean_squared_error(actual, predicted)
    mae = mean_absolute_error(actual, predicted)
    r2 = r2_score(actual, predicted)
    return rmse, mae, r2


# Irisデータセットをロードし、DataFrameを準備
iris = load_iris()
iris_df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
iris_df['quality'] = (iris.target == 2).astype(int)  # 簡単のためにバイナリターゲットを作成

# トレーニングとテストデータセットに分割
train_df, test_df = train_test_split(iris_df, test_size=0.2, random_state=42)

# トレーニングジョブを表すランを開始
with mlflow.start_run() as training_run:
    # トレーニングデータセットをMLflowでロード。トレーニングメトリクスをこのデータセットにリンク
    train_dataset: Dataset = mlflow.data.from_pandas(train_df, name="train")
    train_x = train_dataset.df.drop(["quality"], axis=1)
    train_y = train_dataset.df[["quality"]]

    # トレーニングデータセットにモデルをフィット
    lr = ElasticNet(alpha=0.5, l1_ratio=0.5, random_state=42)
    lr.fit(train_x, train_y)

    # モデルをログし、ElasticNetのパラメータ(alpha, l1_ratio)を指定
    # 新機能として、LoggedModelエンティティはその名前とパラメータにリンク
    model_info = mlflow.sklearn.log_model(
        sk_model=lr,
        name="elasticnet",
        params={
            "alpha": 0.5,
            "l1_ratio": 0.5,
        },
        input_example = train_x
    )

    # LoggedModelとそのプロパティを確認
    logged_model = mlflow.get_logged_model(model_info.model_id)
    print(logged_model.model_id, logged_model.params)
    # m-fa4e1bca8cb64971bce2322a8fd427d3, {'alpha': '0.5', 'l1_ratio': '0.5'}

    # トレーニングデータセットでモデルを評価し、メトリクスをログ
    # これらのメトリクスはLoggedModelエンティティにリンク
    predictions = lr.predict(train_x)
    (rmse, mae, r2) = compute_metrics(train_y, predictions)
    mlflow.log_metrics(
        metrics={
            "rmse": rmse,
            "r2": r2,
            "mae": mae,
        },
        model_id=logged_model.model_id,
        dataset=train_dataset
    )

    # メトリクスを持つLoggedModelを確認
    logged_model = mlflow.get_logged_model(model_info.model_id)
    print(logged_model.model_id, logged_model.metrics)
    # m-fa4e1bca8cb64971bce2322a8fd427d3, [<Metric: dataset_name='train', key='rmse', model_id='m-fa4e1bca8cb64971bce2322a8fd427d3, value=0.7538635773139717, ...>, ...]

これでランが作成されますが、新たなエンティティとしてモデルが記録されます。エクスペリメントページのモデルタブでも確認できます。

Screenshot 2025-04-09 at 21.16.17.png

しばらくして、最新の本番データに基づいた新しい評価データセットを取得したら、新しいモデル評価ジョブを実行して、この新しいデータセットに対するモデルのパフォーマンスを測定できます。このジョブは新しいMLflow Runとして追跡されます。

この例では、2つのMLflow Run(training_runevaluation_run)と1つのMLflow LoggedModelelasticnet)が生成されます。生成された LoggedModel から、すべてのパラメータとメタデータ、およびトレーニングと評価のランからリンクされたすべてのメトリクスを確認できます。

# テストデータセット評価ジョブを表すランを開始
with mlflow.start_run() as evaluation_run:
  # テストデータセットをMLflowでロード。テストメトリクスをこのデータセットにリンク
  test_dataset: mlflow.entities.Dataset = mlflow.data.from_pandas(test_df, name="test")
  test_x = test_dataset.df.drop(["quality"], axis=1)
  test_y = test_dataset.df[["quality"]]

  # モデルをロード
  model = mlflow.sklearn.load_model(f"models:/{logged_model.model_id}")

  # トレーニングデータセットでモデルを評価し、メトリクスをログ。モデルにリンク
  predictions = model.predict(test_x)
  (rmse, mae, r2) = compute_metrics(test_y, predictions)
  mlflow.log_metrics(
    metrics={
      "rmse": rmse,
      "r2": r2,
      "mae": mae,
    },
    dataset=test_dataset,
    model_id=logged_model.model_id
  )

改めてモデルを確認すると、最初のトレーニングにおけるランとメトリクス、評価のランとメトリクスをモデルから確認できるようになっています。

Screenshot 2025-04-09 at 21.17.21.png

get_logged_modelでも情報を確認できます。

print(mlflow.get_logged_model(logged_model.model_id).to_dictionary())
{'artifact_location': 'dbfs:/databricks/mlflow-tracking/3126308776674605/logged_models/m-c86bf92aab5146fda4b404b0fedae336/artifacts', 'creation_timestamp': 1744200949778, 'experiment_id': '3126308776674605', 'last_updated_timestamp': 1744200955164, 'metrics': [<Metric: dataset_digest='d95ce242', dataset_name='train', key='rmse', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='b41bd03fb85c4648a50b8f13ac4249a7', step=0, timestamp=1744200955317, value=0.13264009364619966>, <Metric: dataset_digest='d95ce242', dataset_name='train', key='r2', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='b41bd03fb85c4648a50b8f13ac4249a7', step=0, timestamp=1744200955317, value=0.395372792495956>, <Metric: dataset_digest='d95ce242', dataset_name='train', key='mae', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='b41bd03fb85c4648a50b8f13ac4249a7', step=0, timestamp=1744200955317, value=0.3209158276037644>, <Metric: dataset_digest='cc28e2f0', dataset_name='test', key='rmse', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='c526255db4f34c169ad46b8529b47a4b', step=0, timestamp=1744201004520, value=0.13442354610166166>, <Metric: dataset_digest='cc28e2f0', dataset_name='test', key='r2', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='c526255db4f34c169ad46b8529b47a4b', step=0, timestamp=1744201004520, value=0.4211426244426051>, <Metric: dataset_digest='cc28e2f0', dataset_name='test', key='mae', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='c526255db4f34c169ad46b8529b47a4b', step=0, timestamp=1744201004520, value=0.3256178886187552>], 'model_id': 'm-c86bf92aab5146fda4b404b0fedae336', 'model_type': '', 'name': 'elasticnet', 'params': {'alpha': '0.5', 'l1_ratio': '0.5'}, 'source_run_id': 'b41bd03fb85c4648a50b8f13ac4249a7', 'status': 2, 'status_message': '', 'tags': {'mlflow.databricks.cluster.id': '0409-121238-ckjb5rwi-v2n', 'mlflow.databricks.notebook.commandID': '1744200760564_8172306878656848519_7ccb8f652f2640609f3486a1a2b0f332', 'mlflow.databricks.notebookID': '3126308776674605', 'mlflow.databricks.notebookPath': '/Users/takaaki.yayoi@databricks.com/20250409_mlflow3.0/mlflow3-ml-example', 'mlflow.databricks.webappURL': 'https://xxxxx.cloud.databricks.com', 'mlflow.databricks.workspaceID': '5099015744649857', 'mlflow.databricks.workspaceURL': 'https://xxxxx.cloud.databricks.com', 'mlflow.source.name': '/Users/takaaki.yayoi@databricks.com/20250409_mlflow3.0/mlflow3-ml-example', 'mlflow.source.type': 'NOTEBOOK', 'mlflow.user': 'spark-f6ea5246-5ebd-427d-9450-f0'}}

次に、モデルをUCに登録します。UCモデルバージョンページでモデルID、パラメータ、およびメトリクスも確認できます。

# カタログに対する `USE CATALOG` 権限、およびスキーマに対する `USE SCHEMA` 権限が必要です。
# 必要に応じて、ここでカタログ名とスキーマ名を変更してください。

CATALOG = "takaakiyayoi_catalog"
SCHEMA = "mlflow"
MODEL = "ml_model"
MODEL_NAME = f"{CATALOG}.{SCHEMA}.{MODEL}"

uc_model_version = mlflow.register_model(model_info.model_uri, name=MODEL_NAME)

これで、Unity Catalogのモデルバージョンページでモデルバージョンとすべての集中化されたパフォーマンスデータを確認できます。

Screenshot 2025-04-09 at 21.18.05.png

次のセルに示すように、APIを使用して同じ情報を取得することもできます。

# モデルバージョンを取得
from mlflow import MlflowClient
client = MlflowClient()
model_version = client.get_model_version(name=MODEL_NAME, version=uc_model_version.version)
print(model_version)
<ModelVersion: aliases=[], creation_timestamp=1744201072223, current_stage=None, deployment_job_state=<ModelVersionDeploymentJobState: current_task_name='', job_id='', job_state='DEPLOYMENT_JOB_CONNECTION_STATE_UNSPECIFIED', run_id='', run_state='DEPLOYMENT_JOB_RUN_STATE_UNSPECIFIED'>, description='', last_updated_timestamp=1744201073758, metrics=[<Metric: dataset_digest='d95ce242', dataset_name='train', key='rmse', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='b41bd03fb85c4648a50b8f13ac4249a7', step=0, timestamp=1744200955317, value=0.13264009364619966>,
 <Metric: dataset_digest='d95ce242', dataset_name='train', key='r2', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='b41bd03fb85c4648a50b8f13ac4249a7', step=0, timestamp=1744200955317, value=0.395372792495956>,
 <Metric: dataset_digest='d95ce242', dataset_name='train', key='mae', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='b41bd03fb85c4648a50b8f13ac4249a7', step=0, timestamp=1744200955317, value=0.3209158276037644>,
 <Metric: dataset_digest='cc28e2f0', dataset_name='test', key='rmse', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='c526255db4f34c169ad46b8529b47a4b', step=0, timestamp=1744201004520, value=0.13442354610166166>,
 <Metric: dataset_digest='cc28e2f0', dataset_name='test', key='r2', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='c526255db4f34c169ad46b8529b47a4b', step=0, timestamp=1744201004520, value=0.4211426244426051>,
 <Metric: dataset_digest='cc28e2f0', dataset_name='test', key='mae', model_id='m-c86bf92aab5146fda4b404b0fedae336', run_id='c526255db4f34c169ad46b8529b47a4b', step=0, timestamp=1744201004520, value=0.3256178886187552>], model_id='m-c86bf92aab5146fda4b404b0fedae336', name='takaakiyayoi_catalog.mlflow.ml_model', params=[<LoggedModelParameter: key='alpha', value='0.5'>,
 <LoggedModelParameter: key='l1_ratio', value='0.5'>], run_id='b41bd03fb85c4648a50b8f13ac4249a7', run_link=None, source='models:/m-c86bf92aab5146fda4b404b0fedae336', status='READY', status_message='', tags={}, user_id='takaaki.yayoi@databricks.com', version='1'>

こちらで、デプロイメントジョブと連携しています。

はじめてのDatabricks

はじめてのDatabricks

Databricks無料トライアル

Databricks無料トライアル

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?