Felsöka bedömningsskript med HTTP-server för Azure Machine Learning-slutsatsdragning

HTTP-servern för Azure Machine Learning-slutsatsdragning är ett Python-paket som exponerar din bedömningsfunktion som en HTTP-slutpunkt och omsluter Flask-serverkoden och beroendena i ett enda paket. Den ingår i de fördefinierade Docker-avbildningarna för slutsatsdragning som används när du distribuerar en modell med Azure Machine Learning. Med enbart paketet kan du distribuera modellen lokalt för produktion och du kan också enkelt verifiera ditt bedömningsskript (post) i en lokal utvecklingsmiljö. Om det uppstår ett problem med bedömningsskriptet returnerar servern ett fel och platsen där felet inträffade.

Servern kan också användas för att skapa valideringsportar i en pipeline för kontinuerlig integrering och distribution. Du kan till exempel starta servern med kandidatskriptet och köra testpaketet mot den lokala slutpunkten.

Den här artikeln riktar sig främst till användare som vill använda slutsatsdragningsservern för att felsöka lokalt, men den hjälper dig också att förstå hur du använder slutsatsdragningsservern med onlineslutpunkter.

Lokal felsökning av slutpunkter online

Genom att felsöka slutpunkter lokalt innan du distribuerar dem till molnet kan du få fel i koden och konfigurationen tidigare. Om du vill felsöka slutpunkter lokalt kan du använda:

  • HTTP-servern för Azure Machine Learning-slutsatsdragning
  • en lokal slutpunkt

Den här artikeln fokuserar på HTTP-servern för Azure Machine Learning-slutsatsdragning.

Följande tabell innehåller en översikt över scenarier som hjälper dig att välja vad som fungerar bäst för dig.

Scenario Slutsatsdragning av HTTP-server Lokal slutpunkt
Uppdatera den lokala Python-miljön utan återskapande av Docker-avbildning Ja Nej
Uppdateringsbedömningsskript Ja Ja
Uppdatera distributionskonfigurationer (distribution, miljö, kod, modell) Nej Ja
Integrera VS Code-felsökningsprogram Ja Ja

Genom att köra slutsatsdragningens HTTP-server lokalt kan du fokusera på att felsöka ditt bedömningsskript utan att påverkas av konfigurationerna av distributionscontainer.

Förutsättningar

  • Kräver: Python >=3.8
  • Anaconda

Dricks

HTTP-servern för Azure Machine Learning-slutsatsdragning körs på Windows- och Linux-baserade operativsystem.

Installation

Kommentar

För att undvika paketkonflikter installerar du servern i en virtuell miljö.

Om du vill installera azureml-inference-server-http packagekör du följande kommando i din cmd/terminal:

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

Felsöka ditt bedömningsskript lokalt

Om du vill felsöka ditt bedömningsskript lokalt kan du testa hur servern beter sig med ett dummy-bedömningsskript, använda VS Code för att felsöka med azureml-inference-server-http-paketet eller testa servern med ett faktiskt bedömningsskript, en modellfil och en miljöfil från vår lagringsplats för exempel.

Testa serverbeteendet med ett dummy-bedömningsskript

  1. Skapa en katalog för att lagra dina filer:

    mkdir server_quickstart
    cd server_quickstart
    
  2. Undvik paketkonflikter genom att skapa en virtuell miljö och aktivera den:

    python -m venv myenv
    source myenv/bin/activate
    

    Dricks

    Efter testningen kör du deactivate för att inaktivera den virtuella Python-miljön.

  3. azureml-inference-server-http Installera paketet från pypi-feeden:

    python -m pip install azureml-inference-server-http
    
  4. Skapa ditt postskript (score.py). I följande exempel skapas ett grundläggande postskript:

    echo '
    import time
    
    def init():
        time.sleep(1)
    
    def run(input_data):
        return {"message":"Hello, World!"}
    ' > score.py
    
  5. Starta servern (azmlinfsrv) och ange score.py som postskript:

    azmlinfsrv --entry_script score.py
    

    Kommentar

    Servern finns på 0.0.0.0, vilket innebär att den lyssnar på värddatorns alla IP-adresser.

  6. Skicka en bedömningsbegäran till servern med hjälp av curl:

    curl -p 127.0.0.1:5001/score
    

    Servern bör svara så här.

    {"message": "Hello, World!"}
    

