Beispiel für Modelle in Unity Catalog

Dieses Beispiel veranschaulicht, wie Sie Modelle in Unity Catalog verwenden, um eine Machine Learning-Anwendung zu erstellen, die die tägliche Stromerzeugung eines Windparks vorhersagt. Das Beispiel veranschaulicht die folgenden Schritte:

  • Nachverfolgen und Protokollieren von Modellen mit MLflow.
  • Registrieren von Modellen in Unity Catalog.
  • Beschreiben und Bereitstellen von Modellen für Rückschlüsse mithilfe von Aliasen.
  • Integrieren registrierter Modelle in Produktionsanwendungen.
  • Suchen und Ermitteln von Modellen in Unity Catalog.
  • Löschen von Modellen.

In diesem Artikel wird beschrieben, wie Sie diese Schritte mithilfe der Benutzeroberflächen und APIs der MLflow-Nachverfolgung und der Modelle in Unity Catalog ausführen.

Anforderungen

Stellen Sie sicher, dass alle Anforderungen unter Anforderungen erfüllt sind. Darüber hinaus gehen die Codebeispiele in diesem Artikel davon aus, dass Sie über die folgenden Berechtigungen verfügen:

  • Die Berechtigung USE CATALOG für den Katalog main.
  • Die Berechtigungen CREATE MODEL und USE SCHEMA für das Schema main.default.

Notebook

Der gesamte Code in diesem Artikel wird im folgenden Notebook bereitgestellt.

Beispiel-Notebook für Modelle in Unity Catalog

Notebook abrufen

Installieren des MLflow-Python-Clients

Dieses Beispiel erfordert die MLflow-Python-Clientversion 2.5.0 oder höher und TensorFlow. Fügen Sie oben in Ihrem Notebook die folgenden Befehle hinzu, um diese Abhängigkeiten zu installieren.

%pip install --upgrade "mlflow-skinny[databricks]>=2.5.0" tensorflow
dbutils.library.restartPython()

Laden des Datasets, Trainieren des Modells und Registrieren bei Unity Catalog

In diesem Abschnitt wird gezeigt, wie Sie das Windpark-Dataset laden, ein Modell trainieren und das Modell bei Unity Catalog registrieren. Die Modelltrainingsausführung und -metriken werden in einer Experimentausführung nachverfolgt.

Laden des Datasets

Der folgende Code lädt ein Dataset mit Wetterdaten und Informationen zur Stromerzeugung für einen Windpark in den USA. Das Dataset enthält die Merkmale wind direction, wind speed und air temperature, von denen alle sechs Stunden (einmal um 00:00, einmal um 08:00 und einmal um 16:00) Stichproben genommen werden sowie die tägliche aggregierte Stromerzeugung (power), über mehrere Jahre hinweg.

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"]

Konfigurieren des MLflow-Clients für den Zugriff auf Modelle in Unity Catalog

Standardmäßig erstellt der MLflow-Python-Client Modelle in der Arbeitsbereichsmodellregistrierung in Azure Databricks. Um ein Upgrade auf Modelle in Unity Catalog durchzuführen, konfigurieren Sie den Client für den Zugriff auf Modelle in Unity Catalog:

import mlflow
mlflow.set_registry_uri("databricks-uc")

Trainieren und Registrieren von Modellen

Der folgende Code trainiert ein neuronales Netz mithilfe von TensorFlow Keras, um die Stromerzeugung basierend auf den Wettermerkmalen im Dataset vorherzusagen, und nutzt MLflow-APIs, um das angepasste Modell bei Unity Catalog zu registrieren.

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

MODEL_NAME = "main.default.wind_forecasting"

def train_and_register_keras_model(X, y):
  with mlflow.start_run():
    model = Sequential()
    model.add(Dense(100, input_shape=(X.shape[-1],), activation="relu", name="hidden_layer"))
    model.add(Dense(1))
    model.compile(loss="mse", optimizer="adam")

    model.fit(X, y, epochs=100, batch_size=64, validation_split=.2)
    example_input = X[:10].to_numpy()
    mlflow.tensorflow.log_model(
        model,
        artifact_path="model",
        input_example=example_input,
        registered_model_name=MODEL_NAME
    )
  return model

X_train, y_train = get_training_data()
model = train_and_register_keras_model(X_train, y_train)

Anzeigen des Modells auf der Benutzeroberfläche

Sie können registrierte Modelle und Modellversionen in Unity Catalog mit dem Katalog-Explorer anzeigen und verwalten. Suchen Sie nach dem Modell, das Sie gerade im Katalog main mit dem Schema default erstellt haben.

Die Seite „Registriertes Modell“

Bereitstellen einer Modellversion für Rückschlüsse

Modelle in Unity Catalog unterstützen Aliase für die Modellbereitstellung. Aliase bieten veränderliche benannte Verweise (z. B. „Champion“ oder „Challenger“) auf eine bestimmte Version eines registrierten Modells. Sie können mithilfe dieser Aliase in nachgelagerten Rückschlussworkflows auf Modellversionen verweisen und diese als Ziel festlegen.

Nachdem Sie zum registrierten Modell im Katalog-Explorer navigiert sind, klicken Sie unter der Spalte Aliase, um der neuesten Modellversion den Alias „Champion“ zuzuweisen. Klicken Sie anschließend auf „Weiter“, um die Änderungen zu speichern.

Festlegen eines registrierten Modellalias

Laden von Modellversionen mithilfe der API

