Creación avanzada de scripts de entrada
SE APLICA A: Azure ML del SDK de Python v1
En este artículo se explica cómo escribir scripts de entrada para casos de uso especializados.
Requisitos previos
En este artículo se da por supuesto que ya tiene un modelo de aprendizaje automático entrenado que planea implementar con Azure Machine Learning. Para más información sobre la implementación de modelos, consulte Implementación de modelos de Machine Learning en Azure.
Generación automática de un esquema de Swagger
Para generar automáticamente un esquema para el servicio web, proporcione un ejemplo de la entrada y salida del constructor de uno de los objetos de tipo definidos. El tipo y ejemplo se usan para crear automáticamente el esquema. A continuación, Azure Machine Learning crea una especificación OpenAPI (anteriormente, especificación de Swagger) para el servicio web durante la implementación.
Advertencia
No debe usar datos confidenciales o privados para la entrada o salida de ejemplo. La página de Swagger para la inferencia hospedada en AML expone los datos de ejemplo.
Actualmente se admiten estos tipos:
pandas
numpy
pyspark
- Objeto estándar de Python
Para usar la generación de esquemas, incluya el paquete inference-schema
de código abierto, versión 1.1.0 o superior, en el archivo de dependencias. Para obtener más información sobre este paquete, consulte InferenceSchema en GitHub. Para generar el consumo de servicios web automatizados compatible con Swagger, la función run() del script de puntuación debe tener la forma de API de:
- Primer parámetro de tipo
StandardPythonParameterType
, denominado Entradas y anidados - Un segundo parámetro opcional de tipo
StandardPythonParameterType
, denominado GlobalParameters - Devuelve un diccionario de tipo
StandardPythonParameterType
, denominado Results y anidado
Defina los formatos de ejemplo de entrada y salida de las variables input_sample
y output_sample
, que representan los formatos de solicitud y respuesta del servicio web. Use estos ejemplos en los decoradores de entrada y salida de la función run()
. El siguiente ejemplo de Scikit-learn usa generación de esquemas.
Punto de conexión compatible con Power BI
En el ejemplo siguiente se muestra cómo definir la forma de la API según las instrucciones anteriores. Este método se admite para consumir el servicio Web implementado desde Power BI.
import json
import pickle
import numpy as np
import pandas as pd
import azureml.train.automl
from sklearn.externals import joblib
from sklearn.linear_model import Ridge
from inference_schema.schema_decorators import input_schema, output_schema
from inference_schema.parameter_types.standard_py_parameter_type import StandardPythonParameterType
from inference_schema.parameter_types.numpy_parameter_type import NumpyParameterType
from inference_schema.parameter_types.pandas_parameter_type import PandasParameterType
def init():
global model
# Replace filename if needed.
model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_regression_model.pkl')
# Deserialize the model file back into a sklearn model.
model = joblib.load(model_path)
# providing 3 sample inputs for schema generation
numpy_sample_input = NumpyParameterType(np.array([[1,2,3,4,5,6,7,8,9,10],[10,9,8,7,6,5,4,3,2,1]],dtype='float64'))
pandas_sample_input = PandasParameterType(pd.DataFrame({'name': ['Sarah', 'John'], 'age': [25, 26]}))
standard_sample_input = StandardPythonParameterType(0.0)
# This is a nested input sample, any item wrapped by `ParameterType` will be described by schema
sample_input = StandardPythonParameterType({'input1': numpy_sample_input,
'input2': pandas_sample_input,
'input3': standard_sample_input})
sample_global_parameters = StandardPythonParameterType(1.0) # this is optional
sample_output = StandardPythonParameterType([1.0, 1.0])
outputs = StandardPythonParameterType({'Results':sample_output}) # 'Results' is case sensitive
@input_schema('Inputs', sample_input)
# 'Inputs' is case sensitive
@input_schema('GlobalParameters', sample_global_parameters)
# this is optional, 'GlobalParameters' is case sensitive
@output_schema(outputs)
def run(Inputs, GlobalParameters):
# the parameters here have to match those in decorator, both 'Inputs' and
# 'GlobalParameters' here are case sensitive
try:
data = Inputs['input1']
# data will be convert to target format
assert isinstance(data, np.ndarray)
result = model.predict(data)
return result.tolist()
except Exception as e:
error = str(e)
return error
Sugerencia
El valor devuelto del script puede ser cualquier objeto de Python que sea serializable para JSON. Por ejemplo, si el modelo devuelve una trama de datos de Pandas que contiene varias columnas, puede usar un decorador de salida similar al código siguiente:
output_sample = pd.DataFrame(data=[{"a1": 5, "a2": 6}])
@output_schema(PandasParameterType(output_sample))
...
result = model.predict(data)
return result
Datos binarios (es decir, imagen)
Si el modelo acepta datos binarios, como una imagen, debe modificar el archivo score.py usado para la implementación para aceptar solicitudes HTTP sin procesar. Para aceptar los datos sin procesar, use la clase AMLRequest
en el script de entrada y agregue el elemento decorador @rawhttp
a la función run()
.
Este es un ejemplo de score.py
que acepta datos binarios:
from azureml.contrib.services.aml_request import AMLRequest, rawhttp
from azureml.contrib.services.aml_response import AMLResponse
from PIL import Image
import json
def init():
print("This is init()")
@rawhttp
def run(request):
print("This is run()")
if request.method == 'GET':
# For this example, just return the URL for GETs.
respBody = str.encode(request.full_path)
return AMLResponse(respBody, 200)
elif request.method == 'POST':
file_bytes = request.files["image"]
image = Image.open(file_bytes).convert('RGB')
# For a real-world solution, you would load the data from reqBody
# and send it to the model. Then return the response.
# For demonstration purposes, this example just returns the size of the image as the response.
return AMLResponse(json.dumps(image.size), 200)
else:
return AMLResponse("bad request", 500)
Importante
La clase AMLRequest
está en el espacio de nombres azureml.contrib
. Las entidades de este espacio de nombres cambian con frecuencia mientras trabajamos para mejorar el servicio. Todo el contenido de este espacio de nombres debe considerarse una versión preliminar que no es completamente compatible con Microsoft.
Si necesita probar esto en su entorno de desarrollo local, puede instalar los componentes mediante el comando siguiente:
pip install azureml-contrib-services
Nota
No se recomienda500 como código de estado personalizado, como en azureml-fe, el código de estado se volverá a escribir en 502.
- El código de estado se pasa a través de azureml-fe y, a continuación, se enviará al cliente.
- Azureml-fe solo vuelve a escribir el código 500 devuelto del lado del modelo para que sea 502 y el cliente recibe un código 502.
- Pero si el propio azureml-fe devuelve un código 500, el lado cliente seguirá recibiendo este código.
La clase AMLRequest
solo permite acceder a los datos publicados sin procesar en el archivo score.py, no hay ningún componente del lado cliente. Desde un cliente, los datos se publican de la forma habitual. Por ejemplo, el siguiente código de Python lee un archivo de imagen y envía los datos:
import requests
uri = service.scoring_uri
image_path = 'test.jpg'
files = {'image': open(image_path, 'rb').read()}
response = requests.post(uri, files=files)
print(response.json)
Uso compartido de recursos entre orígenes (CORS)
El uso compartido de recursos entre orígenes es una manera de permitir que los recursos de una página web se soliciten desde otro dominio. CORS funciona a través de los encabezados HTTP enviados con la solicitud del cliente y se devuelven con la respuesta del servicio. Para más información sobre CORS y los encabezados válidos, consulte Intercambio de recursos de origen cruzado en Wikipedia.
Para configurar la implementación del modelo para que admita CORS, use la clase AMLResponse
en el script de entrada. Esta clase permite establecer los encabezados en el objeto de respuesta.
En el ejemplo siguiente se establece el encabezado Access-Control-Allow-Origin
para la respuesta desde el script de entrada:
from azureml.contrib.services.aml_request import AMLRequest, rawhttp
from azureml.contrib.services.aml_response import AMLResponse
def init():
print("This is init()")
@rawhttp
def run(request):
print("This is run()")
print("Request: [{0}]".format(request))
if request.method == 'GET':
# For this example, just return the URL for GET.
# For a real-world solution, you would load the data from URL params or headers
# and send it to the model. Then return the response.
respBody = str.encode(request.full_path)
resp = AMLResponse(respBody, 200)
resp.headers["Allow"] = "OPTIONS, GET, POST"
resp.headers["Access-Control-Allow-Methods"] = "OPTIONS, GET, POST"
resp.headers['Access-Control-Allow-Origin'] = "http://www.example.com"
resp.headers['Access-Control-Allow-Headers'] = "*"
return resp
elif request.method == 'POST':
reqBody = request.get_data(False)
# For a real-world solution, you would load the data from reqBody
# and send it to the model. Then return the response.
resp = AMLResponse(reqBody, 200)
resp.headers["Allow"] = "OPTIONS, GET, POST"
resp.headers["Access-Control-Allow-Methods"] = "OPTIONS, GET, POST"
resp.headers['Access-Control-Allow-Origin'] = "http://www.example.com"
resp.headers['Access-Control-Allow-Headers'] = "*"
return resp
elif request.method == 'OPTIONS':
resp = AMLResponse("", 200)
resp.headers["Allow"] = "OPTIONS, GET, POST"
resp.headers["Access-Control-Allow-Methods"] = "OPTIONS, GET, POST"
resp.headers['Access-Control-Allow-Origin'] = "http://www.example.com"
resp.headers['Access-Control-Allow-Headers'] = "*"
return resp
else:
return AMLResponse("bad request", 400)
Importante
La clase AMLResponse
está en el espacio de nombres azureml.contrib
. Las entidades de este espacio de nombres cambian con frecuencia mientras trabajamos para mejorar el servicio. Todo el contenido de este espacio de nombres debe considerarse una versión preliminar que no es completamente compatible con Microsoft.
Si necesita probar esto en su entorno de desarrollo local, puede instalar los componentes mediante el comando siguiente:
pip install azureml-contrib-services
Advertencia
Azure Machine Learning solo enruta las solicitudes POST y GET a los contenedores que ejecutan el servicio de puntuación. Esto puede producir errores porque los exploradores usan solicitudes OPTIONS para preparar solicitudes CORS.
Carga de los modelos registrados
Hay dos maneras de buscar modelos en el script de entrada:
AZUREML_MODEL_DIR
: variable de entorno que contiene la ruta de acceso a la ubicación del modeloModel.get_model_path
: API que devuelve la ruta de acceso al archivo de modelo mediante el nombre del modelo registrado
AZUREML_MODEL_DIR
AZUREML_MODEL_DIR
es una variable de entorno que se crea durante la implementación del servicio. Puede usar esta variable de entorno para buscar la ubicación de los modelos implementados.
En la tabla siguiente se describe el valor de AZUREML_MODEL_DIR
en función del número de modelos implementados:
Implementación | Valor de la variable de entorno |
---|---|
Modelo único | Ruta de acceso a la carpeta que contiene el modelo. |
Varios modelos | Ruta de acceso a la carpeta que contiene todos los modelos. Los modelos se encuentran por nombre y versión en esta carpeta ($MODEL_NAME/$VERSION ). |
Durante el registro y la implementación de un modelo, este se coloca en la ruta de acceso AZUREML_MODEL_DIR y se conserva su nombre de archivo original.
Para obtener la ruta de acceso a un archivo de modelo en el script de entrada, combine la variable de entorno con la ruta de acceso al archivo que busca.
Ejemplo de modelo único
# Example when the model is a file
model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_regression_model.pkl')
# Example when the model is a folder containing a file
file_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'my_model_folder', 'sklearn_regression_model.pkl')
Ejemplo de varios modelos
En este escenario, se registran dos modelos con el área de trabajo:
my_first_model
: contiene un archivo (my_first_model.pkl
) y solo existe una versión,1
my_second_model
: contiene un archivo (my_second_model.pkl
) y hay dos versiones,1
y2
Cuando se implementó el servicio, ambos modelos se proporcionan en la operación de implementación:
first_model = Model(ws, name="my_first_model", version=1)
second_model = Model(ws, name="my_second_model", version=2)
service = Model.deploy(ws, "myservice", [first_model, second_model], inference_config, deployment_config)
En la imagen de Docker que hospeda el servicio, la variable de entorno AZUREML_MODEL_DIR
contiene el directorio donde se encuentran los modelos. En este directorio, cada uno de los modelos se encuentra en una ruta de acceso al directorio de MODEL_NAME/VERSION
. Donde MODEL_NAME
es el nombre del modelo registrado y VERSION
es la versión del modelo. Los archivos que componen el modelo registrado se almacenan en estos directorios.
En este ejemplo, las rutas de acceso serían $AZUREML_MODEL_DIR/my_first_model/1/my_first_model.pkl
y $AZUREML_MODEL_DIR/my_second_model/2/my_second_model.pkl
.
# Example when the model is a file, and the deployment contains multiple models
first_model_name = 'my_first_model'
first_model_version = '1'
first_model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), first_model_name, first_model_version, 'my_first_model.pkl')
second_model_name = 'my_second_model'
second_model_version = '2'
second_model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), second_model_name, second_model_version, 'my_second_model.pkl')
get_model_path
Cuando registra un modelo, puede proporcionar un nombre de modelo que se usa para administrar este en el registro. Usará este nombre con el método Model.get_model_path() para recuperar la ruta de acceso del archivo del modelo en el sistema de archivos local. Si registra una carpeta o una colección de archivos, esta API devolverá la ruta de acceso del directorio que contiene esos archivos.
Al registrar un modelo, se le asigna un nombre. El nombre se corresponde con la ubicación donde se coloque el modelo, ya sea localmente o durante la implementación del servicio.
Ejemplos específicos del marco
Consulte los artículos siguientes para obtener más ejemplos de scripts de entrada para casos de uso específicos de aprendizaje automático:
Contenido relacionado
- Solución de problemas de una implementación de modelo remota
- Implementación de un modelo en un clúster de Azure Kubernetes Service con v1
- Consumir un modelo de Azure Machine Learning que está implementado como un servicio web
- Actualizar un servicio web implementado (v1)
- Uso de un contenedor personalizado para implementar un modelo en un punto de conexión en línea
- Uso de TLS para proteger un servicio web con Azure Machine Learning
- Supervisión y recopilación de datos de los puntos de conexión del servicio web ML
- Recopilación de datos de modelos en producción
- Desencadenar aplicaciones, procesos o flujos de trabajo de CI/CD basados en eventos de Azure Machine Learning