Menggunakan model Azure Machine Learning yang disebarkan sebagai layanan web

Menyebarkan model Azure Machine Learning sebagai layanan web membuat titik akhir REST API. Anda dapat mengirim data ke titik akhir ini dan menerima prediksi yang dihasilkan oleh model. Dalam dokumen ini, pelajari cara membuat klien untuk layanan web dengan menggunakan C#, Go, Java, dan Python.

Anda membuat layanan web saat menyebarkan model ke lingkungan lokal, Azure Container Instances, Azure Kubernetes Service, atau array gerbang yang dapat diprogram bidang (FPGA). Anda mengambil URI yang digunakan untuk mengakses layanan web dengan menggunakan SDK Azure Machine Learning. Jika autentikasi diaktifkan, Anda juga dapat menggunakan SDK untuk mendapatkan kunci autentikasi atau token.

Alur kerja umum untuk membuat klien yang menggunakan layanan web pembelajaran mesin adalah:

  1. Gunakan SDK untuk mendapatkan informasi koneksi.
  2. Tentukan jenis data permintaan yang digunakan oleh model.
  3. Buat aplikasi yang memanggil layanan web.

Tip

Contoh dalam dokumen ini dibuat secara manual tanpa menggunakan spesifikasi OpenAPI (Swagger). Jika telah mengaktifkan spesifikasi OpenAPI untuk penyebaran, Anda dapat menggunakan alat seperti swagger-codegen guna membuat pustaka klien untuk layanan.

Informasi koneksi

Catatan

Gunakan SDK Azure Machine Learning untuk mendapatkan informasi layanan web. Ini adalah SDK Python. Anda dapat menggunakan bahasa apa pun untuk membuat klien untuk layanan.

Kelas azureml.core.Webservice menyediakan informasi yang Anda perlukan untuk membuat klien. Properti Webservice berikut berguna untuk membuat aplikasi klien:

  • auth_enabled - Jika autentikasi kunci diaktifkan, True; jika tidak, False.
  • token_auth_enabled - Jika autentikasi token diaktifkan, True; jika tidak, False.
  • scoring_uri - Alamat REST API.
  • swagger_uri - Alamat spesifikasi OpenAPI. URI ini tersedia jika Anda mengaktifkan pembuatan skema otomatis. Untuk informasi selengkapnya, lihat Menyebarkan model dengan Azure Machine Learning.

Ada beberapa cara untuk mengambil informasi ini untuk layanan web yang disebarkan:

  • Saat Anda menyebarkan model, objek Webservice dihasilkan dengan informasi tentang layanan:

    service = Model.deploy(ws, "myservice", [model], inference_config, deployment_config)
    service.wait_for_deployment(show_output = True)
    print(service.scoring_uri)
    print(service.swagger_uri)
    
  • Anda dapat menggunakan Webservice.list untuk mengambil daftar layanan web yang disebarkan untuk model di ruang kerja. Anda dapat menambahkan filter untuk mempersempit daftar informasi yang dihasilkan. Untuk informasi selengkapnya tentang apa yang dapat difilter, lihat dokumentasi referensi Webservice.list.

    services = Webservice.list(ws)
    print(services[0].scoring_uri)
    print(services[0].swagger_uri)
    
  • Jika mengetahui nama layanan yang disebarkan, Anda dapat membuat instans baru Webservice, dan memberikan ruang kerja dan nama layanan sebagai parameter. Objek baru berisi informasi tentang layanan yang disebarkan.

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

Tabel berikut menunjukkan seperti apa tampilan URI ini:

jenis URI Contoh
Penskoran URI http://104.214.29.152:80/api/v1/service/<service-name>/score
URI Swagger http://104.214.29.152/api/v1/service/<service-name>/swagger.json

Tip

Alamat IP akan berbeda untuk penyebaran Anda. Setiap kluster AKS akan memiliki alamat IP sendiri yang dibagikan oleh penyebaran ke kluster tersebut.

Layanan web yang diamankan

Jika Anda mengamankan layanan web yang disebarkan menggunakan sertifikat TLS/SSL, Anda dapat menggunakan HTTPS untuk menyambung ke layanan menggunakan URI penskoran atau swagger. HTTPS membantu mengamankan komunikasi antara klien dan layanan web dengan mengenkripsi komunikasi di antara keduanya. Enkripsi menggunakan Keamanan Lapisan Transportasi (TLS). TLS terkadang masih disebut sebagai Lapisan Soket Aman (SSL), yang merupakan pendahulu TLS.

Penting

Layanan web yang disebarkan oleh Azure Machine Learning hanya mendukung TLS versi 1.2. Saat membuat aplikasi klien, pastikan aplikasi tersebut mendukung versi ini.

Untuk informasi selengkapnya, lihat Menggunakan TLS untuk mengamankan layanan web melalui Azure Machine Learning.

Autentikasi untuk layanan

Azure Machine Learning menyediakan dua cara untuk mengontrol akses ke layanan web Anda.

Metode autentikasi ACI AKS
Kunci Dinonaktifkan secara default Diaktifkan secara default
Token Tidak Tersedia Dinonaktifkan secara default

Saat mengirim permintaan ke layanan yang diamankan dengan kunci atau token, gunakan header Otorisasi untuk meneruskan kunci atau token. Kunci atau token harus diformat sebagai Bearer <key-or-token>, di mana <key-or-token> adalah nilai kunci atau token Anda.

Perbedaan utama antara kunci dan token adalah kunci bersifat statik dan dapat diregenerasi secara manual, dan token perlu direfresh setelah kedaluwarsa. Autentikasi berbasis kunci didukung untuk Instans Kontainer Azure dan Azure Kubernetes Service yang menyebarkan layanan web, dan autentikasi berbasis token hanya tersedia untuk penyebaran Azure Kubernetes Service. Untuk informasi selengkapnya tentang mengonfigurasi autentikasi, lihat Mengonfigurasi autentikasi untuk model yang disebarkan sebagai layanan web.

Autentikasi dengan kunci

Saat mengaktifkan autentikasi untuk penyebaran, Anda secara otomatis membuat kunci autentikasi.

  • Autentikasi diaktifkan secara default saat Anda menyebarkan ke Azure Kubernetes Service.
  • Autentikasi dinonaktifkan secara default saat Anda menyebarkan ke Azure Container Instances.

Untuk mengontrol autentikasi, gunakan parameter auth_enabled saat Anda membuat atau memperbarui penyebaran.

Jika autentikasi diaktifkan, Anda dapat menggunakan metode get_keys untuk mengambil kunci autentikasi primer dan sekunder:

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

Penting

Jika Anda perlu meregenerasi kunci, gunakan service.regen_key.

Autentikasi dengan token

Saat Anda mengaktifkan autentikasi token untuk layanan web, pengguna harus memberikan token JWT Azure Machine Learning ke layanan web untuk mengaksesnya.

  • Autentikasi token dinonaktifkan secara default saat Anda menyebarkan ke Azure Kubernetes Service.
  • Autentikasi token tidak didukung saat Anda menyebarkan ke Azure Container Instances.

Untuk mengontrol autentikasi token, gunakan parameter token_auth_enabled saat Anda membuat atau memperbarui penyebaran.

Jika autentikasi token diaktifkan, Anda dapat menggunakan metode get_token untuk mengambil token pembawa dan waktu kedaluwarsa token tersebut:

token, refresh_by = service.get_token()
print(token)

Jika memiliki Azure CLI dan ekstensi pembelajaran mesin, Anda dapat menggunakan perintah berikut untuk mendapatkan token:

az ml service get-access-token -n <service-name>

Penting

Saat ini satu-satunya cara untuk mengambil token adalah dengan menggunakan SDK Azure Machine Learning atau ekstensi pembelajaran mesinAzure CLI.

Anda perlu meminta token baru setelah waktu token refresh_by.

Meminta data

REST API mengharapkan isi permintaan berupa dokumen JSON dengan struktur berikut:

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

Penting

Struktur data harus sesuai dengan apa yang diharapkan oleh skrip dan model penskoran dalam layanan. Skrip penskoran mungkin mengubah data sebelum meneruskannya ke model.

Data biner

Untuk informasi tentang cara mengaktifkan dukungan untuk data biner di layanan Anda, lihat Data biner.

Tip

Mengaktifkan dukungan untuk data biner terjadi di file score.py yang digunakan oleh model yang disebarkan. Dari klien, gunakan fungsionalitas HTTP bahasa pemrogram Anda. Misalnya, cuplikan berikut mengirimkan konten file JPG ke layanan web:

import requests
# Load image data
data = open('example.jpg', 'rb').read()
# Post raw data to scoring URI
res = request.post(url='<scoring-uri>', data=data, headers={'Content-Type': 'application/> octet-stream'})

Berbagi sumber daya lintas asal (CORS)

Untuk informasi tentang mengaktifkan dukungan CORS di layanan Anda, lihat Berbagi sumber daya lintas-asal.

Menghubungi layanan (C#)

Contoh ini menunjukkan cara menggunakan C# untuk memanggil layanan web yang dibuat dari contoh Pelatihan dalam catatan buku:

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 or token
            string scoringUri = "<your web service URI>";
            string authKey = "<your key or token>";

            // 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);
            }
        }
    }
}

Hasil yang ditampilkan mirip dengan dokumen JSON berikut:

[217.67978776218715, 224.78937091757172]

Menghubungi layanan (Go)

Contoh ini menunjukkan cara menggunakan Go untuk memanggil layanan web yang dibuat dari contoh Pelatihan dalam catatan buku:

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 or token (if any) for your service
var authKey string = "<your key or token>"

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))
}

Hasil yang ditampilkan mirip dengan dokumen JSON berikut:

[217.67978776218715, 224.78937091757172]

Menghubungi layanan (Java)

Contoh ini menunjukkan cara menggunakan Java untuk memanggil layanan web yang dibuat dari contoh Pelatihan dalam catatan buku:

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 or token
        String key = "<your key or token>";
        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());
    }
}

Hasil yang ditampilkan mirip dengan dokumen JSON berikut:

[217.67978776218715, 224.78937091757172]

Menghubungi layanan (Python)

Contoh ini menunjukkan cara menggunakan Python untuk memanggil layanan web yang dibuat dari contoh Pelatihan dalam catatan buku:

import requests
import json

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

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

Hasil yang ditampilkan mirip dengan dokumen JSON berikut:

[217.67978776218715, 224.78937091757172]

Skema layanan web (spesifikasi OpenAPI)

Jika menggunakan pembuatan skema otomatis dengan penyebaran, Anda bisa mendapatkan alamat spesifikasi OpenAPI untuk layanan dengan menggunakan properti swagger_uri. (Misalnya, print(service.swagger_uri).) Gunakan permintaan GET atau buka URI di browser untuk mengambil spesifikasi.

Dokumen JSON berikut adalah contoh skema (spesifikasi OpenAPI) yang dibuat untuk penyebaran:

{
    "swagger": "2.0",
    "info": {
        "title": "myservice",
        "description": "API specification for Azure Machine Learning myservice",
        "version": "1.0"
    },
    "schemes": [
        "https"
    ],
    "consumes": [
        "application/json"
    ],
    "produces": [
        "application/json"
    ],
    "securityDefinitions": {
        "Bearer": {
            "type": "apiKey",
            "name": "Authorization",
            "in": "header",
            "description": "For example: Bearer abc123"
        }
    },
    "paths": {
        "/": {
            "get": {
                "operationId": "ServiceHealthCheck",
                "description": "Simple health check endpoint to ensure the service is up at any given point.",
                "responses": {
                    "200": {
                        "description": "If service is up and running, this response will be returned with the content 'Healthy'",
                        "schema": {
                            "type": "string"
                        },
                        "examples": {
                            "application/json": "Healthy"
                        }
                    },
                    "default": {
                        "description": "The service failed to execute due to an error.",
                        "schema": {
                            "$ref": "#/definitions/ErrorResponse"
                        }
                    }
                }
            }
        },
        "/score": {
            "post": {
                "operationId": "RunMLService",
                "description": "Run web service's model and get the prediction output",
                "security": [
                    {
                        "Bearer": []
                    }
                ],
                "parameters": [
                    {
                        "name": "serviceInputPayload",
                        "in": "body",
                        "description": "The input payload for executing the real-time machine learning service.",
                        "schema": {
                            "$ref": "#/definitions/ServiceInput"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The service processed the input correctly and provided a result prediction, if applicable.",
                        "schema": {
                            "$ref": "#/definitions/ServiceOutput"
                        }
                    },
                    "default": {
                        "description": "The service failed to execute due to an error.",
                        "schema": {
                            "$ref": "#/definitions/ErrorResponse"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "ServiceInput": {
            "type": "object",
            "properties": {
                "data": {
                    "type": "array",
                    "items": {
                        "type": "array",
                        "items": {
                            "type": "integer",
                            "format": "int64"
                        }
                    }
                }
            },
            "example": {
                "data": [
                    [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
                ]
            }
        },
        "ServiceOutput": {
            "type": "array",
            "items": {
                "type": "number",
                "format": "double"
            },
            "example": [
                3726.995
            ]
        },
        "ErrorResponse": {
            "type": "object",
            "properties": {
                "status_code": {
                    "type": "integer",
                    "format": "int32"
                },
                "message": {
                    "type": "string"
                }
            }
        }
    }
}

Untuk informasi selengkapnya, lihat Spesifikasi OpenAPI.

Untuk utilitas yang dapat membuat pustaka klien dari spesifikasi, lihat swagger-codegen.

Tip

Anda dapat mengambil dokumen JSON skema setelah Anda menyebarkan layanan. Gunakan properti swagger_uri dari layanan web yang disebarkan (misalnya, service.swagger_uri) untuk mendapatkan URI ke file Swagger layanan web lokal.

Menggunakan layanan dari Power BI

Power BI mendukung konsumsi layanan web Azure Machine Learning untuk memperkaya data di Power BI dengan prediksi.

Untuk menghasilkan layanan web yang didukung untuk penggunaan di Power BI, skema harus mendukung format yang diperlukan oleh Power BI. Pelajari cara membuat skema yang didukung Power BI.

Setelah layanan web disebarkan, layanan ini dapat digunakan dari aliran data Power BI. Pelajari cara menggunakan layanan web Azure Machine Learning dari Power BI.

Langkah berikutnya

Untuk melihat arsitektur referensi untuk penskoran real time Python dan model pembelajaran mendalam, buka pusat arsitektur Azure.