Die Komponente „MLflow-Modelle“ definiert Funktionen zum Laden von Modellen aus mehreren Machine Learning-Frameworks. Beispielsweise wird mlflow.tensorflow.load_model() verwendet, um TensorFlow-Modelle zu laden, die im MLflow-Format gespeichert wurden. mlflow.sklearn.load_model() wird verwendet, um scikit-learn-Modelle zu laden, die im MLflow-Format gespeichert wurden.

Diese Funktionen können Modelle aus Modellen in Unity Catalog laden.

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_champion_uri = "models:/{model_name}@Champion".format(model_name=MODEL_NAME)

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

Vorhersagen der Stromerzeugung mit dem Champion-Modell

In diesem Abschnitt wird das Champion-Modell verwendet, um Wettervorhersagedaten für den Windpark auszuwerten. Die forecast_power()-Anwendung lädt die neueste Version des Vorhersagemodells aus der angegebenen Phase und verwendet es, um die Stromerzeugung für die nächsten fünf Tage vorherzusagen.

from mlflow.tracking import MlflowClient

def plot(model_name, model_alias, model_version, power_predictions, past_power_output):
  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'\nwith alias '%s' (Version %d)" % (model_name, model_alias, 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_alias):
  import pandas as pd
  client = MlflowClient()
  model_version = client.get_model_version_by_alias(model_name, model_alias).version
  model_uri = "models:/{model_name}@{model_alias}".format(model_name=MODEL_NAME, model_alias=model_alias)
  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_alias, int(model_version), power_predictions, past_power_output)

forecast_power(MODEL_NAME, "Champion")

Hinzufügen von Modell- und Modellversionsbeschreibungen mithilfe der API

Der Code in diesem Abschnitt zeigt, wie Sie mithilfe der MLflow-API Modell- und Modellversionsbeschreibungen hinzufügen können.

client = MlflowClient()
client.update_registered_model(
  name=MODEL_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_NAME,
  version=1,
  description="This model version was built using TensorFlow Keras. It is a feed-forward neural network with one hidden layer."
)

Erstellen einer neuen Modellversion

Klassische Machine Learning-Methoden sind auch bei der Stromerzeugungsvorhersage effektiv. Der folgende Code trainiert ein Modell mit einer zufälligen Gesamtstruktur (Random Forest) mit scikit-learn und registriert es über die mlflow.sklearn.log_model()-Funktion bei Unity Catalog.

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)

  example_input = val_x.iloc[[0]]

  # Specify the `registered_model_name` parameter of the `mlflow.sklearn.log_model()`
  # function to register the model to <UC>. This automatically
  # creates a new model version
  mlflow.sklearn.log_model(
    sk_model=rand_forest,
    artifact_path="sklearn-model",
    input_example=example_input,
    registered_model_name=MODEL_NAME
  )

Abrufen der neuen Modellversionsnummer

Der folgende Code zeigt, wie Sie die neueste Modellversionsnummer für einen Modellnamen abrufen.

client = MlflowClient()
model_version_infos = client.search_model_versions("name = '%s'" % MODEL_NAME)
new_model_version = max([model_version_info.version for model_version_info in model_version_infos])

Hinzufügen einer Beschreibung zur neuen Modellversion

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."
)

Markieren der neuen Modellversion als „Challenger“ und Testen des Modells

Vor der Bereitstellung eines Modells zum Bereitstellen von Produktionsdatenverkehr empfiehlt es sich, es an einem Beispiel von Produktionsdaten zu testen. Zuvor haben Sie den Alias „Champion“ verwendet, um die Modellversion anzugeben, die den Großteil der Produktionsworkloads bedient. Der folgende Code weist der neuen Modellversion den Alias „Challenger“ zu und bewertet dessen Leistung.

client.set_registered_model_alias(
  name=MODEL_NAME,
  alias="Challenger",
  version=new_model_version
)

forecast_power(MODEL_NAME, "Challenger")

Bereitstellen der neuen Modellversion als Champion-Modellversion

Nachdem überprüft wurde, ob die neue Modellversion in Tests gut funktioniert, weist der folgende Code den Alias „Champion“ der neuen Modellversion zu und verwendet genau denselben Anwendungscode aus dem Abschnitt Vorhersagen der Stromerzeugung mit dem Champion-Modell, um eine Stromerzeugungsvorhersage zu erstellen.

client.set_registered_model_alias(
  name=MODEL_NAME,
  alias="Champion",
  version=new_model_version
)

forecast_power(MODEL_NAME, "Champion")

Es gibt jetzt zwei Modellversionen des Vorhersagemodells: die im Keras-Modell trainierte Modellversion und die in scikit-learn trainierte Version. Beachten Sie, dass der Challenger-Alias der neuen scikit-learn-Modellversion zugewiesen bleibt, sodass alle Downstreamworkloads für die Challenger-Modellversion weiterhin erfolgreich ausgeführt werden:

Produktmodellversionen

Löschen von Modellen

Wenn eine Modellversion nicht mehr verwendet wird, können Sie sie löschen. Sie können auch ein vollständiges registriertes Modell löschen. Dadurch werden alle zugehörigen Modellversionen entfernt. Beachten Sie, dass beim Löschen einer Modellversion alle Aliase gelöscht werden, die der Modellversion zugewiesen sind.

Löschen der Version 1 mithilfe der MLflow-API

client.delete_model_version(
   name=MODEL_NAME,
   version=1,
)

Löschen des Modells mithilfe der MLflow-API

client = MlflowClient()
client.delete_registered_model(name=MODEL_NAME)