Efter testningen kan du trycka på Ctrl + C för att avsluta servern. Nu kan du ändra bedömningsskriptet (score.py) och testa ändringarna genom att köra servern igen (azmlinfsrv --entry_script score.py).

Integrera med Visual Studio Code

Det finns två sätt att använda Visual Studio Code (VS Code) och Python-tillägget för att felsöka med azureml-inference-server-http-package (start- och anslutningslägen).

  • Startläge: Konfigurera launch.json i VS Code och starta HTTP-servern för Azure Machine Learning-slutsatsdragning i VS Code.

    1. Starta VS Code och öppna mappen som innehåller skriptet (score.py).

    2. Lägg till följande konfiguration launch.json för arbetsytan i 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. Starta felsökningssessionen i VS Code. Välj "Kör" –> "Starta felsökning" (eller F5).

  • Anslutningsläge: Starta HTTP-servern för Azure Machine Learning-slutsatsdragning på en kommandorad och använd VS Code + Python-tillägget för att ansluta till processen.

    Kommentar

    Om du använder Linux-miljön installerar gdb du först paketet genom att köra sudo apt-get install -y gdb.

    1. Lägg till följande konfiguration launch.json för arbetsytan i 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. Starta slutsatsdragningsservern med CLI (azmlinfsrv --entry_script score.py).

    3. Starta felsökningssessionen i VS Code.

      1. I VS Code väljer du "Kör" –> "Starta felsökning" (eller F5).
      2. Ange process-ID för azmlinfsrv (inte gunicorn) med hjälp av loggarna (från slutsatsdragningsservern) som visas i CLI. Skärmbild av CLI som visar serverns process-ID.

      Kommentar

      Om processväljaren inte visas anger du process-ID:t manuellt i processId fältet i launch.json.

På båda sätten kan du ange brytpunkt och felsöka steg för steg.

Exempel från slutpunkt till slutpunkt

I det här avsnittet kör vi servern lokalt med exempelfiler (bedömningsskript, modellfil och miljö) i vår exempellagringsplats. Exempelfilerna används också i vår artikel för Distribuera och poängsätta en maskininlärningsmodell med hjälp av en onlineslutpunkt

  1. Klona exempellagringsplatsen.

    git clone --depth 1 https://github.com/Azure/azureml-examples
    cd azureml-examples/cli/endpoints/online/model-1/
    
  2. Skapa och aktivera en virtuell miljö med conda. I det här exemplet azureml-inference-server-http installeras paketet automatiskt eftersom det ingår som ett beroende bibliotek för azureml-defaults paketet i conda.yml på följande sätt.

    # 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. Granska bedömningsskriptet.

    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. Kör slutsatsdragningsservern med att ange bedömningsskript och modellfil. Den angivna modellkatalogen (model_dir parametern) definieras som AZUREML_MODEL_DIR variabel och hämtas i bedömningsskriptet. I det här fallet anger vi den aktuella katalogen (./) eftersom underkatalogen anges i bedömningsskriptet som model/sklearn_regression_model.pkl.

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

    Exempelstartloggen visas om servern startade och bedömningsskriptet anropades. Annars kommer det att finnas felmeddelanden i loggen.

  5. Testa bedömningsskriptet med exempeldata. Öppna en annan terminal och gå till samma arbetskatalog för att köra kommandot. curl Använd kommandot för att skicka en exempelbegäran till servern och få ett bedömningsresultat.

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

    Poängresultatet returneras om det inte finns några problem i bedömningsskriptet. Om du hittar något fel kan du försöka uppdatera bedömningsskriptet och starta servern igen för att testa det uppdaterade skriptet.

Servervägar

Servern lyssnar på port 5001 (som standard) på dessa vägar.

Name Flöde
Liveness-avsökning 127.0.0.1:5001/
Poäng 127.0.0.1:5001/score
OpenAPI (swagger) 127.0.0.1:5001/swagger.json

Serverparametrar

Följande tabell innehåller de parametrar som godkänts av servern:

Parameter Obligatoriskt Standardvärde beskrivning
entry_script Sant Ej tillämpligt Den relativa eller absoluta sökvägen till bedömningsskriptet.
model_dir Falsk Ej tillämpligt Den relativa eller absoluta sökvägen till katalogen som innehåller modellen som används för slutsatsdragning.
port Falsk 5001 Serverns serverport.
worker_count Falsk 1 Antalet arbetstrådar som ska bearbeta samtidiga begäranden.
appinsights_instrumentation_key Falsk Ej tillämpligt Instrumentationsnyckeln till application insights där loggarna kommer att publiceras.
access_control_allow_origins Falsk Ej tillämpligt Aktivera CORS för angivna ursprung. Avgränsa flera ursprung med ",".
Exempel: "microsoft.com, bing.com"

Begärandeflöde

Följande steg förklarar hur Http-servern för Azure Machine Learning-slutsatsdragning (azmlinfsrv) hanterar inkommande begäranden:

  1. En Python CLI-omslutning finns runt serverns nätverksstack och används för att starta servern.
  2. En klient skickar en begäran till servern.
  3. När en begäran tas emot går den via WSGI-servern och skickas sedan till en av arbetarna.
  4. Begäranden hanteras sedan av en Flask-app som läser in inmatningsskriptet och eventuella beroenden.
  5. Slutligen skickas begäran till ditt postskript. Postskriptet gör sedan ett slutsatsdragningsanrop till den inlästa modellen och returnerar ett svar.

Diagram över HTTP-serverprocessen.

Förstå loggar

Här beskriver vi loggar för HTTP-servern för Azure Machine Learning-slutsatsdragning. Du kan hämta loggen när du kör den azureml-inference-server-http lokalt eller hämta containerloggar om du använder onlineslutpunkter.

Kommentar

Loggningsformatet har ändrats sedan version 0.8.0. Om du hittar loggen i ett annat format uppdaterar azureml-inference-server-http du paketet till den senaste versionen.

Dricks

Om du använder onlineslutpunkter börjar loggen från slutsatsdragningsservern med Azure Machine Learning Inferencing HTTP server <version>.

Startloggar

När servern startas visas serverinställningarna först av loggarna på följande sätt:

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>

När du till exempel startar servern följde exemplet från slutpunkt till slutpunkt:

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.

Loggformat

Loggarna från slutsatsdragningsservern genereras i följande format, förutom startskripten eftersom de inte ingår i Python-paketet:

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

Här <pid> är process-ID:t och <level> är det första tecknet på loggningsnivån – E för ERROR, I för INFO osv.

Det finns sex nivåer av loggning i Python, med tal som är associerade med allvarlighetsgrad:

Loggningsnivå Numeriskt värde
KRITISK 50
ERROR 40
WARNING 30
INFO 20
FELSÖKNING 10
NOTSET 0

Felsökningsguide

I det här avsnittet tillhandahåller vi grundläggande felsökningstips för HTTP-server för Azure Machine Learning-slutsatsdragning. Om du vill felsöka onlineslutpunkter läser du även Felsöka distribution av onlineslutpunkter

Grundläggande steg

De grundläggande stegen för felsökning är:

  1. Samla in versionsinformation för din Python-miljö.
  2. Kontrollera att python-paketversionen azureml-inference-server-http som anges i miljöfilen matchar den AzureML-slutsatsdragning av HTTP-serverversionen som visas i startloggen. Ibland leder PIP:s beroendelösare till oväntade versioner av installerade paket.
  3. Om du anger Flask (och eller dess beroenden) i din miljö tar du bort dem. Beroendena omfattar Flask, Jinja2, itsdangerous, Werkzeug, MarkupSafeoch click. Flask visas som ett beroende i serverpaketet och det är bäst att låta servern installera det. På så sätt får du dem automatiskt när servern stöder nya versioner av Flask.

Serverversion

