Implantar os modelos do MLflow em implantações em lote

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

Neste artigo, saiba como implantar seu modelo do MLflow no Azure Machine Learning para inferência em lote usando pontos de extremidade em lote. Ao implantar modelos do MLflow em pontos de extremidade em lote, o Azure Machine Learning:

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

Observação

Para obter mais informações sobre os tipos de arquivo de entrada com suporte e detalhes sobre como o modelo do MLflow funciona, consulte Considerações ao implantar na inferência em lote.

Sobre este exemplo

Este exemplo mostra como você pode implantar um modelo de MLflow em um ponto de extremidade em lote para executar previsões em lotes. Este exemplo usa um modelo de MLflow com base no conjunto de dados de doenças cardíacas da UCI. O banco de dados contém 76 atributos, mas estamos usando um subconjunto de 14 deles. O modelo tenta prever a presença de doenças cardíacas em um paciente. Ele é inteiro com valor 0 (sem presença) a 1 (presença).

O modelo foi treinado usando um classificador XGBBoost e todo o pré-processamento necessário foi empacotado como um pipeline scikit-learn, tornando esse modelo um pipeline de ponta a ponta 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 desse exemplo estão em:

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

Acompanhar em Jupyter Notebooks

Você pode acompanhar este exemplo nos notebooks a seguir. No repositório clonado, abra o notebook: mlflow-for-batch-tabular.ipynb.

Pré-requisitos

