Depurar scripts de puntuación con el servidor HTTP de inferencia de Azure Machine Learning
El servidor HTTP de inferencia de Azure Machine Learning es un paquete de Python que expone su función de puntuación como un punto de conexión HTTP y envuelve el código y las dependencias del servidor Flask en un paquete singular. El servidor se incluye en las imágenes de Docker precompiladas para inferencia que se usan al implementar un modelo con Azure Machine Learning. El uso del paquete por sí solo le permite implementar el modelo localmente para la producción y validar fácilmente su script de puntuación (entrada) en un entorno de desarrollo local. Si hay un problema con el script de puntuación, el servidor devuelve un error y la ubicación del error.
El servidor también puede usarse para crear puertas de validación en una canalización continua de integración e implementación. Puede, por ejemplo, iniciar el servidor con el script candidato y ejecutar el conjunto de pruebas en el punto de conexión local.
En este artículo se admiten desarrolladores que desean usar el servidor de inferencia para depurar localmente y se describe cómo usar el servidor de inferencia con puntos de conexión en línea en Windows.
Requisitos previos
Para usar el servidor HTTP de inferencia de Azure Machine Learning para la depuración local, la configuración debe incluir los siguientes componentes:
- Python 3.8 o versiones posteriores
- Anaconda
El servidor HTTP de inferencia de Azure Machine Learning se ejecuta en Windows y en los sistemas operativos basados en Linux.
Explorar las opciones de depuración local para puntos de conexión en línea
Si depura los puntos de conexión localmente antes de implementarlos en la nube, podrá detectar antes los errores en el código y la configuración. Para depurar puntos de conexión localmente, tiene varias opciones, entre las que se incluyen:
- El servidor HTTP de inferencia de Azure Machine Learning
- Un punto de conexión local
En este artículo se describe cómo trabajar con el servidor HTTP de inferencia de Azure Machine Learning en Windows.
En la tabla siguiente se proporciona información general sobre escenarios que le ayudarán a elegir la mejor opción:
Escenario | Servidor HTTP de inferencia | Punto de conexión local |
---|---|---|
Actualización del entorno de Python local, sin recompilación de imágenes de Docker | Sí | No |
Actualización del script de puntuación | Sí | Sí |
Actualización de las configuraciones de implementación (implementación, entorno, código, modelo) | No | Sí |
Integrar depurador de Microsoft Visual Studio Code (VS Code) | Sí | Sí |
Al ejecutar el servidor HTTP de inferencia localmente, puede centrarse en depurar el script de puntuación sin preocuparse por las configuraciones del contenedor de implementación.
Instalar paquete azureml-inference-server-http
Para instalar el paquete azureml-inference-server-http
, ejecute el siguiente comando:
python -m pip install azureml-inference-server-http
Nota:
Para evitar conflictos de paquetes, instale el servidor HTTP de inferencia en un entorno virtual.
Puede usar el comando pip install virtualenv
para habilitar entornos virtuales para la configuración.
Depuración local del script de puntuación
Para depurar el script de puntuación localmente, tiene varias opciones para probar el comportamiento del servidor:
- Pruebe un script de puntuación ficticio.
- Use Visual Studio Code para depurar con el paquete azureml-inference-server-http.
- Ejecute un script de puntuación real, un archivo de modelo y un archivo de entorno desde nuestro repositorio de ejemplos.
Probar el comportamiento del servidor con script de puntuación ficticio
Cree un directorio denominado server_quickstart para almacenar los archivos:
mkdir server_quickstart cd server_quickstart
Para evitar conflictos con los paquetes, cree un entorno virtual, como myenv, y actívelo:
python -m virtualenv myenv
Nota:
En Linux, ejecute el comando
source myenv/bin/activate
para activar el entorno virtual.Después de probar el servidor, puede ejecutar el comando
deactivate
para desactivar el entorno virtual de Python.Instale el paquete
azureml-inference-server-http
desde la fuente pypi:python -m pip install azureml-inference-server-http
Creación del script de entrada. En el ejemplo siguiente se crea un script de entrada básico y se guarda en un archivo denominado 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
Inicie el servidor con el comando
azmlinfsrv
y establezca el archivo score.py como script de entrada:azmlinfsrv --entry_script score.py
Nota:
El servidor se hospeda en 0.0.0.0, lo que significa que escucha todas las direcciones IP del equipo host.
Envíe una solicitud de puntuación al servidor mediante la utilidad
curl
:curl -p 127.0.0.1:5001/score
El servidor envía la siguiente respuesta:
{"message": "Hello, World!"}
Después de realizar las pruebas, seleccione Ctrl + C para finalizar el servidor.
Ahora puede modificar el archivo de script de puntuación (score.py) y probar los cambios ejecutando el servidor de nuevo con el comando azmlinfsrv --entry_script score.py
.
Integrar con Visual Studio Code
Para usar VS Code y la extensión de Python para depurar con el paquete azureml-inference-server-http, puede usar los modos Iniciar y Adjuntar.
Para el modo Iniciar, configure el archivo launch.json en VS Code e inicie el servidor HTTP de inferencia de Azure Machine Learning en VS Code:
Inicie VS Code y abra la carpeta que contiene el script (score.py).
Agregue la siguiente configuración al archivo launch.json para esa área de trabajo en 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" ] } ] }
Inicie la sesión de depuración en VS Code seleccionando Ejecutar>Iniciar depuración o use el método abreviado de teclado F5.
Para el modo Adjuntar, inicie el servidor HTTP de inferencia de Azure Machine Learning en una ventana de comandos y use VS Code con la extensión de Python para asociarlo al proceso:
Nota:
Para Linux, instale primero el paquete
gdb
ejecutando el comandosudo apt-get install -y gdb
.Agregue la siguiente configuración al archivo launch.json para esa área de trabajo en VS Code:
launch.json
{ "version": "0.2.0", "configurations": [ { "name": "Python: Attach using Process Id", "type": "python", "request": "attach", "processId": "${command:pickProcess}", "justMyCode": true } ] }
En una ventana de comandos, inicie el servidor HTTP de inferencia mediante el comando
azmlinfsrv --entry_script score.py
.Inicie la sesión de depuración en VS Code:
Seleccione Ejecutar>Iniciar depuración o use el método abreviado de teclado F5.
En la ventana de comandos, vea los registros del servidor de inferencia y busque el id. de proceso del comando
azmlinfsrv
(no elgunicorn
):En el depurador de VS Code, escriba el identificador de proceso del comando
azmlinfsrv
.Si no ve el selector de procesos de VS Code, puede escribir manualmente el id. de proceso en el campo
processId
del archivo launch.json para esa área de trabajo.
En ambos modos, puede establecer puntos de interrupción y depurar el script paso a paso.
Usar un ejemplo completo
El siguiente procedimiento ejecuta el servidor localmente con archivos de ejemplo (script de puntuación, archivo de modelo y entorno) desde el repositorio de ejemplo de Azure Machine Learning. Para obtener más ejemplos de cómo usar estos archivos de ejemplo, consulte Implementar y puntuar un modelo de Machine Learning mediante un punto de conexión en línea.
Clone el repositorio de ejemplo:
git clone --depth 1 https://github.com/Azure/azureml-examples cd azureml-examples/cli/endpoints/online/model-1/
Cree y active un entorno virtual con conda:
En este ejemplo, el paquete
azureml-inference-server-http
se instala automáticamente. El paquete se incluye como una biblioteca dependiente del paqueteazureml-defaults
en el archivo 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
Revise el script de puntuación:
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()
Ejecute el servidor HTTP de inferencia especificando el script de puntuación y el archivo de modelo:
El directorio del modelo especificado en el parámetro
model_dir
se define mediante la variableAZUREML_MODEL_DIR
y se recupera en el script de puntuación.En este caso, especifique el directorio actual ./ porque el subdirectorio se especifica en el script de puntuación como model/sklearn_regression_model.pkl.
azmlinfsrv --entry_script ./onlinescoring/score.py --model_dir ./
Cuando el servidor se inicia e invoca correctamente el script de puntuación, se abre el registro de inicio de ejemplo. De lo contrario, el registro muestra mensajes de error.
Pruebe el script de puntuación con datos de ejemplo:
Abra otra ventana de comandos y cambie al mismo directorio de trabajo donde se ejecuta el comando.
Use la utilidad
curl
para enviar una solicitud de ejemplo al servidor y recibir un resultado de puntuación:curl --request POST "127.0.0.1:5001/score" --header "Content-Type:application/json" --data @sample-request.json
Cuando no hay ningún problema en el script de puntuación, el script devuelve el resultado de puntuación. Si se producen problemas, puede intentar actualizar el script de puntuación e iniciar el servidor de nuevo para probar el script actualizado.
Revisar rutas del servidor
El servidor HTTP de inferencia escucha en el puerto 5001 de forma predeterminada en las rutas siguientes:
Nombre | Ruta |
---|---|
Sondeo de ejecución | 127.0.0.1:5001/ |
Puntuación | 127.0.0.1:5001/score |
OpenAPI (swagger) | 127.0.0.1:5001/swagger.json |
Revisar parámetros del servidor
El servidor HTTP de inferencia acepta los parámetros siguientes:
Parámetro | Obligatorio | Valor predeterminado | Description |
---|---|---|---|
entry_script |
True | N/D | Identifica la ruta de acceso relativa o absoluta al script de puntuación. |
model_dir |
False | N/D | Identifica la ruta de acceso relativa o absoluta al directorio que contiene el modelo usado para la inferencia. |
port |
False | 5001 | Especifica el puerto de servicio del servidor. |
worker_count |
False | 1 | Proporciona el número de subprocesos de trabajo para procesar solicitudes simultáneas. |
appinsights_instrumentation_key |
False | N/D | Proporciona la clave de instrumentación a Application Insights donde se publican los registros. |
access_control_allow_origins |
False | N/D | Habilita CORS para los orígenes especificados, donde varios orígenes están separados por una coma (,), como microsoft.com, bing.com . |
Explorar procesamiento de solicitud de servidor
En los pasos siguientes se muestra cómo el servidor HTTP de inferencia de Azure Machine Learning (azmlinfsrv
) controla las solicitudes entrantes:
Alrededor de la pila de red del servidor, un contenedor de la CLI de Python inicia el servidor.
Un cliente envía una solicitud al servidor.
El servidor envía la solicitud a través del servidor de Interfaz de puerta de enlace de servidor web (WSGI), que envía la solicitud a una aplicación de trabajo de Flask:
La aplicación de trabajo Flask controla la solicitud, lo que incluye cargar el script de entrada y todas las dependencias.
El script de entrada recibe la solicitud. El script de entrada realiza una llamada de inferencia al modelo cargado y devuelve una respuesta:
Explorar registros de servidor
Hay dos maneras de obtener datos de registro para la prueba del servidor HTTP de inferencia:
- Ejecute el paquete
azureml-inference-server-http
localmente y vea la salida de los registros. - Use puntos de conexión en línea y vea los registros de contenedor. El registro del servidor de inferencia se denomina <versión> del servidor HTTP de inferencia de Azure Machine Learning.
Nota:
El formato de registro ha cambiado desde la versión 0.8.0. Si el registro usa un estilo diferente del esperado, actualice el paquete azureml-inference-server-http
a la versión más reciente.
Visualizar registros de inicio
Cuando se inicia el servidor, los registros muestran la configuración del servidor inicial de la siguiente manera:
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 ejemplo, al iniciar el servidor siguiendo el ejemplo de un extremo a otro, el registro se muestra de la siguiente manera:
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.
Comprender formato de datos de registro
Todos los registros del servidor HTTP de inferencia, excepto el script del iniciador, presentan datos en el formato siguiente:
<UTC Time> | <level> [<pid>] <logger name> - <message>
La entrada consta de los siguientes componentes:
<UTC Time>
: hora a la que se introdujo la entrada en el registro.<pid>
: id. del proceso asociado a la entrada.<level>
: primer carácter del nivel de registro de la entrada, comoE
para ERROR,I
para INFO, etc.<logger name>
: nombre del recurso asociado a la entrada de registro.<message>
: contenido del mensaje de registro.
Hay seis niveles de registro en Python con valores numéricos asignados según la gravedad:
Nivel de registro | Valor numérico |
---|---|
CRITICAL (CRÍTICA) | 50 |
ERROR | 40 |
ADVERTENCIA | 30 |
INFO | 20 |
DEBUG | 10 |
NOTSET | 0 |
Solucionar problemas de servidor
En las secciones siguientes se proporcionan sugerencias básicas de solución de problemas para el servidor HTTP de inferencia de Azure Machine Learning. Para solucionar problemas de puntos de conexión en línea, consulte Solucionar problemas de implementación de puntos de conexión en línea.
Compruebe los paquetes instalados
Siga estos pasos para solucionar los problemas que puedan aparecer con los paquetes instalados.
Recopile información sobre los paquetes instalados y las versiones del entorno de Python.
Confirme que la versión del paquete de Python
azureml-inference-server-http
especificada en el archivo de entorno coincide con la versión del servidor HTTP de inferencia de Azure Machine Learning que se muestra en el registro de inicio.En algunos casos, el solucionador de dependencias pip instala versiones de paquete inesperadas. Es posible que tenga que ejecutar
pip
para corregir los paquetes y versiones instalados.Si especifica Flask o sus dependencias en el entorno, quite estos elementos.
- Los paquetes dependientes incluyen
flask
,jinja2
,itsdangerous
,werkzeug
,markupsafe
yclick
. flask
aparece como una dependencia en el paquete de servidor. El mejor enfoque es permitir que el servidor de inferencia instale el paqueteflask
.- Cuando el servidor de inferencia está configurado para admitir nuevas versiones de Flask, el servidor recibe automáticamente las actualizaciones del paquete a medida que están disponibles.
- Los paquetes dependientes incluyen
Comprobar versión del servidor
El paquete de servidor azureml-inference-server-http
se publica en PyPI. La página PyPI enumera el registro de cambios y todas las versiones anteriores.
Si usa una versión anterior del paquete, actualice la configuración a la más reciente. En la tabla siguiente se resumen las versiones estables, los problemas comunes y los ajustes recomendados:
Versión del paquete | Descripción | Problema | Resolución |
---|---|---|---|
0.4.x | Agrupadas en imágenes de entrenamiento con fecha de 20220601 o anterior y versiones .1.34 de paquete azureml-defaults a través de 1.43 . La versión estable más reciente es 0.4.13. |
En las versiones del servidor anteriores a la 0.4.11, es posible que encuentre problemas de dependencia de Flask, como "can't import name Markup from jinja2" . |
Realice la actualización a las versiones 0.4.13 o 0.8.x, la versión más reciente, si es posible. |
0.6.x | Preinstalado en imágenes de inferencia con fecha de 20220516 y versiones anteriores. La versión estable más reciente es 0.6.1. |
N/D | N/D |
0.7.x | Admite Flask 2. La versión estable más reciente es 0.7.7. | N/D | N/D |
0.8.x | Se ha cambiado el formato de registro. Finalizó la compatibilidad con Python 3.6. | N/D | N/D |
Comprobar dependencias del paquete
Los paquetes dependientes más relevantes para el paquete de servidor azureml-inference-server-http
incluyen:
flask
opencensus-ext-azure
inference-schema
Si especificó el paquete azureml-defaults
en el entorno de Python, el paquete azureml-inference-server-http
es dependiente. La dependencia se instala automáticamente.
Sugerencia
Si usa el SDK de Python v1 y no especifica explícitamente el paquete azureml-defaults
en el entorno de Python, es posible que el SDK agregue automáticamente el paquete. Sin embargo, la versión del empaquetador está bloqueada en relación con la versión del SDK. Por ejemplo, si la versión del SDK es 1.38.0
, la entrada azureml-defaults==1.38.0
se agrega a los requisitos pip del entorno.
TypeError durante el inicio del servidor
Es posible que encuentre los siguientes TypeError
durante el inicio del 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 error se produce cuando tiene Flask 2 instalado en el entorno de Python, pero la versión del paquete azureml-inference-server-http
no es compatible con Flask 2. La compatibilidad con Flask 2 está disponible en la versión del paquete azureml-inference-server-http
0.7.0 y versiones posteriores, y la versión del paquete azureml-defaults
1.44 y versiones posteriores.
Si no usa el paquete Flask 2 en una imagen de Docker de Azure Machine Learning, use la versión más reciente del paquete de
azureml-inference-server-http
oazureml-defaults
.Si usa el paquete Flask 2 en una imagen de Docker de Azure Machine Learning, confirme que la versión de compilación de la imagen es julio de 2022 o posterior.
La versión de la imagen la pueden encontrar en los registros del contenedor. Por ejemplo:
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 |
La fecha de compilación de la imagen aparece después de la notación
Materialization Build
. En el ejemplo anterior, la versión de la imagen es20220708
o el 8 de julio de 2022. La imagen de este ejemplo es compatible con Flask 2.Si no ve un mensaje similar en el registro de contenedor, la imagen no está actualizada y debe actualizarse. Si usa una imagen de arquitectura de dispositivo unificado de proceso (CUDA) y no encuentra una imagen más reciente, compruebe si la imagen está en desuso en AzureML-Containers. Puede encontrar reemplazos designados para imágenes en desuso.
Si usa el servidor con un punto de conexión en línea, también puede encontrar los registros en la sección Registros de la página Puntos de conexión de Estudio de Azure Machine Learning.
Si implementa con SDK v1 y no especifica explícitamente una imagen en la configuración de implementación, el servidor aplica el paquete openmpi4.1.0-ubuntu20.04
con una versión que coincida con el conjunto de herramientas del SDK local. Sin embargo, es posible que la versión instalada no sea la versión más reciente disponible de la imagen.
Para la versión 1.43 del SDK, el servidor instala la versión del paquete openmpi4.1.0-ubuntu20.04:20220616
de forma predeterminada, pero esta versión del paquete no es compatible con SDK 1.43. Asegúrese de usar el SDK más reciente para la implementación.
Si no puede actualizar la imagen, puede evitar temporalmente el problema anclando las entradas azureml-defaults==1.43
o azureml-inference-server-http~=0.4.13
en el archivo de entorno. Estas entradas dirigen al servidor para instalar la versión anterior con flask 1.0.x
.
ImportError o ModuleNotFoundError durante el inicio del servidor
Es posible que encuentre ImportError
o ModuleNotFoundError
en módulos concretos, como opencensus
, jinja2
, markupsafe
o click
, durante el inicio del servidor. En el ejemplo siguiente se muestra el mensaje de error:
ImportError: cannot import name 'Markup' from 'jinja2'
Los errores de importación y del módulo se producen cuando se usa la versión 0.4.10, o cualquier versión anterior, del servidor que no ancle la dependencia de Flask a una versión compatible. Para evitar el problema, instale una versión posterior del servidor.