Modelos no exemplo Unity Catalog

Este exemplo ilustra como usar Modelos no Unity Catalog para criar um aplicativo machine learning que prevê a produção diária de energia de um parque eólico. O exemplo mostra como:

  • Rastreie e modelos logged com MLflow.

  • modelos de registro para Unity Catalog.

  • Descreva modelos e implante-os para inferência usando aliases.

  • Integre modelos registrados com aplicativos de produção.

  • Pesquise e descubra modelos no Unity Catalog.

  • Exclua modelos.

Os artigos descrevem como executar essas passos usando o acompanhamento e modelos do MLflow em UIs e APIs do Unity Catalog.

Requisitos

Certifique-se de atender a todos os requisitos em Requisitos. Além disso, os exemplos de código neste artigo pressupõem que você tenha os seguintes privilégios:

  • USE CATALOG privilégio no catálogo main .

  • CREATE MODEL e privilégios USE SCHEMA no esquema main.default .

Notebook

Todo o código neste artigo é fornecido no Notebook a seguir.

Modelos no Notebook de exemplo Unity Catalog

Abra o bloco de anotações em outra guia

Instale o cliente MLflow Python

Este exemplo requer o cliente MLflow Python versão 2.5.0 ouacima e o TensorFlow. Adicione os seguintes comandos na parteacima do seu Notebook para instalar essas dependências.

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

Carregar conjunto de dados, modelo de ensino e registro no Unity Catalog

Esta seção mostra como carregar o dataset do parque eólico, ensinar o modelo e registrar o modelo no Unity Catalog. A execução de treinamento do modelo e as métricas são rastreadas em uma execução de experimento.

Carregar conjunto de dados

O código a seguir carrega um dataset contendo dados meteorológicos e informações de saída de energia para um parque eólico nos Estados Unidos. O dataset contém recursos wind direction, wind speed e air temperature amostrados a cada seis horas (uma vez em 00:00, uma vez em 08:00 e uma vez em 16:00), bem como a produção de energia agregada diária (power), ao longo de vários anos.

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

Configure o cliente MLflow para acessar modelos no Unity Catalog

Por default, o cliente MLflow Python cria modelos no registro de modelo workspace no Databricks. Para atualizar para modelos no Unity Catalog, configure o cliente para acessar os modelos no Unity Catalog:

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

modelo de ensino e registro

O código a seguir ensina uma rede neural usando TensorFlow Keras para prever a saída de energia com base nos recursos climáticos no dataset e usa APIs MLflow para registrar o modelo ajustado no Unity Catalog.

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)

Exibir o modelo na interface do usuário

Você pode view e gerenciar modelos registrados e versões de modelos no Unity Catalog usando o Catalog Explorer. Procure o modelo que você acabou de criar no catálogo main e no esquema default .

Página modelo registrado

aprimorou uma versão do modelo para inferência

Os modelos no Unity Catalog suportam aliases para implantação de modelos. Os aliases fornecem referências mutáveis e nomeadas (por exemplo, "Champion" ou "Challenger") a uma versão específica de um modelo registrado. O senhor pode fazer referência e direcionar versões do modelo usando esses aliases no fluxo de trabalho de inferência downstream.

Depois de navegar até o modelo registrado no Catalog Explorer, clique na coluna Aliases para atribuir o alias "Champion" à versão mais recente do modelo e pressione "Continue" para salvar as alterações.

Definir alias de modelo registrado

Carregar versões de modelo usando a API

O componente MLflow Models define funções para carregar modelos de várias estruturas machine learning . Por exemplo, mlflow.tensorflow.load_model() é usado para carregar modelos TensorFlow que foram salvos no formato MLflow e mlflow.sklearn.load_model() é usado para carregar modelos Scikit-Learn que foram salvos no formato MLflow.

Essas funções podem carregar modelos de Modelos no Unity Catalog.

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)

Preveja a potência de saída com o modelo campeão

Nesta seção, o modelo campeão é usado para avaliar os dados de previsão do tempo para o parque eólico. O aplicativo forecast_power() carrega a versão mais recente do modelo de previsão do estágio especificado e o usa para prever a produção de energia nos próximos cinco dias.

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

Adicione descrições de modelos e versões de modelos usando a API

O código nesta seção mostra como você pode adicionar descrições de modelo e versão de modelo usando a API MLflow.

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

Criar uma nova versão do modelo

Técnicas clássicas machine learning também são eficazes para previsão de energia. O código a seguir ensina um modelo de floresta aleatória usando Scikit-Learn e registra-o no Unity Catalog usando a função mlflow.sklearn.log_model().

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
  )

Buscar o novo número de versão do modelo

O código a seguir mostra como recuperar o número da versão do modelo mais recente para um nome de modelo.

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

Adicione uma descrição à nova versão do modelo

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

Marque a nova versão do modelo como Challenger e teste o modelo

Antes de aprimorar um modelo para atender ao tráfego de produção, é uma prática recomendada testá-lo em uma amostra de dados de produção. Anteriormente, você usava o alias “Champion” para denotar a versão do modelo que atende à maioria das cargas de trabalho de produção. O código a seguir atribui o alias “Challenger” à nova versão do modelo e avalia seu desempenho.

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

forecast_power(MODEL_NAME, "Challenger")

melhorou a nova versão do modelo como a versão do modelo Champion

Depois de verificar se a nova versão do modelo funciona bem nos testes, o código a seguir atribui o alias “Champion” à nova versão do modelo e usa exatamente o mesmo código de aplicativo da saída de energia da previsão com a seção do modelo campeão para produzir uma previsão de energia.

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

forecast_power(MODEL_NAME, "Champion")

Agora existem duas versões do modelo de previsão: a versão do modelo treinada no modelo Keras e a versão treinada no Scikit-Learn. Observe que o alias “Challenger” permanece atribuído à nova versão do modelo Scikit-Learn , portanto, qualquer carga de trabalho downstream que visa a versão do modelo “Challenger” continua a ser executada com êxito:

Versões do modelo do produto

Excluir modelos

Quando uma versão de modelo não estiver mais sendo usada, você poderá excluí-la. Você também pode excluir um modelo registrado inteiro; isso remove todas as versões de modelo associadas. Observe que a exclusão de uma versão de modelo limpa todos os aliases atribuídos à versão de modelo.

Excluir Version 1 usando a API MLflow

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

Exclua o modelo usando a API MLflow

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