Depuração interativa com o Visual Studio Code

APLICA-SE A:azureml do SDK do Python v1

Saiba como depurar interativamente os experimentos, pipelines e implantações do Azure Machine Learning usando o Visual Studio Code (VS Code) e o debugpy.

Executar e depurar experimentos localmente

Use a extensão do Azure Machine Learning para validar, executar e depurar seus experimentos de aprendizado de máquina antes de enviá-los para a nuvem.

Pré-requisitos

Depurar o experimento localmente

Importante

Antes de executar o experimento localmente, verifique se:

  • O Docker está em execução.
  • A configuração azureML.CLI Compatibility Mode do Visual Studio Code está definida como 1.0, conforme especificado nos pré-requisitos
  1. No VS Code, abra a exibição da extensão do Azure Machine Learning.

  2. Expanda o nó de assinatura que contém seu workspace. Se você ainda não tiver um, crie um workspace do Azure Machine Learning usando a extensão.

  3. Expanda o nó do workspace.

  4. Clique com o botão direito do mouse no nó Experimentos e selecione Criar experimento. Quando o prompt aparecer, forneça um nome para o experimento.

  5. Expanda o nó Experimentos, clique com o botão direito do mouse no experimento que você deseja executar e selecione Executar Experimento.

  6. Na lista de opções, selecione Local.

  7. Na primeira vez, use somente no Windows. Quando for solicitado a permitir o Compartilhamento de Arquivos, selecione Sim. Quando você habilita o compartilhamento de arquivos, isso permite que o Docker monte o diretório que contém o script no contêiner. Além disso, ele também permite que o Docker armazene os logs e as saídas de sua execução em um diretório temporário no seu sistema.

  8. Selecione Sim para depurar seu experimento. Caso contrário, selecione Não. A seleção do ‘não’ executa seu experimento localmente sem anexar ao depurador.

  9. Selecione Criar nova Configuração de Execução para criar sua configuração de execução. A configuração de execução define o script que você deseja executar, as dependências e os conjuntos de valores usados. Como alternativa, se você já tiver um, selecione-o na lista suspensa.

    1. Escolha seu ambiente. Você pode escolher qualquer um dos coletados pelo Azure Machine Learning ou criar seu próprio ambiente.
    2. Forneça o nome do script a ser executado. O caminho é relativo ao diretório aberto no VS Code.
    3. Escolha se deseja ou não usar um conjunto de dados do Azure Machine Learning. Você pode criar conjunto de dados do Azure Machine Learning usando a extensão.
    4. O debugpy é necessário para anexar o depurador ao contêiner que está executando o experimento. Para adicionar o debugpy como uma dependência, selecione Adicionar Debugpy. Caso contrário, selecione Ignorar. Se você não adicionar o debugpy como uma dependência, o experimento será executado sem anexar ao depurador.
    5. Um arquivo de configuração que contém as definições de configuração de execução é aberto no editor. Se estiver satisfeito com as configurações, selecione Enviar experimento. Como alternativa, abra a paleta de comandos (Exibir > Paleta de Comandos) na barra de menus e insira o comando AzureML: Submit experiment na caixa de texto.
  10. Depois que o experimento for enviado, uma imagem do Docker que contém o script e as configurações especificadas na sua configuração de execução serão criadas.

    Quando o processo de criação de imagem do Docker é iniciado, o conteúdo do arquivo 60_control_log.txt é transmitido para o console de saída no VS Code.

    Observação

    A primeira vez que a imagem do Docker é criada pode demorar vários minutos.

  11. Depois que a imagem for criada, um prompt será exibido para iniciar o depurador. Defina seus pontos de interrupção em seu script e selecione Iniciar depurador quando você estiver pronto para iniciar a depuração. Isso anexa o depurador do VS Code ao contêiner que executa o experimento. Como alternativa, na extensão do Azure Machine Learning, passe o mouse sobre o nó da sua execução atual e selecione o ícone do ‘executar’ para iniciar o depurador.

    Importante

    Você não pode ter várias sessões de depuração para um único experimento. No entanto, você pode depurar dois ou mais experimentos usando várias instâncias de VS Code.

Neste ponto você consegue depurar passo a passo o seu código usando o VS Code.

