Registrando modelos MLflow
Este artigo descreve como registrar seus modelos treinados (ou artefatos) como modelos MLflow. Ele explora as diferentes maneiras de personalizar como o MLflow empacota seus modelos e como ele executa esses modelos.
Porquê registar modelos em vez de artefactos?
De artefatos a modelos no MLflow descreve a diferença entre registrar artefatos ou arquivos, em comparação com o registro de modelos MLflow.
Um modelo MLflow também é um artefato. No entanto, esse modelo tem uma estrutura específica que serve como um contrato entre a pessoa que criou o modelo e a pessoa que pretende usá-lo. Este contrato ajuda a construir uma ponte entre os próprios artefatos e seus significados.
O registro em log do modelo tem estas vantagens:
- Você pode carregar modelos diretamente, para inferência, com
mlflow.<flavor>.load_model
, e pode usar apredict
função - As entradas de pipeline podem usar modelos diretamente
- Você pode implantar modelos sem indicação de um script de pontuação ou um ambiente
- O Swagger é habilitado automaticamente em pontos de extremidade implantados e o estúdio de Aprendizado de Máquina do Azure pode usar o recurso Teste
- Você pode usar o painel de IA responsável
Esta seção descreve como usar o conceito do modelo no Azure Machine Learning com MLflow:
Registrando modelos usando o autolog
Você pode usar a funcionalidade de log automático MLflow. O Autolog permite que o MLflow instrua a estrutura em uso para registrar todas as métricas, parâmetros, artefatos e modelos que a estrutura considera relevantes. Por padrão, se o registro automático estiver habilitado, a maioria dos modelos será registrada. Em algumas situações, alguns sabores podem não registrar um modelo. Por exemplo, o sabor PySpark não registra modelos que excedem um determinado tamanho.
Use um ou mlflow.autolog()
mlflow.<flavor>.autolog()
para ativar o registro automático. Este exemplo usa autolog()
para registrar um modelo de classificador treinado com XGBoost:
import mlflow
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
mlflow.autolog()
model = XGBClassifier(use_label_encoder=False, eval_metric="logloss")
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
Gorjeta
Se usar pipelines de Machine Learning, por exemplo , pipelines Scikit-Learn, use a autolog
funcionalidade desse tipo de pipeline para registrar modelos. O log do modelo acontece automaticamente quando o fit()
método é chamado no objeto de pipeline. O Treinamento e acompanhamento de um classificador XGBoost com o notebook MLflow demonstra como registrar um modelo com pré-processamento, usando pipelines.
Registrando modelos com uma assinatura, ambiente ou amostras personalizados
O método MLflow mlflow.<flavor>.log_model
pode registrar modelos manualmente. Esse fluxo de trabalho pode controlar diferentes aspetos do registro em log do modelo.
Use este método quando:
- Você deseja indicar pacotes pip ou um ambiente conda que diferem daqueles que são detetados automaticamente
- Você deseja incluir exemplos de entrada
- Você deseja incluir artefatos específicos no pacote necessário
autolog
não infere corretamente a sua assinatura. Isso é importante quando você lida com entradas tensoras, onde a assinatura precisa de formas específicas- O comportamento de registro automático não cobre seu propósito por algum motivo
Este exemplo de código registra um modelo para um classificador XGBoost:
import mlflow
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
from mlflow.models import infer_signature
from mlflow.utils.environment import _mlflow_conda_env
mlflow.autolog(log_models=False)
model = XGBClassifier(use_label_encoder=False, eval_metric="logloss")
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
# Signature
signature = infer_signature(X_test, y_test)
# Conda environment
custom_env =_mlflow_conda_env(
additional_conda_deps=None,
additional_pip_deps=["xgboost==1.5.2"],
additional_conda_channels=None,
)
# Sample
input_example = X_train.sample(n=1)
# Log the model manually
mlflow.xgboost.log_model(model,
artifact_path="classifier",
conda_env=custom_env,
signature=signature,
input_example=input_example)
Nota
autolog
tem alog_models=False
configuração. Isso impede o registro automático do modelo MLflow. O registro automático do modelo MLflow acontece mais tarde, como um processo manual- Use o
infer_signature
método para tentar inferir a assinatura diretamente de entradas e saídas - O
mlflow.utils.environment._mlflow_conda_env
método é um método privado no MLflow SDK. Neste exemplo, ele torna o código mais simples, mas use-o com cuidado. Pode mudar no futuro. Como alternativa, você pode gerar a definição YAML manualmente como um dicionário Python.
Registrando modelos com um comportamento diferente no método predict
Ao registrar um modelo com um ou mlflow.autolog
mlflow.<flavor>.log_model
, o sabor do modelo determina como executar a inferência e o que o modelo retorna. O MLflow não impõe nenhum comportamento específico sobre a geração de predict
resultados. Em alguns cenários, talvez você queira fazer algum pré-processamento ou pós-processamento antes e depois da execução do modelo.
Nessa situação, implemente pipelines de aprendizado de máquina que se movem diretamente de entradas para saídas. Embora esta implementação seja possível e, por vezes, incentivada a melhorar o desempenho, pode tornar-se difícil de alcançar. Nesses casos, pode ajudar a personalizar como seu modelo lida com a inferência , conforme explicado na próxima seção.
Registrando modelos personalizados
O MLflow suporta muitas estruturas de aprendizado de máquina, incluindo
- CatBoost
- FastAI
- h2o
- Keras
- LightGBM
- MLeap
- MXNet Glúon
- ONNX
- Profeta
- PyTorch
- Scikit-Aprender
- espaCy
- Faísca MLLib
- statsmodels
- TensorFlow
- XGBoost
No entanto, talvez seja necessário alterar a maneira como um sabor funciona, registrar um modelo não suportado nativamente pelo MLflow ou até mesmo registrar um modelo que usa vários elementos de diferentes estruturas. Nesses casos, talvez seja necessário criar um sabor de modelo personalizado.
Para resolver o problema, o MLflow introduz o pyfunc
sabor (a partir de uma função Python). Esse sabor pode registrar qualquer objeto como um modelo, desde que esse objeto satisfaça duas condições:
- Você implementa o método de método
predict
, pelo menos - O objeto Python herda de
mlflow.pyfunc.PythonModel
Gorjeta
Os modelos serializáveis que implementam a API Scikit-learn podem usar o sabor Scikit-learn para registrar o modelo, independentemente de o modelo ter sido construído com o Scikit-learn. Se você puder persistir seu modelo no formato Pickle e o objeto tiver os predict()
métodos e predict_proba()
(pelo menos), poderá usar mlflow.sklearn.log_model()
para registrar o modelo dentro de uma execução MLflow.
Se você criar um wrapper em torno de seu objeto de modelo existente, torna-se mais simples criar um sabor para seu modelo personalizado. O MLflow serializa e empacota para você. Os objetos Python são serializáveis quando o objeto pode ser armazenado no sistema de arquivos como um arquivo, geralmente no formato Pickle. No tempo de execução, o objeto pode se materializar a partir desse arquivo. Isso restaura todos os valores, propriedades e métodos disponíveis quando foi salvo.
Use este método quando:
- Você pode serializar seu modelo no formato Pickle
- Você quer manter o estado do modelo, como foi logo após o treinamento
- Você deseja personalizar como a
predict
função funciona.
Este exemplo de código encapsula um modelo criado com XGBoost, para fazer com que ele se comporte em uma implementação padrão de sabor XGBoost. Em vez disso, ele retorna as probabilidades em vez das classes:
from mlflow.pyfunc import PythonModel, PythonModelContext
class ModelWrapper(PythonModel):
def __init__(self, model):
self._model = model
def predict(self, context: PythonModelContext, data):
# You don't have to keep the semantic meaning of `predict`. You can use here model.recommend(), model.forecast(), etc
return self._model.predict_proba(data)
# You can even add extra functions if you need to. Since the model is serialized,
# all of them will be available when you load your model back.
def predict_batch(self, data):
pass
Registre um modelo personalizado na execução:
import mlflow
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
from mlflow.models import infer_signature
mlflow.xgboost.autolog(log_models=False)
model = XGBClassifier(use_label_encoder=False, eval_metric="logloss")
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_probs = model.predict_proba(X_test)
accuracy = accuracy_score(y_test, y_probs.argmax(axis=1))
mlflow.log_metric("accuracy", accuracy)
signature = infer_signature(X_test, y_probs)
mlflow.pyfunc.log_model("classifier",
python_model=ModelWrapper(model),
signature=signature)
Gorjeta
Aqui, o infer_signature
método usa y_probs
para inferir a assinatura. Nossa coluna de destino tem a classe de destino, mas nosso modelo agora retorna as duas probabilidades para cada classe.