Partilhar via


Depurar scripts de pontuação com o servidor HTTP de inferência do Azure Machine Learning

O servidor HTTP de inferência do Azure Machine Learning é um pacote Python que expõe sua função de pontuação como um ponto de extremidade HTTP e encapsula o código e as dependências do servidor Flask em um pacote singular. O servidor é incluído nas imagens pré-criadas do Docker para inferência que são usadas ao implantar um modelo com o Azure Machine Learning. Usando apenas o pacote, você pode implantar o modelo localmente para produção e validar facilmente seu script de pontuação (entrada) em um ambiente de desenvolvimento local. Se houver um problema com o script de pontuação, o servidor retornará um erro e o local do erro.

O servidor também pode ser usado para criar portas de validação em um pipeline contínuo de integração e implantação. Por exemplo, você pode iniciar o servidor com o script candidato e executar o conjunto de testes no ponto de extremidade local.

Este artigo oferece suporte a desenvolvedores que desejam usar o servidor de inferência para depurar localmente e descreve como usar o servidor de inferência com pontos de extremidade online no Windows.

Pré-requisitos

Para usar o servidor HTTP de inferência do Azure Machine Learning para depuração local, sua configuração deve incluir os seguintes componentes:

  • Python 3.8 ou posterior
  • Anaconda

O servidor HTTP de inferência do Azure Machine Learning é executado em sistemas operacionais baseados em Windows e Linux.

Explore as opções de depuração local para endpoints online

Ao depurar pontos de extremidade localmente antes de implantar na nuvem, você pode detetar erros em seu código e configuração anteriormente. Para depurar pontos de extremidade localmente, você tem várias opções, incluindo:

Este artigo descreve como trabalhar com o servidor HTTP de inferência do Azure Machine Learning no Windows.

A tabela a seguir fornece uma visão geral dos cenários para ajudá-lo a escolher a melhor opção:

Cenário Servidor HTTP de inferência Ponto final local
Atualize o ambiente Python local sem a reconstrução da imagem do Docker Sim No
Atualizar script de pontuação Sim Sim
Atualizar configurações de implantação (implantação, ambiente, código, modelo) Não Sim
Integrar o depurador do Microsoft Visual Studio Code (VS Code) Sim Sim

Ao executar o servidor HTTP de inferência localmente, você pode se concentrar em depurar seu script de pontuação sem se preocupar com as configurações do contêiner de implantação.

Instalar o pacote azureml-inference-server-http

Para instalar o azureml-inference-server-http pacote, execute o seguinte comando:

python -m pip install azureml-inference-server-http

Nota

Para evitar conflitos de pacote, instale o servidor HTTP de inferência em um ambiente virtual. Você pode usar o pip install virtualenv comando para habilitar ambientes virtuais para sua configuração.

Depurar seu script de pontuação localmente

Para depurar seu script de pontuação localmente, você tem várias opções para testar o comportamento do servidor:

  • Experimente um script de pontuação fictício.
  • Use o Visual Studio Code para depurar com o pacote azureml-inference-server-http .
  • Execute um script de pontuação real, um arquivo de modelo e um arquivo de ambiente a partir de nosso repositório de exemplos.

Testar o comportamento do servidor com script de pontuação fictícia

  1. Crie um diretório chamado server_quickstart para armazenar seus arquivos:

    mkdir server_quickstart
    cd server_quickstart
    
  2. Para evitar conflitos de pacotes, crie um ambiente virtual, como o myenv, e ative-o:

    python -m virtualenv myenv
    

    Nota

    No Linux, execute o source myenv/bin/activate comando para ativar o ambiente virtual.

    Depois de testar o servidor, você pode executar o deactivate comando para desativar o ambiente virtual Python.

  3. Instale o azureml-inference-server-http pacote a partir do feed pypi :

    python -m pip install azureml-inference-server-http
    
  4. Crie seu script de entrada. O exemplo a seguir cria um script de entrada básico e o salva em um arquivo chamado score.py:

    echo -e "import time def init(): \n\t time.sleep(1) \n\n def run(input_data): \n\t return {"message":"Hello, World!"}" > score.py
    
  5. Inicie o servidor com o azmlinfsrv comando e defina o arquivo score.py como o script de entrada:

    azmlinfsrv --entry_script score.py
    

    Nota

    O servidor está hospedado em 0.0.0.0, o que significa que ele ouve todos os endereços IP da máquina de hospedagem.

  6. Envie uma solicitação de pontuação para o servidor usando o curl utilitário:

    curl -p 127.0.0.1:5001/score
    

    O servidor publica a seguinte resposta:

    {"message": "Hello, World!"}
    
  7. Após o teste, selecione Ctrl + C para encerrar o servidor.

