使用 Azure Cache for Redis 将机器学习模型部署到 Azure Functions

在本文中,你将使用 Azure Cache for Redis 实例将 Azure 机器学习中的模型部署为 Azure Functions 中的函数应用。

Azure Cache for Redis 性能优异并且可缩放。 在与 Azure 机器学习模型配对时,可以在应用程序中获得低延迟和高吞吐量。 缓存在一些情况下特别有用:在进行数据推理时,以及用于实际的模型推理结果时。 在任一情况下,元数据或结果存储在内存中,因而提高了性能。

注意

虽然 Azure 机器学习和 Azure Functions 都已正式发布,但将模型从机器学习服务部署到 Functions 的功能目前处于预览阶段。

先决条件

重要

本文中的代码片段假设你已设置以下变量:

  • ws - Azure 机器学习工作区。
  • model - 将要部署的注册模型。
  • inference_config - 用于模型的推理配置。

有关设置这些变量的详细信息,请参阅使用 Azure 机器学习部署模型

创建用于 Redis 的 Azure 缓存实例

你将能够使用任何基本、标准或高级缓存实例将机器学习模型部署到 Azure Functions。 若要创建缓存实例,请执行以下步骤。

  1. 转到 Azure 门户主页或打开边栏菜单,然后选择“创建资源”。

  2. 在“新建”页上选择“数据库”,然后选择“Azure Cache for Redis”。

    Select Azure Cache for Redis.

  3. 在“新建 Redis 缓存”页上配置新缓存的设置。

    设置 建议值 说明
    DNS 名称 输入任何全局唯一的名称。 缓存名称必须是介于 1 到 63 个字符之间的字符串。 该字符串只能包含数字、字母或连字符。 该名称必须以数字或字母开头和结尾,且不能包含连续的连字符。 缓存实例的主机名是 <DNS name>.redis.cache.chinacloudapi.cn
    订阅 单击下拉箭头并选择你的订阅。 要在其下创建此新的 Azure Cache for Redis 实例的订阅。
    资源组 单击下拉箭头并选择一个资源组,或者选择“新建”并输入新的资源组名称。 要在其中创建缓存和其他资源的资源组的名称。 将所有应用资源放入一个资源组可以轻松地统一管理或删除这些资源。
    位置 单击下拉箭头并选择一个位置。 选择与要使用该缓存的其他服务靠近的区域
    定价层 单击下拉箭头并选择一个定价层 定价层决定可用于缓存的大小、性能和功能。 有关详细信息,请参阅用于 Redis 的 Azure 缓存概述
  4. 选择“网络”选项卡,或选择“网络”按钮(位于页面底部) 。

  5. 在“网络”选项卡中,选择你的连接方法。

  6. 选择“下一步:高级”选项卡,或者选择页面底部的“下一步:高级”按钮 。

  7. 在基本或标准缓存实例的“高级”选项卡中,如果想要启用非 TLS 端口,请选择启用开关。

  8. 在高级缓存实例的“高级”选项卡中,配置非 TLS 端口、群集和数据持久性的设置。

  9. 选择“下一步: 标记”选项卡,或选择页面底部的“下一步: 标记”按钮 。

  10. 或者,在“标记”选项卡中,如果希望对资源分类,请输入名称或值。

  11. 选择“查看 + 创建” 。 随后你会转到“查看 + 创建”选项卡,Azure 将在此处验证配置。

  12. 显示绿色的“已通过验证”消息后,选择“创建”。

创建缓存需要花费片刻时间。 可以在 Azure Cache for Redis 的“概述”页上监视进度。 如果“状态”显示为“正在运行”,则表示该缓存可供使用。

准备部署

在部署之前,必须确定将模型作为 Web 服务运行所需的内容。 以下列表描述了部署所需的核心项:

  • 一个入口脚本 。 此脚本接受请求,使用模型为请求评分并返回结果。

    重要

    入口脚本特定于你的模型;它必须能够识别传入请求数据的格式、模型所需数据的格式以及返回给客户端的数据的格式。

    如果请求数据的格式对模型不可用,则该脚本可以将其转换为可接受的格式。 在将响应返回给客户端之前,它还可以对响应进行转换。

    默认情况下,在为函数打包时,输入被视为文本。 如果想使用输入的原始字节(例如用于 Blob 触发器),则应使用 AMLRequest 接受原始数据

