ワークスペースモデルレジストリの例

このドキュメントでは、ワークスペースモデルレジストリについて説明します。 Databricks では、 Unity Catalog上でモデルを使用することをお勧めします。Unity Catalog のモデルは、一元化されたモデル ガバナンス、ワークスペース間のアクセス、系列、デプロイを提供します。 ワークスペースモデルレジストリは将来非推奨になります。

この例では、Workspace モデルレジストリを使用して、風力発電所の毎日の電力出力を予測する機械学習アプリケーションを構築する方法を示します。 この例では、次の方法を示します。

  • MLflow を使用した追跡と記録済みモデル

  • モデルレジストリへのモデルの登録

  • モデルを記述し、モデルバージョンを作成する ステージの移行

  • 登録済みモデルを本番アプリケーションと統合する

  • モデルレジストリでのモデルの検索と検出

  • モデルのアーカイブと削除

この記事では、MLflow トラッキングと MLflow モデルレジストリの UI と APIsを使用してこれらのステップを実行する方法について説明します。

MLflow 追跡とレジストリ APIsを使用してこれらすべての手順を実行するノートブックについては、 Model Registry サンプル ノートブックを参照してください。

データセットの読み込み、モデルのトレーニング、MLflowトラッキングによるトラッキング

モデルレジストリにモデルを登録する前に、まずトレーニングする エクス ペリメント の実行中に モデルを ログに記録する必要があります。このセクションでは、風力発電所のデータセットを読み込み、モデルをトレーニングし、トレーニングする実行を MLflow に記録する方法について説明します。

データセットの読み込み

次のコードは、米国の風力発電所の気象データと電力出力情報を含むデータセットを読み込みます。 データセットには、6 時間ごとにサンプリングされた wind directionwind speed、および air temperature フィーチャ ( 00:00に 1 回、 08:00に 1 回、 16:00に 1 回)、および数年にわたる毎日の総出力 (power) が含まれています。

import pandas as pd
wind_farm_data = pd.read_csv("https://github.com/dbczumar/model-registry-demo-notebook/raw/master/dataset/windfarm_data.csv", index_col=0)

def get_training_data():
  training_data = pd.DataFrame(wind_farm_data["2014-01-01":"2018-01-01"])
  X = training_data.drop(columns="power")
  y = training_data["power"]
  return X, y

def get_validation_data():
  validation_data = pd.DataFrame(wind_farm_data["2018-01-01":"2019-01-01"])
  X = validation_data.drop(columns="power")
  y = validation_data["power"]
  return X, y

def get_weather_and_forecast():
  format_date = lambda pd_date : pd_date.date().strftime("%Y-%m-%d")
  today = pd.Timestamp('today').normalize()
  week_ago = today - pd.Timedelta(days=5)
  week_later = today + pd.Timedelta(days=5)

  past_power_output = pd.DataFrame(wind_farm_data)[format_date(week_ago):format_date(today)]
  weather_and_forecast = pd.DataFrame(wind_farm_data)[format_date(week_ago):format_date(week_later)]
  if len(weather_and_forecast) < 10:
    past_power_output = pd.DataFrame(wind_farm_data).iloc[-10:-5]
    weather_and_forecast = pd.DataFrame(wind_farm_data).iloc[-10:]

  return weather_and_forecast.drop(columns="power"), past_power_output["power"]

モデルをトレーニングする

次のコードは、TensorFlow Keras を使用してニューラルネットワークをトレーニングし、データセット内の天気特徴に基づいて電力出力を予測します。 MLflow は、モデルのハイパーパラメーター、パフォーマンス メトリック、ソース コード、および成果物を追跡するために使用されます。

def train_keras_model(X, y):
  import tensorflow.keras
  from tensorflow.keras.models import Sequential
  from tensorflow.keras.layers import Dense

  model = Sequential()
  model.add(Dense(100, input_shape=(X_train.shape[-1],), activation="relu", name="hidden_layer"))
  model.add(Dense(1))
  model.compile(loss="mse", optimizer="adam")

  model.fit(X_train, y_train, epochs=100, batch_size=64, validation_split=.2)
  return model

