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

Но сначала позвольте мне объяснить, почему управляемая конечная точка — это новый популярный способ использования ваших прогнозов и какие другие варианты может предложить Azure. До публичного выпуска управляемой конечной точки существовало два варианта использования модели машинного обучения в режиме реального времени в качестве веб-службы:

  • ACI. Используя Azure Container Instances, вы можете развернуть модель в экземпляре контейнера фиксированного размера. Настройка довольно проста, но этот тип развертывания не рекомендуется для использования в производственной среде из-за его ограниченной конфигурации. В этом развертывании отсутствует безопасная сетевая конфигурация, и его нельзя масштабировать. Подробнее об этом развертывании можно узнать здесь. Код для развертывания этого веб-сервиса можно найти в мой git.
  • Kubernetes — Azure предлагает пакет SDK для Python для развертывания модели в кластере Kuberentes. Kubernetes решает все проблемы ACI и лучше подходит для производства. Несмотря на сложность Kubernetes, код развертывания с использованием azureml sdk довольно прост. Если ваша облачная инфраструктура имеет простую настройку сети, эта услуга может быть для вас. Но если ваша сеть включает в себя несколько подсетей, возникнет множество проблем, связанных с сетью, которые необходимо решить, чтобы сделать веб-службу kubernetes функциональной.

Управляемая конечная точка сочетает в себе лучшее из обоих миров. Его легко развертывать, масштабировать и настраивать в сети без проблем с сетью, присущих kubernetes.

Развертывание частной управляемой конечной точки

Новый SDK azureml использует клиентов для взаимодействия со службами и сущностями для выполнения операций этих служб. Эта настройка более совместима с остальной инфраструктурой Azure, чем предыдущая версия azureml SDK.

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

# import required libraries
from azure.ai.ml import MLClient
from azure.ai.ml.entities import (
    ManagedOnlineEndpoint,
    ManagedOnlineDeployment,
    Model,
    Environment,
    CodeConfiguration,
)
from azure.identity import DefaultAzureCredential

Используйте DefaultAzureCredential, чтобы получить токен авторизации. Если вы войдете в систему, используя свою учетную запись, этот токен будет получен с помощью AD. Если вы развертываете эту службу из AzureDevops, вам потребуются учетные данные субъекта-службы, доступные во время развертывания, с использованием следующего соглашения об именах: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET. Подробнее о принципале обслуживания здесь.

def get_ml_client(env_variables):
"""
Get authentication token to access MLClient resource. ML CLient is defined by 
following ML workspace variables: subscription id, resourcegroup and workspace name.
Args:
  env_variables (dict): environment variables containding subscription id, 
                resorce group and workspace name used to establish MLCient. 
"""

    credential = DefaultAzureCredential(exclude_shared_token_cache_credential=True)
    ml_client = MLClient(
        credential, env_variables['WS_SUBSCRIPTION_ID'], env_variables['WS_RESOURCE_GROUP'], env_variables['WS_NAME']
    )

    return ml_client

Следующая функция устанавливает и развертывает частную управляемую конечную точку, используя для запуска экземпляр небольшого размера. Обратите внимание, что для конечной точки public_network_access установлено значение «включено», а egress_public_network_access«отключено». Параметр доступа к общедоступной сети в функции ManagedOnlineEndpoit позволяет вызывать конечную точку из-за пределов настройки частной сети. В то время как параметр egress_public_network_access в ManagedOnlineDeployment управляет доступом конечной точки к ресурсам Azure. Если в вашей рабочей области машинного обучения отключен доступ к общедоступной сети, ваше развертывание конечной точки также должно отключить доступ к общедоступной сети. Этот тип настройки создает частную безопасную конечную точку, через которую осуществляется доступ к ресурсам Azure.