Agora você pode modificar o arquivo de script de pontuação (score.py) e testar suas alterações executando o servidor novamente com o azmlinfsrv --entry_script score.py comando.

Integração com o Visual Studio Code

Para usar o VS Code e a extensão Python para depuração com o pacote azureml-inference-server-http , você pode usar os modos Iniciar e Anexar.

  • Para o modo de inicialização, configure o arquivo launch.json no VS Code e inicie o servidor HTTP de inferência do Azure Machine Learning no VS Code:

    1. Inicie o VS Code e abra a pasta que contém o script (score.py).

    2. Adicione a seguinte configuração ao arquivo launch.json para esse espaço de trabalho no VS Code:

      launch.json

      {
          "version": "0.2.0",
          "configurations": [
              {
                  "name": "Debug score.py",
                  "type": "python",
                  "request": "launch",
                  "module": "azureml_inference_server_http.amlserver",
                  "args": [
                      "--entry_script",
                      "score.py"
                  ]
              }
          ]
        }
      
    3. Inicie a sessão de depuração no VS Code selecionando Executar>Iniciar Depuração ou use o atalho de teclado F5.

  • Para o modo Anexar, inicie o servidor HTTP de inferência do Azure Machine Learning em uma janela de comando e use o VS Code com a Extensão Python para anexar ao processo:

    Nota

    Para Linux, primeiro instale o gdb pacote executando o sudo apt-get install -y gdb comando.

    1. Adicione a seguinte configuração ao arquivo launch.json para esse espaço de trabalho no VS Code:

      launch.json

      {
          "version": "0.2.0",
          "configurations": [
              {
                  "name": "Python: Attach using Process Id",
                  "type": "python",
                  "request": "attach",
                  "processId": "${command:pickProcess}",
                  "justMyCode": true
              }
          ]
        }
      
    2. Em uma janela de comando, inicie o servidor HTTP de inferência usando o azmlinfsrv --entry_script score.py comando.

    3. Inicie a sessão de depuração no VS Code:

      1. Selecione Executar>Iniciar Depuração ou use o atalho de teclado F5.

      2. Na janela de comando, exiba os logs do servidor de inferência e localize a azmlinfsrv ID do processo do comando (não o gunicorn):

        Captura de tela que mostra uma janela de comando exibindo logs do servidor HTTP de inferência e a ID do processo do comando azmlinfsrv realçado.

      3. No Depurador de código VS, insira a ID do processo do azmlinfsrv comando.

        Se não vir o seletor de processos VS Code, pode introduzir manualmente o processId ID do processo no campo do ficheiro launch.json para essa área de trabalho.

Para ambos os modos, você pode definir pontos de interrupção e depurar o script passo a passo.

Use um exemplo de ponta a ponta

