Solucionar problemas de pipelines de aprendizado de máquina
APLICA-SE A: SDK do Python do AzureML v1
Neste artigo, você aprenderá a solucionar problemas ao obter erros ao executar um pipeline de machine learning no SDK do Azure Machine Learning e no designer do Azure Machine Learning.
Dicas de solução de problemas
A tabela a seguir contém problemas comuns durante o desenvolvimento de pipeline, com possíveis soluções.
Problema | Solução possível |
---|---|
Não é possível passar dados para o diretório PipelineData |
Verifique se você criou um diretório no script que corresponde ao local em que seu pipeline espera os dados de saída da etapa. Na maioria dos casos, um argumento de entrada define o diretório de saída e, em seguida, você cria o diretório explicitamente. Use os.makedirs(args.output_dir, exist_ok=True) para criar o diretório de saída. Consulte o tutorial para obter um exemplo de script de pontuação que mostra esse padrão de design. |
Bugs de dependência | Se você vir erros de dependência em seu pipeline remoto que não ocorreram durante o teste local, confirme se as suas dependências e versões de ambiente remoto correspondem àquelas em seu ambiente de teste. (Confira Criação de ambiente, cache e reutilização) |
Erros ambíguos com destinos de computação | Tente excluir e recriar os destinos de computação. Recriar destinos de computação é rápido e pode resolver alguns problemas transitórios. |
O pipeline não está reutilizando as etapas | A reutilização de etapa é habilitada por padrão, mas certifique-se de que você não a desabilitou em uma etapa de pipeline. Se a reutilização estiver desabilitada, o allow_reuse parâmetro na etapa será definido como False . |
O pipeline está sendo executado desnecessariamente | Para garantir que as etapas sejam executadas somente quando seus dados ou scripts subjacentes forem alterados, desassocie os diretórios de código-fonte para cada etapa. Se usar o mesmo diretório de origem para várias etapas, poderá ocorrer uma reexecução desnecessária. Use o parâmetro source_directory em um objeto etapa de pipeline para apontar para seu diretório isolado para essa etapa e verifique se você não está usando o mesmo caminho source_directory para várias etapas. |
Etapa reduzindo as épocas de treinamento ou outro comportamento de looping | Tente alternar qualquer gravação de arquivo, incluindo registro em log, de as_mount() para as_upload() . O modo de montagem usa um sistema de arquivos virtualizado remoto e carrega todo o arquivo cada vez que é anexado. |
O destino de computação leva muito tempo para iniciar | As imagens do Docker para destinos de computação são carregadas do ACR (Registro de Contêiner do Azure). Por padrão, o Azure Machine Learning cria um ACR que usa a camada de serviço básica. Alterar o ACR para o espaço de trabalho para a camada Standard ou Premium pode reduzir o tempo necessário para criar e carregar imagens. Para obter mais informações, confira Níveis de serviço do Registro de Contêiner do Azure. |
Erros de autenticação
Se executar uma operação de gerenciamento em um destino de computação de um trabalho remoto, você receberá um dos seguintes erros:
{"code":"Unauthorized","statusCode":401,"message":"Unauthorized","details":[{"code":"InvalidOrExpiredToken","message":"The request token was either invalid or expired. Please try again with a valid token."}]}
{"error":{"code":"AuthenticationFailed","message":"Authentication failed."}}
Por exemplo, você receberá um erro se tentar criar ou anexar um destino de computação de um Pipeline de ML que é enviado para execução remota.
Solução de problemas ParallelRunStep
O script para um ParallelRunStep
deve conter duas funções:
init()
: Use essa função para qualquer preparação dispendiosa ou comum para inferência posterior. Por exemplo, use-a para carregar o modelo em um objeto global. Essa função é chamada apenas uma vez no início do processo.run(mini_batch)
: a função é executada para cada instância demini_batch
.mini_batch
:ParallelRunStep
invoca o método run e transmitirá uma lista ou oDataFrame
Pandas como um argumento para o método. Cada entrada em min_batch é um caminho de arquivo se a entrada for umFileDataset
ou umDataFrame
Pandas se a entrada for umTabularDataset
.response
: o método run() deve retornar umDataFrame
Pandas ou uma matriz. Para append_row output_action, esses elementos retornados são acrescentados ao arquivo de saída comum. Para summary_only, o conteúdo dos elementos é ignorado. Para todas as ações de saída, cada elemento de saída retornado indica uma execução bem-sucedida do elemento de entrada no minilote de entrada. Verifique se dados suficientes foram incluídos no resultado da execução para mapear a entrada para o resultado da saída da execução. A saída de execução é gravada no arquivo de saída e não é garantido que esteja em ordem; você deverá usar uma chave na saída para mapeá-la para a entrada.
%%writefile digit_identification.py
# Snippets from a sample script.
# Refer to the accompanying digit_identification.py
# (https://github.com/Azure/MachineLearningNotebooks/tree/master/how-to-use-azureml/machine-learning-pipelines/parallel-run)
# for the implementation script.
import os
import numpy as np
import tensorflow as tf
from PIL import Image
from azureml.core import Model
def init():
global g_tf_sess
# Pull down the model from the workspace
model_path = Model.get_model_path("mnist")
# Construct a graph to execute
tf.reset_default_graph()
saver = tf.train.import_meta_graph(os.path.join(model_path, 'mnist-tf.model.meta'))
g_tf_sess = tf.Session()
saver.restore(g_tf_sess, os.path.join(model_path, 'mnist-tf.model'))
def run(mini_batch):
print(f'run method start: {__file__}, run({mini_batch})')
resultList = []
in_tensor = g_tf_sess.graph.get_tensor_by_name("network/X:0")
output = g_tf_sess.graph.get_tensor_by_name("network/output/MatMul:0")
for image in mini_batch:
# Prepare each image
data = Image.open(image)
np_im = np.array(data).reshape((1, 784))
# Perform inference
inference_result = output.eval(feed_dict={in_tensor: np_im}, session=g_tf_sess)
# Find the best probability, and add it to the result list
best_result = np.argmax(inference_result)
resultList.append("{}: {}".format(os.path.basename(image), best_result))
return resultList
Se você tiver outro arquivo ou pasta no mesmo diretório que o script de inferência, poderá consultá-lo localizando o diretório de trabalho atual.
script_dir = os.path.realpath(os.path.join(__file__, '..',))
file_path = os.path.join(script_dir, "<file_name>")
Parâmetros para ParallelRunConfig
ParallelRunConfig
é a principal configuração para a instância ParallelRunStep
no pipeline do Azure Machine Learning. Use-a para encapsular o script e configurar os parâmetros necessários, incluindo todas as seguintes entradas:
entry_script
: um script de usuário como um caminho de arquivo local que é executado em paralelo em vários nós. Sesource_directory
estiver presente, use um caminho relativo. Caso contrário, use qualquer caminho que seja acessível no computador.mini_batch_size
: O tamanho do minilote passado para uma única chamada derun()
. (opcional; o valor padrão são arquivos10
paraFileDataset
e1MB
paraTabularDataset
.)- Para
FileDataset
, é o número de arquivos com um valor mínimo de1
. Você pode combinar vários arquivos em um minilote. - Para
TabularDataset
, é o tamanho dos dados. Os valores de exemplo são1024
,1024KB
,10MB
e1GB
. O valor recomendado é1MB
. O minilote deTabularDataset
nunca ultrapassará os limites do arquivo. Por exemplo, se você tiver arquivos .csv com vários tamanhos, o menor arquivo será de 100 KB, e o maior será de 10 MB. Se você definirmini_batch_size = 1MB
, os arquivos com um tamanho menor que 1 MB são tratados como um minilote. Arquivos com um tamanho maior que 1 MB são divididos em vários minilotes.
- Para
error_threshold
: O número de falhas de registro paraTabularDataset
e falhas de arquivo paraFileDataset
que devem ser ignorados durante o processamento. Se a contagem de erros de toda a entrada ficar acima desse valor, o trabalho é anulado. O limite de erro é para toda a entrada, não para um minilote individual enviado ao métodorun()
. O intervalo é[-1, int.max]
. A parte-1
indica que é para ignorar todas as falhas durante o processamento.output_action
: um dos seguintes valores indica como a saída é organizada:summary_only
: O script de usuário armazena a saída.ParallelRunStep
usa a saída somente para o cálculo do limite de erro.append_row
: para todas as entradas, somente um arquivo é criado na pasta de saída para acrescentar todas as saídas separadas por linha.
append_row_file_name
: para personalizar o nome do arquivo de saída para append_row output_action (opcional; o valor padrão éparallel_run_step.txt
).source_directory
: Caminhos para pastas que contêm todos os arquivos a serem executados no destino de computação (opcional).compute_target
: ApenasAmlCompute
tem suporte.node_count
: O número de nós de computação a serem usados para executar o script do usuário.process_count_per_node
: O número de processos por nó. A melhor prática é definir como o número de GPU ou CPU que um nó tem (opcional; o valor padrão é1
).environment
: A definição de ambiente Python. Você pode configurá-lo para usar um ambiente Python existente ou para configurar um ambiente temporário. A definição também é responsável por configurar as dependências de aplicativo necessárias (opcional).logging_level
: Detalhamento do log. Os valores no detalhamento crescente são:WARNING
,INFO
eDEBUG
. (opcional; o valor padrão éINFO
)run_invocation_timeout
: O tempo limite de invocação do métodorun()
em segundos. (opcional; o valor padrão é60
)run_max_try
: contagem máxima de tentativas derun()
para um minilote. Umrun()
falhará se uma exceção for gerada ou nada será retornado quandorun_invocation_timeout
for atingido (opcional; o valor padrão é3
).
Especifique mini_batch_size
, node_count
, process_count_per_node
, logging_level
, run_invocation_timeout
e run_max_try
como PipelineParameter
, de modo que, ao reenviar uma execução de pipeline, você possa ajustar os valores de parâmetro. Nesse exemplo, você usa PipelineParameter
para mini_batch_size
e Process_count_per_node
, e altera esses valores quando reenviar uma execução posteriormente.
Parâmetros para criar o ParallelRunStep
Crie o ParallelRunStep usando o script, a configuração do ambiente e os parâmetros. Especifique o destino de computação que você já anexou ao seu workspace como o destino de execução do seu script de inferência. Use ParallelRunStep
para criar a etapa do pipeline de inferência de lote, que usa todos os seguintes parâmetros:
name
: O nome da etapa, com as seguintes restrições de nomenclatura: unique, 3-32 characters e regex ^[a-z]([-a-z0-9]*[a-z0-9])?$.parallel_run_config
: Um objetoParallelRunConfig
, conforme definido anteriormente.inputs
: um ou mais conjuntos de dados do Azure Machine Learning de tipo único a serem particionados para processamento paralelo.side_inputs
: um ou mais dados de referência ou conjuntos de dados usados como entradas laterais sem a necessidade de partição.output
: um objetoOutputFileDatasetConfig
que corresponde ao diretório de saída.arguments
: uma lista de argumentos passados para o script do usuário. Use unknown_args para recuperá-los em seu script de entrada (opcional).allow_reuse
: Se a etapa deve reutilizar os resultados anteriores quando executada com as mesmas configurações/entradas. Se esse parâmetro forFalse
, uma nova execução será gerada para essa etapa durante a execução do pipeline. (opcional; o valor padrão éTrue
.)
from azureml.pipeline.steps import ParallelRunStep
parallelrun_step = ParallelRunStep(
name="predict-digits-mnist",
parallel_run_config=parallel_run_config,
inputs=[input_mnist_ds_consumption],
output=output_dir,
allow_reuse=True
)
Técnicas de depuração
Há três técnicas principais para a depuração de pipelines:
- Depurar etapas de pipeline individuais no computador local
- Usar registro em log e Application Insights para isolar e diagnosticar a origem do problema
- Anexar um depurador remoto a um pipeline em execução no Azure
Testar scripts localmente
Uma das falhas mais comuns em um pipeline é que o script de domínio não é executado conforme o esperado, ou contém erros de tempo de execução no contexto de computação remota, que são difíceis de depurar.
Os pipelines propriamente ditos não podem ser executados localmente. No entanto, a execução dos scripts em isolamento no computador local permite depurar mais rápido porque não precisa esperar o processo de compilação do ambiente e da computação. É necessário algum trabalho de desenvolvimento para fazer isso:
- Se seus dados estiverem em um armazenamento em nuvem, será necessário baixar os dados e disponibilizá-los para o script. Usar uma pequena amostra de seus dados é uma boa maneira de reduzir o tempo de execução e obter rapidamente comentários sobre o comportamento do script
- Se estiver tentando simular uma etapa intermediária do pipeline, talvez seja necessário criar manualmente os tipos de objeto que o script específico está esperando na etapa anterior
- Você precisa definir seu próprio ambiente e replicar as dependências definidas em seu ambiente de computação remota
Quando tiver uma configuração de script para ser executada no seu ambiente local, é mais fácil fazer tarefas de depuração, tais como:
- Anexar uma configuração de depuração personalizada
- Pausar a execução e inspecionar o estado do objeto
- Capturar o tipo ou erros lógicos que só serão expostos em tempo de execução
Dica
Depois que confirmar que o script está sendo executado conforme o esperado, uma boa próxima etapa é executar o script em um pipeline de etapa única antes de tentar executá-lo em um pipeline com várias etapas.
Configurar, gravar e examinar logs de pipeline
Testar scripts localmente é uma ótima maneira de depurar os principais fragmentos de código e a lógica complexa antes de começar a criar um pipeline. Em algum momento, você precisará depurar scripts durante a execução real do pipeline, principalmente ao diagnosticar o comportamento que ocorre durante a interação entre as etapas do pipeline. É recomendável liberal o uso de instruções print()
nos scripts de etapa para que seja possível ver o estado do objeto e os valores esperados durante a execução remota, semelhante a como seria a depuração de código JavaScript.
Opções e comportamento de registro em log
A tabela a seguir fornece informações para diferentes opções de depuração para pipelines. Não é uma lista completa, já que existem outras opções, além de Azure Machine Learning e Python, mostradas aqui.
Biblioteca | Type | Exemplo | Destino | Recursos |
---|---|---|---|---|
SDK do Azure Machine Learning | Métrica | run.log(name, val) |
Portal de Interface do usuário do Azure Machine Learning | Como acompanhar experimentos azureml.core.Run class |
Impressão/registro em log do Python | Registro | print(val) logging.info(message) |
Logs de driver, designer do Azure Machine Learning | Como acompanhar experimentos Registro em log do Python |
Exemplo de opções de registro em log
import logging
from azureml.core.run import Run
run = Run.get_context()
# Azure Machine Learning Scalar value logging
run.log("scalar_value", 0.95)
# Python print statement
print("I am a python print statement, I will be sent to the driver logs.")
# Initialize Python logger
logger = logging.getLogger(__name__)
logger.setLevel(args.log_level)
# Plain Python logging statements
logger.debug("I am a plain debug statement, I will be sent to the driver logs.")
logger.info("I am a plain info statement, I will be sent to the driver logs.")
handler = AzureLogHandler(connection_string='<connection string>')
logger.addHandler(handler)
Designer do Azure Machine Learning
Para pipelines criados no designer, é possível encontrar o arquivo 70_driver_log na página de criação ou na página de detalhes de execução de pipeline.
Habilitar o registro em log para pontos de extremidade em tempo real
Para solucionar problemas e depurar pontos de extremidade em tempo real no designer, é necessário habilitar o registro em log do Application Insight usando o SDK. O registro em log permite solucionar problemas e depurar questões de uso e implantação de modelo. Para obter mais informações, consulte Logging for deployed Models.
Obter logs da página de criação
Ao enviar uma execução de pipeline e permanecer na página de criação, será possível encontrar os arquivos de log gerados para cada componente, à medida que cada componente terminar a execução.
Selecione um componente que concluiu a execução na tela de criação.
No painel direito do componente, acesse a guia Saídas e logs.
Expanda o painel direito e selecione o 70_driver_log.txt para exibir o arquivo no navegador. Também é possível baixar os logs localmente.
Obter logs de execuções de pipeline
Também é possível encontrar os arquivos de log para execuções específicas na página de detalhes de execução do pipeline, que pode ser encontrada na seção Pipelines ou Experimentos do estúdio.
Selecione uma execução de pipeline criada no designer.
Selecione um componente no painel de visualização.
No painel direito do componente, acesse a guia Saídas e logs.
Expanda o painel direito para ver o arquivo std_log.txt no navegador ou selecione o arquivo para baixar os logs localmente.
Importante
Para atualizar um pipeline da página de detalhes de execução do pipeline, é necessário clonar a execução do pipeline para um novo rascunho do pipeline. Uma execução de pipeline é um instantâneo do pipeline. Ele é semelhante a um arquivo de log e não pode ser alterado.
Depuração interativa com o Visual Studio Code
Em alguns casos, talvez seja necessário depurar interativamente o código Python usado no pipeline de ML. Usando Visual Studio Code (VS Code) e debugpy, é possível anexar ao código conforme ele é executado no ambiente de treinamento. Para obter mais informações, acesse a Depuração interativa no guia VS Code.
HyperdriveStep e AutoMLStep falham com o isolamento de rede
Depois de usar o HyperdriveStep e o AutoMLStep, quando você tentar registrar o modelo, poderá receber um erro.
Você está usando o SDK do Azure Machine Learning v1.
Seu workspace do Azure Machine Learning está configurado para o isolamento de rede (VNet).
Seu pipeline tentará registrar o modelo gerado pela etapa anterior. No exemplo a seguir, o parâmetro
inputs
é o modelo_salvo de um HyperdriveStep:register_model_step = PythonScriptStep(script_name='register_model.py', name="register_model_step01", inputs=[saved_model], compute_target=cpu_cluster, arguments=["--saved-model", saved_model], allow_reuse=True, runconfig=rcfg)
Solução alternativa
Importante
Esse comportamento não ocorre ao utilizar o SDK do Azure Machine Learning v2.
Para contornar esse erro, utilize a classe Executar para obter o modelo criado a partir do HyperdriveStep ou AutoMLStep. A seguir está um exemplo de script que obtém o modelo de saída de um HyperDriveStep:
%%writefile $script_folder/model_download9.py
import argparse
from azureml.core import Run
from azureml.pipeline.core import PipelineRun
from azureml.core.experiment import Experiment
from azureml.train.hyperdrive import HyperDriveRun
from azureml.pipeline.steps import HyperDriveStepRun
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
'--hd_step_name',
type=str, dest='hd_step_name',
help='The name of the step that runs AutoML training within this pipeline')
args = parser.parse_args()
current_run = Run.get_context()
pipeline_run = PipelineRun(current_run.experiment, current_run.experiment.name)
hd_step_run = HyperDriveStepRun((pipeline_run.find_step_run(args.hd_step_name))[0])
hd_best_run = hd_step_run.get_best_run_by_primary_metric()
print(hd_best_run)
hd_best_run.download_file("outputs/model/saved_model.pb", "saved_model.pb")
print("Successfully downloaded model")
O arquivo pode ser utilizado a partir de um PythonScriptStep:
from azureml.pipeline.steps import PythonScriptStep
conda_dep = CondaDependencies()
conda_dep.add_pip_package("azureml-sdk")
conda_dep.add_pip_package("azureml-pipeline")
rcfg = RunConfiguration(conda_dependencies=conda_dep)
model_download_step = PythonScriptStep(
name="Download Model 9",
script_name="model_download9.py",
arguments=["--hd_step_name", hd_step_name],
compute_target=compute_target,
source_directory=script_folder,
allow_reuse=False,
runconfig=rcfg
)
Próximas etapas
Para obter um tutorial completo usando o
ParallelRunStep
, consulte o Tutorial : Criar um pipeline de Azure Machine Learning para pontuação de lote.Para obter um exemplo completo mostrando o Machine Learning automatizado em pipelines de ML, consulte Usar o ML automatizado em um pipeline de Azure Machine Learning no Python.
Consulte a ajuda de referência do SDK para ajuda com o pacote azureml-pipelines-core e o pacote azureml-pipelines-steps.
Consulte a lista de exceções de designer e códigos de erro.