import mlflow

X_train, y_train = get_training_data()

with mlflow.start_run():
  # Automatically capture the model's parameters, metrics, artifacts,
  # and source code with the `autolog()` function
  mlflow.tensorflow.autolog()

  train_keras_model(X_train, y_train)
  run_id = mlflow.active_run().info.run_id

MLflow UIを使用したモデルの登録と管理

新しい登録済みモデルを作成する

  1. Databricks ノートブックの右側のサイドバーにあるエクスペリメント アイコン をクリックして、MLflow エクスペリメント の実行サイドバーに移動します。 エクスペリメント アイコン

    実行サイドバー
  2. TensorFlow Kerasモデル トレーニングセッションに対応する MLflow 実行を見つけ、[実行 の詳細の表示] アイコンをクリックして MLflow 実行 UI で開きます。

  3. MLflow UI で、[ 成果物 ] セクションまで下にスクロールし、 model という名前のディレクトリをクリックします。 表示される [ モデルに登録する モデル ] ボタンをクリックします。

    登録する model
  4. ドロップダウン メニューから [ 新しいモデルの作成 ] を選択し、モデル名 power-forecasting-modelを入力します。

  5. [ 登録する] をクリックします。 これにより、 power-forecasting-model という新しいモデルが登録され、新しいモデル バージョン Version 1が作成されます。

    新しいモデルバージョン

    しばらくすると、MLflow UI に新しく登録されたモデルへのリンクが表示されます。 このリンクをたどって、MLflow モデルレジストリ UI で新しいモデル バージョンを開きます。

モデルレジストリ UI を調べる

MLflow モデルレジストリ UI のモデル バージョン ページには、作成者、作成時刻、現在のステージなど、登録されている予測モデルの Version 1 に関する情報が表示されます。

モデル バージョン ページ

モデル バージョン ページには、MLflow 実行 UI でモデルを作成するために使用された MLflow 実行を開く [ ソースの実行 ] リンクもあります。 MLflow 実行 UI から [ ソース ノートブック] リンクにアクセスして、モデルのトレーニングに使用された Databricks ノートブックのスナップショットを表示できます。

ソース実行
ソース ノートブック

MLflow Model Registry に戻るには、サイドバーの [モデル アイコン モデル] をクリックします 。

結果の MLflow モデルレジストリ ホーム ページには、Databricks ワークスペースに登録されているすべてのモデルの一覧が、バージョンとステージを含めて表示されます。

電力予測モデルの リンクをクリックして、登録済みモデル ページを開き、予測モデルのすべてのバージョンを表示します。

モデルの説明を追加する

登録済みモデルとモデルバージョンに説明を追加できます。 登録されたモデルの説明は、複数のモデルバージョンに適用される情報(モデリングの問題とデータセットの一般的な概要など)を記録するのに役立ちます。 モデルバージョンの記述は、特定のモデルバージョンの一意の属性(モデルの開発に使用される方法論やアルゴリズムなど)を詳述するのに役立ちます。

  1. 登録済みの電力予測モデルに高レベルの説明を追加します。 アイコンをクリックし、 編集アイコン 次の説明を入力します。

    This model forecasts the power output of a wind farm based on weather data. The weather data consists of three features: wind speed, wind direction, and air temperature.
    
    モデルの説明を追加する
  2. [保存]をクリックします。

  3. 登録済みモデル ページの [バージョン 1] リンクをクリックして、モデル バージョン ページに戻ります。

  4. アイコンをクリックし、 編集アイコン 次の説明を入力します。

    This model version was built using TensorFlow Keras. It is a feed-forward neural network with one hidden layer.
    
    モデル バージョンの説明を追加する
  5. [保存]をクリックします。

モデル バージョンの移行

MLflow モデルレジストリでは、いくつかのモデル ステージ ( なしステージング運用、 Archived) が定義されています。各段階には固有の意味があります。 たとえば、 ステージング はモデル テスト用ですが、 運用環境 はテストまたはレビュー プロセスを完了し、アプリケーションにデプロイされたモデル用です。

  1. [ステージ] ボタンをクリックすると、使用可能なモデル ステージのリストと、使用可能なステージの移行オプションが表示されます。

  2. [-> 本番に移行]を選択し、ステージの移行確認ウィンドウで [OK]を押して、モデルを 本番に移行します。

    本番運用への移行

    モデル バージョンが 運用環境に移行すると、現在のステージが UI に表示され、移行を反映するエントリがアクティビティ ログに追加されます。

    本番運用段階
    モデル バージョンのアクティビティ

MLflow モデルレジストリを使用すると、複数のモデル バージョンで同じステージを共有できます。 ステージ別にモデルを参照する場合、モデルレジストリは最新のモデル バージョン (バージョン ID が最大のモデル バージョン) を使用します。 [登録済みモデル] ページには、特定のモデルのすべてのバージョンが表示されます。

登録済みモデルページ

MLflow APIを使用したモデルの登録と管理

プログラムによるモデル名の定義

モデルが登録され、 運用環境に移行されたので、MLflow プログラムによる APIsを使用してモデルを参照できます。 登録済みモデルの名前を次のように定義します。

model_name = "power-forecasting-model"

モデルを登録する

model_name = get_model_name()

import mlflow

# The default path where the MLflow autologging function stores the TensorFlow Keras model
artifact_path = "model"
model_uri = "runs:/{run_id}/{artifact_path}".format(run_id=run_id, artifact_path=artifact_path)

model_details = mlflow.register_model(model_uri=model_uri, name=model_name)

import time
from mlflow.tracking.client import MlflowClient
from mlflow.entities.model_registry.model_version_status import ModelVersionStatus

# Wait until the model is ready
def wait_until_ready(model_name, model_version):
  client = MlflowClient()
  for _ in range(10):
    model_version_details = client.get_model_version(
      name=model_name,
      version=model_version,
    )
    status = ModelVersionStatus.from_string(model_version_details.status)
    print("Model status: %s" % ModelVersionStatus.to_string(status))
    if status == ModelVersionStatus.READY:
      break
    time.sleep(1)

wait_until_ready(model_details.name, model_details.version)

API を使用したモデルとモデル バージョンの説明の追加

from mlflow.tracking.client import MlflowClient

client = MlflowClient()
client.update_registered_model(
  name=model_details.name,
  description="This model forecasts the power output of a wind farm based on weather data. The weather data consists of three features: wind speed, wind direction, and air temperature."
)

client.update_model_version(
  name=model_details.name,
  version=model_details.version,
  description="This model version was built using TensorFlow Keras. It is a feed-forward neural network with one hidden layer."
)

API を使用してモデルバージョンを移行し、詳細を取得する

client.transition_model_version_stage(
  name=model_details.name,
  version=model_details.version,
  stage='production',
)
model_version_details = client.get_model_version(
  name=model_details.name,
  version=model_details.version,
)
print("The current model stage is: '{stage}'".format(stage=model_version_details.current_stage))

latest_version_info = client.get_latest_versions(model_name, stages=["production"])
latest_production_version = latest_version_info[0].version
print("The latest production version of the model '%s' is '%s'." % (model_name, latest_production_version))

APIを使用した登録済みモデルバージョンの読み込み

MLflow モデル コンポーネントは、複数の機械学習フレームワークからモデルを読み込むための関数を定義します。 たとえば、mlflow.tensorflow.load_model() は MLflow 形式で保存された TensorFlow モデルをロードするために使用され、 mlflow.sklearn.load_model() は MLflow 形式で保存された Scikit-Learn モデルをロードするために使用されます。

これらの関数は、MLflow モデルレジストリからモデルを読み込むことができます。

import mlflow.pyfunc

model_version_uri = "models:/{model_name}/1".format(model_name=model_name)

print("Loading registered model version from URI: '{model_uri}'".format(model_uri=model_version_uri))
model_version_1 = mlflow.pyfunc.load_model(model_version_uri)

model_production_uri = "models:/{model_name}/production".format(model_name=model_name)

print("Loading registered model version from URI: '{model_uri}'".format(model_uri=model_production_uri))
model_production = mlflow.pyfunc.load_model(model_production_uri)

本番運用モデルによる出力の予測

このセクションでは、実稼働モデルを使用して、風力発電所の天気予報データを評価します。 forecast_power() アプリケーションは、指定されたステージから最新バージョンの予測モデルを読み込み、それを使用して今後 5 日間の電力本番運用を予測します。

def plot(model_name, model_stage, model_version, power_predictions, past_power_output):
  import pandas as pd
  import matplotlib.dates as mdates
  from matplotlib import pyplot as plt
  index = power_predictions.index
  fig = plt.figure(figsize=(11, 7))
  ax = fig.add_subplot(111)
  ax.set_xlabel("Date", size=20, labelpad=20)
  ax.set_ylabel("Power\noutput\n(MW)", size=20, labelpad=60, rotation=0)
  ax.tick_params(axis='both', which='major', labelsize=17)
  ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d'))
  ax.plot(index[:len(past_power_output)], past_power_output, label="True", color="red", alpha=0.5, linewidth=4)
  ax.plot(index, power_predictions.squeeze(), "--", label="Predicted by '%s'\nin stage '%s' (Version %d)" % (model_name, model_stage, model_version), color="blue", linewidth=3)
  ax.set_ylim(ymin=0, ymax=max(3500, int(max(power_predictions.values) * 1.3)))
  ax.legend(fontsize=14)
  plt.title("Wind farm power output and projections", size=24, pad=20)
  plt.tight_layout()
  display(plt.show())

def forecast_power(model_name, model_stage):
  from mlflow.tracking.client import MlflowClient
  client = MlflowClient()
  model_version = client.get_latest_versions(model_name, stages=[model_stage])[0].version
  model_uri = "models:/{model_name}/{model_stage}".format(model_name=model_name, model_stage=model_stage)
  model = mlflow.pyfunc.load_model(model_uri)
  weather_data, past_power_output = get_weather_and_forecast()
  power_predictions = pd.DataFrame(model.predict(weather_data))
  power_predictions.index = pd.to_datetime(weather_data.index)
  print(power_predictions)
  plot(model_name, model_stage, int(model_version), power_predictions, past_power_output)

新しいモデルバージョンを作成する

従来の機械学習手法は、電力予測にも効果的です。 次のコードは、 Scikit-Learn を使用してランダムフォレストモデルをトレーニングし、 mlflow.sklearn.log_model() 関数を介してMLflowモデルレジストリで登録します。

import mlflow.sklearn
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error

with mlflow.start_run():
  n_estimators = 300
  mlflow.log_param("n_estimators", n_estimators)

  rand_forest = RandomForestRegressor(n_estimators=n_estimators)
  rand_forest.fit(X_train, y_train)

  val_x, val_y = get_validation_data()
  mse = mean_squared_error(rand_forest.predict(val_x), val_y)
  print("Validation MSE: %d" % mse)
  mlflow.log_metric("mse", mse)

  # Specify the `registered_model_name` parameter of the `mlflow.sklearn.log_model()`
  # function to register the model with the MLflow Model Registry. This automatically
  # creates a new model version
  mlflow.sklearn.log_model(
    sk_model=rand_forest,
    artifact_path="sklearn-model",
    registered_model_name=model_name,
  )