O procedimento a seguir executa o servidor localmente com arquivos de exemplo (script de pontuação, arquivo de modelo e ambiente) do repositório de exemplo do Azure Machine Learning. Para obter mais exemplos de como usar esses arquivos de exemplo, consulte Implantar e pontuar um modelo de aprendizado de máquina usando um ponto de extremidade online.

  1. Clone o repositório de exemplo:

    git clone --depth 1 https://github.com/Azure/azureml-examples
    cd azureml-examples/cli/endpoints/online/model-1/
    
  2. Crie e ative um ambiente virtual com conda:

    Neste exemplo, o azureml-inference-server-http pacote é instalado automaticamente. O pacote está incluído como uma biblioteca dependente do azureml-defaults pacote no arquivo conda.yml :

    # Create the environment from the YAML file
    conda env create --name model-env -f ./environment/conda.yml
    # Activate the new environment
    conda activate model-env
    
  3. Reveja o seu script de pontuação:

    onlinescoring/score.py

    import os
    import logging
    import json
    import numpy
    import joblib
    
    
    def init():
        """
        This function is called when the container is initialized/started, typically after create/update of the deployment.
        You can write the logic here to perform init operations like caching the model in memory
        """
        global model
        # AZUREML_MODEL_DIR is an environment variable created during deployment.
        # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)
        # Please provide your model's folder name if there is one
        model_path = os.path.join(
            os.getenv("AZUREML_MODEL_DIR"), "model/sklearn_regression_model.pkl"
        )
        # deserialize the model file back into a sklearn model
        model = joblib.load(model_path)
        logging.info("Init complete")
    
    
    def run(raw_data):
        """
        This function is called for every invocation of the endpoint to perform the actual scoring/prediction.
        In the example we extract the data from the json input and call the scikit-learn model's predict()
        method and return the result back
        """
        logging.info("model 1: request received")
        data = json.loads(raw_data)["data"]
        data = numpy.array(data)
        result = model.predict(data)
        logging.info("Request processed")
        return result.tolist()
    
  4. Execute o servidor HTTP de inferência especificando o script de pontuação e o arquivo de modelo:

    O diretório modelo especificado no model_dir parâmetro é definido usando a AZUREML_MODEL_DIR variável e recuperado no script de pontuação.

    Nesse caso, você especifica o diretório atual ./ porque o subdiretório é especificado no script de pontuação como model/sklearn_regression_model.pkl.

    azmlinfsrv --entry_script ./onlinescoring/score.py --model_dir ./
    

    Quando o servidor é iniciado e invoca com êxito o script de pontuação, o log de inicialização de exemplo é aberto. Caso contrário, o log mostra mensagens de erro.

  5. Teste o script de pontuação com dados de exemplo:

    Abra outra janela de comando e mude para o mesmo diretório de trabalho onde você executa o comando.

    Use o curl utilitário para enviar uma solicitação de exemplo para o servidor e receber um resultado de pontuação:

    curl --request POST "127.0.0.1:5001/score" --header "Content-Type:application/json" --data @sample-request.json
    

    Quando não há problemas no seu script de pontuação, o script retorna o resultado da pontuação. Se ocorrerem problemas, você pode tentar atualizar o script de pontuação e iniciar o servidor novamente para testar o script atualizado.

Revisar rotas do servidor

O servidor HTTP de inferência escuta na porta 5001 por padrão nas seguintes rotas:

Nome Rota
Sonda de vivacidade 127.0.0.1:5001/
Pontuação 127.0.0.1:5001/score
OpenAPI (swagger) 127.0.0.1:5001/swagger.json

Revisar os parâmetros do servidor

O servidor HTTP de inferência aceita os seguintes parâmetros:

Parâmetro Necessário Predefinição Description
entry_script True N/A Identifica o caminho relativo ou absoluto para o script de pontuação.
model_dir False N/A Identifica o caminho relativo ou absoluto para o diretório que contém o modelo usado para inferência.
port False 5001 Especifica a porta de serviço do servidor.
worker_count False 1 Fornece o número de threads de trabalho para processar solicitações simultâneas.
appinsights_instrumentation_key False N/A Fornece a chave de instrumentação para os insights do aplicativo onde os logs são publicados.
access_control_allow_origins False N/A Habilita o CORS para as origens especificadas, onde várias origens são separadas por uma vírgula (,), como microsoft.com, bing.com.

Explore o processamento de solicitações do servidor

As etapas a seguir demonstram como o servidor HTTP de inferência do Azure Machine Learning (azmlinfsrv) lida com solicitações de entrada:

  1. Um wrapper de CLI Python fica ao redor da pilha de rede do servidor e é usado para iniciar o servidor.

  2. Um cliente envia uma solicitação para o servidor.

  3. O servidor envia a solicitação através do servidor WSGI (Web Server Gateway Interface), que despacha a solicitação para um aplicativo de trabalho Flask:

  4. O aplicativo Flask worker lida com a solicitação, o que inclui o carregamento do script de entrada e quaisquer dependências.

  5. Seu script de entrada recebe a solicitação. O script de entrada faz uma chamada de inferência para o modelo carregado e retorna uma resposta:

Diagrama que mostra como o servidor HTTP de inferência processa solicitações de entrada.

Explore os logs do servidor

Há duas maneiras de obter dados de log para o teste do servidor HTTP de inferência:

  • Execute o azureml-inference-server-http pacote localmente e visualize a saída de logs.
  • Use pontos de extremidade online e visualize os logs de contêiner. O log do servidor de inferência é chamado Versão do servidor <>HTTP de Inferência do Azure Machine Learning.

Nota

O formato de registo foi alterado desde a versão 0.8.0. Se o log usar um estilo diferente do esperado, atualize o azureml-inference-server-http pacote para a versão mais recente.

Ver registos de arranque

Quando o servidor é iniciado, os logs mostram as configurações iniciais do servidor da seguinte maneira:

Azure Machine Learning Inferencing HTTP server <version>

Server Settings
---------------
Entry Script Name: <entry_script>
Model Directory: <model_dir>
Worker Count: <worker_count>
Worker Timeout (seconds): None
Server Port: <port>
Application Insights Enabled: false
Application Insights Key: <appinsights_instrumentation_key>
Inferencing HTTP server version: azmlinfsrv/<version>
CORS for the specified origins: <access_control_allow_origins>

Server Routes
---------------
Liveness Probe: GET   127.0.0.1:<port>/
Score:          POST  127.0.0.1:<port>/score

<logs>

Por exemplo, quando você inicia o servidor seguindo o exemplo de ponta a ponta, o log é exibido da seguinte maneira:

Azure Machine Learning Inferencing HTTP server v0.8.0

Server Settings
---------------
Entry Script Name: /home/user-name/azureml-examples/cli/endpoints/online/model-1/onlinescoring/score.py
Model Directory: ./
Worker Count: 1
Worker Timeout (seconds): None
Server Port: 5001
Application Insights Enabled: false
Application Insights Key: None
Inferencing HTTP server version: azmlinfsrv/0.8.0
CORS for the specified origins: None

Server Routes
---------------
Liveness Probe: GET   127.0.0.1:5001/
Score:          POST  127.0.0.1:5001/score

2022-12-24 07:37:53,318 I [32726] gunicorn.error - Starting gunicorn 20.1.0
2022-12-24 07:37:53,319 I [32726] gunicorn.error - Listening at: http://0.0.0.0:5001 (32726)
2022-12-24 07:37:53,319 I [32726] gunicorn.error - Using worker: sync
2022-12-24 07:37:53,322 I [32756] gunicorn.error - Booting worker with pid: 32756
Initializing logger
2022-12-24 07:37:53,779 I [32756] azmlinfsrv - Starting up app insights client
2022-12-24 07:37:54,518 I [32756] azmlinfsrv.user_script - Found user script at /home/user-name/azureml-examples/cli/endpoints/online/model-1/onlinescoring/score.py
2022-12-24 07:37:54,518 I [32756] azmlinfsrv.user_script - run() is not decorated. Server will invoke it with the input in JSON string.
2022-12-24 07:37:54,518 I [32756] azmlinfsrv.user_script - Invoking user's init function
2022-12-24 07:37:55,974 I [32756] azmlinfsrv.user_script - Users's init has completed successfully
2022-12-24 07:37:55,976 I [32756] azmlinfsrv.swagger - Swaggers are prepared for the following versions: [2, 3, 3.1].
2022-12-24 07:37:55,977 I [32756] azmlinfsrv - AML_FLASK_ONE_COMPATIBILITY is set, but patching is not necessary.

Compreender o formato dos dados de registo

