Speciális bejegyzésszkript létrehozása

ÉRVÉNYES:Python SDK azureml v1

Ez a cikk bemutatja, hogyan írhat bejegyzésszkripteket speciális használati esetekhez.

Előfeltételek

Ez a cikk feltételezi, hogy már rendelkezik egy betanított gépi tanulási modellel, amelyet az Azure Machine Tanulás kíván üzembe helyezni. A modell üzembe helyezésével kapcsolatos további információkért lásd : Gépi tanulási modellek üzembe helyezése az Azure-ban.

Swagger-séma automatikus létrehozása

Ha automatikusan létre szeretne hozni egy sémát a webszolgáltatáshoz, adjon meg egy mintát a konstruktorban az egyik megadott típusú objektum bemenetéről és/vagy kimenetéről. A rendszer a séma automatikus létrehozásához használja a típust és a mintát. Az Azure Machine Tanulás ezután létrehoz egy OpenAPI-specifikációt (korábbi nevén Swagger-specifikációt) a webszolgáltatáshoz az üzembe helyezés során.

Figyelmeztetés

Nem használhat bizalmas vagy privát adatokat a mintabemenethez vagy a kimenethez. Az AML által üzemeltetett következtetés Swagger oldala elérhetővé teszi a mintaadatokat.

Jelenleg az alábbi típusok támogatottak:

  • pandas
  • numpy
  • pyspark
  • Standard Python-objektum

A sémalétrehozás használatához adja meg a nyílt forráskódú inference-schema csomag 1.1.0-s vagy újabb verzióját a függőségi fájlban. További információ a csomagról: InferenceSchema a GitHubon. Ahhoz, hogy megfelelő Swaggert hozzon létre az automatizált webszolgáltatás-használathoz, a pontozó szkriptfuttatási() függvény api-alakjának a következőnek kell lennie:

  • Egy bemeneti és beágyazott típusú StandardPythonParameterType első paraméter
  • A GlobalParameters nevű választható második paraméter StandardPythonParameterType
  • Eredmény és beágyazott típusú StandardPythonParameterTypeszótár visszaadása

Adja meg a bemeneti és kimeneti mintaformátumokat a input_sampleoutput_sample webszolgáltatás kérés- és válaszformátumait képviselő változókban. Használja ezeket a mintákat a függvény bemeneti és kimeneti függvényének dekorátoraiban run() . Az alábbi scikit-learn példa sémagenerálást használ.

Power BI-kompatibilis végpont

Az alábbi példa bemutatja, hogyan definiálhat API-alakzatokat az előző utasításoknak megfelelően. Ez a módszer az üzembe helyezett webszolgáltatás Power BI-ból való használatához támogatott.

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

Tipp.

A szkript visszatérési értéke bármely Olyan Python-objektum lehet, amely JSON-ra szerializálható. Ha például a modell egy több oszlopot tartalmazó Pandas-adatkeretet ad vissza, az alábbi kódhoz hasonló kimeneti dekorátort használhat:

output_sample = pd.DataFrame(data=[{"a1": 5, "a2": 6}])
@output_schema(PandasParameterType(output_sample))
...
result = model.predict(data)
return result

Bináris (azaz kép) adatok

Ha a modell bináris adatokat fogad el, például egy képet, módosítania kell az üzembe helyezéshez használt score.py fájlt, hogy nyers HTTP-kéréseket fogadjon el. Nyers adatok elfogadásához használja a AMLRequest bejegyzésszkript osztályát, és adja hozzá a @rawhttp dekorátort a run() függvényhez.

Íme egy példa egy score.py bináris adatokat elfogadó példára:

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)

Fontos

Az AMLRequest osztály a azureml.contrib névtérben van. A névtér entitásai gyakran változnak a szolgáltatás fejlesztése során. Ebben a névtérben minden olyan előzetes verziónak kell tekinteni, amelyet a Microsoft nem támogat teljes mértékben.

Ha ezt a helyi fejlesztési környezetben kell tesztelnie, az összetevőket az alábbi paranccsal telepítheti:

pip install azureml-contrib-services

Feljegyzés

Az 500 nem ajánlott egyéni állapotkódként, mivel az azureml-fe oldalon az állapotkód át lesz írva az 502-re.

  • Az állapotkódot a rendszer az azureml-fe fájlon keresztül továbbítja, majd elküldi az ügyfélnek.
  • Az azureml-fe csak a modell oldaláról visszaadott 500-ast írja át 502-re, az ügyfél 502-et kap.
  • Ha azonban az azureml-fe maga 500-as értéket ad vissza, az ügyféloldal továbbra is 500-as értéket kap.

Az AMLRequest osztály csak a score.py fájlban lévő nyers közzétett adatok elérését teszi lehetővé, nincs ügyféloldali összetevő. Egy ügyféltől a szokásos módon tehet közzé adatokat. A következő Python-kód például beolvassa a képfájlt, és közzéteszi az adatokat:

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)

Eltérő eredetű erőforrások megosztása (CORS)

A forrásközi erőforrásmegosztás lehetővé teszi, hogy egy weblap erőforrásait egy másik tartományból kérhesse. A CORS az ügyfélkéréssel küldött ÉS a szolgáltatás válaszával visszaadott HTTP-fejléceken keresztül működik. További információ a CORS-ról és az érvényes fejlécekről: Forrásközi erőforrásmegosztás a Wikipédiában.

Ha úgy szeretné konfigurálni a modell üzembe helyezését, hogy támogassa a CORS-t, használja az osztályt a AMLResponse bejegyzésszkriptben. Ez az osztály lehetővé teszi a fejlécek beállítását a válaszobjektumon.

Az alábbi példa a Access-Control-Allow-Origin bejegyzésszkript válaszának fejlécét állítja be:

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)

Fontos

Az AMLResponse osztály a azureml.contrib névtérben van. A névtér entitásai gyakran változnak a szolgáltatás fejlesztése során. Ebben a névtérben minden olyan előzetes verziónak kell tekinteni, amelyet a Microsoft nem támogat teljes mértékben.

Ha ezt a helyi fejlesztési környezetben kell tesztelnie, az összetevőket az alábbi paranccsal telepítheti:

pip install azureml-contrib-services

Figyelmeztetés

Az Azure Machine Tanulás csak a POST és GET kéréseket irányítja a pontozási szolgáltatást futtató tárolókhoz. Ez hibákat okozhat a böngészők által a CORS-kérések előtti BEÁLLÍTÁSOK kéréseket használó böngészők miatt.

Regisztrált modellek betöltése

Kétféleképpen kereshet modelleket az indítási szkriptben:

  • AZUREML_MODEL_DIR: A modell helyének elérési útját tartalmazó környezeti változó
  • Model.get_model_path: Egy API, amely a regisztrált modellnév használatával adja vissza a modellfájl elérési útját

AZUREML_MODEL_DIR

AZUREML_MODEL_DIR a szolgáltatás üzembe helyezése során létrehozott környezeti változó. Ezzel a környezeti változóval megkeresheti az üzembe helyezett modell(ek) helyét.

Az alábbi táblázat az üzembe helyezett modellek számától függően írja le az értékeket AZUREML_MODEL_DIR :

Telepítés Környezeti változó értéke
Egyetlen modell A modellt tartalmazó mappa elérési útja.
Több modell Az összes modellt tartalmazó mappa elérési útja. A modellek név és verzió szerint találhatók ebben a mappában ($MODEL_NAME/$VERSION)

A modellregisztráció és az üzembe helyezés során a modellek a AZUREML_MODEL_DIR elérési útba kerülnek, és az eredeti fájlnevek megmaradnak.

Ha be szeretné szerezni egy modellfájl elérési útját a beviteli szkriptben, kombinálja a környezeti változót a keresett fájl elérési útjával.

Példa egymodellre

# 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')

Több modellre példa

Ebben a forgatókönyvben két modell van regisztrálva a munkaterületen:

  • my_first_model: Egy fájlt (my_first_model.pkl) tartalmaz, és csak egy verzió van, 1
  • my_second_model: Egy fájlt (my_second_model.pkl) tartalmaz, és két verziót tartalmaz, 1 és 2

A szolgáltatás üzembe helyezésekor mindkét modell elérhető az üzembe helyezési műveletben:

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)

A szolgáltatást üzemeltető Docker-lemezképen a AZUREML_MODEL_DIR környezeti változó tartalmazza azt a könyvtárat, amelyben a modellek találhatók. Ebben a könyvtárban minden modell a könyvtár elérési útján MODEL_NAME/VERSIONtalálható. Hol MODEL_NAME található a regisztrált modell neve, és VERSION hol található a modell verziója. A regisztrált modellt alkotó fájlok ezekben a könyvtárakban vannak tárolva.

Ebben a példában az elérési utak $AZUREML_MODEL_DIR/my_first_model/1/my_first_model.pkl az és $AZUREML_MODEL_DIR/my_second_model/2/my_second_model.pkla .

# 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

A modell regisztrálásakor a modellnek a regisztrációs adatbázisban való kezelésére használt modellnevet ad meg. Ezt a nevet használhatja a Model.get_model_path() metódussal a helyi fájlrendszeren található modellfájl- vagy -fájlok elérési útjának lekérésére. Ha egy mappát vagy fájlgyűjteményt regisztrál, ez az API a fájlokat tartalmazó könyvtár elérési útját adja vissza.

Amikor regisztrál egy modellt, nevet ad neki. A név megfelel a modell elhelyezésének, helyileg vagy a szolgáltatás üzembe helyezése során.

Keretrendszerspecifikus példák

Az alábbi cikkekben további bejegyzésszkript-példákat talál adott gépi tanulási használati esetekre: