Использование модели Машинного обучения Azure, развернутой в качестве веб-службы

При развертывании модели Машинного обучения Azure в качестве веб-службы создается конечная точка REST API. Через эту конечную точку вы можете отправлять данные в модель и получать от нее прогнозы. В этом документе описано, как создать клиенты для работы с веб-службой на языках C#, Go, Java и Python.

Веб-служба создается при развертывании модели в локальной среде, Экземплярах контейнеров Azure, Службе Azure Kubernetes или программируемых пользователем вентильных матрицах (ППВМ). Универсальный код ресурса (URI) для доступа к веб-службе можно получить с помощью пакета SDK для Машинного обучения Azure. Если включена проверка подлинности, с помощью этого пакета SDK вы можете также получить и ключи или маркеры проверки подлинности.

Ниже приведен общий рабочий процесс создания клиента, который использует веб-службу Машинного обучения:

  1. Получение сведений о подключении с помощью пакета SDK.
  2. Определение типа данных запроса, которые используются моделью.
  3. Создание приложения, которое обращается к веб-службе.

Совет

Примеры в этом документе создаются вручную без использования спецификаций OpenAPI (Swagger). Если вы используете спецификацию OpenAPI для развертывания, то вы можете использовать такие инструменты, как swagger-codegen, для создания клиентских библиотек для своей службы.

Важно!

Для использования некоторых команд Azure CLI, приведенных в этой статье, используйте расширение azure-cli-ml (версия 1) для Машинного обучения Azure. Поддержка расширения версии 1 будет прекращена 30 сентября 2025 г. Вы можете установить и использовать расширение версии 1 до этой даты.

Рекомендуется перейти на расширение ml (версия 2) до 30 сентября 2025 г. Дополнительные сведения о расширении версии 2 см. на странице расширения CLI для Azure ML и пакета SDK для Python версии 2.

Сведения о подключении

Примечание

Для получения информации о веб-службе используется пакет SDK для Машинного обучения Azure. Этот пакет SDK написан на Python. Вы можете использовать любой язык для создания клиента для службы.

Класс azureml.core.Webservice предоставляет необходимые сведения для создания клиента. Следующие свойства Webservice могут быть полезны при создании клиентского приложения:

  • auth_enabled — если включена проверка подлинности на основе ключей, имеет значение True, в противном случае — False.
  • token_auth_enabled — если включена проверка подлинности на основе маркеров, имеет значение True, в противном случае — False.
  • scoring_uri — адрес REST API.
  • swagger_uri — адрес спецификации OpenAPI. Этот универсальный код ресурса (URI) доступен, если включено автоматическое создание схем. Дополнительные сведения см. в статье Развертывание моделей машинного обучения в Azure.

Эти сведения для развернутой веб-службы можно получить несколькими способами.

ОБЛАСТЬ ПРИМЕНЕНИЯ:Пакет SDK для Python для ML Azure версии 1

  • При развертывании модели, возвращается объект Webservice с информацией о службе:

    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)
    
  • С помощью Webservice.list можно получить список развернутых веб-служб для моделей в рабочей области. Добавляя фильтры, можно сузить список возвращаемых сведений. Дополнительные сведения о возможностях фильтрации см. в справочной документации по Webservice.list.

    services = Webservice.list(ws)
    print(services[0].scoring_uri)
    print(services[0].swagger_uri)
    
  • Если вы знаете имя развернутой службы, создайте новый экземпляр класса Webservice и предоставьте ему в качестве параметров имя рабочей области и имя службы. Созданный объект будет содержать сведения о развернутой службе.

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

В следующей таблице показано, как выглядят эти универсальные коды ресурса (URI).

Тип URI Пример
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

Совет

IP-адрес будет отличаться для вашего развертывания. У каждого кластера AKS будет собственный IP-адрес, совместно используемый развертываниями в этом кластере.

Защищенная веб-служба

Если вы защитили развернутую веб-службу с помощью сертификата TLS/SSL, то вы можете использовать протокол HTTPS для подключения к службе с помощью URI оценки или Swagger. Протокол HTTPS обеспечивает безопасность обмена данными между клиентом и веб-службой путем шифрования данных, передаваемых между ними. Для шифрования используется протокол TLS. Протокол TLS иногда по-прежнему называется SSL (предшественник TLS).

Важно!

Веб-службы, развернутые Машинным обучением Azure, поддерживают только протокол TLS версии 1.2. При создании клиентского приложения убедитесь, что оно поддерживает эту версию.

Дополнительные сведения см. в статье Использование TLS для защиты веб-службы с помощью Машинного обучения Azure.

Проверка подлинности служб

Машинное обучение Azure предоставляет два способа управления доступом к веб-службам.

Метод проверки подлинности ACI AKS
Клавиши Отключено по умолчанию Включено по умолчанию
Токен Недоступно Отключено по умолчанию

При отправке запроса к службе, защищенной с помощью ключа или маркера, используйте заголовок Authorization для передачи ключа или маркера. Ключ или маркер должен использовать формат Bearer <key-or-token>, где <key-or-token> — это значение ключа или маркера.

Основное различие между ключами и маркерами состоит в том, что ключи являются статическими и могут быть повторно созданы вручную, а маркеры необходимо обновлять после истечения срока действия. Проверка подлинности на основе ключей поддерживается для веб-служб, развернутых в Экземплярах контейнеров Azure и Службе Azure Kubernetes, а проверка подлинности на основе маркеров доступна только для развертываний Службы Kubernetes Azure. Дополнительные сведения о настройке проверки подлинности см. в разделе Настройка проверки подлинности для моделей, развернутых в виде веб-служб.

Проверка подлинности на основе ключей

При включении проверки подлинности для развертывания автоматически создаются ключи проверки подлинности.

  • Проверка подлинности включена по умолчанию при развертывании в Службе Azure Kubernetes.
  • Проверка подлинности отключена по умолчанию при развертывании в Экземплярах контейнеров Azure.

Для управления проверкой подлинности используйте параметр auth_enabled при создании или обновлении развертывания.

Если включена проверка подлинности, можно использовать метод get_keys для извлечения первичного и вторичного ключей проверки подлинности:

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

Важно!

Если вам нужно повторно создать ключ, используйте service.regen_key.

Проверка подлинности на основе маркеров

Если для веб-службы включена проверка подлинности на основе маркеров, то для обращения к ней пользователь должен предоставить веб-службе маркер JWT Машинного обучения Azure.

  • Проверка подлинности на основе маркеров отключена по умолчанию при развертывании в Службе Azure Kubernetes.
  • Проверка подлинности на основе маркеров не поддерживается при развертывании в Экземплярах контейнеров Azure.

Для управления проверкой подлинности используйте параметр token_auth_enabled при создании или обновлении развертывания.

Если включена проверка подлинности на основе маркеров, можно использовать метод get_token для получения маркера носителя и его срока действия.

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

Если у вас установлены Azure CLI и расширение машинного обучения, то для получения маркера можно использовать следующую команду.

ОБЛАСТЬ ПРИМЕНЕНИЯ: Расширение ML для Azure CLI версии 1

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

Важно!

В настоящее время получить маркер можно только с помощью пакета SDK для Машинного обучения Azure или Azure CLI расширения машинного обучения.

После истечения срока действия маркера безопасности refresh_by необходимо запрашивать новый маркер.

Данные запроса

REST API ожидает, что текст запроса содержит документ JSON со следующей структурой:

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

Важно!

Структура данных должна совпадать с той, которую ожидают скрипт оценки и модель, размещенные в службе. Скрипт оценки может изменять данные перед передачей в модель.

Двоичные данные

Чтобы узнать, как включить поддержку двоичных данных в службе, ознакомьтесь с двоичными данными.

Совет

Для включения поддержки двоичных данных используется файл score.py, который использует развернутая модель. На клиенте используйте функции HTTP применяемого вами языка программирования. Например, следующий фрагмент кода отправляет содержимое JPG-файла в веб-службу.

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

Общий доступ к ресурсам независимо от источника (CORS)

Чтобы узнать, как включить поддержку CORS в службе, ознакомьтесь с общим доступом к ресурсам независимо от источника.

Вызов службы с помощью C#

В этом примере демонстрируется вызов веб-службы, созданный на языке C# на основе примера train-within-notebook:

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

Возвращаемые результаты аналогичны приведенному ниже документу JSON.

[217.67978776218715, 224.78937091757172]

Вызов службы с помощью Go

В этом примере демонстрируется вызов веб-службы, созданный на языке Go на основе примера train-within-notebook:

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

Возвращаемые результаты аналогичны приведенному ниже документу JSON.

[217.67978776218715, 224.78937091757172]

Вызов службы с помощью Java

В этом примере демонстрируется вызов веб-службы, созданный на языке Java на основе примера train-within-notebook:

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

Возвращаемые результаты аналогичны приведенному ниже документу JSON.

[217.67978776218715, 224.78937091757172]

Вызов службы с помощью Python

В этом примере демонстрируется вызов веб-службы, созданный на языке Python на основе примера train-within-notebook:

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)

Возвращаемые результаты аналогичны приведенному ниже документу JSON.

[217.67978776218715, 224.78937091757172]

Схема веб-службы (спецификация OpenAPI)

Если вы использовали автоматическое создание схем в развертывании, то вы можете получить адрес спецификации OpenAPI для службы с помощью свойства swagger_uri. (Например, print(service.swagger_uri).) Используйте запрос GET или откройте универсальный код ресурса (URI) в браузере, чтобы получить эту спецификацию.

Следующий документ JSON является примером схемы (спецификации OpenAPI), созданной для развертывания.

{
    "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"
                }
            }
        }
    }
}

Дополнительные сведения см. в спецификации OpenAPI.

Сведения о служебной программе, которая может создавать клиентские библиотеки на основе спецификации, можно получить на странице swagger-codegen.

Совет

После развертывания службы можно получить документ JSON схемы. Используйте свойство swagger_uri развернутой веб-службы (например, service.swagger_uri), чтобы получить универсальный код ресурса (URI) для файла Swagger локальной веб-службы.

Использование службы из Power BI

Power BI поддерживает использование веб-служб Машинного обучения Azure, что позволяет обогатить данные в Power BI с помощью прогнозов.

Чтобы создаваемую веб-службу можно было использовать в Power BI, ее схема должна поддерживать формат, требуемый для Power BI. Узнайте, как создать схему, поддерживаемую Power BI.

После развертывания веб-службы ее можно использовать в потоках данных Power BI. Узнайте, как использовать веб-службу Машинного обучения Azure в Power BI.

Дальнейшие действия

Чтобы просмотреть эталонную архитектуру для оценки в реальном времени моделей Python и глубокого обучения, перейдите в Центр архитектуры Azure.