Todos os logs do servidor HTTP de inferência, exceto o script iniciador, apresentam dados no seguinte formato:

<UTC Time> | <level> [<pid>] <logger name> - <message>

A entrada consiste nos seguintes componentes:

  • <UTC Time>: Hora em que a entrada foi inserida no log.
  • <pid>: ID do processo associado à entrada.
  • <level>: Primeiro caractere do nível de log para a entrada, como E para ERROR, I para INFO e assim por diante.
  • <logger name>: Nome do recurso associado à entrada de log.
  • <message>: Conteúdo da mensagem de log.

Há seis níveis de registro em Python com valores numéricos atribuídos de acordo com a gravidade:

Nível de registo Valor numérico
CRÍTICA 50
ERRO 40
ADVERTÊNCIA 30
INFORMAÇÃO 20
DEPURAR 10
NOTSET 0

Solucionar problemas do servidor

As seções a seguir fornecem dicas básicas de solução de problemas para o servidor HTTP de inferência do Azure Machine Learning. Para solucionar problemas de pontos de extremidade online, consulte Solucionar problemas de implantação de pontos de extremidade online.

Verifique os pacotes instalados

Siga estas etapas para resolver problemas com pacotes instalados.

  1. Reúna informações sobre pacotes instalados e versões para seu ambiente Python.

  2. Confirme se a versão do azureml-inference-server-http pacote Python especificada no arquivo de ambiente corresponde à versão do servidor HTTP de inferência do Azure Machine Learning exibida no log de inicialização.

    Em alguns casos, o resolvedor de dependência pip instala versões de pacote inesperadas. Talvez seja necessário executar pip para corrigir os pacotes e versões instalados.

  3. Se você especificar o Flask ou suas dependências em seu ambiente, remova esses itens.

    • Os pacotes dependentes incluem flask, jinja2, itsdangerous, werkzeug, markupsafee click.
    • flask está listado como uma dependência no pacote do servidor. A melhor abordagem é permitir que o servidor de inferência instale o flask pacote.
    • Quando o servidor de inferência é configurado para suportar novas versões do Flask, o servidor recebe automaticamente as atualizações do pacote à medida que ficam disponíveis.

Verificar a versão do servidor

O azureml-inference-server-http pacote do servidor é publicado no PyPI. A página PyPI lista o changelog e todas as versões anteriores.

Se você estiver usando uma versão anterior do pacote, atualize sua configuração para a versão mais recente. A tabela a seguir resume versões estáveis, problemas comuns e ajustes recomendados:

Versão de pacote Description Problema Resolução
0.4.x Incluído em imagens de treinamento datadas 20220601 ou anteriores e azureml-defaults versões .1.34 de pacote através do 1.43. Última versão estável é 0.4.13. Para versões de servidor anteriores à 0.4.11, você pode encontrar problemas de dependência do Flask, como "can't import name Markup from jinja2". Atualize para a versão 0.4.13 ou 0.8.x, a versão mais recente, se possível.
0,6.x Pré-instalado na inferência de imagens datadas 20220516 e anteriores. Última versão estável é 0.6.1. N/A N/A
0,7.x Suporta Flask 2. Última versão estável é 0.7.7. N/A N/A
0.8.x Formato de log alterado. O suporte ao Python 3.6 terminou. N/A N/A

Verificar dependências do pacote

Os pacotes dependentes mais relevantes para o pacote de azureml-inference-server-http servidor incluem:

  • flask
  • opencensus-ext-azure
  • inference-schema

Se você especificou o azureml-defaults pacote em seu ambiente Python, o azureml-inference-server-http pacote é um pacote dependente. A dependência é instalada automaticamente.

Gorjeta

Se você usar o Python SDK v1 e não especificar explicitamente o azureml-defaults pacote em seu ambiente Python, o SDK poderá adicionar automaticamente o pacote. No entanto, a versão do empacotador está bloqueada em relação à versão do SDK. Por exemplo, se a versão do SDK for 1.38.0, a azureml-defaults==1.38.0 entrada será adicionada aos requisitos de pip do ambiente.

TypeError durante a inicialização do servidor

