Compartir a través de


Scripts de entrada avanzada

SE APLICA A:SDK de Azure Machine Learning v1 para Python

Importante

En este artículo se proporciona información sobre el uso del SDK de Azure Machine Learning v1. El SDK v1 está en desuso a partir del 31 de marzo de 2025 y la compatibilidad con él finalizará el 30 de junio de 2026. Puede instalar y usar el SDK v1 hasta esa fecha.

Se recomienda realizar la transición al SDK v2 antes del 30 de junio de 2026. Para más información sobre el SDK v2, consulte ¿Qué es el SDK de Python de Azure Machine Learning v2 y la referencia del SDK v2?

En este artículo se explica cómo escribir scripts de entrada para casos de uso especializados en Azure Machine Learning. Un script de entrada, que también se denomina script de puntuación, acepta solicitudes, usa un modelo para puntuar los datos y devuelve una respuesta.

Requisitos previos

Un modelo de aprendizaje automático entrenado que va a 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 o salida en el constructor para uno de los objetos de tipo definidos. El tipo y muestra se usan para crear automáticamente el esquema. Después, Azure Machine Learning crea una especificación openAPI (anteriormente, una especificación de Swagger) para el servicio web durante la implementación.

Advertencia

No use datos confidenciales ni privados para la entrada o salida de ejemplo. En Azure Machine Learning, la página Swagger para la inferencia expone los datos de ejemplo.

Actualmente se admiten los siguientes tipos:

  • pandas
  • numpy
  • pyspark
  • Objeto estándar de Python

Para usar la generación de esquemas, incluya la versión 1.1.0 o posterior del paquete de código abierto inference-schema en el archivo de dependencias. Para obtener más información sobre este paquete, consulte InferenceSchema en GitHub. Para generar Swagger compatible para el consumo automático de servicios web, la función run del script de puntuación debe cumplir las siguientes condiciones:

  • El primer parámetro debe tener el tipo StandardPythonParameterType, denominarse Inputs y estar anidado.
  • Debe haber un segundo parámetro opcional de tipo StandardPythonParameterType denominado GlobalParameters.
  • La función debe devolver un diccionario de tipo StandardPythonParameterType denominado Results y estar anidado.

Defina los formatos de muestra de entrada y salida de las variables sample_input y sample_output, 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. En el ejemplo scikit-learn de la sección siguiente se usa la generación de esquemas.

Punto de conexión compatible con Power BI

En el ejemplo siguiente se muestra cómo definir la run función según las instrucciones de la sección anterior. Puede usar este script al consumir el servicio web implementado desde Power BI.

import os
import json
import pickle
import numpy as np
import pandas as pd
import azureml.train.automl
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 the file name 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)


# Provide three 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)

# The following sample is a nested input sample. Any item wrapped by `ParameterType` is described by the schema.
sample_input = StandardPythonParameterType({'input1': numpy_sample_input, 
                                        'input2': pandas_sample_input, 
                                        'input3': standard_sample_input})

sample_global_parameters = StandardPythonParameterType(1.0) # This line 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) 
# The preceding line is optional. "GlobalParameters" is case sensitive.

@output_schema(outputs)

def run(Inputs, GlobalParameters): 
    # The parameters in the preceding line have to match those in the decorator. "Inputs" and 
    # "GlobalParameters" are case sensitive.
    try:
        data = Inputs['input1']
        # The data gets converted to the 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 serializable a JSON. Por ejemplo, si el modelo devuelve un dataframe 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 (imagen)

Si el modelo acepta datos binarios, como una imagen, debe modificar el archivo score.py que usa la implementación para que acepte solicitudes HTTP sin procesar. Para aceptar los datos sin procesar, use la clase AMLRequest en el script de entrada y agregue el decorador @rawhttp a la función run.

El siguiente script de score.py 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, return the URL for GET requests.
        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, load the data from the request body
        # and send it to the model. Then return the response.

        # For demonstration purposes, this example 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 en este espacio de nombres están en vista previa. Cambian con frecuencia mientras el servicio sufre mejoras. Microsoft no ofrece compatibilidad completa con estas entidades.

Si necesita probar el código que usa esta clase en el entorno de desarrollo local, puede instalar los componentes mediante el comando siguiente:

pip install azureml-contrib-services

Nota

No se recomienda usar 500 como código de estado personalizado. En el lado del enrutador de inferencia de Azure Machine Learning (azureml-fe), el código de estado se vuelve a escribir en 502.

  • El código de estado se pasa a través azureml-fe y, a continuación, se envía al cliente.
  • El azureml-fe código reescribe el 500 que el modelo devuelve como 502. El cliente recibe un código de 502.
  • Si el azureml-fe propio código devuelve 500, el lado cliente sigue recibiendo un código de 500.

Cuando usas la AMLRequest clase, solo puedes acceder a los datos publicados sin procesar en el archivo "score.py". No hay ningún componente del lado cliente. Puede publicar datos como de costumbre desde un cliente. 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

El uso compartido de recursos entre orígenes (CORS) proporciona una manera de solicitar recursos en una página web desde otro dominio. CORS funciona a través de encabezados HTTP que se envían con la solicitud de cliente y se devuelven con la respuesta del servicio. Para obtener más información sobre CORS y encabezados válidos, consulte Compartición de recursos entre orígenes.

Para configurar la implementación de modelo para que admita CORS, use la clase AMLResponse en el script de entrada. Al usar esta clase, puede 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 AMLRequest está en el espacio de nombres azureml.contrib. Las entidades en este espacio de nombres están en vista previa. Cambian con frecuencia mientras el servicio sufre mejoras. Microsoft no ofrece compatibilidad completa con estas entidades.

Si necesita probar el código que usa esta clase en el 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. Pueden producirse errores si los navegadores usan solicitudes OPTIONS para emitir solicitudes de verificación previa.

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 modelo.
  • Model.get_model_path: una 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 describen los valores posibles de AZUREML_MODEL_DIR para un número variable 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 con el formato <model-name>/<version>.

Durante el registro y la implementación del modelo, los modelos se colocan en la AZUREML_MODEL_DIR ruta y se conservan sus nombres de archivo originales.

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 está buscando.

Modelo único

En el ejemplo siguiente se muestra cómo encontrar el camino cuando tiene un modelo único.

import os

# In the following example, the model is a file.
model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_regression_model.pkl')

# In the following example, the model is a folder that contains a file.
file_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'my_model_folder', 'sklearn_regression_model.pkl')
Varios modelos

En el ejemplo siguiente se muestra cómo encontrar la ruta cuando tienes varios modelos. En este escenario, se registran dos modelos con el área de trabajo:

  • my_first_model: este modelo contiene un archivo, my_first_model.pkl y tiene una versión, 1.
  • my_second_model: este modelo contiene un archivo, my_second_model.pkl, y tiene dos versiones, 1 y 2.

Al implementar el servicio, se proporcionan ambos modelos en la operación de implementación:

from azureml.core import Workspace, Model

# Get a handle to the workspace.
ws = Workspace.from_config()

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 AZUREML_MODEL_DIR variable de entorno contiene la carpeta donde se encuentran los modelos. En esta carpeta, cada modelo se encuentra en una ruta de carpeta de <model-name>/<version>. En esta ruta de acceso, <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 estas carpetas.

En este ejemplo, la ruta de acceso del primer modelo es $AZUREML_MODEL_DIR/my_first_model/1/my_first_model.pkl. El camino del segundo modelo es $AZUREML_MODEL_DIR/my_second_model/2/my_second_model.pkl.

# In the following example, 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 el modelo en el registro. Utilice este nombre junto con el método Model.get_model_path para obtener la ruta del archivo o de los archivos del modelo en el sistema de archivos local. Si registra una carpeta o una colección de archivos, esta API devuelve la ruta de acceso de la carpeta 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

Para obtener más ejemplos de scripts de entrada para casos de uso específicos de aprendizaje automático, consulte los siguientes artículos: