Distribuire un modello da usare con Azure AI Search

SI APPLICA A:Python SDK azureml v1

Questo articolo illustra come usare Azure Machine Learning per distribuire un modello da usare con Azure AI Search.

Azure AI Search esegue operazioni di elaborazione del contenuto su contenuto eterogeneo, per renderlo disponibile per le query da parte di esseri umani o applicazioni. Questo processo può essere migliorato usando un modello distribuito da Azure Machine Learning.

Azure Machine Learning può distribuire un modello sottoposto a training come servizio Web. Il servizio Web viene quindi incorporato in una competenza di Azure AI Search che diventa parte della pipeline di elaborazione.

Importante

Le informazioni contenute in questo articolo sono specifiche per la distribuzione del modello. Sono fornite informazioni sulle configurazioni di distribuzione supportate che consentono l'uso del modello da parte di Azure AI Search.

Per informazioni su come configurare Azure AI Search per l'uso del modello distribuito, vedere l'esercitazione Creare e distribuire una competenza personalizzata con Azure Machine Learning.

Quando si distribuisce un modello per l'uso con Azure AI Search, la distribuzione deve soddisfare i requisiti seguenti:

  • Usare il servizio Azure Kubernetes per ospitare il modello per l'inferenza.
  • Abilitare TLS (Transport Layer Security) per il servizio Azure Kubernetes. TLS si usa per proteggere le comunicazioni HTTPS tra Azure AI Search e il modello distribuito.
  • Lo script di immissione deve usare il pacchetto inference_schema per generare uno schema OpenAPI (Swagger) per il servizio.
  • Lo script di immissione deve anche accettare dati JSON come input e generare JSON come output.

Prerequisiti

Connettersi all'area di lavoro

Un'area di lavoro di Azure Machine Learning fornisce una posizione centralizzata per lavorare con tutti gli artefatti creati durante l'uso di Azure Machine Learning. L'area di lavoro mantiene una cronologia di tutti i processi di training che include i log, le metriche, gli output e uno snapshot degli script.

Per connettersi a un'area di lavoro esistente, usare il codice seguente:

Importante

Questo frammento di codice prevede che la configurazione dell'area di lavoro sia salvata nella directory corrente o nella relativa directory padre. Per altre informazioni, vedere Creare e gestire aree di lavoro di Azure Machine Learning. Per altre informazioni sul salvataggio della configurazione in un file, vedere Creare un file di configurazione dell'area di lavoro.

from azureml.core import Workspace

try:
    # Load the workspace configuration from local cached inffo
    ws = Workspace.from_config()
    print(ws.name, ws.location, ws.resource_group, ws.location, sep='\t')
    print('Library configuration succeeded')
except:
    print('Workspace not found')

Creare un cluster Kubernetes

Tempo stimato: circa 20 minuti.

Un cluster Kubernetes è un set di istanze di macchine virtuali (denominate nodi) usate per l'esecuzione di applicazioni in contenitori.

Quando si distribuisce un modello da Azure Machine Learning al servizio Azure Kubernetes, il modello e tutte le risorse necessarie per ospitarlo come servizio Web vengono inseriti in un contenitore Docker. Questo contenitore viene quindi distribuito nel cluster.

Il codice seguente illustra come creare un nuovo cluster del servizio Azure Kubernetes per l'area di lavoro:

Suggerimento

È anche possibile collegare un servizio Azure Kubernetes esistente all'area di lavoro di Azure Machine Learning. Per altre informazioni, vedere Come distribuire modelli nel servizio Azure Kubernetes.

Importante

Si noti che il codice usa il metodo enable_ssl() per abilitare TLS per il cluster. Questo è necessario quando si prevede di usare il modello distribuito da Azure AI Search.

from azureml.core.compute import AksCompute, ComputeTarget
# Create or attach to an AKS inferencing cluster

# Create the provisioning configuration with defaults
prov_config = AksCompute.provisioning_configuration()

# Enable TLS (sometimes called SSL) communications
# Leaf domain label generates a name using the formula
#  "<leaf-domain-label>######.<azure-region>.cloudapp.azure.com"
#  where "######" is a random series of characters
prov_config.enable_ssl(leaf_domain_label = "contoso")

cluster_name = 'amlskills'
# Try to use an existing compute target by that name.
# If one doesn't exist, create one.
try:
    
    aks_target = ComputeTarget(ws, cluster_name)
    print("Attaching to existing cluster")
except Exception as e:
    print("Creating new cluster")
    aks_target = ComputeTarget.create(workspace = ws, 
                                  name = cluster_name, 
                                  provisioning_configuration = prov_config)
    # Wait for the create process to complete
    aks_target.wait_for_completion(show_output = True)

Importante

L'utente riceverà fatture di Azure finché esiste il cluster del servizio Azure Kubernetes. Assicurarsi di eliminare il cluster del servizio Azure Kubernetes quando non serve più.

Per altre informazioni sull'uso del servizio Azure Kubernetes con Azure Machine Learning, vedere Come eseguire la distribuzione nel servizio Azure Kubernetes.

Scrivere lo script di immissione

Lo script di immissione riceve i dati inviati al servizio Web, li passa al modello e restituisce i risultati dell'assegnazione del punteggio. Lo script seguente carica il modello all'avvio e quindi usa il modello per assegnare un punteggio ai dati. Questo file è a volte denominato score.py.

Suggerimento

Lo script di avvio è specifico del modello. Ad esempio, lo script deve conoscere il framework da usare con il modello, i formati di dati e così via.

Importante

Quando si prevede di usare il modello distribuito da Azure AI Search, è necessario usare il pacchetto inference_schema per abilitare la generazione dello schema per la distribuzione. Questo pacchetto fornisce elementi Decorator che consentono di definire il formato di dati di input e output per il servizio Web che esegue l'inferenza usando il modello.

from azureml.core.model import Model
from nlp_architect.models.absa.inference.inference import SentimentInference
from spacy.cli.download import download as spacy_download
import traceback
import json
# Inference schema for schema discovery
from inference_schema.schema_decorators import input_schema, output_schema
from inference_schema.parameter_types.numpy_parameter_type import NumpyParameterType
from inference_schema.parameter_types.standard_py_parameter_type import StandardPythonParameterType

def init():
    """
    Set up the ABSA model for Inference  
    """
    global SentInference
    spacy_download('en')
    aspect_lex = Model.get_model_path('hotel_aspect_lex')
    opinion_lex = Model.get_model_path('hotel_opinion_lex') 
    SentInference = SentimentInference(aspect_lex, opinion_lex)

# Use inference schema decorators and sample input/output to
# build the OpenAPI (Swagger) schema for the deployment
standard_sample_input = {'text': 'a sample input record containing some text' }
standard_sample_output = {"sentiment": {"sentence": "This place makes false booking prices, when you get there, they say they do not have the reservation for that day.", 
                                        "terms": [{"text": "hotels", "type": "AS", "polarity": "POS", "score": 1.0, "start": 300, "len": 6}, 
                                                  {"text": "nice", "type": "OP", "polarity": "POS", "score": 1.0, "start": 295, "len": 4}]}}
@input_schema('raw_data', StandardPythonParameterType(standard_sample_input))
@output_schema(StandardPythonParameterType(standard_sample_output))    
def run(raw_data):
    try:
        # Get the value of the 'text' field from the JSON input and perform inference
        input_txt = raw_data["text"]
        doc = SentInference.run(doc=input_txt)
        if doc is None:
            return None
        sentences = doc._sentences
        result = {"sentence": doc._doc_text}
        terms = []
        for sentence in sentences:
            for event in sentence._events:
                for x in event:
                    term = {"text": x._text, "type":x._type.value, "polarity": x._polarity.value, "score": x._score,"start": x._start,"len": x._len }
                    terms.append(term)
        result["terms"] = terms
        print("Success!")
        # Return the results to the client as a JSON document
        return {"sentiment": result}
    except Exception as e:
        result = str(e)
        # return error message back to the client
        print("Failure!")
        print(traceback.format_exc())
        return json.dumps({"error": result, "tb": traceback.format_exc()})

Per altre informazioni sugli script di immissione, vedere Come e dove eseguire la distribuzione.

Definire l'ambiente software

Per definire le dipendenze di Python per il servizio viene usata la classe Environment. Include le dipendenze richieste sia dal modello, sia dallo script di immissione. In questo esempio installa i pacchetti dal normale indice pypi, nonché da un repository GitHub.

from azureml.core.conda_dependencies import CondaDependencies 
from azureml.core import Environment

conda = None
pip = ["azureml-defaults", "azureml-monitoring", 
       "git+https://github.com/NervanaSystems/nlp-architect.git@absa", 'nlp-architect', 'inference-schema',
       "spacy==2.0.18"]

conda_deps = CondaDependencies.create(conda_packages=None, pip_packages=pip)

myenv = Environment(name='myenv')
myenv.python.conda_dependencies = conda_deps

Per altre informazioni sugli ambienti, vedere Creare e gestire ambienti per il training e la distribuzione.

Definire la configurazione della distribuzione

La configurazione della distribuzione definisce l'ambiente di hosting del servizio Azure Kubernetes usato per eseguire il servizio Web.

Suggerimento

In caso di dubbi sulle esigenze di memoria, CPU o GPU della distribuzione, è possibile usare la profilatura per scoprirle. Per altre informazioni, vedere Come e dove distribuire un modello.

from azureml.core.model import Model
from azureml.core.webservice import Webservice
from azureml.core.image import ContainerImage
from azureml.core.webservice import AksWebservice, Webservice

# If deploying to a cluster configured for dev/test, ensure that it was created with enough
# cores and memory to handle this deployment configuration. Note that memory is also used by
# things such as dependencies and Azure Machine Learning components.

aks_config = AksWebservice.deploy_configuration(autoscale_enabled=True, 
                                                       autoscale_min_replicas=1, 
                                                       autoscale_max_replicas=3, 
                                                       autoscale_refresh_seconds=10, 
                                                       autoscale_target_utilization=70,
                                                       auth_enabled=True, 
                                                       cpu_cores=1, memory_gb=2, 
                                                       scoring_timeout_ms=5000, 
                                                       replica_max_concurrent_requests=2, 
                                                       max_request_wait_time=5000)

Per altre informazioni, vedere la documentazione di riferimento per AksService.deploy_configuration.

Definire la configurazione dell'inferenza

La configurazione dell'inferenza punta allo script di immissione e all'oggetto ambiente:

from azureml.core.model import InferenceConfig
inf_config = InferenceConfig(entry_script='score.py', environment=myenv)

Per altre informazioni, vedere la documentazione di riferimento per InferenceConfig.

Distribuire il modello

Distribuire il modello nel cluster del servizio Azure Kubernetes e attendere che crei il servizio. In questo esempio, due modelli registrati vengono caricati dal registro e distribuiti nel servizio Azure Kubernetes. Dopo la distribuzione, il file score.py nella distribuzione carica questi modelli e li usa per eseguire l'inferenza.

from azureml.core.webservice import AksWebservice, Webservice

c_aspect_lex = Model(ws, 'hotel_aspect_lex')
c_opinion_lex = Model(ws, 'hotel_opinion_lex') 
service_name = "hotel-absa-v2"

aks_service = Model.deploy(workspace=ws,
                           name=service_name,
                           models=[c_aspect_lex, c_opinion_lex],
                           inference_config=inf_config,
                           deployment_config=aks_config,
                           deployment_target=aks_target,
                           overwrite=True)

aks_service.wait_for_deployment(show_output = True)
print(aks_service.state)

Per altre informazioni, vedere la documentazione di riferimento per Model.

Eseguire una query di esempio per il servizio

L'esempio seguente usa le informazioni di distribuzione archiviate nella variabile aks_service dalla sezione di codice precedente. La variabile viene usata per recuperare l'URL di assegnazione del punteggio e il token di autenticazione necessari per comunicare con il servizio:

import requests
import json

primary, secondary = aks_service.get_keys()

# Test data
input_data = '{"raw_data": {"text": "This is a nice place for a relaxing evening out with friends. The owners seem pretty nice, too. I have been there a few times including last night. Recommend."}}'

# Since authentication was enabled for the deployment, set the authorization header.
headers = {'Content-Type':'application/json',  'Authorization':('Bearer '+ primary)} 

# Send the request and display the results
resp = requests.post(aks_service.scoring_uri, input_data, headers=headers)
print(resp.text)

Il risultato restituito dal servizio è simile al codice JSON seguente:

{"sentiment": {"sentence": "This is a nice place for a relaxing evening out with friends. The owners seem pretty nice, too. I have been there a few times including last night. Recommend.", "terms": [{"text": "place", "type": "AS", "polarity": "POS", "score": 1.0, "start": 15, "len": 5}, {"text": "nice", "type": "OP", "polarity": "POS", "score": 1.0, "start": 10, "len": 4}]}}

Per informazioni su come usare questo modello da Azure AI Search, vedere l'esercitazione Creare e distribuire una competenza personalizzata con Azure Machine Learning.

Pulire le risorse

Se il cluster del servizio Azure Kubernetes è stato creato in modo specifico per questo esempio, eliminare le risorse dopo aver completato i test con Azure AI Search.

Importante

La fatturazione di Azure si basa sulla durata della distribuzione del cluster del servizio Azure Kubernetes. Assicurarsi di pulirlo al termine dell'utilizzo.

aks_service.delete()
aks_target.delete()

Passaggi successivi