Se a qualquer momento você quiser cancelar a execução, clique com o botão direito do mouse no nó de execução e selecione Cancelar execução.

Assim como nas execuções de experimento remoto, você pode expandir o nó de execução para inspecionar os logs e as saídas.

Dica

As imagens do Docker que usam as mesmas dependências definidas em seu ambiente são reutilizadas entre as execuções. No entanto, se você executar um experimento usando um ambiente novo ou diferente, uma nova imagem será criada. Como essas imagens são salvas no armazenamento local, é recomendável remover imagens antigas ou não utilizadas do Docker. Para remover imagens do sistema, use a CLI do Docker ou a extensão VS Code do Docker.

Depurar e solucionar problemas de pipelines do aprendizado de máquina

Em alguns casos, talvez seja necessário depurar interativamente o código Python usado no pipeline de ML. Ao usar o VS Code (Visual Studio Code) e o debugpy, é possível anexar ao código conforme ele é executado no ambiente de treinamento.

Pré-requisitos

  • Um workspace do Azure Machine Learning configurado para usar uma Rede Virtual do Azure.

  • Um pipeline do Azure Machine Learning que usa scripts Python como parte das etapas do pipeline. Por exemplo, um PythonScriptStep.

  • Um cluster de Computação do Azure Machine Learning, que está na rede virtual e é usado pelo pipeline para o treinamento.

  • Um ambiente de desenvolvimento que está na rede virtual. O ambiente de desenvolvimento pode ser um dos seguintes:

    • Uma Máquina Virtual do Azure na rede virtual
    • Uma instância de Computação da VM do Notebook na rede virtual
    • Um computador cliente que tem conectividade de rede privada com a rede virtual, seja por VPN ou via ExpressRoute.

Para saber mais sobre como usar uma Rede Virtual do Azure com o Azure Machine Learning, consulte Visão geral de isolamento e privacidade da rede virtual.

Dica

Embora você possa trabalhar com os recursos do Azure Machine Learning que não estão atrás de uma rede virtual, recomenda-se usar uma rede virtual.

Como ele funciona

Suas etapas de pipeline do ML executam scripts Python. Esses scripts são modificados para executar as seguintes ações:

  1. Registre o endereço IP do host em que estão executando. Você usa o endereço IP para conectar o depurador ao script.

  2. Iniciar o componente de depuração debugpy e aguardar até que um depurador se conecte.

  3. A partir do ambiente de desenvolvimento, você monitora os logs criados pelo processo de treinamento para localizar o endereço IP em que o script está sendo executado.

  4. Você informa o endereço IP ao VS Code para conectar o depurador, usando um arquivo launch.json.

  5. Você anexa o depurador e percorre o script interativamente.

Configurar scripts do Python

Para habilitar a depuração, faça as seguintes alterações nos scripts do Python, usados pelas etapas em seu pipeline do ML:

  1. Adicione as seguintes instruções de importação:

    import argparse
    import os
    import debugpy
    import socket
    from azureml.core import Run
    
  2. Adicione os seguintes argumentos. Esses argumentos permitem que você habilite o depurador conforme necessário e defina o tempo limite para anexar o depurador:

    parser.add_argument('--remote_debug', action='store_true')
    parser.add_argument('--remote_debug_connection_timeout', type=int,
                        default=300,
                        help=f'Defines how much time the Azure Machine Learning compute target '
                        f'will await a connection from a debugger client (VSCODE).')
    parser.add_argument('--remote_debug_client_ip', type=str,
                        help=f'Defines IP Address of VS Code client')
    parser.add_argument('--remote_debug_port', type=int,
                        default=5678,
                        help=f'Defines Port of VS Code client')
    
  3. Adicione as seguintes instruções. Essas instruções carregam o contexto de execução atual para que você possa registrar em log o endereço IP do nó em que o código está sendo executado:

    global run
    run = Run.get_context()
    
  4. Adicione uma instrução if que inicia o debugpy e aguarda a anexação de um depurador. Se nenhum depurador for anexado antes do tempo limite, o script continuará normalmente. Lembre-se de substituir os valores HOST e PORT na função listen com seus próprios valores.

    if args.remote_debug:
        print(f'Timeout for debug connection: {args.remote_debug_connection_timeout}')
        # Log the IP and port
        try:
            ip = args.remote_debug_client_ip
        except:
            print("Need to supply IP address for VS Code client")
        print(f'ip_address: {ip}')
        debugpy.listen(address=(ip, args.remote_debug_port))
        # Wait for the timeout for debugger to attach
        debugpy.wait_for_client()
        print(f'Debugger attached = {debugpy.is_client_connected()}')
    

O exemplo de Python a seguir mostra um arquivo train.py simples que habilita a depuração:

# Copyright (c) Microsoft. All rights reserved.
# Licensed under the MIT license.

import argparse
import os
import debugpy
import socket
from azureml.core import Run

print("In train.py")
print("As a data scientist, this is where I use my training code.")

parser = argparse.ArgumentParser("train")

parser.add_argument("--input_data", type=str, help="input data")
parser.add_argument("--output_train", type=str, help="output_train directory")

# Argument check for remote debugging
parser.add_argument('--remote_debug', action='store_true')
parser.add_argument('--remote_debug_connection_timeout', type=int,
                    default=300,
                    help=f'Defines how much time the Azure Machine Learning compute target '
                    f'will await a connection from a debugger client (VSCODE).')
parser.add_argument('--remote_debug_client_ip', type=str,
                    help=f'Defines IP Address of VS Code client')
parser.add_argument('--remote_debug_port', type=int,
                    default=5678,
                    help=f'Defines Port of VS Code client')

# Get run object, so we can find and log the IP of the host instance
global run
run = Run.get_context()

args = parser.parse_args()

# Start debugger if remote_debug is enabled
if args.remote_debug:
    print(f'Timeout for debug connection: {args.remote_debug_connection_timeout}')
    # Log the IP and port
    ip = socket.gethostbyname(socket.gethostname())
    # try:
    #     ip = args.remote_debug_client_ip
    # except:
    #     print("Need to supply IP address for VS Code client")
    print(f'ip_address: {ip}')
    debugpy.listen(address=(ip, args.remote_debug_port))
    # Wait for the timeout for debugger to attach
    debugpy.wait_for_client()
    print(f'Debugger attached = {debugpy.is_client_connected()}')

print("Argument 1: %s" % args.input_data)
print("Argument 2: %s" % args.output_train)

if not (args.output_train is None):
    os.makedirs(args.output_train, exist_ok=True)
    print("%s created" % args.output_train)

Configurar pipeline do ML

Para fornecer os pacotes necessários do Python para iniciar o debugpy e obter o contexto de execução, crie um ambiente e defina pip_packages=['debugpy', 'azureml-sdk==<SDK-VERSION>']. Altere a versão do SDK para corresponder àquela que você está usando. O trecho de código a seguir demonstra como criar um ambiente:

# Use a RunConfiguration to specify some additional requirements for this step.
from azureml.core.runconfig import RunConfiguration
from azureml.core.conda_dependencies import CondaDependencies
from azureml.core.runconfig import DEFAULT_CPU_IMAGE

# create a new runconfig object
run_config = RunConfiguration()

# enable Docker 
run_config.environment.docker.enabled = True

# set Docker base image to the default CPU-based image
run_config.environment.docker.base_image = DEFAULT_CPU_IMAGE

# use conda_dependencies.yml to create a conda environment in the Docker image for execution
run_config.environment.python.user_managed_dependencies = False

# specify CondaDependencies obj
run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn'],
                                                                           pip_packages=['debugpy', 'azureml-sdk==<SDK-VERSION>'])

Na seção Configurar scripts Python, novos argumentos foram adicionados aos scripts usados pelas etapas de pipeline do ML. O trecho de código a seguir demonstra como usar esses argumentos para habilitar a depuração para o componente e definir um tempo limite. Também demonstra como usar o ambiente criado anteriormente por meio da configuração runconfig=run_config:

# Use RunConfig from a pipeline step
step1 = PythonScriptStep(name="train_step",
                         script_name="train.py",
                         arguments=['--remote_debug', '--remote_debug_connection_timeout', 300,'--remote_debug_client_ip','<VS-CODE-CLIENT-IP>','--remote_debug_port',5678],
                         compute_target=aml_compute,
                         source_directory=source_directory,
                         runconfig=run_config,
                         allow_reuse=False)

