Implantar modelos do MLflow em implantações em lote no Azure Machine Learning

APLICA-SE A:Extensão de ML da CLI do Azure v2 (atual)SDK do Python azure-ai-ml v2 (atual)

Este artigo descreve como implantar modelos do MLflow no Azure Machine Learning para inferência em lote usando pontos de extremidade em lote. Quando você implanta modelos do MLflow em pontos de extremidade em lote, o Azure Machine Learning conclui as seguintes tarefas:

  • Fornece uma imagem base do MLflow ou do ambiente com curadoria que contém as dependências necessárias para executar um trabalho em lotes do Machine Learning.
  • Cria um pipeline de trabalho em lotes com um script de pontuação para você que pode ser usado para processar dados usando a paralelização.

Para obter mais informações sobre os tipos de arquivos de entrada com suporte e detalhes sobre como o modelo do MLflow funciona, confira Considerações sobre a implantação na inferência em lote.

Pré-requisitos

  • Uma assinatura do Azure. Caso não tenha uma assinatura do Azure, crie uma conta gratuita antes de começar. Experimente a versão gratuita ou paga do Azure Machine Learning.

  • Um workspace do Azure Machine Learning. Para criar um workspace, confira Gerenciar workspaces do Azure Machine Learning.

  • Certifique-se de que você tenha as seguintes permissões no espaço de trabalho do Machine Learning:

    • Criar ou gerenciar implantações e pontos de extremidade em lote: use uma função de Proprietário, Colaborador ou Personalizada que permita Microsoft.MachineLearningServices/workspaces/batchEndpoints/*.
    • Crie implantações do Azure Resource Manager no grupo de recursos do espaço de trabalho: use uma função de Proprietário, Colaborador ou Personalizada que permita Microsoft.Resources/deployments/write no grupo de recursos onde o espaço de trabalho está implantado.
  • Instale o seguinte software para trabalhar com o Machine Learning:

    Execute o seguinte comando para instalar a CLI do Azure e a extensão do Azure Machine Learning ml:

    az extension add -n ml
    

    As implantações de componente de pipeline para pontos de extremidade do Lote são introduzidas na versão 2.7 da extensão ml da CLI do Azure. Use o comando az extension update --name ml para obter a versão mais recente.


Conectar-se ao workspace

O workspace é o recurso de nível superior do Machine Learning. Ele fornece um local centralizado para trabalhar com todos os artefatos criados ao usar o Machine Learning. Nesta seção, você se conecta ao workspace em que executa as suas tarefas de implantação.

No comando a seguir, insira os valores para a sua ID de assinatura, workspace, local e grupo de recursos:

az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>

Explorar o exemplo

O exemplo deste artigo mostra como implantar um modelo do MLflow em um ponto de extremidade em lote para executar previsões em lote. O modelo do MLflow é baseado no conjunto de dados UCI Heart Disease. O banco de dados contém 76 atributos, mas o exemplo usa apenas um subconjunto de 14. O modelo tenta prever a presença de doenças cardíacas em um paciente com um valor inteiro de 0 (sem presença) a 1 (presença).

O modelo é treinado com um classificador XGBBoost. Todo o pré-processamento necessário é empacotado como um pipeline scikit-learn, o que torna o modelo um pipeline abrangente, que vai de dados brutos a previsões.

O exemplo neste artigo é baseado em exemplos de códigos contidos no repositório azureml-examples . Para executar os comandos localmente sem precisar copiar/colar o YAML e outros arquivos, primeiro clone o repositório e altere os diretórios para a pasta:

git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli

Os arquivos deste exemplo estão localizados na seguinte pasta:

cd endpoints/batch/deploy-models/heart-classifier-mlflow

Acompanhar em Jupyter Notebooks

Você pode acompanhar esta amostra usando um Jupyter Notebook público. No repositório clonado, abra o notebook mlflow-for-batch-tabular.ipynb.

Implantar o modelo do MLflow

Nesta seção, você implantará um modelo do MLflow em um ponto de extremidade em lote para que possa executar a inferência em lote em novos dados. Antes de prosseguir com a implantação, você precisa garantir que o seu modelo esteja registrado e que haja um cluster de cálculo disponível no workspace.

Registre o modelo

Os pontos de extremidade em lote só podem implantar modelos registrados. Neste artigo, você usará uma cópia local do modelo no repositório. Como resultado, você só precisa publicar o modelo no registro no workspace.

Observação

Se o modelo que você está implantando já estiver registrado, continue na seção Criar cluster de cálculo.

Registre o modelo executando o seguinte comando:

MODEL_NAME='heart-classifier-mlflow'
az ml model create --name $MODEL_NAME --type "mlflow_model" --path "model"

Criar um cluster de cálculo

Você precisa garantir que as implantações em lote possam ser executadas em alguma infraestrutura disponível (computação). As implantações em lote podem ser executadas em qualquer computação do Machine Learning que já exista no workspace. Implantações em lote múltiplas podem ter a mesma infraestrutura de computação.

Neste artigo, você trabalhará em um cluster de cálculo do Machine Learning chamado cpu-cluster. O exemplo a seguir verifica se existe uma computação no workspace ou cria uma computação.

Criar um cluster de computação:

az ml compute create -n batch-cluster --type amlcompute --min-instances 0 --max-instances 5

Criar o ponto de extremidade em lote

Para criar um ponto de extremidade, você precisa de um nome e uma descrição. O nome do ponto de extremidade aparece no URI associado ao ponto de extremidade. Portanto, ele precisa ser exclusivo em uma região do Azure. Por exemplo, pode haver apenas um ponto de extremidade em lote com o nome mybatchendpoint na região WestUS2.

  1. Coloque o nome do ponto de extremidade em uma variável para facilitar a referência posteriormente:

    Execute o comando a seguir:

    ENDPOINT_NAME="heart-classifier"
    
  2. Criar o ponto de extremidade:

    1. Para criar um ponto de extremidade, crie uma configuração do YAML como o seguinte código:

      endpoint.yml

      $schema: https://azuremlschemas.azureedge.net/latest/batchEndpoint.schema.json
      name: heart-classifier-batch
      description: A heart condition classifier for batch inference
      auth_mode: aad_token
      
    2. Crie o ponto de extremidade com o seguinte comando:

      az ml batch-endpoint create -n $ENDPOINT_NAME -f endpoint.yml
      

Criar a implantação em lote

Os modelos do MLflow não exigem que você indique um ambiente ou um script de pontuação ao criar a implantação. O ambiente ou o script de pontuação é criado automaticamente para você. No entanto, você pode especificar o ambiente ou o script de pontuação se quiser personalizar como a implantação faz a inferência.

  1. Para criar uma implantação no ponto de extremidade criado, crie uma configuração do YAML conforme mostrado no código a seguir. Você pode verificar o esquema YAML do ponto de extremidade do lote completo para obter propriedades extras.

    deployment-simple/deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json
    endpoint_name: heart-classifier-batch
    name: classifier-xgboost-mlflow
    description: A heart condition classifier based on XGBoost
    type: model
    model: azureml:heart-classifier-mlflow@latest
    compute: azureml:batch-cluster
    resources:
      instance_count: 2
    settings:
      max_concurrency_per_instance: 2
      mini_batch_size: 2
      output_action: append_row
      output_file_name: predictions.csv
      retry_settings:
        max_retries: 3
        timeout: 300
      error_threshold: -1
      logging_level: info
    
  2. Crie a implantação com o seguinte comando:

    az ml batch-deployment create --file deployment-simple/deployment.yml --endpoint-name $ENDPOINT_NAME --set-default
    

Importante

Configure o valor de timeout na implantação de acordo com o tempo necessário para o modelo executar a inferência em um lote individual. Quanto maior o tamanho do lote, maior o valor de timeout. Tenha em mente que o valor de mini_batch_size indica o número de arquivos em um lote e não o número de amostras. Quando você trabalha com os dados de tabela, cada arquivo pode conter várias linhas, o que aumenta o tempo necessário para que o ponto de extremidade em lote processe cada arquivo. Nesses casos, use valores de timeout mais altos para evitar erros de tempo limite.

Invocar o ponto de extremidade

Embora você possa invocar uma implantação específica dentro de um ponto de extremidade, é comum invocar o ponto de extremidade propriamente dito e permitir que ele decida qual implantação usar. Esse tipo de implantação é chamado de implantação “padrão”. Essa abordagem permite alterar a implantação padrão, o que possibilita alterar o modelo que atende à implantação sem alterar o contrato com o usuário que invoca o ponto de extremidade.

Use a seguinte instrução para atualizar a implantação padrão:

DEPLOYMENT_NAME="classifier-xgboost-mlflow"
az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME

O ponto de extremidade em lote já está pronto para uso.

Teste a implantação

Para testar o ponto de extremidade, você usará uma amostra de dados não rotulados localizados neste repositório que pode ser usado com o modelo. Os pontos de extremidade em lote só podem processar dados localizados na nuvem e acessíveis no workspace do Machine Learning. Neste exemplo, você carregará a amostra em um armazenamento de dados do Machine Learning. Você criará um ativo de dados que pode ser usado para invocar o ponto de extremidade para pontuação. Tenha em mente que os pontos de extremidade em lote aceitam dados que podem ser colocados em vários tipos de locais.

  1. Em primeiro lugar, crie o ativo de dados. O ativo de dados consiste em uma pasta com vários arquivos CSV que queremos processar em paralelo usando pontos de extremidade em lote. Você pode ignorar essa etapa, pois seus dados já estão registrados como um ativo de dados ou você deseja usar um tipo de entrada diferente.

    1. Crie uma definição de ativo de dados em YAML:

      heart-dataset-unlabeled.yml

      $schema: https://azuremlschemas.azureedge.net/latest/data.schema.json
      name: heart-dataset-unlabeled
      description: An unlabeled dataset for heart classification.
      type: uri_folder
      path: data
      
    2. Crie o ativo de dados:

      az ml data create -f heart-dataset-unlabeled.yml
      
  2. Depois de carregar os dados, invoque o ponto de extremidade.

    Dica

    Nos comandos a seguir, observe que o nome da implantação não é indicado na operação invoke. O ponto de extremidade encaminha automaticamente o trabalho para a implantação padrão porque o ponto de extremidade tem apenas uma implantação. Você pode direcionar uma implantação específica indicando o argumento/parâmetro deployment_name.

    Execute o comando a seguir:

    JOB_NAME = $(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input azureml:heart-dataset-unlabeled@latest --query name -o tsv)
    

    Observação

    O utilitário jq pode não ser instalado em todas as instalações. Para obter instruções de instalação, confira Baixar o jq.

  3. Um trabalho em lote é iniciado assim que o comando retorna. Você pode monitorar o status do trabalho até que ele seja concluído:

    Execute o comando a seguir:

    az ml job show -n $JOB_NAME --web
    

Analisar saídas

As previsões de saída são geradas no arquivo predictions.csv, conforme indicado na configuração de implantação. O trabalho gera uma saída chamada pontuação, em que esse arquivo é colocado. Apenas um arquivo é gerado por trabalho em lote.

O arquivo é estruturado da seguinte forma:

  • Uma linha por ponto de dados enviado ao modelo. Para dados de tabela, o arquivo predictions.csv contém uma linha para cada linha presente em cada arquivo processado. Para outros tipos de dados (imagens, áudio, texto), há uma linha por arquivo processado.

  • As seguintes colunas estão no arquivo (na ordem especificada):

    • row (opcional): o índice de linha correspondente no arquivo de dados de entrada. Essa coluna se aplica somente se os dados de entrada são de tabela. As previsões são retornadas na mesma ordem em que aparecem no arquivo de entrada. Você pode contar com o número da linha para corresponder à previsão correspondente.

    • prediction: a previsão associada aos dados de entrada. Esse valor é retornado “no estado em que se encontra”, como fornecido pela função predict(). do modelo.

    • file_name: o nome do arquivo em que os dados são lidos. Em dados de tabela, use esse campo para determinar qual previsão pertence a quais dados de entrada.

Você pode baixar os resultados do trabalho usando o nome do trabalho.

Para baixar as previsões, use o seguinte comando:

az ml job download --name $JOB_NAME --output-name score --download-path ./

Depois de baixar o arquivo, você poderá abrir o arquivo com sua ferramenta de edição preferida. O exemplo a seguir carrega as previsões usando um dataframe Pandas.

import pandas as pd

score = pd.read_csv(
    "named-outputs/score/predictions.csv", names=["row", "prediction", "file"]
)

A saída exibe uma tabela:

Linha Previsão Arquivo
0 0 heart-unlabeled-0.csv
1 1 heart-unlabeled-0.csv
2 0 heart-unlabeled-0.csv
... ... ...
307 0 heart-unlabeled-3.csv

Dica

Observe que, neste exemplo, os dados de entrada contêm dados de tabela no formato CSV. Há quatro arquivos de entrada diferentes: heart-unlabeled-0.csv, heart-unlabeled-1.csv, heart-unlabeled-2.csv e heart-unlabeled-3.csv.

Analisar as considerações sobre a inferência em lote

O Machine Learning dá suporte à implantação de modelos do MLflow em pontos de extremidade em lote sem indicar um script de pontuação. Essa abordagem é uma forma conveniente de implantar modelos que exigem o processamento de grandes volumes de dados, semelhante ao processamento em lote. O Machine Learning usa informações na especificação de modelo do MLflow para orquestrar o processo de inferência.

Explorar a distribuição do trabalho em funções de trabalho

Os pontos de extremidade do lote distribuem o trabalho no nível do arquivo para dados estruturados e não estruturados. Como consequência, há suporte apenas a arquivo URI e pastas URI para esse recurso. Cada trabalho processa lotes de Mini batch size arquivos por vez. Para dados tabulares, os pontos de extremidade em lote não levam em conta o número de linhas dentro de cada arquivo ao distribuir o trabalho.

Aviso

As estruturas de pasta aninhadas não são exploradas durante a inferência. Se você particionar seus dados usando pastas, lembre-se de nivelar a estrutura antes de continuar.

As implantações em lote chamam a função predict do modelo do MLflow uma vez por arquivo. Para arquivos CSV com várias linhas, essa ação pode impor uma demanda de memória na computação subjacente. O comportamento pode aumentar o tempo necessário para o modelo pontuar um arquivo individual, especialmente para modelos caros, como modelos de linguagem grande. Se você encontrar várias exceções de memória insuficiente ou entradas de tempo limite em logs, considere a possibilidade de dividir os dados em arquivos menores com menos linhas ou implementar o envio em lote no nível da linha dentro do script de pontuação do modelo.

Analisar o suporte para tipos de arquivo

Há suporte para os seguintes tipos de dados na inferência em lote ao implantar modelos do MLflow sem um ambiente ou um script de pontuação. Para processar um tipo de arquivo diferente ou executar a inferência de maneira diferente, você pode criar a implantação personalizando a implantação do modelo do MLflow com um script de pontuação.

Extensão de arquivo Tipo retornado como uma entrada do modelo Requisito de assinatura
.csv, .parquet, .pqt pd.DataFrame ColSpec. Se não for fornecido, a tipagem de colunas não será imposta.
.png, .jpg, .jpeg, .tiff, .bmp, .gif np.ndarray TensorSpec. A entrada é remodelada para corresponder à forma de tensores, se disponível. Se nenhuma assinatura estiver disponível, tensores do tipo np.uint8 serão inferidos. Para obter mais informações, confira Considerações sobre o processamento de imagens de modelos do MLflow.

Aviso

Qualquer arquivo sem suporte que possa estar presente nos dados de entrada causa uma falha no trabalho. Nesses casos, você verá um erro semelhante a ERROR:azureml:Error processing input file: '/mnt/batch/tasks/.../a-given-file.avro'. Não há suporte para o tipo de arquivo 'avro'.

Noções básicas sobre a imposição de assinatura para modelos do MLflow

Os trabalhos de implantação em lote impõem os tipos de dados da entrada ao ler os dados usando a assinatura de modelo do MLflow disponível. Como resultado, a entrada de dados fica em conformidade com os tipos indicados na assinatura do modelo. Se os dados não puderem ser analisados conforme o esperado, ocorrerá uma falha no trabalho com um erro semelhante a ERROR:azureml:Error processing input file: '/mnt/batch/tasks/.../a-given-file.csv'. Exceção: literal inválido para int() com base 10: 'valor'.

Dica

As assinaturas dos modelos do MLflow são opcionais, mas são altamente recomendadas. Elas apresentam um modo conveniente para a detecção antecipada de problemas de compatibilidade de dados. Para obter mais informações sobre como registrar modelos com assinaturas, consulte Como registrar modelos com uma assinatura, ambiente ou amostras personalizados.

Você pode inspecionar a assinatura do modelo do modelo abrindo o arquivo MLmodel associado ao modelo MLflow. Para obter mais detalhes sobre como as assinaturas funcionam no MLflow, confira Assinaturas no MLflow.

Analisar o suporte a variantes

As implantações em lote só dão suporte à implantação de modelos do MLflow com uma variante pyfunc. Para implantar outra variante, confira Personalizar a implantação de modelo com o script de pontuação.

Personalizar a implantação de modelo com o script de pontuação

Os modelos MLflow podem ser implantados em pontos de extremidade em lote sem indicar um script de pontuação na definição de implantação. No entanto, você pode optar por indicar esse arquivo (geralmente chamado de driver em lote) para personalizar a execução da inferência.

Normalmente, você seleciona esse fluxo de trabalho para os seguintes cenários:

  • Processar tipos de arquivos sem suporte nas implantações em lote do MLflow.
  • Personalizar como o modelo será executado, por exemplo, usar uma variante específica para carregá-lo com a função mlflow.<flavor>.load().
  • Concluir o pré ou pós-processamento em sua rotina de pontuação, quando ele não for concluído pelo próprio modelo.
  • Ajustar a apresentação do modelo que não se ajusta bem com os dados de tabela, como um grafo de tensor que representa uma imagem.
  • Permitir que o modelo leia dados em partes porque ele não pode processar cada arquivo de uma só vez devido a restrições de memória.

Importante

Para indicar um script de pontuação para uma implantação de modelo do MLflow, você precisa especificar o ambiente em que a implantação é executada.

Usar o script de pontuação

Use as seguintes etapas para implantar um modelo do MLflow com um script de pontuação personalizado:

  1. Identifique a pasta em que o modelo do MLflow é colocado.

    1. No portal do Azure Machine Learning, navegue até Modelos.

    2. Selecione o modelo a ser implantado e escolha a guia Artefatos.

    3. Anote a pasta exibida. Essa pasta foi indicada quando o modelo foi registrado.

      Captura de tela que mostra a pasta em que os artefatos do modelo são colocados.

  2. Crie um script de pontuação. Observe como o nome da pasta anterior model está incluído na função init().

    deployment-custom/code/batch_driver.py

    # Copyright (c) Microsoft. All rights reserved.
    # Licensed under the MIT license.
    
    import os
    import glob
    import mlflow
    import pandas as pd
    import logging
    
    
    def init():
        global model
        global model_input_types
        global model_output_names
    
        # AZUREML_MODEL_DIR is an environment variable created during deployment
        # It is the path to the model folder
        # Please provide your model's folder name if there's one
        model_path = glob.glob(os.environ["AZUREML_MODEL_DIR"] + "/*/")[0]
    
        # Load the model, it's input types and output names
        model = mlflow.pyfunc.load(model_path)
        if model.metadata and model.metadata.signature:
            if model.metadata.signature.inputs:
                model_input_types = dict(
                    zip(
                        model.metadata.signature.inputs.input_names(),
                        model.metadata.signature.inputs.pandas_types(),
                    )
                )
            if model.metadata.signature.outputs:
                if model.metadata.signature.outputs.has_input_names():
                    model_output_names = model.metadata.signature.outputs.input_names()
                elif len(model.metadata.signature.outputs.input_names()) == 1:
                    model_output_names = ["prediction"]
        else:
            logging.warning(
                "Model doesn't contain a signature. Input data types won't be enforced."
            )
    
    
    def run(mini_batch):
        print(f"run method start: {__file__}, run({len(mini_batch)} files)")
    
        data = pd.concat(
            map(
                lambda fp: pd.read_csv(fp).assign(filename=os.path.basename(fp)), mini_batch
            )
        )
    
        if model_input_types:
            data = data.astype(model_input_types)
    
        # Predict over the input data, minus the column filename which is not part of the model.
        pred = model.predict(data.drop("filename", axis=1))
    
        if pred is not pd.DataFrame:
            if not model_output_names:
                model_output_names = ["pred_col" + str(i) for i in range(pred.shape[1])]
            pred = pd.DataFrame(pred, columns=model_output_names)
    
        return pd.concat([data, pred], axis=1)
    
  3. Crie um ambiente em que o script de pontuação possa ser executado. Como o modelo neste exemplo é MLflow, os requisitos do Conda também são especificados no pacote do modelo. Para obter mais informações sobre os modelos do MLflow e os arquivos incluídos, confira O formato MLmodel.

    Nesta etapa, você criará o ambiente usando as dependências do Conda do arquivo. Você também precisa incluir o pacote azureml-core, que é necessário para as implantações em lote.

    Dica

    Se o modelo já estiver registrado no registro de modelo, baixe e copie o arquivo conda.yml associado ao modelo. O arquivo está disponível no Estúdio do Azure Machine Learning em Modelos>Selecione seu modelo na lista>Artefatos. Na pasta raiz, selecione o arquivo conda.yml e escolha Baixar ou copie o conteúdo dele.

    Importante

    Este exemplo usa um ambiente conda especificado em /heart-classifier-mlflow/environment/conda.yaml. Esse arquivo foi criado pela combinação do arquivo de dependências do Conda do MLflow original e adição do pacote azureml-core. Não é possível usar o arquivo conda.yml diretamente do modelo.

    A definição de ambiente é incluída na própria definição de implantação como um ambiente anônimo. Você verá as seguintes linhas na implantação:

    environment:
      name: batch-mlflow-xgboost
      image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
      conda_file: environment/conda.yaml
    
  4. Configure a implantação:

    Para criar uma implantação no ponto de extremidade criado, crie uma configuração de YAML conforme mostrado no snippet de código a seguir. Você pode verificar o esquema YAML do ponto de extremidade do lote completo para obter propriedades extras.

    deployment-custom/deployment.yml

    $schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json
    endpoint_name: heart-classifier-batch
    name: classifier-xgboost-custom
    description: A heart condition classifier based on XGBoost
    type: model
    model: azureml:heart-classifier-mlflow@latest
    environment:
      name: batch-mlflow-xgboost
      image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
      conda_file: environment/conda.yaml
    code_configuration:
      code: code
      scoring_script: batch_driver.py
    compute: azureml:batch-cluster
    resources:
      instance_count: 2
    settings:
      max_concurrency_per_instance: 2
      mini_batch_size: 2
      output_action: append_row
      output_file_name: predictions.csv
      retry_settings:
        max_retries: 3
        timeout: 300
      error_threshold: -1
      logging_level: info
    
  5. Criar a implantação:

    Execute o código a seguir:

    az ml batch-deployment create --file deployment-custom/deployment.yml --endpoint-name $ENDPOINT_NAME
    

O ponto de extremidade em lote já está pronto para uso.

Limpar os recursos

Depois de concluir o exercício, exclua os recursos que não são mais necessários.

Execute o seguinte código para excluir o ponto de extremidade em lote e todas as implantações subjacentes:

az ml batch-endpoint delete --name $ENDPOINT_NAME --yes

Esse comando não exclui os trabalhos de pontuação em lote.