对于 run 函数,请确保它连接到 Redis 终结点。

import json
import numpy as np
import os
import redis
from sklearn.externals import joblib

def init():
    global model
    global azrediscache
    azrediscache = redis.StrictRedis(host='<host_url>', port=6380, password="<access_key>", ssl=True)
    model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_mnist_model.pkl')
    model = joblib.load(model_path)

@input_schema('data', NumpyParameterType(input_sample))
@output_schema(NumpyParameterType(output_sample))
def run(data):
    try:
        input = azrediscache.get(data)
        result = model.predict(input)
        data = np.array(json.loads(data))
        result = model.predict(data)
        # You can return any data type, as long as it is JSON serializable.
        return result.tolist()
    except Exception as e:
        error = str(e)
        return error

有关入口脚本的详细信息,请参阅定义评分代码

  • 依赖项,如运行入口脚本或模型所需的帮助程序脚本或 Python/Conda 包

这些实体被封装到推理配置中。 推理配置引用入口脚本和其他依赖项。

重要

创建用于 Azure Functions 的推理配置时,需要使用 Environment 对象。 请注意,如果要定义自定义环境,必须将版本 >= 1.0.45 的 azureml-defaults 添加为 pip 依赖项。 此包包含将模型作为 Web 服务托管时所需的功能。 下面的示例演示如何创建环境对象并将其用于推理配置:

from azureml.core.environment import Environment
from azureml.core.conda_dependencies import CondaDependencies

# Create an environment and add conda dependencies to it
myenv = Environment(name="myenv")
# Enable Docker based environment
myenv.docker.enabled = True
# Build conda dependencies
myenv.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn'],
                                                           pip_packages=['azureml-defaults', 'redis'])
inference_config = InferenceConfig(entry_script="score.py", environment=myenv)

有关环境的详细信息,请参阅创建和管理用于训练和部署的环境

有关推理配置的详细信息,请参阅使用 Azure 机器学习部署模型

重要

部署到 Azure Functions 时,无需创建部署配置

安装 SDK 预览版包以获取 Functions 支持

若要为 Azure Functions 生成包,需要安装 SDK 预览版包。

pip install azureml-contrib-functions

创建映像

若要创建部署到 Azure Functions 的 Docker 映像,请使用 azureml.contrib.functions.package 或想要使用的触发器的特定包函数。 下面的代码片段演示如何通过模型和推理配置创建包含 HTTP 触发器的新包:

注意

该代码片段假定 model 包含已注册的模型,并且 inference_config 包含推理环境的配置。 有关详细信息,请参阅使用 Azure 机器学习部署模型

from azureml.contrib.functions import package
from azureml.contrib.functions import HTTP_TRIGGER
model_package = package(ws, [model], inference_config, functions_enabled=True, trigger=HTTP_TRIGGER)
model_package.wait_for_creation(show_output=True)
# Display the package location/ACR path
print(model_package.location)

show_output=True 时,将显示 Docker 生成过程的输出。 此过程完成后,即在 Azure 容器注册表中为工作区创建了映像。 映像生成后,会显示其在 Azure 容器注册表中的位置。 返回的位置采用 <acrinstance>.azurecr.io/package@sha256:<imagename> 格式。

注意

Functions 打包当前支持 HTTP 触发器、Blob 触发器和服务总线触发器。 有关触发器的详细信息,请参阅 Azure Functions 绑定

重要

保存位置信息,因为会在部署映像时使用。

将映像部署为 Web 应用

  1. 使用以下命令获取包含映像的 Azure 容器注册表的登录凭据。 将 <myacr> 替换为之前从 package.location 返回的值:

    az acr credential show --name <myacr>
    

    此命令的输出类似于以下 JSON 文档:

    {
    "passwords": [
        {
        "name": "password",
        "value": "abcdefghijklmmopqrstuv1234567890"
        },
        {
        "name": "password2",
        "value": "1234567890abcdefghijklmmopqrstuv"
        }
    ],
    "username": "charlie.roy"
    }
    

    保存“用户名”和某个“密码”的值

  2. 如果还没有用于部署服务的资源组或应用服务计划,则可通过以下命令来创建这两项:

    az group create --name myresourcegroup --location "China North"
    az appservice plan create --name myplanname --resource-group myresourcegroup --sku B1 --is-linux
    

    此示例使用了“Linux 基本”定价层级 (--sku B1)。

    重要

    Azure 机器学习创建的映像使用 Linux,因此必须使用 --is-linux 参数。

  3. 创建要用于 Web 作业存储的存储帐户并获取其连接字符串。 将 <webjobStorage> 替换为要使用的名称。

    az storage account create --name <webjobStorage> --location chinanorth --resource-group myresourcegroup --sku Standard_LRS
    
    az storage account show-connection-string --resource-group myresourcegroup --name <webJobStorage> --query connectionString --output tsv
    
  4. 使用以下命令来创建函数应用。 将 <app-name> 替换为要使用的名称。 将 <acrinstance><imagename> 替换为之前返回的 package.location 的值。 将 <webjobStorage> 替换为上一步中存储帐户的名称:

    az functionapp create --resource-group myresourcegroup --plan myplanname --name <app-name> --deployment-container-image-name <acrinstance>.azurecr.io/package:<imagename> --storage-account <webjobStorage>
    

    重要

    此时,函数应用已创建。 但是,由于你尚未向包含映像的 Azure 容器注册表提供 HTTP 触发器的连接字符串或凭据,因此函数应用未处于活动状态。 在接下来的步骤中,为容器注册表提供连接字符串和身份验证信息。

  5. 若要为函数应用提供访问容器注册表所需的凭据,请使用以下命令。 将 <app-name> 替换为函数应用的名称。 将 <acrinstance><imagetag> 替换为上一步中 AZ CLI 调用中的值。 将 <username><password> 替换为之前检索到的 ACR 登录信息:

    az functionapp config container set --name <app-name> --resource-group myresourcegroup --docker-custom-image-name <acrinstance>.azurecr.io/package:<imagetag> --docker-registry-server-url https://<acrinstance>.azurecr.io --docker-registry-server-user <username> --docker-registry-server-password <password>
    

    此命令将返回类似以下 JSON 文档的信息:

    [
    {
        "name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
        "slotSetting": false,
        "value": "false"
    },
    {
        "name": "DOCKER_REGISTRY_SERVER_URL",
        "slotSetting": false,
        "value": "[server-name].azurecr.io"
    },
    {
        "name": "DOCKER_REGISTRY_SERVER_USERNAME",
        "slotSetting": false,
        "value": "[username]"
    },
    {
        "name": "DOCKER_REGISTRY_SERVER_PASSWORD",
        "slotSetting": false,
        "value": null
    },
    {
        "name": "DOCKER_CUSTOM_IMAGE_NAME",
        "value": "DOCKER|[server-name].azurecr.io/package:20190827195524"
    }
    ]
    

此时,函数应用开始加载映像。

重要

加载映像可能需要几分钟时间。 可以使用 Azure 门户监视进度。

测试 Azure Functions HTTP 触发器

现在,我们将运行并测试 Azure Functions HTTP 触发器。

  1. 在 Azure 门户中转到函数应用。
  2. 在“开发人员”下,选择“代码 + 测试”。
  3. 在右侧,选择“输入”选项卡。
  4. 选择“运行”按钮,以测试 Azure Functions HTTP 触发器。

现在,你已成功地使用 Azure Cache for Redis 实例将 Azure 机器学习中的模型部署为函数应用。 通过导航到以下部分中的链接,详细了解 Azure Cache for Redis。

清理资源

如果想要继续学习下一篇教程,可以保留本快速入门中创建的资源,以便重复使用。

否则,如果你已完成本快速入门,可以删除本快速入门中创建的 Azure 资源,以免产生费用。

重要

删除资源组的操作不可逆。 删除资源组时,包含在其中的所有资源会被永久删除。 请确保不会意外删除错误的资源组或资源。 如果在现有资源组(其中包含要保留的资源)中为托管此示例而创建了相关资源,可在左侧逐个删除这些资源,而不是删除资源组。

删除资源组的步骤

  1. 登录到 Azure 门户,然后选择“资源组”。

  2. 在“按名称筛选...”框中键入资源组的名称。 在资源组的结果列表中选择“...”,然后选择“删除资源组” 。

系统会要求确认是否删除资源组。 键入资源组的名称进行确认,然后选择“删除”。

片刻之后,将会删除该资源组及其所有资源。

后续步骤