Quando o pipeline é executado, cada etapa cria uma execução filho. Se a depuração estiver habilitada, o script modificado registrará informações nos logs, semelhante ao seguinte texto no 70_driver_log.txt para a execução do filho:

Timeout for debug connection: 300
ip_address: 10.3.0.5

Salve o valor ip_address. Ele será usado na próxima seção.

Dica

Você também pode encontrar o endereço IP nos logs de execução da execução do filho desta etapa do pipeline. Para saber mais sobre como ver essas informações, confira Monitorar execuções de experimento e métricas do Azure Machine Learning.

Configurar o ambiente de desenvolvimento

  1. Para instalar o debugpy em seu ambiente de desenvolvimento do VS Code, use o seguinte comando:

    python -m pip install --upgrade debugpy
    

    Para saber mais sobre como usar o debugpy com o VS Code, confira Depuração Remota.

  2. Para configurar o VS Code para se comunicar com a computação do Azure Machine Learning que está executando o depurador, crie uma nova configuração de depuração:

    1. No VS Code, selecione o menu Depurar e depois selecione Configurações abertas. Um arquivo chamado launch.json será aberto.

    2. No arquivo launch.json, localize a linha que contém "configurations": [ e insira o seguinte texto depois dele. Altere a entrada "host": "<IP-ADDRESS>" para o endereço IP retornado nos logs da seção anterior. Altere a entrada "localRoot": "${workspaceFolder}/code/step" para um diretório local que contenha uma cópia do script que está sendo depurado:

      {
          "name": "Azure Machine Learning Compute: remote debug",
          "type": "python",
          "request": "attach",
          "port": 5678,
          "host": "<IP-ADDRESS>",
          "redirectOutput": true,
          "pathMappings": [
              {
                  "localRoot": "${workspaceFolder}/code/step1",
                  "remoteRoot": "."
              }
          ]
      }
      

      Importante

      Se já houver outras entradas na seção Configurações, adicione uma vírgula (,) após o código inserido.

      Dica

      A prática recomendada, especialmente para pipelines, é manter os recursos de scripts em diretórios separados para que o código seja relevante apenas para cada uma das etapas. Neste exemplo, o valor localRoot de exemplo faz referência a /code/step1.

      Se você estiver depurando vários scripts em diretórios diferentes, crie uma seção de configuração separada para cada script.

    3. Salve o arquivo launch.json.

Conectar o depurador

  1. Abra o VS Code e abra uma cópia local do script.

  2. Defina os pontos de interrupção em que você deseja que o script pare depois de anexado.

  3. Enquanto o processo filho estiver executando o script e o Timeout for debug connection é exibido nos logs, use a tecla F5 ou selecione Depurar. Quando solicitado, selecione a configuração Azure Machine Learning: Depuração remota. Você também pode selecionar o ícone de depuração na barra lateral, a entrada Azure Machine Learning: Depuração remota no menu suspenso Depurar, e depois usar a seta verde para anexar o depurador.

    A essa altura, o VS Code se conecta ao debugpy no nó de computação e para no ponto de interrupção definido anteriormente. Agora você pode percorrer o código enquanto ele é executado, exibir variáveis, ​​etc.

    Observação

    Se o log exibir uma entrada informando Debugger attached = False, significa que o tempo limite expirou e o script continuou sem o depurador. Envie o pipeline novamente e conecte o depurador após a mensagem Timeout for debug connection e antes do tempo limite expirar.

Depurar e solucionar problemas de implantações

Em alguns casos, talvez seja necessário depurar interativamente o código Python contido na implantação de modelo. Por exemplo, se o script de entrada estiver falhando e o motivo não puder ser determinado pelo log adicional. Usando VS Code e o debugpy, você pode anexar ao código em execução dentro do contêiner do Docker.

Dica

Se você estiver usando pontos de extremidade online gerenciados e implantações localmente, confira Depurar pontos de extremidade online gerenciados localmente no Visual Studio Code (versão prévia).

Importante

Esse método de depuração não funciona ao usar Model.deploy() e LocalWebservice.deploy_configuration para implantar um modelo localmente. Em vez disso, você deve criar uma imagem usando o método Model.package().

As implantações de serviço Web local exigem uma instalação do Docker em funcionamento no sistema local. Para obter mais informações, confira a Documentação do Docker. Ao trabalhar com instâncias de computação, o Docker já estará instalado.

Configurar o ambiente de desenvolvimento

  1. Para instalar o debugpy em seu ambiente de desenvolvimento local do VS Code, use o seguinte comando:

    python -m pip install --upgrade debugpy
    

    Para saber mais sobre como usar o debugpy com o VS Code, confira Depuração Remota.

  2. Para configurar o VS Code para se comunicar com a imagem do Docker, crie uma nova configuração de depuração:

    1. No VS Code, selecione o menu Depurar na extensão Executar e depois selecione Configurações abertas. Um arquivo chamado launch.json será aberto.

    2. No arquivo launch.json, localize o item “configurações” (a linha que contém "configurations": [) e insira o seguinte texto.

      {
          "name": "Azure Machine Learning Deployment: Docker Debug",
          "type": "python",
          "request": "attach",
          "connect": {
              "port": 5678,
              "host": "0.0.0.0",
          },
          "pathMappings": [
              {
                  "localRoot": "${workspaceFolder}",
                  "remoteRoot": "/var/azureml-app"
              }
          ]
      }
      

      Após a inserção, o arquivo launch.jsno deve ser semelhante ao seguinte:

      {
      // Use IntelliSense to learn about possible attributes.
      // Hover to view descriptions of existing attributes.
      // For more information, visit: https://go.microsoft.com/fwlink/linkid=830387
      "version": "0.2.0",
      "configurations": [
          {
              "name": "Python: Current File",
              "type": "python",
              "request": "launch",
              "program": "${file}",
              "console": "integratedTerminal"
          },
          {
              "name": "Azure Machine Learning Deployment: Docker Debug",
              "type": "python",
              "request": "attach",
              "connect": {
                  "port": 5678,
                  "host": "0.0.0.0"
                  },
              "pathMappings": [
                  {
                      "localRoot": "${workspaceFolder}",
                      "remoteRoot": "/var/azureml-app"
                  }
              ]
          }
          ]
      }
      

      Importante

      Se já houver outras entradas na seção de configurações, adicione uma vírgula ( , ) após o código inserido.

      Esta seção anexa ao contêiner do Docker usando a porta 5678.

    3. Salve o arquivo launch.json.

Criar uma imagem que inclui o debugpy

  1. Modifique o ambiente do Conda para a sua implantação, de modo que ele inclua o debugpy. O seguinte exemplo demonstra como adicioná-lo usando o parâmetro pip_packages:

    from azureml.core.conda_dependencies import CondaDependencies 
    
    
    # Usually a good idea to choose specific version numbers
    # so training is made on same packages as scoring
    myenv = CondaDependencies.create(conda_packages=['numpy==1.15.4',
                                'scikit-learn==0.19.1', 'pandas==0.23.4'],
                                 pip_packages = ['azureml-defaults==1.0.83', 'debugpy'])
    
    with open("myenv.yml","w") as f:
        f.write(myenv.serialize_to_string())
    
  2. Para iniciar o debugpy e esperar por uma conexão quando o serviço for iniciado, adicione o seguinte ao topo do seu arquivo score.py:

    import debugpy
    # Allows other computers to attach to debugpy on this IP address and port.
    debugpy.listen(('0.0.0.0', 5678))
    # Wait 30 seconds for a debugger to attach. If none attaches, the script continues as normal.
    debugpy.wait_for_client()
    print("Debugger attached...")
    
  3. Crie uma imagem com base na definição de ambiente e extraia a imagem para o registro local.

    Observação

    Este exemplo pressupõe que ws aponta para o workspace do Azure Machine Learning e que model é o modelo implantado. O arquivo myenv.yml contém as dependências do Conda criadas na etapa 1.

    from azureml.core.conda_dependencies import CondaDependencies
    from azureml.core.model import InferenceConfig
    from azureml.core.environment import Environment
    
    
    myenv = Environment.from_conda_specification(name="env", file_path="myenv.yml")
    myenv.docker.base_image = None
    myenv.docker.base_dockerfile = "FROM mcr.microsoft.com/azureml/openmpi3.1.2-ubuntu18.04:latest"
    inference_config = InferenceConfig(entry_script="score.py", environment=myenv)
    package = Model.package(ws, [model], inference_config)
    package.wait_for_creation(show_output=True)  # Or show_output=False to hide the Docker build logs.
    package.pull()
    

    Após criar e baixar a imagem (esse processo poderá levar mais de 10 minutos), o caminho da imagem (incluirá repositório, nome e marca, que neste caso também será o resumo) será finalmente exibido em uma mensagem semelhante à seguinte:

    Status: Downloaded newer image for myregistry.azurecr.io/package@sha256:<image-digest>
    
  4. Para facilitar o trabalho com a imagem localmente, use o comando a seguir para adicionar uma tag à essa imagem. No comando a seguir, substitua myimagepath pelo valor do local da etapa anterior.

    docker tag myimagepath debug:1
    

    Para o restante das etapas, você pode ver a imagem local como debug:1, em vez do valor do caminho da imagem completa.

Depurar o serviço

Dica

Se você definiu um tempo limite para a conexão do debugpy no arquivo score.py, conecte o VS Code à sessão de depuração antes que o tempo limite expire. Inicie o VS Code, abra a cópia local de score.py, defina um ponto de interrupção e prepare-o antes de usar as etapas nesta seção.

Para obter mais informações sobre depuração e definição de pontos de interrupção, confira Depuração.

  1. Para iniciar um contêiner do Docker usando a imagem, use o seguinte comando:

    docker run -it --name debug -p 8000:5001 -p 5678:5678 -v <my_local_path_to_score.py>:/var/azureml-app/score.py debug:1 /bin/bash
    

    Este comando anexa seu score.py localmente ao do contêiner. Portanto, todas as alterações feitas no editor são automaticamente refletidas no contêiner

  2. Para uma melhor experiência, entre no contêiner com a nova interface do VS code. Selecione a Docker extensão na barra lateral do VS Code, localize o contêiner local criado, nesta documentação é o debug:1. Clique com o botão direito do mouse nesse contêiner e selecione "Attach Visual Studio Code". Uma nova interface do VS Code será aberta automaticamente, mostrando o interior do contêiner criado.

    Interface VS Code do contêiner

  3. Dentro do contêiner, execute o seguinte comando no shell

    runsvdir /var/runit
    

    É possível ver a seguinte saída no shell, dentro do contêiner:

    Saída do console de execução do contêiner

  4. Para anexar o VS Code à depuração dentro do contêiner, abra o VS Code e use a tecla F5 ou selecione Debug. Quando solicitado, selecione a configuração Implantação do Azure Machine Learning: Depurar Docker. Você também pode selecionar o ícone de extensão Executar na barra lateral, na entrada Implantação do Azure Machine Learning: Depurar Docker no menu suspenso Depurar, e depois usar a seta verde para anexar o depurador.

    O ícone de depuração, o botão Iniciar depuração e o seletor de configuração

    Após selecionar a seta verde e anexar o depurador, na interface do contêiner do VS Code você poderá ver algumas novas informações:

    Informações anexadas do depurador de contêiner

    Além disso, na interface principal do VS Code, pode-se ver o seguinte:

    Ponto de interrupção do VS Code no score.py

Agora, o local score.py que está anexado ao contêiner, já parou nos pontos de interrupção que você definiu. A essa altura o VS Code se conecta ao debugpy dentro do contêiner do Docker e para o contêiner do Docker no ponto de interrupção definido anteriormente. Agora você pode percorrer o código enquanto ele é executado, exibir variáveis, ​​etc.

Para obter mais informações sobre como usar o VS Code para depurar o Python, confira Depurar o código Python.

Parar o contêiner

Para parar o contêiner, use o seguinte comando:

docker stop debug

Próximas etapas

Agora que você configurou o VS Code Remoto, é possível usar uma instância de computação como computação remota do VS Code para depurar interativamente seu código.

Saiba mais sobre como solucionar os problemas: