使用联机终结点部署机器学习模型并对其进行评分

适用范围:Azure CLI ml 扩展 v2(最新版)Python SDK azure-ai-ml v2(最新版)

本文介绍如何将模型部署到联机终结点以用于实时推理。 首先在本地计算机上部署一个模型以调试任何错误。 然后,在 Azure 中部署和测试模型,查看部署日志,并监视服务级别协议 (SLA)。 在本文结束时,你将拥有一个可缩放的 HTTPS/REST 终结点,可用于实时推理。

联机终结点是用于实时推理的终结点。 有两种类型的联机终结点:托管联机终结点Kubernetes 联机终结点。 有关终结点的详细信息以及托管联机终结点与 Kubernetes 联机终结点之间的差异,请参阅什么是 Azure 机器学习终结点

托管联机终结点有助于以统包方式部署机器学习模型。 托管联机终结点在 Azure 中以一种可缩放的、完全托管的方式使用功能强大的 CPU 和 GPU 计算机。 托管联机终结点负责处理、缩放、保护和监视你的模型,使你没有设置和管理底层基础结构的开销。

本文档中的主要示例使用托管联机终结点进行部署。 若要改用 Kubernetes,请参阅本文档中与托管联机终结点讨论内联的注释。

先决条件

适用范围Python SDK azure-ai-ml v2(最新版)

在按照本文中的步骤操作之前,请确保满足以下先决条件:

  • Azure 基于角色的访问控制 (Azure RBAC) 用于授予对 Azure 机器学习中的操作的访问权限。 若要执行本文中的步骤,必须为用户帐户分配 Azure 机器学习工作区的所有者参与者角色,或者分配一个允许 Microsoft.MachineLearningServices/workspaces/onlineEndpoints/* 的自定义角色。 有关详细信息,请参阅管理对 Azure 机器学习工作区的访问

  • (可选)若要在本地部署,必须在本地计算机上安装 Docker 引擎强烈建议选择此选项,以便更轻松地调试问题。

  • 确保为部署分配了足够的虚拟机 (VM) 配额。 Azure 机器学习会保留 20% 的计算资源,以便在某些 VM SKU 上执行升级。 例如,如果在部署中请求 10 个实例,则必须为 VM SKU 的每个核心数指定 12 个配额。 未能考虑额外的计算资源会导致错误。 有些 VM SKU 不受额外配额预留的限制。 有关配额分配的更多信息,请参阅部署的虚拟机配额分配

  • 或者,可以在有限的时间内使用 Azure 机器学习的共享配额池中的配额。 Azure 机器学习提供了一个共享配额池,不同区域中的用户可以根据可用性从中访问配额以执行有限时间的测试。 使用工作室将 Llama-2、Phi、Nemotron、Mistral、Dolly 和 Deci-DeciLM 模型从模型目录部署到托管联机终结点时,Azure 机器学习允许你在短时间访问其共享配额池,以便执行测试。 有关共享配额池的详细信息,请参阅 Azure 机器学习共享配额

准备你的系统

克隆示例存储库

若要运行训练示例,请首先克隆示例存储库 (azureml-examples),然后更改为 azureml-examples/sdk/python/endpoints/online/managed 目录:

git clone --depth 1 https://github.com/Azure/azureml-examples
cd azureml-examples/sdk/python/endpoints/online/managed

提示

使用 --depth 1 仅克隆最新提交到存储库的内容,从而减少完成操作所需的时间。

本文中的信息基于 online-endpoints-simple-deployment.ipynb 笔记本。 该笔记本包含与本文相同的内容,尽管代码的顺序略有不同。

连接到 Azure 机器学习工作区

工作区是 Azure 机器学习的顶级资源,为使用 Azure 机器学习时创建的所有项目提供了一个集中的处理位置。 在本部分,你将连接到在其中执行部署任务的工作区。 若要遵循说明进行操作,请打开你的 online-endpoints-simple-deployment.ipynb 笔记本。

  1. 导入所需的库:

    # 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
    

    备注

    如果你使用的是 Kubernetes 联机终结点,请从 azure.ai.ml.entities 库导入 KubernetesOnlineEndpointKubernetesOnlineDeployment 类。

  2. 配置工作区详细信息并获取工作区句柄:

    若要连接到工作区,需要提供标识符参数 - 订阅、资源组和工作区名称。 你将在 azure.ai.mlMLClient 中使用这些详细信息来获取所需 Azure 机器学习工作区的句柄。 此示例使用默认的 Azure 身份验证

    # enter details of your Azure Machine Learning workspace
    subscription_id = "<SUBSCRIPTION_ID>"
    resource_group = "<RESOURCE_GROUP>"
    workspace = "<AZUREML_WORKSPACE_NAME>"
    
    # get a handle to the workspace
    ml_client = MLClient(
        DefaultAzureCredential(), subscription_id, resource_group, workspace
    )
    

定义终结点

若要定义联机终结点,请指定终结点名称身份验证模式。 有关托管联机终结点的详细信息,请参阅联机终结点

配置终结点

首先定义联机终结点的名称,然后配置终结点。

终结点名称在 Azure 区域中必须是唯一的。 有关命名规则的详细信息,请参阅终结点限制

# Define an endpoint name
endpoint_name = "my-endpoint"

# Example way to define a random name
import datetime

endpoint_name = "endpt-" + datetime.datetime.now().strftime("%m%d%H%M%f")

# create an online endpoint
endpoint = ManagedOnlineEndpoint(
    name = endpoint_name, 
    description="this is a sample endpoint",
    auth_mode="key"
)

前面的代码使用 key 进行基于密钥的身份验证。 若要使用基于 Azure 机器学习令牌的身份验证,请使用 aml_token。 若要使用基于 Microsoft Entra 令牌的身份验证(预览版),请使用 aad_token。 有关身份验证的详细信息,请参阅对联机终结点的客户端进行身份验证

定义部署

部署是一组资源,用于承载执行实际推理的模型。 在此示例中,你将部署一个执行回归的 scikit-learn 模型,并使用评分脚本 score.py 根据给定的输入请求执行该模型。

若要了解部署的关键属性,请参阅联机部署

配置部署

部署配置使用你希望部署的模型的位置。

若要配置部署,请执行以下操作:

model = Model(path="../model-1/model/sklearn_regression_model.pkl")
env = Environment(
    conda_file="../model-1/environment/conda.yaml",
    image="mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest",
)

blue_deployment = ManagedOnlineDeployment(
    name="blue",
    endpoint_name=endpoint_name,
    model=model,
    environment=env,
    code_configuration=CodeConfiguration(
        code="../model-1/onlinescoring", scoring_script="score.py"
    ),
    instance_type="Standard_DS3_v2",
    instance_count=1,
)
  • Model - 使用 path(上传文件的位置)指定内联模型属性。 SDK 会自动上传模型文件并使用自动生成的名称注册模型。
  • Environment - SDK 使用包含上传文件位置的内联定义自动上传 conda.yaml 文件并注册环境。 随后,为了构建环境,部署使用 image(在本示例中为 mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest)作为基础映像,并将 conda_file 依赖项安装在基础映像之上。
  • CodeConfiguration - 在部署期间,本地文件(如评分模型的 Python 源)是从开发环境上传的。

有关联机部署定义的详细信息,请参阅 OnlineDeployment 类

了解评分脚本

提示

联机终结点的评分脚本格式与早期版本的 CLI 和 Python SDK 中使用的格式相同。

评分脚本必须具有一个 init() 函数和一个 run() 函数。

此示例使用 score.py 文件score.py

import os
import logging
import json
import numpy
import joblib


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)
    # Please provide your model's folder name if there is one
    model_path = os.path.join(
        os.getenv("AZUREML_MODEL_DIR"), "model/sklearn_regression_model.pkl"
    )
    # deserialize the model file back into a sklearn model
    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.
    In the example we extract the data from the json input and call the scikit-learn model's predict()
    method and return the result back
    """
    logging.info("model 1: request received")
    data = json.loads(raw_data)["data"]
    data = numpy.array(data)
    result = model.predict(data)
    logging.info("Request processed")
    return result.tolist()

初始化或启动容器时,将调用函数 init()。 初始化通常在创建或更新部署后立即发生。 可通过 init 函数编写逻辑以执行全局初始化操作,例如在内存中高速缓存模型(如此 score.py 文件所示)。

每次调用终结点时,都将调用 run() 函数,该函数将执行实际的评分和预测。 在此 score.py 文件中,run() 函数将从 JSON 输入中提取数据,调用 scikit-learn 模型的 predict() 方法,然后返回预测结果。

使用本地终结点在本地部署和调试

强烈建议在本地测试运行终结点,以在部署到 Azure 之前验证和调试代码和配置。 Azure CLI 和 Python SDK 支持本地终结点和部署,而 Azure 机器学习工作室和 ARM 模板则不支持。

若要在本地部署,必须安装并运行 Docker 引擎。 Docker 引擎通常在计算机启动时启动。 如果它不启动,可以对 Docker 引擎进行故障排除

提示

可以使用 Azure 机器学习推理 HTTP 服务器 Python 包在本地调试评分脚本而无需 Docker 引擎。 使用推理服务器进行调试有助于在部署到本地终结点之前调试评分脚本,以便在不受部署容器配置影响的情况下进行调试。

有关在部署到 Azure 之前在本地调试联机终结点的详细信息,请参阅联机终结点调试

在本地部署模型

首先创建一个终结点。 (可选)对于本地终结点,可以跳过此步骤并直接创建部署(下一步骤),这继而将创建所需的元数据。 在本地部署模型对于开发和测试目的很有用。

ml_client.online_endpoints.begin_create_or_update(endpoint, local=True)

现在,在终结点下面创建一个名为 blue 的部署。

ml_client.online_deployments.begin_create_or_update(
    deployment=blue_deployment, local=True
)

local=True 标志指示 SDK 在 Docker 环境中部署终结点。

提示

使用 Visual Studio Code 在本地测试和调试终结点。 有关详细信息,请参阅在 Visual Studio Code 中以本地方式调试联机终结点

验证本地部署是否成功

检查部署状态,查看模型是否已部署且未出错:

ml_client.online_endpoints.get(name=endpoint_name, local=True)

该方法返回ManagedOnlineEndpoint 实体provisioning_stateSucceeded

ManagedOnlineEndpoint({'public_network_access': None, 'provisioning_state': 'Succeeded', 'scoring_uri': 'http://localhost:49158/score', 'swagger_uri': None, 'name': 'endpt-10061534497697', 'description': 'this is a sample endpoint', 'tags': {}, 'properties': {}, 'id': None, 'Resource__source_path': None, 'base_path': '/path/to/your/working/directory', 'creation_context': None, 'serialize': <msrest.serialization.Serializer object at 0x7ffb781bccd0>, 'auth_mode': 'key', 'location': 'local', 'identity': None, 'traffic': {}, 'mirror_traffic': {}, 'kind': None})

下表包含 provisioning_state 的可能值:

说明
Creating 正在创建资源。
更新 正在更新资源。
正在删除 正在删除此资源。
成功 创建/更新操作成功。
已失败 创建/更新/删除操作失败。

调用本地终结点以使用模型为数据评分

使用 invoke 命令并传递 JSON 文件中存储的查询参数,调用终结点来为模型评分。

ml_client.online_endpoints.invoke(
    endpoint_name=endpoint_name,
    request_file="../model-1/sample-request.json",
    local=True,
)

如果要使用 REST 客户端(例如 curl),必须具有评分 URI。 要获取评分 URI,请运行以下代码。 在返回的数据中,找到 scoring_uri 属性。

endpoint = ml_client.online_endpoints.get(endpoint_name, local=True)
scoring_uri = endpoint.scoring_uri

在日志中查看 invoke 操作的输出

在示例 score.py 文件中,run() 方法将一些输出记录到控制台。

可以使用 get_logs 方法查看此输出:

ml_client.online_deployments.get_logs(
    name="blue", endpoint_name=endpoint_name, local=True, lines=50
)

将联机终结点部署到 Azure

接下来,将联机终结点部署到 Azure。 作为生产环境的最佳做法,建议你注册将在部署中使用的模型和环境。

注册模型和环境

建议在部署到 Azure 之前注册模型和环境,以便在部署期间指定它们的注册名称和版本。 注册资产就可以重复使用资产,而无需在每次创建部署时上传它们,从而提高可重复性和可追溯性。

备注

与部署到 Azure 不同,本地部署不支持使用注册的模型和环境。 相反,本地部署使用本地模型文件并使用仅具有本地文件的环境。 若要部署到 Azure,可以使用本地或注册资产(模型和环境)。 在本文的这一小节中,我们使用注册资产部署到 Azure,但你也可以选择使用本地资产。 有关上传本地文件以用于本地部署的部署配置示例,请参阅配置部署

  1. 注册模型

    from azure.ai.ml.entities import Model
    from azure.ai.ml.constants import AssetTypes
    
    file_model = Model(
        path="../../model-1/model/",
        type=AssetTypes.CUSTOM_MODEL,
        name="my-model",
        description="Model created from local file.",
    )
    ml_client.models.create_or_update(file_model)
    
  2. 注册环境:

    from azure.ai.ml.entities import Environment
    
    env_docker_conda = Environment(
        image="mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04",
        conda_file="../../model-1/environment/conda.yaml",
        name="my-env",
        description="Environment created from a Docker image plus Conda environment.",
    )
    ml_client.environments.create_or_update(env_docker_conda)
    

若要了解如何将模型注册为资产,以便在部署期间指定其注册名称和版本,请参阅使用 SDK 在机器学习中将模型注册为资产

有关创建环境的详细信息,请参阅使用 CLI 和 SDK (v2) 管理 Azure 机器学习环境

配置使用注册资产的部署

部署配置使用要部署的注册模型和注册环境。

若要配置部署,请使用注册的模型和环境:

model = "azureml:my-model:1"
env = "azureml:my-env:1"
 
blue_deployment_with_registered_assets = ManagedOnlineDeployment(
    name="blue",
    endpoint_name=endpoint_name,
    model=model,
    environment=env,
    code_configuration=CodeConfiguration(
        code="../model-1/onlinescoring", scoring_script="score.py"
    ),
    instance_type="Standard_DS3_v2",
    instance_count=1,
)

使用不同的 CPU 和 GPU 实例类型及映像

可以在部署配置中为本地部署和部署到 Azure 指定 CPU 或 GPU 实例类型和映像。

你先前配置了一个使用通用类型 Standard_DS3_v2 实例和非 GPU Docker 映像 mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest 的部署。 对于 GPU 计算,应选择 GPU 计算类型 SKU 和 GPU Docker 映像。

可以在托管联机终结点支持的 VM SKU 中查看支持的常规用途类型和 GPU 实例类型。 有关 Azure 机器学习 CPU 和 GPU 基础映像的列表,请参阅 Azure 机器学习基础映像

备注

若要使用 Kubernetes 而不是托管终结点作为计算目标,请参阅 Kubernetes 计算目标简介

接下来,将联机终结点部署到 Azure。

“部署到 Azure”

  1. 创建终结点:

    使用前面定义的 endpoint 和之前创建的 MLClient,现在可以在工作区中创建终结点。 此命令会启动终结点创建操作,并在终结点创建操作继续时返回确认响应。

    ml_client.online_endpoints.begin_create_or_update(endpoint)
    
  2. 创建部署:

    使用前面定义的 blue_deployment_with_registered_assets 和之前创建的 MLClient,现在可以在工作区中创建部署。 此命令将启动部署创建操作,并在部署创建操作继续时返回确认响应。

    ml_client.online_deployments.begin_create_or_update(blue_deployment_with_registered_assets)
    

    提示

    • 如果你不希望阻塞 Python 控制台,可以将 no_wait=True 标志添加到参数中。 但是,此选项会停止以交互方式显示部署状态。
    # blue deployment takes 100 traffic
    endpoint.traffic = {"blue": 100}
    ml_client.online_endpoints.begin_create_or_update(endpoint)
    

若要调试部署中的错误,请参阅对联机终结点部署进行故障排除

检查终结点的状态

  1. 检查终结点的状态,查看模型是否已部署且未出错:

    ml_client.online_endpoints.get(name=endpoint_name)
    
  2. 使用 list 方法以表格格式列出工作区中的所有终结点:

    for endpoint in ml_client.online_endpoints.list():
        print(endpoint.name)
    

    该方法返回 ManagedOnlineEndpoint 实体的列表(迭代器)。

  3. 可以通过指定更多参数来获取更多信息。 例如,像表格一样输出终结点列表:

    print("Kind\tLocation\tName")
    print("-------\t----------\t------------------------")
    for endpoint in ml_client.online_endpoints.list():
        print(f"{endpoint.kind}\t{endpoint.location}\t{endpoint.name}")
    

检查联机部署的状态

检查日志,查看模型是否已部署且未出错。

  1. 可以使用 get_logs 方法查看日志输出:

    ml_client.online_deployments.get_logs(
        name="blue", endpoint_name=endpoint_name, lines=50
    )
    
  2. 默认情况下,日志是从推理服务器容器拉取的。 若要查看存储初始化表达式容器中的日志,请添加 container_type="storage-initializer" 选项。 有关部署日志的更多信息,请参阅获取容器日志

    ml_client.online_deployments.get_logs(
        name="blue", endpoint_name=endpoint_name, lines=50, container_type="storage-initializer"
    )
    

调用终结点,以使用模型为数据评分

使用前面创建的 MLClient,获取终结点的句柄。 然后,可以使用具有以下参数的 invoke 命令调用终结点:

  • endpoint_name - 终结点的名称
  • request_file - 包含请求数据的文件
  • deployment_name - 要在终结点中测试的特定部署的名称
  1. 使用 json 文件发送示例请求。

    # test the blue deployment with some sample data
    ml_client.online_endpoints.invoke(
        endpoint_name=endpoint_name,
        deployment_name="blue",
        request_file="../model-1/sample-request.json",
    )
    

(可选)更新部署

如果你要更新代码、模型或环境,请更新配置,然后运行 MLClientonline_deployments.begin_create_or_update 方法来创建或更新部署

备注

如果你在单个 begin_create_or_update 方法中更新实例计数(以缩放你的部署)和其他模型设置(例如代码、模型或环境),则首先将执行缩放操作,然后将应用其他更新。 在生产环境中单独执行这些操作是一个很好的做法。

若要了解 begin_create_or_update 的工作原理,请执行以下操作:

  1. 打开 online/model-1/onlinescoring/score.py 文件。

  2. 更改 init() 函数的最后一行:在 logging.info("Init complete") 后面,添加 logging.info("Updated successfully")

  3. 保存文件。

  4. 运行方法:

    ml_client.online_deployments.begin_create_or_update(blue_deployment_with_registered_assets)
    
  5. 由于修改了在创建或更新终结点时运行的 init() 函数,因此日志中会包含消息 Updated successfully。 运行以下命令检索日志:

    ml_client.online_deployments.get_logs(
        name="blue", endpoint_name=endpoint_name, lines=50
    )
    

begin_create_or_update 方法也适用于本地部署。 将同一方法与 local=True 标志配合使用。

备注

本部分中的部署更新是就地滚动更新的示例。

  • 对于托管联机终结点,部署将更新为一次更新 20% 的节点的新配置。 也就是说,如果部署有 10 个节点,则一次将更新 2 个节点。
  • 对于 Kubernetes 联机终结点,系统将使用新配置以迭代方式创建新的部署实例,并删除旧部署实例。
  • 对于生产用途,应考虑蓝绿部署,它为更新 Web 服务提供了更安全的替代方法。

(可选)配置自动缩放

自动缩放会自动运行适量的资源来处理应用程序的负载。 托管联机终结点支持通过与 Azure Monitor 自动缩放功能的集成进行自动缩放。 要配置自动缩放,请参阅如何自动缩放联机终结点

(可选)使用 Azure Monitor 监视 SLA

若要查看指标并根据 SLA 设置警报,请完成监视联机终结点中所述的步骤。

(可选)与 Log Analytics 集成

CLI 的 get-logs 命令或 SDK 的 get_logs 方法只提供自动选择的实例最近发出的几百行日志。 但是,Log Analytics 提供一种用于持久存储和分析日志的方式。 有关使用日志记录的详细信息,请参阅监视联机终结点

删除终结点和部署

删除终结点及其所有基础部署:

ml_client.online_endpoints.begin_delete(name=endpoint_name)