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 nomain
catálogo.CREATE MODEL
eUSE SCHEMA
privilégios nomain.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
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 speed
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"]
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.
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.
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:
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)