Exemplo de modelos no Catálogo do Unity
Este exemplo ilustra como usar Modelos no Catálogo do Unity para criar um aplicativo de aprendizado de máquina que prevê a produção diária de energia de um parque eólico. O exemplo mostra como:
- Rastrear e registrar modelos com o MLflow.
- Registrar os modelos no Catálogo do Unity.
- Descrever modelos e implantá-los para inferência usando aliases.
- Integrar modelos registrados com aplicativos de produção.
- Pesquisar e descobrir modelos no Catálogo do Unity.
- Excluir modelos.
O artigo descreve como você pode executar essas etapas usando as UIs e APIs do MLflow Tracking e Modelos no Catálogo do Unity.
Requisitos
Verifique se você atende 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 nomain
catálogo.CREATE MODEL
eUSE SCHEMA
privilégios nomain.default
esquema.
Notebook
Todo o código neste artigo é fornecido no notebook a seguir.
Modelos no Catálogo do Unity exemplo de notebook
Instalar o cliente Python do MLflow
Este exemplo requer o cliente Python do MLflow versão 2.5.0 ou superior e o TensorFlow. Adicione os comandos a seguir na parte superior do notebook para instalar essas dependências.
%pip install --upgrade "mlflow-skinny[databricks]>=2.5.0" tensorflow
dbutils.library.restartPython()
Carregar conjunto de dados, treinar modelo e registrar-se no Catálogo do Unity
Esta seção mostra como carregar o conjunto de dados do parque eólico, treinar um modelo e registrar o modelo no Catálogo do Unity. A execução e as métricas de treinamento do modelo são rastreadas em uma execução de experimento.
Carregar conjunto de dados
O código a seguir carrega um conjunto de dados que contém informações de tempo e de saída de energia para um farm de vento no Estados Unidos. O conjunto de resultados contémwind direction
, wind speed
e air temperature
. Os recursos são amostrados a cada seis horas (uma vez às 00:00
, uma vez às 08:00
e uma vez às 16:00
), bem como a saída de energia de agregação diária (power
), em 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 do MLflow para acessar modelos no Catálogo do Unity
Por padrão, o cliente Python do MLflow cria modelos no registro de modelos do espaço de trabalho no Azure Databricks. Para atualizar para modelos no Catálogo do Unity, configure o cliente para acessar modelos no Catálogo do Unity:
import mlflow
mlflow.set_registry_uri("databricks-uc")
Treinar e registrar modelo
O código a seguir treina uma rede neural usando o TensorFlow Keras para prever a saída de energia com base nos recursos meteorológicos no conjunto de dados e usa APIs do MLflow para registrar o modelo ajustado no Catálogo do Unity.
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 exibir e gerenciar os modelos registrados e as versões de modelos no Catálogo do Unity usando o Gerenciador de Catálogos. Procure o modelo que você acabou de criar no catálogo main
e no esquema default
.
Implantar uma versão de modelo para inferência
Os modelos no Catálogo do Unity dão suporte a aliases para implantação de modelo. Os aliases fornecem referências mutáveis e nomeadas (por exemplo, "Champion" ou "Challenger") para uma versão específica de um modelo registrado. Você pode referenciar 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 "Champion" à versão mais recente do modelo e pressione "Continuar" para salvar as alterações.
Carregar versões do modelo usando a API
O componente de modelos MLflow 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 Catálogo do Unity.
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 da 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 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 de modelo usando a API
O código nesta seção mostra como você pode adicionar descrições de versão de modelo e modelo usando a API do 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 de modelo
As técnicas clássicas de aprendizado de máquina 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 registra-o com o registro de modelo MLflow por meio da 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 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."
)
Marcar a nova versão do modelo como Challenger e testar o modelo
Antes de implantar um modelo para atender ao tráfego de produção, é uma prática recomendada testá-lo em um exemplo de dados de produção. Anteriormente, você usava o alias "Champion" 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 bom desempenho 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 seção Previsão de saída de energia com o modelo Champion 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 há 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 direcionadas à versão do modelo "Challenger" continuam sendo executadas com êxito:
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 do modelo.
Excluir Version 1
usando a API do MLflow
client.delete_model_version(
name=MODEL_NAME,
version=1,
)
Excluir o modelo usando a API do MLflow
client = MlflowClient()
client.delete_registered_model(name=MODEL_NAME)