def deploy_webservice(ml_client, env_variables):
    """
    Deploys azure managed endpoint as a private endpoint.
    Args:
        ml_client (azure.ai.ml.MLClient): azure MLClient resource
        env_variables (dict): environment variables
    """

    env = ml_client.environments.get(env_variables['RUN_ENV_NAME'], version=env_variables['RUN_ENV_VERSION'])
    print('updated webservice name ', env)
    model = ml_client.models.get(env_variables['MODEL_NAME'], version=env_variables['MODEL_VERSION'])
    endpoint_name = env_variables['ENDPOINT_NAME']
    source_directory = os.path.join(os.getcwd(), os.environ['ARTIFACT_PATH'], 'src')

    # create an online endpoint
    private_endpoint = ManagedOnlineEndpoint(
        name=endpoint_name,
        description="this is a sample online endpoint",
        auth_mode="key",
        public_network_access="enabled",
        tags={"foo": "bar"}
    )

    private_deployment = ManagedOnlineDeployment(name=f'{endpoint_name}-deployment',
                                                 endpoint_name=endpoint_name,
                                                 model=model,
                                                 code_configuration=CodeConfiguration(
                                                     code=source_directory, scoring_script="score.py"
                                                 ),
                                                 environment=env,
                                                 instance_type='Standard_DS3_v2',
                                                 instance_count=1,
                                                 egress_public_network_access="disabled"
                                                 )

    ml_client.online_endpoints.begin_create_or_update(private_endpoint).result()
    ml_client.begin_create_or_update(private_deployment)

    private_endpoint.traffic = {f'{endpoint_name}-deployment': 100}  # allocate 100% of traffic to blue deployment
    ml_client.online_endpoints.begin_create_or_update(private_endpoint)

Развертывание и распределение трафика могут занять некоторое время при первом развертывании конечной точки. Вы можете проверить, готово ли развертывание к вызову, с помощью следующего кода.

endpoint = ml_client.online_endpoints.get(name=env_variables['ENDPOINT_NAME'])
assert endpoint.provisioning_state == 'Succeeded'

while endpoint.traffic[env_variables['DEPLOYMENT_NAME']] == 0:
    endpoint = ml_client.online_endpoints.get(name=env_variables['ENDPOINT_NAME'])
    time.sleep(30)

print('Endpoint is ready to be called.')

Пользовательская среда для частной управляемой конечной точки

В развертывании используется пользовательская среда, зарегистрированная в рабочей области машинного обучения. Следуйте инструкциям в моем предыдущем посте о том, как создать и опубликовать пользовательскую среду Docker в ACR. Обратите внимание, что с рабочей областью машинного обучения связан реестр контейнеров Azure. При публикации среды убедитесь, что эта среда создана как репозиторий в экземпляре ACR, используемом рабочей областью машинного обучения.

Следующий код создает пользовательскую среду из образа Docker, опубликованного в ACR.

from azure.ai.ml.entities import Environment

env = Environment(
    image="{container_name}.azurecr.io/{repository_name}",
    name='custom-env',
    description='Custom environment'
    )

ml_client.environments.create_or_update(env)

Сценарий оценки

Сценарий оценки, передаваемый функции ManagedOnlineDeployment, состоит из двух частей:

  • Функция init() вызывается при развертывании управляемой конечной точки. Эта часть обычно содержит инициализацию ресурсов, таких как модель прогнозирования, зарегистрированная в рабочей области Azure ML, и любые ресурсы, необходимые для прогнозирования из хранилища BLOB-объектов. Эти ресурсы передаются в прогнозирующую часть скрипта как глобальные переменные.
  • Функция run() вызывается при вызове управляемой конечной точки. Данные принимаются в формате json, обрабатываются и подготавливаются к прогнозированию. Модель, сохраненная как глобальная переменная на предыдущих шагах, вызывается для прогнозирования, и выходные данные форматируются.
import joblib
import json
import logging
import os
import numpy as np
import pandas as pd
import traceback


def jsonifys(status_code=200, **kwargs):
    response = jsonify(**kwargs)
    response.status_code = status_code
    return response


def init():
    """
    This function is called when the container is initialized/started, typically after create/update of the deployment.
    You can write the logic here to perform init operations like caching the model in memory
    """

    global model
    # AZUREML_MODEL_DIR is an environment variable created during deployment.
    # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)

    model_path = os.path.join(
        os.getenv("AZUREML_MODEL_DIR"), "model_name"
    )
    model = joblib.load(model_path)
    logging.info("Init complete")


def run(raw_data):
    """
    This function is called for every invocation of the endpoint to perform the actual scoring/prediction.
    """

    try:
      logging.info("model 1: request received")
      data = json.loads(raw_data)["data"]
      result_data = np.array(data)
      
      result_df = pd.DataFrame(columns=['Prediction'])
      result_df['Prediction'] = model.predict(result_data)
      logging.info("Request processed")
              return jsonifys(status_code=200, body= results_df.to_json(orient='index'))
    except Exception as e:
        print(e)
        return jsonifys(status_code=400, error=traceback.format_exc())

Заключительные слова

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

Подробнее об управляемой конечной точке можно узнать в руководстве по Azure.