Consumir um modelo de Azure Machine Learning implantado como um serviço webConsume an Azure Machine Learning model deployed as a web service

A implantação de um modelo do Azure Machine Learning como um serviço da Web cria uma API REST.Deploying an Azure Machine Learning model as a web service creates a REST API. Você pode enviar dados para essa API e receber a previsão retornada pelo modelo.You can send data to this API and receive the prediction returned by the model. Neste documento, saiba como criar clientes para o serviço da Web usando C#, Go, Java e Python.In this document, learn how to create clients for the web service by using C#, Go, Java, and Python.

Você cria um serviço web ao implantar uma imagem em Instâncias de Contêiner do Azure, Serviço de Kubernetes do Azure ou o Project Brainwave (matrizes de portas programáveis em campo).You create a web service when you deploy an image to Azure Container Instances, Azure Kubernetes Service, or Project Brainwave (field programmable gate arrays). Você cria imagens de modelos registrados e arquivos de pontuação.You create images from registered models and scoring files. Você recuperar o URI usado para acessar um serviço web usando o SDK do Azure Machine Learning.You retrieve the URI used to access a web service by using the Azure Machine Learning SDK. Se a autenticação estiver ativada, você também poderá usar o SDK para obter as chaves de autenticação.If authentication is enabled, you can also use the SDK to get the authentication keys.

O fluxo de trabalho geral para a criação de um cliente que usa um serviço web machine learning é:The general workflow for creating a client that uses a machine learning web service is:

  1. Use o SDK para obter as informações de conexão.Use the SDK to get the connection information.
  2. Determinar o tipo de dados de solicitação usados pelo modelo.Determine the type of request data used by the model.
  3. Crie um aplicativo que chame o serviço da web.Create an application that calls the web service.

informações de conexãoConnection information

Observação

Use o SDK do Azure Machine Learning para obter as informações do serviço Web.Use the Azure Machine Learning SDK to get the web service information. Esse é um SDK de Python.This is a Python SDK. Você pode usar qualquer linguagem para criar um cliente para o serviço.You can use any language to create a client for the service.

A classe azureml.core.Webservice fornece as informações necessárias para criar um cliente.The azureml.core.Webservice class provides the information you need to create a client. As seguintes propriedades Webservice que são úteis para criar um aplicativo cliente:The following Webservice properties are useful for creating a client application:

  • auth_enabled - Se a autenticação estiver ativada, True; caso contrário, False.auth_enabled - If authentication is enabled, True; otherwise, False.
  • scoring_uri -O endereço da API REST.scoring_uri - The REST API address.

Existem três maneiras de recuperar essas informações para serviços da Web implementados:There are a three ways to retrieve this information for deployed web services:

  • Quando você implanta um modelo, um objeto Webservice é retornado com informações sobre o serviço:When you deploy a model, a Webservice object is returned with information about the service:

    service = Webservice.deploy_from_model(name='myservice',
                                           deployment_config=myconfig,
                                           models=[model],
                                           image_config=image_config,
                                           workspace=ws)
    print(service.scoring_uri)
    
  • Você pode usar Webservice.list para recuperar uma lista de serviços da Web implementados para modelos em sua área de trabalho.You can use Webservice.list to retrieve a list of deployed web services for models in your workspace. Você pode adicionar filtros para restringir a lista de informações retornadas.You can add filters to narrow the list of information returned. Para obter mais informações sobre o que pode ser filtrado, consulte a documentação de referência do Webservice.list.For more information about what can be filtered on, see the Webservice.list reference documentation.

    services = Webservice.list(ws)
    print(services[0].scoring_uri)
    
  • Se você souber o nome do serviço implantado, você pode criar uma nova instância de Webservice e fornecer o nome do espaço de trabalho e o serviço como parâmetros.If you know the name of the deployed service, you can create a new instance of Webservice, and provide the workspace and service name as parameters. O novo objeto contém informações sobre o serviço implantado.The new object contains information about the deployed service.

    service = Webservice(workspace=ws, name='myservice')
    print(service.scoring_uri)
    

Chave de autenticaçãoAuthentication key

Ao habilitar a autenticação para uma implantação, você cria automaticamente as chaves de autenticação.When you enable authentication for a deployment, you automatically create authentication keys.

  • A autenticação é ativada por padrão ao implantar no Serviço de Kubernetes do Azure.Authentication is enabled by default when you are deploying to Azure Kubernetes Service.
  • A autenticação é desabilitada por padrão durante a implantação nas Instâncias de Contêiner do Azure.Authentication is disabled by default when you are deploying to Azure Container Instances.

Para controlar a autenticação, use o parâmetro auth_enabled ao criar ou atualizar uma implantação.To control authentication, use the auth_enabled parameter when you are creating or updating a deployment.

Se a autenticação estiver ativada, você poderá usar o método get_keys para recuperar uma chave de autenticação primária e secundária:If authentication is enabled, you can use the get_keys method to retrieve a primary and secondary authentication key:

primary, secondary = service.get_keys()
print(primary)

Importante

Se você precisar regenerar uma chave, use service.regen_key.If you need to regenerate a key, use service.regen_key.

Dados de solicitaçãoRequest data

A API REST espera que o corpo da solicitação seja um documento JSON com a seguinte estrutura:The REST API expects the body of the request to be a JSON document with the following structure:

{
    "data":
        [
            <model-specific-data-structure>
        ]
}

Importante

A estrutura dos dados precisa corresponder ao esperado pelo script e modelo de pontuação no serviço.The structure of the data needs to match what the scoring script and model in the service expect. O script de pontuação pode modificar os dados antes de transmiti-lo ao modelo.The scoring script might modify the data before passing it to the model.

Por exemplo, o modelo na Train dentro do bloco de anotações exemplo espera uma matriz de números de 10.For example, the model in the Train within notebook example expects an array of 10 numbers. O script de pontuação deste exemplo cria uma matriz Numpy da solicitação e a transmite para o modelo.The scoring script for this example creates a Numpy array from the request, and passes it to the model. O exemplo a seguir mostra os dados espera que esse serviço:The following example shows the data this service expects:

{
    "data": 
        [
            [
                0.0199132141783263, 
                0.0506801187398187, 
                0.104808689473925, 
                0.0700725447072635, 
                -0.0359677812752396, 
                -0.0266789028311707, 
                -0.0249926566315915, 
                -0.00259226199818282, 
                0.00371173823343597, 
                0.0403433716478807
            ]
        ]
}

O serviço da web pode aceitar vários conjuntos de dados em uma solicitação.The web service can accept multiple sets of data in one request. Ele retorna um documento JSON contendo uma matriz de respostas.It returns a JSON document containing an array of responses.

Dados bináriosBinary data

Se o modelo aceita dados binários, como uma imagem, modifique o arquivo score.py usado para a implantação para aceitar solicitações HTTP brutas.If your model accepts binary data, such as an image, you must modify the score.py file used for your deployment to accept raw HTTP requests. Aqui está um exemplo de um score.py que aceita dados binários:Here's an example of a score.py that accepts binary data:

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 GETs
        respBody = str.encode(request.full_path)
        return AMLResponse(respBody, 200)
    elif request.method == 'POST':
        reqBody = request.get_data(False)
        # For a real world solution, you would load the data from reqBody 
        # and send to the model. Then return the response.
        
        # For demonstration purposes, this example just returns the posted data as the response.
        return AMLResponse(reqBody, 200)
    else:
        return AMLResponse("bad request", 500)

Importante

O namespace azureml.contrib muda com frequência enquanto trabalhamos para melhorar o serviço.The azureml.contrib namespace changes frequently, as we work to improve the service. Assim, tudo nesse namespace deve ser considerado como uma versão prévia e sem o suporte total da Microsoft.As such, anything in this namespace should be considered as a preview, and not fully supported by Microsoft.

Se você precisar testar isso em seu ambiente de desenvolvimento local, instale os componentes no namespace contrib usando o seguinte comando:If you need to test this on your local development environment, you can install the components in the contrib namespace by using the following command:

pip install azureml-contrib-services

Chamar o serviço (C#)Call the service (C#)

Este exemplo demonstra como usar o C # para chamar o serviço da Web criado a partir do exemplo Treinar no caderno:This example demonstrates how to use C# to call the web service created from the Train within notebook example:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;

namespace MLWebServiceClient
{
    // The data structure expected by the service
    internal class InputData
    {
        [JsonProperty("data")]
        // The service used by this example expects an array containing
        //   one or more arrays of doubles
        internal double[,] data;
    }
    class Program
    {
        static void Main(string[] args)
        {
            // Set the scoring URI and authentication key
            string scoringUri = "<your web service URI>";
            string authKey = "<your key>";

            // Set the data to be sent to the service.
            // In this case, we are sending two sets of data to be scored.
            InputData payload = new InputData();
            payload.data = new double[,] {
                {
                    0.0199132141783263,
                    0.0506801187398187,
                    0.104808689473925,
                    0.0700725447072635,
                    -0.0359677812752396,
                    -0.0266789028311707,
                    -0.0249926566315915,
                    -0.00259226199818282,
                    0.00371173823343597,
                    0.0403433716478807
                },
                {
                    -0.0127796318808497, 
                    -0.044641636506989, 
                    0.0606183944448076, 
                    0.0528581912385822, 
                    0.0479653430750293, 
                    0.0293746718291555, 
                    -0.0176293810234174, 
                    0.0343088588777263, 
                    0.0702112981933102, 
                    0.00720651632920303
                }
            };

            // Create the HTTP client
            HttpClient client = new HttpClient();
            // Set the auth header. Only needed if the web service requires authentication.
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authKey);

            // Make the request
            try {
                var request = new HttpRequestMessage(HttpMethod.Post, new Uri(scoringUri));
                request.Content = new StringContent(JsonConvert.SerializeObject(payload));
                request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                var response = client.SendAsync(request).Result;
                // Display the response from the web service
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            catch (Exception e)
            {
                Console.Out.WriteLine(e.Message);
            }
        }
    }
}

Os resultados retornados são semelhantes ao seguinte documento JSON:The results returned are similar to the following JSON document:

[217.67978776218715, 224.78937091757172]

Chamar o serviço (Ir)Call the service (Go)

Este exemplo demonstra como usar o recurso Go para chamar o serviço da Web criado a partir do exemplo Train dentro do notebook:This example demonstrates how to use Go to call the web service created from the Train within notebook example:

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

// Features for this model are an array of decimal values
type Features []float64

// The web service input can accept multiple sets of values for scoring
type InputData struct {
    Data []Features `json:"data",omitempty`
}

// Define some example data
var exampleData = []Features{
    []float64{
        0.0199132141783263, 
        0.0506801187398187, 
        0.104808689473925, 
        0.0700725447072635, 
        -0.0359677812752396, 
        -0.0266789028311707, 
        -0.0249926566315915, 
        -0.00259226199818282, 
        0.00371173823343597, 
        0.0403433716478807,
    },
    []float64{
        -0.0127796318808497, 
        -0.044641636506989, 
        0.0606183944448076, 
        0.0528581912385822, 
        0.0479653430750293, 
        0.0293746718291555, 
        -0.0176293810234174, 
        0.0343088588777263, 
        0.0702112981933102, 
        0.00720651632920303,
    },
}

// Set to the URI for your service
var serviceUri string = "<your web service URI>"
// Set to the authentication key (if any) for your service
var authKey string = "<your key>"

func main() {
    // Create the input data from example data
    jsonData := InputData{
        Data: exampleData,
    }
    // Create JSON from it and create the body for the HTTP request
    jsonValue, _ := json.Marshal(jsonData)
    body := bytes.NewBuffer(jsonValue)

    // Create the HTTP request
    client := &http.Client{}
    request, err := http.NewRequest("POST", serviceUri, body)
    request.Header.Add("Content-Type", "application/json")

    // These next two are only needed if using an authentication key
    bearer := fmt.Sprintf("Bearer %v", authKey)
    request.Header.Add("Authorization", bearer)

    // Send the request to the web service
    resp, err := client.Do(request)
    if err != nil {
        fmt.Println("Failure: ", err)
    }

    // Display the response received
    respBody, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(respBody))
}

Os resultados retornados são semelhantes ao seguinte documento JSON:The results returned are similar to the following JSON document:

[217.67978776218715, 224.78937091757172]

Ligue para o serviço (Java)Call the service (Java)

Este exemplo demonstra como usar o Java para chamar o serviço da Web criado a partir do exemplo Trainar no notebook:This example demonstrates how to use Java to call the web service created from the Train within notebook example:

import java.io.IOException;
import org.apache.http.client.fluent.*;
import org.apache.http.entity.ContentType;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

public class App {
    // Handle making the request
    public static void sendRequest(String data) {
        // Replace with the scoring_uri of your service
        String uri = "<your web service URI>";
        // If using authentication, replace with the auth key
        String key = "<your key>";
        try {
            // Create the request
            Content content = Request.Post(uri)
            .addHeader("Content-Type", "application/json")
            // Only needed if using authentication
            .addHeader("Authorization", "Bearer " + key)
            // Set the JSON data as the body
            .bodyString(data, ContentType.APPLICATION_JSON)
            // Make the request and display the response.
            .execute().returnContent();
            System.out.println(content);
        }
        catch (IOException e) {
            System.out.println(e);
        }
    }
    public static void main(String[] args) {
        // Create the data to send to the service
        JSONObject obj = new JSONObject();
        // In this case, it's an array of arrays
        JSONArray dataItems = new JSONArray();
        // Inner array has 10 elements
        JSONArray item1 = new JSONArray();
        item1.add(0.0199132141783263);
        item1.add(0.0506801187398187);
        item1.add(0.104808689473925);
        item1.add(0.0700725447072635);
        item1.add(-0.0359677812752396);
        item1.add(-0.0266789028311707);
        item1.add(-0.0249926566315915);
        item1.add(-0.00259226199818282);
        item1.add(0.00371173823343597);
        item1.add(0.0403433716478807);
        // Add the first set of data to be scored
        dataItems.add(item1);
        // Create and add the second set
        JSONArray item2 = new JSONArray();
        item2.add(-0.0127796318808497);
        item2.add(-0.044641636506989);
        item2.add(0.0606183944448076);
        item2.add(0.0528581912385822);
        item2.add(0.0479653430750293);
        item2.add(0.0293746718291555);
        item2.add(-0.0176293810234174);
        item2.add(0.0343088588777263);
        item2.add(0.0702112981933102);
        item2.add(0.00720651632920303);
        dataItems.add(item2);
        obj.put("data", dataItems);

        // Make the request using the JSON document string
        sendRequest(obj.toJSONString());
    }
}

Os resultados retornados são semelhantes ao seguinte documento JSON:The results returned are similar to the following JSON document:

[217.67978776218715, 224.78937091757172]

Chamar o serviço (Python)Call the service (Python)

Este exemplo demonstra como usar o Python para chamar o serviço da Web criado a partir do exemplo Traino no notebook:This example demonstrates how to use Python to call the web service created from the Train within notebook example:

import requests
import json

# URL for the web service
scoring_uri = '<your web service URI>'
# If the service is authenticated, set the key
key = '<your key>'

# Two sets of data to score, so we get two results back
data = {"data": 
            [
                [
                    0.0199132141783263, 
                    0.0506801187398187, 
                    0.104808689473925, 
                    0.0700725447072635, 
                    -0.0359677812752396, 
                    -0.0266789028311707, 
                    -0.0249926566315915, 
                    -0.00259226199818282, 
                    0.00371173823343597, 
                    0.0403433716478807
                ],
                [
                    -0.0127796318808497, 
                    -0.044641636506989, 
                    0.0606183944448076, 
                    0.0528581912385822, 
                    0.0479653430750293, 
                    0.0293746718291555, 
                    -0.0176293810234174, 
                    0.0343088588777263, 
                    0.0702112981933102, 
                    0.00720651632920303]
            ]
        }
# Convert to JSON string
input_data = json.dumps(data)

# Set the content type
headers = { 'Content-Type':'application/json' }
# If authentication is enabled, set the authorization header
headers['Authorization']=f'Bearer {key}'

# Make the request and display the response
resp = requests.post(scoring_uri, input_data, headers = headers)
print(resp.text)

Os resultados retornados são semelhantes ao seguinte documento JSON:The results returned are similar to the following JSON document:

[217.67978776218715, 224.78937091757172]