Preparar modelos do TensorFlow em escala com o Azure Machine Learning

APLICA-SE A: SDK python azure-ai-ml v2 (atual)

Neste artigo, saiba como executar os scripts de preparação do TensorFlow em escala com o SDK Python v2 do Azure Machine Learning.

O código de exemplo neste artigo prepara um modelo do TensorFlow para classificar dígitos manuscritos com uma rede neural profunda (DNN); registar o modelo; e implemente-o num ponto final online.

Quer esteja a desenvolver um modelo do TensorFlow a partir do zero ou esteja a trazer um modelo existente para a cloud, pode utilizar o Azure Machine Learning para aumentar horizontalmente as tarefas de preparação open source com recursos de computação na cloud elástica. Pode criar, implementar, versão e monitorizar modelos de nível de produção com o Azure Machine Learning.

Pré-requisitos

Para beneficiar deste artigo, terá de:

  • Aceder a uma subscrição do Azure. Se ainda não tiver uma, crie uma conta gratuita.
  • Execute o código neste artigo com uma instância de computação do Azure Machine Learning ou o seu próprio bloco de notas do Jupyter.
    • Instância de computação do Azure Machine Learning – não são necessárias transferências ou instalações
      • Conclua o Início Rápido: Introdução ao Azure Machine Learning para criar um servidor de blocos de notas dedicado pré-carregado com o SDK e o repositório de exemplo.
      • Na pasta de aprendizagem profunda de exemplos no servidor de blocos de notas, localize um bloco de notas concluído e expandido ao navegar para este diretório: trabalhos python de sdk > v2 > trabalhos de tensorflow >>> de passo > único train-hyperparameter-tune-deploy-with-tensorflow.
    • O seu servidor de blocos de notas do Jupyter
  • Transfira os seguintes ficheiros:

Também pode encontrar uma versão Jupyter Notebook concluída deste guia na página de exemplos do GitHub.

Antes de poder executar o código neste artigo para criar um cluster de GPU, terá de pedir um aumento de quota para a área de trabalho.

Configurar a tarefa

Esta secção configura a tarefa de preparação ao carregar os pacotes Python necessários, ligar a uma área de trabalho, criar um recurso de computação para executar uma tarefa de comando e criar um ambiente para executar a tarefa.

Ligar à área de trabalho

Primeiro, terá de se ligar à área de trabalho do AzureML. A área de trabalho do AzureML é o recurso de nível superior do serviço. Fornece-lhe um local centralizado para trabalhar com todos os artefactos que cria quando utiliza o Azure Machine Learning.

Estamos a utilizar DefaultAzureCredential para obter acesso à área de trabalho. Esta credencial deve ser capaz de processar a maioria dos cenários de autenticação do SDK do Azure.

Se DefaultAzureCredential não funcionar para si, consulte azure-identity reference documentation ou Set up authentication para obter mais credenciais disponíveis.

# Handle to the workspace
from azure.ai.ml import MLClient

# Authentication package
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()

Se preferir utilizar um browser para iniciar sessão e autenticar, deve anular o comentário do seguinte código e utilizá-lo.

# Handle to the workspace
# from azure.ai.ml import MLClient

# Authentication package
# from azure.identity import InteractiveBrowserCredential
# credential = InteractiveBrowserCredential()

Em seguida, obtenha um identificador para a área de trabalho ao fornecer o ID da Subscrição, o nome do Grupo de Recursos e o nome da área de trabalho. Para localizar estes parâmetros:

  1. Procure o nome da área de trabalho no canto superior direito da barra de ferramentas estúdio do Azure Machine Learning.
  2. Selecione o nome da área de trabalho para mostrar o Grupo de Recursos e o ID da Subscrição.
  3. Copie os valores de Grupo de Recursos e ID de Subscrição para o código.
# Get a handle to the workspace
ml_client = MLClient(
    credential=credential,
    subscription_id="<SUBSCRIPTION_ID>",
    resource_group_name="<RESOURCE_GROUP>",
    workspace_name="<AML_WORKSPACE_NAME>",
)

O resultado da execução deste script é um identificador de área de trabalho que irá utilizar para gerir outros recursos e tarefas.

Nota

  • A criação MLClient não ligará o cliente à área de trabalho. A inicialização do cliente é lenta e aguardará pela primeira vez que precisar de fazer uma chamada. Neste artigo, isto acontecerá durante a criação da computação.

Criar um recurso de computação para executar a tarefa

O AzureML precisa de um recurso de computação para executar uma tarefa. Este recurso pode ser um computador de nó único ou com vários nós com Linux ou SO Windows, ou um recurso de infraestrutura de computação específico, como o Spark.

No script de exemplo seguinte, aprovisionamos um Linux compute cluster. Pode ver a página para obter a Azure Machine Learning pricing lista completa dos tamanhos e preços das VMs. Uma vez que precisamos de um cluster de GPU para este exemplo, vamos escolher um modelo de STANDARD_NC6 e criar uma computação do AzureML.

from azure.ai.ml.entities import AmlCompute

gpu_compute_target = "gpu-cluster"

try:
    # let's see if the compute target already exists
    gpu_cluster = ml_client.compute.get(gpu_compute_target)
    print(
        f"You already have a cluster named {gpu_compute_target}, we'll reuse it as is."
    )

except Exception:
    print("Creating a new gpu compute target...")

    # Let's create the Azure ML compute object with the intended parameters
    gpu_cluster = AmlCompute(
        # Name assigned to the compute cluster
        name="gpu-cluster",
        # Azure ML Compute is the on-demand VM service
        type="amlcompute",
        # VM Family
        size="STANDARD_NC6",
        # Minimum running nodes when there is no job running
        min_instances=0,
        # Nodes in cluster
        max_instances=4,
        # How many seconds will the node running after the job termination
        idle_time_before_scale_down=180,
        # Dedicated or LowPriority. The latter is cheaper but there is a chance of job termination
        tier="Dedicated",
    )

    # Now, we pass the object to MLClient's create_or_update method
    gpu_cluster = ml_client.begin_create_or_update(gpu_cluster).result()

print(
    f"AMLCompute with name {gpu_cluster.name} is created, the compute size is {gpu_cluster.size}"
)

Criar um ambiente de trabalho

Para executar uma tarefa do AzureML, precisará de um ambiente. Um ambiente do AzureML encapsula as dependências (como o runtime de software e bibliotecas) necessárias para executar o script de preparação de machine learning no recurso de computação. Este ambiente é semelhante a um ambiente Python no seu computador local.

O AzureML permite-lhe utilizar um ambiente organizado (ou pronto a utilizar), útil para cenários comuns de preparação e inferência, ou criar um ambiente personalizado com uma imagem do Docker ou uma configuração Conda.

Neste artigo, vai reutilizar o ambiente AzureML-tensorflow-2.7-ubuntu20.04-py38-cuda11-gpudo AzureML organizado. Irá utilizar a versão mais recente deste ambiente com a @latest diretiva .

curated_env_name = "AzureML-tensorflow-2.7-ubuntu20.04-py38-cuda11-gpu@latest"

Configurar e submeter a tarefa de preparação

Nesta secção, vamos começar por introduzir os dados para preparação. Em seguida, vamos abordar como executar um trabalho de preparação com um script de preparação que fornecemos. Irá aprender a criar a tarefa de preparação ao configurar o comando para executar o script de preparação. Em seguida, irá submeter a tarefa de preparação para ser executada no AzureML.

Obter os dados de preparação

Irá utilizar dados da base de dados modificado do Instituto Nacional de Normas e Tecnologia (MNIST) de dígitos manuscritos. Estes dados são obtidos a partir do site de Yan LeCun e armazenados numa conta de armazenamento do Azure.

web_path = "wasbs://datasets@azuremlexamples.blob.core.windows.net/mnist/"

Para obter mais informações sobre o conjunto de dados MNIST, visite o site de Yan LeCun.

Preparar o script de preparação

Neste artigo, fornecemos o script de preparação tf_mnist.py. Na prática, deve ser capaz de utilizar qualquer script de preparação personalizado tal como está e executá-lo com o AzureML sem ter de modificar o código.

O script de preparação fornecido faz o seguinte:

  • processa o pré-processamento de dados, dividindo os dados em dados de teste e de preparação;
  • prepara um modelo, utilizando os dados; e
  • devolve o modelo de saída.

Durante a execução do pipeline, irá utilizar o MLFlow para registar os parâmetros e as métricas. Para saber como ativar o controlo do MLFlow, veja Controlar experimentações e modelos ML com o MLflow.

No script tf_mnist.pyde preparação , criamos uma rede neural profunda (DNN) simples. Este DNN tem:

  • Uma camada de entrada com 28 * 28 = 784 neurónios. Cada neurónio representa um pixel de imagem.
  • Duas camadas ocultas. A primeira camada escondida tem 300 neurónios e a segunda camada escondida tem 100 neurónios.
  • Uma camada de saída com 10 neurónios. Cada neurónio representa uma etiqueta direcionada de 0 a 9.

Diagrama a mostrar uma rede neural profunda com 784 neurónios na camada de entrada, duas camadas ocultas e 10 neurónios na camada de saída.

Criar a tarefa de preparação

Agora que tem todos os recursos necessários para executar a tarefa, está na altura de o criar com o SDK Python v2 do AzureML. Neste exemplo, vamos criar um command.

Um AzureML command é um recurso que especifica todos os detalhes necessários para executar o código de preparação na cloud. Estes detalhes incluem as entradas e saídas, o tipo de hardware a utilizar, o software a instalar e como executar o código. Contém command informações para executar um único comando.

Configurar o comando

Irá utilizar o objetivo command geral para executar o script de preparação e realizar as tarefas pretendidas. Crie um Command objeto para especificar os detalhes de configuração da tarefa de preparação.

from azure.ai.ml import command
from azure.ai.ml import UserIdentityConfiguration
from azure.ai.ml import Input

web_path = "wasbs://datasets@azuremlexamples.blob.core.windows.net/mnist/"

job = command(
    inputs=dict(
        data_folder=Input(type="uri_folder", path=web_path),
        batch_size=64,
        first_layer_neurons=256,
        second_layer_neurons=128,
        learning_rate=0.01,
    ),
    compute=gpu_compute_target,
    environment=curated_env_name,
    code="./src/",
    command="python tf_mnist.py --data-folder ${{inputs.data_folder}} --batch-size ${{inputs.batch_size}} --first-layer-neurons ${{inputs.first_layer_neurons}} --second-layer-neurons ${{inputs.second_layer_neurons}} --learning-rate ${{inputs.learning_rate}}",
    experiment_name="tf-dnn-image-classify",
    display_name="tensorflow-classify-mnist-digit-images-with-dnn",
)
  • As entradas para este comando incluem a localização dos dados, o tamanho do lote, o número de neurónios na primeira e segunda camada e a taxa de aprendizagem. Repare que transmitimos o caminho web diretamente como uma entrada.

  • Para os valores dos parâmetros:

    • indique o cluster gpu_compute_target = "gpu-cluster" de cálculo que criou para executar este comando;
    • fornecer o ambiente curated_env_name organizado que declarou anteriormente;
    • configure a ação da linha de comandos em si— neste caso, o comando é python tf_mnist.py. Pode aceder às entradas e saídas no comando através da ${{ ... }} notação; e
    • configurar metadados, como o nome a apresentar e o nome da experimentação; em que uma experimentação é um contentor para todas as iterações que se faz num determinado projeto. Todas as tarefas submetidas com o mesmo nome de experimentação seriam listadas entre si no AzureML Studio.
  • Neste exemplo, irá utilizar o UserIdentity para executar o comando. Utilizar uma identidade de utilizador significa que o comando utilizará a sua identidade para executar a tarefa e aceder aos dados a partir do blob.

Submeter o trabalho

Chegou a altura de submeter a tarefa a ser executada no AzureML. Desta vez, irá utilizar create_or_update em ml_client.jobs.

ml_client.jobs.create_or_update(job)

Depois de concluída, a tarefa registará um modelo na área de trabalho (como resultado da preparação) e produzirá uma ligação para ver a tarefa no AzureML Studio.

Aviso

O Azure Machine Learning executa scripts de preparação ao copiar todo o diretório de origem. Se tiver dados confidenciais que não pretende carregar, utilize um ficheiro .ignore ou não os inclua no diretório de origem.

O que acontece durante a execução do trabalho

À medida que a tarefa é executada, passa pelas seguintes fases:

  • Preparação: é criada uma imagem do docker de acordo com o ambiente definido. A imagem é carregada para o registo de contentor da área de trabalho e colocada em cache para execuções posteriores. Os registos também são transmitidos para o histórico de tarefas e podem ser visualizados para monitorizar o progresso. Se for especificado um ambiente organizado, será utilizada a cópia de segurança da imagem em cache que o ambiente organizado.

  • Dimensionamento: o cluster tenta aumentar verticalmente se precisar de mais nós para executar a execução do que está atualmente disponível.

  • Em execução: todos os scripts na pasta de script src são carregados para o destino de computação, os arquivos de dados são montados ou copiados e o script é executado. As saídas do stdout e da pasta ./logs são transmitidas em fluxo para o histórico de tarefas e podem ser utilizadas para monitorizar a tarefa.

Otimizar hiperparâmetros de modelo

Agora que já viu como fazer uma execução de preparação do TensorFlow com o SDK, vamos ver se consegue melhorar ainda mais a precisão do modelo. Pode otimizar e otimizar os hiperparâmetros do modelo com as capacidades do sweep Azure Machine Learning.

Para otimizar os hiperparâmetros do modelo, defina o espaço de parâmetros no qual pretende procurar durante a preparação. Irá fazê-lo ao substituir alguns dos parâmetros (batch_size, , first_layer_neuronssecond_layer_neuronse learning_rate) transmitidos para a tarefa de preparação por entradas especiais do azure.ml.sweep pacote.

from azure.ai.ml.sweep import Choice, LogUniform

# we will reuse the command_job created before. we call it as a function so that we can apply inputs
# we do not apply the 'iris_csv' input again -- we will just use what was already defined earlier
job_for_sweep = job(
    batch_size=Choice(values=[32, 64, 128]),
    first_layer_neurons=Choice(values=[16, 64, 128, 256, 512]),
    second_layer_neurons=Choice(values=[16, 64, 256, 512]),
    learning_rate=LogUniform(min_value=-6, max_value=-1),
)

Em seguida, irá configurar o varrimento na tarefa de comando, utilizando alguns parâmetros específicos de varrimento, como a métrica primária a observar e o algoritmo de amostragem a utilizar.

No código seguinte, utilizamos a amostragem aleatória para experimentar diferentes conjuntos de configuração de hiperparâmetros numa tentativa de maximizar a nossa métrica primária, validation_acc.

Também definimos uma política de cessação antecipada: o BanditPolicy. Esta política funciona ao verificar a tarefa a cada duas iterações. Se a métrica primária, validation_acc, ficar fora do intervalo de 10%, o AzureML terminará a tarefa. Isto impede o modelo de continuar a explorar hiperparâmetros que não mostram nenhuma promessa de ajudar a alcançar a métrica de destino.

from azure.ai.ml.sweep import BanditPolicy

sweep_job = job_for_sweep.sweep(
    compute=gpu_compute_target,
    sampling_algorithm="random",
    primary_metric="validation_acc",
    goal="Maximize",
    max_total_trials=8,
    max_concurrent_trials=4,
    early_termination_policy=BanditPolicy(slack_factor=0.1, evaluation_interval=2),
)

Agora, pode submeter esta tarefa como anteriormente. Desta vez, vais fazer um trabalho de limpeza que varre o teu trabalho de comboio.

returned_sweep_job = ml_client.create_or_update(sweep_job)

# stream the output and wait until the job is finished
ml_client.jobs.stream(returned_sweep_job.name)

# refresh the latest status of the job after streaming
returned_sweep_job = ml_client.jobs.get(name=returned_sweep_job.name)

Pode monitorizar a tarefa utilizando a ligação de interface de utilizador do estúdio que é apresentada durante a execução da tarefa.

Localizar e registar o melhor modelo

Depois de todas as execuções serem concluídas, pode encontrar a execução que produziu o modelo com a maior precisão.

from azure.ai.ml.entities import Model

if returned_sweep_job.status == "Completed":

    # First let us get the run which gave us the best result
    best_run = returned_sweep_job.properties["best_child_run_id"]

    # lets get the model from this run
    model = Model(
        # the script stores the model as "model"
        path="azureml://jobs/{}/outputs/artifacts/paths/outputs/model/".format(
            best_run
        ),
        name="run-model-example",
        description="Model created from run.",
        type="custom_model",
    )

else:
    print(
        "Sweep job status: {}. Please wait until it completes".format(
            returned_sweep_job.status
        )
    )

Em seguida, pode registar este modelo.

registered_model = ml_client.models.create_or_update(model=model)

Implementar o modelo como um ponto final online

Depois de registar o modelo, pode implementá-lo como um ponto final online, ou seja, como um serviço Web na cloud do Azure.

Para implementar um serviço de machine learning, normalmente precisará de:

  • Os recursos de modelo que pretende implementar. Estes recursos incluem o ficheiro e os metadados do modelo que já registou na sua tarefa de preparação.
  • Algum código para ser executado como um serviço. O código executa o modelo num determinado pedido de entrada (um script de entrada). Este script de entrada recebe dados submetidos para um serviço Web implementado e transmite-os para o modelo. Depois de o modelo processar os dados, o script devolve a resposta do modelo ao cliente. O script é específico do seu modelo e tem de compreender os dados esperados e devolvidos pelo modelo. Quando utiliza um modelo MLFlow, o AzureML cria automaticamente este script automaticamente.

Para obter mais informações sobre a implementação, veja Implementar e classificar um modelo de machine learning com o ponto final online gerido com o SDK Python v2.

Criar um novo ponto final online

Como primeiro passo para implementar o seu modelo, tem de criar o seu ponto final online. O nome do ponto final tem de ser exclusivo em toda a região do Azure. Para este artigo, irá criar um nome exclusivo com um identificador universalmente exclusivo (UUID).

import uuid

# Creating a unique name for the endpoint
online_endpoint_name = "tff-dnn-endpoint-" + str(uuid.uuid4())[:8]
from azure.ai.ml.entities import (
    ManagedOnlineEndpoint,
    ManagedOnlineDeployment,
    Model,
    Environment,
)

# create an online endpoint
endpoint = ManagedOnlineEndpoint(
    name=online_endpoint_name,
    description="Classify handwritten digits using a deep neural network (DNN) using TensorFlow",
    auth_mode="key",
)

endpoint = ml_client.begin_create_or_update(endpoint).result()

print(f"Endpint {endpoint.name} provisioning state: {endpoint.provisioning_state}")

Depois de criar o ponto final, pode obtê-lo da seguinte forma:

endpoint = ml_client.online_endpoints.get(name=online_endpoint_name)

print(
    f'Endpint "{endpoint.name}" with provisioning state "{endpoint.provisioning_state}" is retrieved'
)

Implementar o modelo no ponto final

Depois de criar o ponto final, pode implementar o modelo com o script de entrada. Um ponto final pode ter várias implementações. Com as regras, o ponto final pode direcionar o tráfego para estas implementações.

No código seguinte, irá criar uma única implementação que processa 100% do tráfego de entrada. Especificámos um nome de cor arbitrário (tff-blue) para a implementação. Também pode utilizar qualquer outro nome, como tff-green ou tff-red para a implementação. O código para implementar o modelo no ponto final faz o seguinte:

  • implementa a melhor versão do modelo que registou anteriormente;
  • classifica o modelo, utilizando o score.py ficheiro; e
  • utiliza o mesmo ambiente organizado (que declarou anteriormente) para efetuar a inferência.
model = registered_model

from azure.ai.ml.entities import CodeConfiguration

# create an online deployment.
blue_deployment = ManagedOnlineDeployment(
    name="tff-blue",
    endpoint_name=online_endpoint_name,
    model=model,
    code_configuration=CodeConfiguration(code="./src", scoring_script="score.py"),
    environment=curated_env_name,
    instance_type="Standard_DS3_v2",
    instance_count=1,
)

blue_deployment = ml_client.begin_create_or_update(blue_deployment).result()

Nota

Espere que esta implementação dedure um pouco de tempo para concluir.

Testar a implementação com uma consulta de exemplo

Agora que implementou o modelo no ponto final, pode prever a saída do modelo implementado, utilizando o invoke método no ponto final. Para executar a inferência, utilize o ficheiro sample-request.json de pedido de exemplo da pasta de pedidos .

# # predict using the deployed model
result = ml_client.online_endpoints.invoke(
    endpoint_name=online_endpoint_name,
    request_file="./request/sample-request.json",
    deployment_name="tff-blue",
)

Em seguida, pode imprimir as predições devolvidas e desenhá-las juntamente com as imagens de entrada. Utilize a cor do tipo de letra vermelho e a imagem invertida (branco a preto) para realçar as amostras mal classificadas.

# compare actual value vs. the predicted values:
import matplotlib.pyplot as plt

i = 0
plt.figure(figsize=(20, 1))

for s in sample_indices:
    plt.subplot(1, n, i + 1)
    plt.axhline("")
    plt.axvline("")

    # use different color for misclassified sample
    font_color = "red" if y_test[s] != result[i] else "black"
    clr_map = plt.cm.gray if y_test[s] != result[i] else plt.cm.Greys

    plt.text(x=10, y=-10, s=result[i], fontsize=18, color=font_color)
    plt.imshow(X_test[s].reshape(28, 28), cmap=clr_map)

    i = i + 1
plt.show()

Nota

Uma vez que a precisão do modelo é elevada, poderá ter de executar a célula algumas vezes antes de ver uma amostra mal classificada.

Limpar os recursos

Se não estiver a utilizar o ponto final, elimine-o para parar de utilizar o recurso. Certifique-se de que nenhuma outra implementação está a utilizar o ponto final antes de o eliminar.

ml_client.online_endpoints.begin_delete(name=online_endpoint_name)

Nota

Espere que esta limpeza leve algum tempo a concluir.

Passos seguintes

Neste artigo, preparou e registou um modelo do TensorFlow. Também implementou o modelo num ponto final online. Veja estes outros artigos para saber mais sobre o Azure Machine Learning.