新しいモデルバージョンに説明を追加する

client.update_model_version(
  name=model_name,
  version=new_model_version,
  description="This model version is a random forest containing 100 decision trees that was trained in scikit-learn."
)

新しいモデル バージョンをStagingに移行し、モデルをテストする

モデルを運用アプリケーションにデプロイする前に、多くの場合、ステージング環境でテストすることをお勧めします。 次のコードは、新しいモデル バージョンを ステージング に移行し、そのパフォーマンスを評価します。

client.transition_model_version_stage(
  name=model_name,
  version=new_model_version,
  stage="Staging",
)

forecast_power(model_name, "Staging")

新しいモデルバージョンをProductionにデプロイする

次のコードでは、新しいモデル バージョンがステージングで適切に動作することを確認した後、モデルを運用環境に移行し、「 運用モデルで電力出力を予測する 」セクションのまったく同じアプリケーション コードを使用して、電力予測を生成します。

client.transition_model_version_stage(
  name=model_name,
  version=new_model_version,
  stage="production",
)

forecast_power(model_name, "production")

運用 ステージには、KerasModel でトレーニングされたモデル バージョンと Scikit-Learnでトレーニングされたバージョンの 2 つのモデル バージョンの [運用] ステージの予測モデルがあります。

製品モデルのバージョン

ステージごとにモデルを参照する場合、MLflow モデル モデルレジストリでは最新の製品バージョンが自動的に使用されます。 これにより、アプリケーション コードを変更せずに運用モデルを更新できます。

モデルのアーカイブと削除

モデルバージョンが使用されなくなったら、アーカイブまたは削除することができます。 登録済みのモデル全体を削除することもできます。これにより、関連付けられているすべてのモデル バージョンが削除されます。

電力予測モデルVersion 1のアーカイブ

電力予測モデルは使用されなくなったため、 Version 1 をアーカイブします。 モデルは、MLflow モデルレジストリ UI または MLflow API を使用してアーカイブできます。

MLflow UIでのVersion 1のアーカイブ

電力予測モデルの Version 1 をアーカイブするには:

  1. MLflow モデルレジストリ UI で対応するモデル バージョン ページを開きます。

    アーカイブへの移行
  2. [ステージ] ボタンをクリックし、[アーカイブ済み] > に移行を選択します。

    アーカイブされたステージ
  3. ステージの移行確認ウィンドウで OK を押します。

    アーカイブされたモデルバージョン

MLflow APIを使用したVersion 1のアーカイブ

次のコードでは、 MlflowClient.update_model_version() 関数を使用して、電力予測モデルの Version 1 をアーカイブします。

from mlflow.tracking.client import MlflowClient

client = MlflowClient()
client.transition_model_version_stage(
  name=model_name,
  version=1,
  stage="Archived",
)

電力予測モデルのVersion 1を削除する

MLflow UI または MLflow API を使用して、モデル バージョンを削除することもできます。

警告

モデル バージョンの削除は永続的であり、元に戻すことはできません。

MLflow UIでVersion 1を削除する

電力予測モデルの Version 1 を削除するには:

  1. MLflow モデルレジストリ UI で、対応するモデル バージョン ページを開きます。

    モデル バージョンの削除
  2. バージョン識別子の横にあるドロップダウン矢印を選択し、[ 削除] をクリックします。

MLflow APIを使用したVersion 1の削除
client.delete_model_version(
   name=model_name,
   version=1,
)
MLflow APIを使用してモデルを削除する

最初に、残りのすべてのモデルバージョンステージを「 なし 」または 「アーカイブ済み」に移行する必要があります。

from mlflow.tracking.client import MlflowClient

client = MlflowClient()
client.transition_model_version_stage(
  name=model_name,
  version=2,
  stage="Archived",
)
client.delete_registered_model(name=model_name)

ノートブック

MLflow モデルレジストリ サンプル ノートブック

ノートブックを新しいタブで開く