Você pode encontrar o seguinte TypeError durante a inicialização do servidor:

TypeError: register() takes 3 positional arguments but 4 were given

  File "/var/azureml-server/aml_blueprint.py", line 251, in register

    super(AMLBlueprint, self).register(app, options, first_registration)

TypeError: register() takes 3 positional arguments but 4 were given

Este erro ocorre quando você tem o Flask 2 instalado em seu ambiente Python, mas sua azureml-inference-server-http versão do pacote não suporta o Flask 2. O suporte para o Flask 2 está disponível na versão do pacote 0.7.0 e posterior, e azureml-defaults na azureml-inference-server-http versão do pacote 1.44 e posterior.

  • Se você não usar o pacote Flask 2 em uma imagem do Docker do Azure Machine Learning, use a versão mais recente do azureml-inference-server-http pacote ou azureml-defaults .

  • Se você usar o pacote Flask 2 em uma imagem do Docker do Azure Machine Learning, confirme se a versão de compilação da imagem é julho de 2022 ou posterior.

    Você pode encontrar a versão da imagem nos logs do contêiner. Por exemplo:

    2022-08-22T17:05:02,147738763+00:00 | gunicorn/run | AzureML Container Runtime Information
    2022-08-22T17:05:02,161963207+00:00 | gunicorn/run | ###############################################
    2022-08-22T17:05:02,168970479+00:00 | gunicorn/run | 
    2022-08-22T17:05:02,174364834+00:00 | gunicorn/run | 
    2022-08-22T17:05:02,187280665+00:00 | gunicorn/run | AzureML image information: openmpi4.1.0-ubuntu20.04, Materialization Build:20220708.v2
    2022-08-22T17:05:02,188930082+00:00 | gunicorn/run | 
    2022-08-22T17:05:02,190557998+00:00 | gunicorn/run | 
    

    A data de compilação da imagem aparece após a Materialization Build notação. No exemplo anterior, a versão da imagem é 20220708 ou 8 de julho de 2022. A imagem neste exemplo é compatível com o Flask 2.

    Se você não vir uma mensagem semelhante no log do contêiner, sua imagem está desatualizada e deve ser atualizada. Se você usar uma imagem CUDA (Compute Unified Device Architecture) e não conseguir encontrar uma imagem mais recente, verifique se a imagem foi preterida no AzureML-Containers. Você pode encontrar substitutos designados para imagens obsoletas.

    Se você usar o servidor com um ponto de extremidade online, também poderá encontrar os logs na página Logs nos Pontos de Extremidade no estúdio do Azure Machine Learning.

Se você implantar com o SDK v1 e não especificar explicitamente uma imagem em sua configuração de implantação, o servidor aplicará o pacote com uma versão que corresponda ao openmpi4.1.0-ubuntu20.04 conjunto de ferramentas SDK local. No entanto, a versão instalada pode não ser a versão mais recente disponível da imagem.

Para o SDK versão 1.43, o servidor instala a versão do pacote por padrão, mas essa versão do pacote não é compatível com o openmpi4.1.0-ubuntu20.04:20220616 SDK 1.43. Certifique-se de usar o SDK mais recente para sua implantação.

Se não for possível atualizar a imagem, você poderá evitar temporariamente o problema fixando as azureml-defaults==1.43 entradas ou azureml-inference-server-http~=0.4.13 no arquivo de ambiente. Essas entradas direcionam o servidor para instalar a versão mais antiga com flask 1.0.xo .

ImportError ou ModuleNotFoundError durante a inicialização do servidor

Você pode encontrar um ImportError ou ModuleNotFoundError em módulos específicos, como opencensus, jinja2, markupsafe, ou , durante clicka inicialização do servidor. O exemplo a seguir mostra a mensagem de erro:

ImportError: cannot import name 'Markup' from 'jinja2'

Os erros de importação e módulo ocorrem quando você usa a versão 0.4.10 ou versões anteriores do servidor que não fixam a dependência do Flask em uma versão compatível. Para evitar o problema, instale uma versão posterior do servidor.