Partilhar via


Exemplo de modelos no Unity Catalog

Este exemplo ilustra como usar Models in Unity Catalog para criar um aplicativo de aprendizado de máquina que prevê a saída diária de energia de um parque eólico. O exemplo mostra como:

  • Rastreie e registre modelos com MLflow.
  • Registre modelos no Unity Catalog.
  • Descreva modelos e implante-os para inferência usando aliases.
  • Integre modelos registados com aplicações de produção.
  • Pesquise e descubra modelos no Catálogo Unity.
  • Excluir modelos.

O artigo descreve como executar essas etapas usando o MLflow Tracking and Models em UIs e APIs do Unity Catalog.

Requisitos

Certifique-se de que cumpre 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 main catálogo.
  • CREATE MODEL e USE SCHEMA privilégios no main.default esquema.

Bloco de Notas

Todo o código neste artigo é fornecido no bloco de anotações a seguir.

Modelos no bloco de anotações de exemplo do Unity Catalog

Obter o bloco de notas

Instalar o cliente Python MLflow

Este exemplo requer o cliente Python MLflow versão 2.5.0 ou superior e o TensorFlow. Adicione os seguintes comandos na parte superior do seu bloco de notas para instalar estas dependências.

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

Carregue o conjunto de dados, treine o modelo e registre-se no Unity Catalog

Esta seção mostra como carregar o conjunto de dados do parque eólico, treinar um 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 conjunto de dados contendo dados meteorológicos e informações de saída de energia para um parque eólico nos Estados Unidos. O conjunto de dados contém wind direction, , e air temperature apresenta amostras a cada seis horas (uma vez a 00:00, uma vez a 08:00, e uma vez a 16:00), bem como a potência agregada diária (power), ao longo wind speedde 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"]

Configurar o cliente MLflow para acessar modelos no Unity Catalog

Por padrão, o cliente Python MLflow cria modelos no registro do modelo de espaço de trabalho no Azure Databricks. Para atualizar para modelos no Unity Catalog, configure o cliente para acessar modelos no Unity Catalog:

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

Modelo de comboio e registo

O código a seguir treina uma rede neural usando o TensorFlow Keras para prever a saída de energia com base nos recursos climáticos no conjunto de dados 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 visualizar e gerenciar modelos registrados e versões de modelos no Catálogo Unity usando o Catalog Explorer. Procure o modelo que você acabou de criar no catálogo e default no main esquema.

Página do modelo registado

Implantar 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 nomeadas mutáveis (por exemplo, "Champion" ou "Challenger") a uma versão específica de um modelo registrado. Você pode fazer referência e direcionar versões de modelo usando esses aliases em fluxos de trabalho de inferência downstream.

Depois de navegar até o modelo registrado no Gerenciador de Catálogos, clique na coluna Aliases para atribuir o alias "Campeão" à versão mais recente do modelo e pressione "Continuar" para salvar as alterações.

Definir alias de modelo registrado

Carregar versões do modelo usando a API

O componente MLflow Models define funções para carregar modelos de várias estruturas de aprendizado de máquina. 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)

Previsão de potência 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 forecast_power() aplicativo carrega a versão mais recente do modelo de previsão do estágio especificado e a 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")

Adicionar descrições de modelo e versão do modelo usando a API

O código nesta seção mostra como você pode adicionar descrições de modelo e versão do 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

As técnicas clássicas de aprendizagem automática também são eficazes para a previsão de energia. O código a seguir treina um modelo de floresta aleatório usando scikit-learn e o registra no Unity Catalog usando a mlflow.sklearn.log_model() função.

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
  )

Obter o número da nova versão do modelo

O código a seguir mostra como recuperar o número de versão mais recente do modelo 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])

Adicionar 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 implantar 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 "Campeão" para indicar 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")

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

Depois de verificar se a nova versão do modelo tem um bom desempenho nos testes, o código a seguir atribui o alias "Campeão" à nova versão do modelo e usa exatamente o mesmo código de aplicativo da saída de potência Forecast 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")

Existem agora 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, todas as cargas de trabalho downstream destinadas à versão do modelo "Challenger" continuam a ser executadas com êxito:

Versões do modelo do produto

Excluir modelos

Quando uma versão do 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 excluir uma versão do modelo limpa todos os aliases atribuídos à versão do modelo.

Excluir Version 1 usando a API MLflow

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

Excluir o modelo usando a API MLflow

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