Converter modelos de ML personalizados em modelos formatados de MLflow

Neste artigo, saiba como converter seu modelo de ML personalizado no formato MLflow. O MLFlow é uma biblioteca de open-source para gerenciar o ciclo de vida dos experimentos de aprendizado de máquina. Em alguns casos, você pode usar uma estrutura de machine learning sem suporte para a variante de modelo MLflow interna. Devido a essa falta da variante de modelo MLflow interna, você não pode registrar o modelo com as APIs fluentes do modelo MLflow. Para resolver esse problema, você pode converter seu modelo em um formato MLflow, no qual pode aplicar os seguintes benefícios dos modelos do Azure Machine Learning e do MLflow.

Com o Azure Machine Learning, os modelos de MLflow obtêm os benefícios adicionais de:

  • Implantação sem códigos
  • Portabilidade como um formato padrão de código aberto
  • Capacidade de implantar localmente e na nuvem

O MLflow oferece suporte para várias estruturas de machine learning, como scikit-learn, Keras e Pytorch. O MLflow pode não abranger todos os casos de uso. Por exemplo, talvez você queira criar um modelo MLflow com uma estrutura que o MLflow não dá suporte nativo. Talvez você queira alterar a maneira como seu modelo faz pré-processamento ou pós-processamento ao executar trabalhos. Para saber mais sobre modelos do MLflow, consulte De artefatos a modelos no MLflow.

Se você não treinou seu modelo com MLFlow e deseja usar a oferta de implantação sem código de MLflow do Azure Machine Learning, precisará converter seu modelo personalizado em MLFLow. Para obter mais informações, consulte modelos Python personalizados.

Pré-requisitos

  • Instalar o pacote mlflow

Criar um wrapper Python para o modelo

Antes de converter o modelo em um formato compatível com MLflow, você precisa criar um wrapper Python para ele. O código a seguir demonstra como criar um wrapper Python para um modelo sklearn.


# Load training and test datasets
from sys import version_info
import sklearn
import mlflow.pyfunc


PYTHON_VERSION = "{major}.{minor}.{micro}".format(major=version_info.major,
                                                  minor=version_info.minor,
                                                  micro=version_info.micro)

# Train and save an SKLearn model
sklearn_model_path = "model.pkl"

artifacts = {
    "sklearn_model": sklearn_model_path
}

# create wrapper
class SKLearnWrapper(mlflow.pyfunc.PythonModel):

    def load_context(self, context):
        import pickle
        self.sklearn_model = pickle.load(open(context.artifacts["sklearn_model"], 'rb'))
    
    def predict(self, model, data):
        return self.sklearn_model.predict(data)

Criar um ambiente Conda

Em seguida, crie um ambiente Conda para o novo Modelo de MLflow que contenha todas as dependências necessárias. Se não for indicado, o ambiente será inferido com base na instalação atual. Caso contrário, ele poderá ser especificado.


import cloudpickle
conda_env = {
    'channels': ['defaults'],
    'dependencies': [
      'python={}'.format(PYTHON_VERSION),
      'pip',
      {
        'pip': [
          'mlflow',
          'scikit-learn=={}'.format(sklearn.__version__),
          'cloudpickle=={}'.format(cloudpickle.__version__),
        ],
      },
    ],
    'name': 'sklearn_env'
}

Carregar o modelo formatado de MLflow e as previsões de teste

Depois que o ambiente estiver pronto, passe o SKlearnWrapper, o ambiente conda e o dicionário de artefatos recém-criado para o método mlflow.pyfunc.save_model(). Fazer isso salva o modelo no disco.

mlflow_pyfunc_model_path = "sklearn_mlflow_pyfunc_custom"
mlflow.pyfunc.save_model(path=mlflow_pyfunc_model_path, python_model=SKLearnWrapper(), conda_env=conda_env, artifacts=artifacts)

Para garantir que o modelo formatado do MLflow recém-salvo não tenha sido alterado durante o salvamento, carregue o modelo e imprima uma previsão de teste para comparar o modelo original.

O código a seguir imprime uma previsão de teste do modelo formatado de mlflow e uma previsão de teste do modelo sklearn. Ele salva as previsões de teste em seu disco para comparação.

loaded_model = mlflow.pyfunc.load_model(mlflow_pyfunc_model_path)

input_data = "<insert test data>"
# Evaluate the model
import pandas as pd
test_predictions = loaded_model.predict(input_data)
print(test_predictions)

# load the model from disk
import pickle
loaded_model = pickle.load(open(sklearn_model_path, 'rb'))
result = loaded_model.predict(input_data)
print(result)

Registrar o modelo formatado de MLflow

Depois de confirmar que o modelo foi salvo corretamente, você pode criar uma execução de teste. Registre e salve o modelo formatado do MLflow no registro de modelo.


mlflow.start_run()

mlflow.pyfunc.log_model(artifact_path=mlflow_pyfunc_model_path, 
                        loader_module=None, 
                        data_path=None, 
                        code_path=None,
                        python_model=SKLearnWrapper(),
                        registered_model_name="Custom_mlflow_model", 
                        conda_env=conda_env,
                        artifacts=artifacts)
mlflow.end_run()

Importante

Em alguns casos, você pode usar uma estrutura de machine learning sem suporte para a variante de modelo MLflow interna. Por exemplo, a biblioteca vaderSentiment é uma biblioteca padrão de NLP (processamento de linguagem natural) usada para análise de sentimento. Devido à falta da variante de modelo MLflow interna, você não pode registrar o modelo com as APIs fluentes do modelo MLflow. Para obter um exemplo sobre como salvar, registrar e registrar um modelo que não tem um sabor de modelo do MLflow interno com suporte, consulte Registrando um modelo de Machine Learning sem suporte.