Serverpaketet azureml-inference-server-http publiceras till PyPI. Du hittar vår ändringslogg och alla tidigare versioner på vår PyPI-sida. Uppdatera till den senaste versionen om du använder en tidigare version.

  • 0.4.x: Den version som paketeras i träningsbilder ≤ 20220601 och i azureml-defaults>=1.34,<=1.43. 0.4.13 är den senaste stabila versionen. Om du använder servern före versionen 0.4.11kan flaskberoendeproblem som inte kan importera namn Markup från jinja2visas. Du rekommenderas att uppgradera till 0.4.13 eller 0.8.x (den senaste versionen) om möjligt.
  • 0.6.x: Den version som är förinstallerad i slutsatsdragningsbilder ≤ 20220516. Den senaste stabila versionen är 0.6.1.
  • 0.7.x: Den första versionen som stöder Flask 2. Den senaste stabila versionen är 0.7.7.
  • 0.8.x: Loggformatet har ändrats och Python 3.6-stödet har tagits bort.

Paketberoenden

De mest relevanta paketen för servern azureml-inference-server-http är följande paket:

  • Kolven
  • opencensus-ext-azure
  • inference-schema

Om du har angett azureml-defaults i Python-miljön azureml-inference-server-http är paketet beroende av och installeras automatiskt.

Dricks

Om du använder Python SDK v1 och inte uttryckligen anger azureml-defaults i Python-miljön kan SDK:t lägga till paketet åt dig. Den låser dock den till den version som SDK:et är på. Om SDK-versionen till exempel är 1.38.0lägger den till azureml-defaults==1.38.0 i miljöns pip-krav.

Vanliga frågor och svar

1. Jag stötte på följande fel under serverstarten:


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

Du har Flask 2 installerat i python-miljön men kör en version av azureml-inference-server-http som inte stöder Flask 2. Stöd för Flask 2 läggs till i azureml-inference-server-http>=0.7.0, som också finns i azureml-defaults>=1.44.

  • Om du inte använder det här paketet i en AzureML docker-avbildning använder du den senaste versionen av azureml-inference-server-http eller azureml-defaults.

  • Om du använder det här paketet med en AzureML docker-avbildning kontrollerar du att du använder en avbildning som är inbyggd i eller efter juli 2022. Avbildningsversionen är tillgänglig i containerloggarna. Du bör kunna hitta en logg som liknar följande:

    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, Materializaton Build:20220708.v2
    2022-08-22T17:05:02,188930082+00:00 | gunicorn/run | 
    2022-08-22T17:05:02,190557998+00:00 | gunicorn/run | 
    

    Byggdatumet för avbildningen visas efter "Materialiseringsversion", som i exemplet ovan är 20220708, eller 8 juli 2022. Den här bilden är kompatibel med Flask 2. Om du inte ser en banderoll som den här i containerloggen är avbildningen inaktuell och bör uppdateras. Om du använder en CUDA-avbildning och inte kan hitta en nyare avbildning kontrollerar du om avbildningen är inaktuell i AzureML-Containers. Om det är det bör du kunna hitta ersättningar.

  • Om du använder servern med en onlineslutpunkt kan du även hitta loggarna under "Distributionsloggar" på onlineslutpunktssidan i Azure Machine Learning-studio. Om du distribuerar med SDK v1 och inte uttryckligen anger en avbildning i distributionskonfigurationen kommer den som standard att använda en version av openmpi4.1.0-ubuntu20.04 som matchar din lokala SDK-verktygsuppsättning, som kanske inte är den senaste versionen av avbildningen. SDK 1.43 använder till openmpi4.1.0-ubuntu20.04:20220616exempel som standard , vilket är inkompatibelt. Se till att du använder den senaste SDK:t för distributionen.

  • Om du av någon anledning inte kan uppdatera avbildningen kan du tillfälligt undvika problemet genom att fästa azureml-defaults==1.43 eller azureml-inference-server-http~=0.4.13, som installerar den äldre versionsservern med Flask 1.0.x.

2. Jag stötte på en ImportError eller ModuleNotFoundError på moduler opencensus, jinja2, MarkupSafe, eller click under start som följande meddelande:

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

Äldre versioner (<= 0.4.10) av servern fäster inte Flasks beroende på kompatibla versioner. Det här problemet har åtgärdats i den senaste versionen av servern.

Nästa steg