Antes de seguir as etapas neste artigo, verifique se você tem os seguintes 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. Se você não tiver um, use as etapas do artigo Gerenciar espaços de trabalho do Azure Machine Learning para criar um.

  • Certifique-se de ter as seguintes permissões no espaço de trabalho:

    • Criar ou gerenciar pontos de extremidade e implantações em lotes: use uma função de Proprietário, Colaborador ou Personalizada que permita Microsoft.MachineLearningServices/workspaces/batchEndpoints/*.

    • Criar implantações do ARM 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 em que o espaço de trabalho está implantado.

  • Você precisa instalar o software a seguir para trabalhar com o Azure Machine Learning:

    A CLI do Azure e a mlextensão do Azure Machine Learning.

    az extension add -n ml
    

    Observação

    Implantações de componente de pipeline para Pontos de Extremidade em Lote foram introduzidas na versão 2.7 da extensão ml para a CLI do Azure. Use az extension update --name ml para obter a última versão.

Conectar-se ao workspace

O workspace é o recurso de nível superior para o Azure Machine Learning. Ele fornece um local centralizado para trabalhar com todos os artefatos que você cria ao usar o Azure Machine Learning. Nesta seção, nos conectaremos ao workspace no qual você executará tarefas de implantação.

Passe os valores para sua ID de assinatura, espaço de trabalho, localização e grupo de recursos no código a seguir:

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

Etapas

Siga essas etapas para implantar um modelo MLflow em um ponto de extremidade em lote para executar a inferência do lote em novos dados:

  1. O ponto de extremidade em lotes somente poderá implantar modelos registrados. Nesse caso, já temos uma cópia local do modelo no repositório, portanto, só precisamos publicar o modelo no registro no workspace. Você poderá pular essa etapa se o modelo que está tentando implantar já estiver registrado.

    MODEL_NAME='heart-classifier-mlflow'
    az ml model create --name $MODEL_NAME --type "mlflow_model" --path "model"
    
  2. Antes de avançar, precisamos garantir que as implantações em lote que estamos prestes a criar possam ser executadas em alguma infraestrutura (computação). As implantações em lote podem ser executadas em qualquer computação do Azure Machine Learning que já exista no workspace. Isso significa que várias implantações em lotes podem compartilhar a mesma infraestrutura de computação. Neste exemplo, vamos trabalhar em um cluster de cálculo do Azure Machine Learning chamado cpu-cluster. Vamos verificar se a computação existe no workspace ou criá-la de outra forma.

    Crie um cluster de computação da seguinte maneira:

    az ml compute create -n batch-cluster --type amlcompute --min-instances 0 --max-instances 5
    
  3. Agora é hora de criar o ponto de extremidade e a implantação do lote. Vamos começar com o ponto de extremidade. Os pontos de extremidade exigem apenas um nome e uma descrição a serem criados. O nome do ponto de extremidade terminará no URI associado ao ponto de extremidade. Por esse motivo, nomes de ponto de extremidade em lote devem ser exclusivos dentro de uma região do Azure. Por exemplo, pode haver apenas um ponto de extremidade em lote com o nome mybatchendpoint em westus2.

    Nesse caso, vamos colocar o nome do ponto de extremidade em uma variável para que possamos referenciá-lo facilmente mais tarde.

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

    Para criar um novo ponto de extremidade, crie uma configuração YAML como a seguinte:

    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
    

    Depois, crie o ponto de extremidade com o seguinte comando:

    az ml batch-endpoint create -n $ENDPOINT_NAME -f endpoint.yml
    
  5. Agora, criaremos a implantação. Os modelos do MLflow não exigem que você indique um ambiente ou um script de pontuação ao criar as implantações conforme elas são criadas para você. No entanto, você pode especificá-los se quiser personalizar como a implantação faz inferência.

    Para criar uma nova implantação no ponto de extremidade criado, crie uma configuração YAML semelhante à seguinte. 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
    

    Em seguida, 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 timeout em sua implantação com base em quanto tempo o modelo leva para executar a inferência em um único lote. Quanto maior o tamanho do lote, mais tempo esse valor deve ser. Lembre-se que mini_batch_size indica o número de arquivos em um lote, não o número de exemplos. Ao trabalhar com dados tabulares, cada arquivo pode conter várias linhas, o que aumentará o tempo necessário para que o ponto de extremidade do lote processe cada arquivo. Use valores altos nesses casos para evitar erros de tempo limite.

  6. Embora você possa invocar uma implantação específica dentro de um ponto de extremidade, geralmente desejará invocar o ponto de extremidade em si e permitir que o ponto de extremidade decida qual implantação usar. Essa implantação é chamada de implantação "padrão". Isso permite alterar a implantação padrão e, portanto, alterar o modelo que atende à implantação sem alterar o contrato com o usuário invocando 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
    
  7. Neste estágio, nosso ponto de extremidade em lotes está pronto para ser usado.

Testando a implantação

Para testar nosso ponto de extremidade, usaremos um exemplo de dados não rotulados localizados neste repositório e que podem ser usados com o modelo. Os pontos de extremidade do lote só podem processar dados localizados na nuvem e que podem ser acessados no workspace do Azure Machine Learning. Neste exemplo, vamos carregá-lo em um armazenamento de dados do Azure Machine Learning. Particularmente, vamos criar um ativo de dados que pode ser usado para invocar o ponto de extremidade para pontuação. No entanto, observe que os pontos de extremidade em lote aceitam dados que podem ser colocados em vários tipos de locais.

  1. Vamos criar o ativo de dados primeiro. Esse 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.

    a. 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
    

    b. Crie o ativo de dados:

    az ml data create -f heart-dataset-unlabeled.yml
    
  2. Agora que os dados estão carregados e prontos para serem usados, vamos invocar o ponto de extremidade:

    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. Você pode obter instruções de instalação neste link.

    Dica

    Observe como não estamos indicando o nome da implantação na operação de invocação. Isso ocorre porque o ponto de extremidade roteia automaticamente o trabalho para a implantação padrão. Como nosso ponto de extremidade tem apenas uma implantação, essa é a padrão. Você pode direcionar uma implantação específica indicando o argumento/parâmetro deployment_name.

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

    az ml job show -n $JOB_NAME --web
    

Analisando as 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 nomeada chamada score onde esse arquivo é colocado. Apenas um arquivo é gerado por trabalho em lote.

O arquivo é estruturado da seguinte forma:

  • Há uma linha por cada ponto de dados que foi enviado para o modelo. Para dados tabulares, isso significa que o arquivo (predictions.csv) contém uma linha para cada linha presente em cada um dos arquivos processados. Para outros tipos de dados (por exemplo, imagens, áudio, texto), há uma linha por cada arquivo processado.

  • As colunas a seguir estão no arquivo (em ordem):

    • row (opcional): o índice de linha correspondente no arquivo de dados de entrada. Isso só se aplica se os dados de entrada forem tabulares. Para qualquer arquivo específico, as previsões são retornadas na mesma ordem em que aparecem no arquivo de entrada para que você possa contar com o número da linha para corresponder à previsão correspondente.
    • prediction: a previsão associada aos dados de entrada. Esse valor é retornado "como está" que foi fornecido pela função predict(). do modelo.
    • file_name: o nome do arquivo do qual os dados foram lidos. Em dados tabulares, use esse campo para saber 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 que o arquivo for baixado, você poderá abri-lo usando sua ferramenta favorita. O exemplo a seguir carrega as previsões usando dataframe Pandas.

import pandas as pd

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

A saída tem a seguinte aparência:

row prediction 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 eram dados tabulares no formato CSV e havia quatro arquivos de entrada diferentes (heart-unlabeled-0.csv, heart-unlabeled-1.csv, heart-unlabeled-2.csv e heart-unlabeled-3.csv).

Considerações ao implantar em inferência em lote

O Azure Machine Learning dá suporte à implantação de modelos de MLflow em pontos de extremidade em lote sem indicar um script de pontuação. Isso representa uma maneira conveniente de implantar modelos que exigem processamento de grandes quantidades de dados em lotes. O Azure Machine Learning usa informações na especificação do modelo do MLflow para orquestrar o processo de inferência.

Como o trabalho é distribuído nos trabalhadores

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ê estiver particionando seus dados usando pastas, certifique-se de nivelar a estrutura com antecedência.

Implantações em lote chamarão a função predict do modelo MLflow uma vez por arquivo. Para arquivos CSV que contêm várias linhas, isso pode impor uma pressão de memória na computação subjacente e pode aumentar o tempo necessário para que o modelo marque um único arquivo (especialmente para modelos caros, como modelos de linguagem grandes). Se você encontrar várias exceções de memória insuficiente ou entradas de tempo limite em logs, considere dividir os dados em arquivos menores com menos linhas ou implementar o envio em lote no nível da linha dentro do script de modelo/pontuação.

Suporte a tipos de arquivo

Os seguintes tipos de dados têm suporte para inferência em lote ao implantar modelos MLflow sem um ambiente e um script de pontuação. Se você gosta de processar um tipo de arquivo diferente ou executar a inferência de uma maneira diferente daquela que os pontos de extremidade do lote fazem por padrão, você sempre pode criar a implantação com um script de pontuação, conforme explicado em Usando modelos MLflow com um script de pontuação.

Extensão de arquivo Tipo retornado como entrada do modelo Requisito de assinatura
.csv, .parquet, .pqt pd.DataFrame ColSpec. Se não for fornecido, a digitação 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 diretrizes adicionais, leia Considerações sobre imagens de processamento de modelos MLflow.

Aviso

Lembre-se de que qualquer arquivo sem suporte que possa estar presente nos dados de entrada fará com que o trabalho falhe. Você verá uma entrada de erro da seguinte maneira: "ERROR:azureml:Erro ao processar o arquivo de entrada: '/mnt/batch/tasks/.../a-given-file.avro'. O tipo de arquivo 'avro' não tem suporte.".

Imposição de assinatura para modelos MLflow

Os tipos de dados da entrada são impostos por trabalhos de implantação em lote ao ler os dados usando a assinatura de modelo do MLflow disponível. Isso significa que sua entrada de dados deve estar em conformidade com os tipos indicados na assinatura do modelo. Se os dados não puderem ser analisados conforme o esperado, o trabalho falhará com uma mensagem de erro semelhante à seguinte: "ERROR:azureml:Error processing input file: '/mnt/batch/tasks/.../a-given-file.csv'. Exceção: literal inválido para int() com base 10: 'value'".

Dica

As assinaturas em modelos MLflow são opcionais, mas são altamente incentivadas, pois fornecem uma maneira conveniente de detectar problemas de compatibilidade de dados antecipadamente. Para obter mais informações sobre como registrar modelos com assinaturas, leia Modelos de log 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, consulte Assinaturas no MLflow.

Suporte a variante

As implantações em lote só dão suporte à implantação de modelos MLflow com uma variante pyfunc. Se precisar implantar uma variante diferente, consulte Usando modelos MLflow com um script de pontuação.

Como personalizar implantações de modelo do MLflow com um 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 de lote) para personalizar como a inferência é executada.

Normalmente, você selecionará esse fluxo de trabalho quando:

  • Precisar processar um tipo de arquivo sem suporte por implantações em lote de implantações de MLflow.
  • Precisar personalizar a maneira como o modelo é executado, por exemplo, usar um sabor específico para carregá-lo com mlflow.<flavor>.load().
  • Precisar fazer o processamento pré/pos em sua rotina de pontuação quando ele não é feito pelo próprio modelo.
  • A saída do modelo não pode ser bem representada em dados tabulares. Por exemplo, é um tensor que representa uma imagem.
  • O modelo não pode processar cada arquivo de uma só vez devido a restrições de memória e ele precisa lê-lo em partes.

Importante

Se você optar por indicar um script de pontuação para uma implantação de modelo do MLflow, também precisará especificar o ambiente em que a implantação será executada.

Etapas

Use as etapas a seguir para implantar um modelo MLflow com um script de pontuação personalizado.

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

    a. Acesse Portal de Interface do usuário do Azure Machine Learning.

    b. Vá para a seção Modelos.

    c. Selecione o modelo que você está tentando implantar e clique na guia Artefatos.

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

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

  2. Crie um script de pontuação. Observe como o nome model da pasta que você identificou antes foi 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. Vamos criar um ambiente em que o script de pontuação possa ser executado. Como nosso modelo é MLflow, os requisitos do Conda também são especificados no pacote de modelos (para obter mais detalhes sobre modelos do MLflow e os arquivos incluídos nele, consulte O formato MLmodel). Em seguida, vamos criar o ambiente usando as dependências Conda do arquivo. No entanto, também precisamos incluir o pacote azureml-core necessário para implantações em lote.

    Dica

    Se o modelo já estiver registrado no registro de modelo, baixe/copie o arquivo conda.yml associado ao modelo acessando Estúdio do Azure Machine Learning> Modelos > Selecione seu modelo na lista > Artefatos. Abra a pasta raiz na navegação e selecione o arquivo conda.yml listado. Clique em Baixar ou copiar seu conteúdo.

    Importante

    Este exemplo usa um ambiente conda especificado em /heart-classifier-mlflow/environment/conda.yaml. Esse arquivo foi criado combinando o arquivo de dependências conda do MLflow original e adicionando o pacote azureml-core. Você não pode usar o arquivo conda.yml diretamente do modelo.

    A definição de ambiente será incluída na própria definição de implantação como um ambiente anônimo. Você exibirá nas 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 nova implantação no ponto de extremidade criado, crie uma configuração YAML semelhante à seguinte. 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. Vamos criar a implantação agora:

    az ml batch-deployment create --file deployment-custom/deployment.yml --endpoint-name $ENDPOINT_NAME
    
  6. Neste estágio, nosso ponto de extremidade em lotes está pronto para ser usado.

Limpar os recursos

Execute o código a seguir para excluir o ponto de extremidade em lote e todas as implantações subjacentes. Os trabalhos de pontuação em lote não serão excluídos.

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

Próximas etapas