如何将已注册的 R 模型部署到联机(实时)终结点

适用于:Azure CLI ml 扩展 v2(当前版本)

本文介绍如何将 R 模型部署到托管终结点 (Web API),使应用程序可以准实时地根据模型对新数据进行评分。

必备条件

创建一个具有此结构的文件夹

为项目创建此文件夹结构:

📂 r-deploy-azureml
 ├─📂 docker-context
 │  ├─ Dockerfile
 │  └─ start_plumber.R
 ├─📂 src
 │  └─ plumber.R
 ├─ deployment.yml
 ├─ endpoint.yml

本文将显示并解释其中每个文件的内容。

Dockerfile

这是定义容器环境的文件。 你还将在此处定义任何其他 R 包的安装。

示例 Dockerfile 如下所示:

# REQUIRED: Begin with the latest R container with plumber
FROM rstudio/plumber:latest

# REQUIRED: Install carrier package to be able to use the crated model (whether from a training job
# or uploaded)
RUN R -e "install.packages('carrier', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"

# OPTIONAL: Install any additional R packages you may need for your model crate to run
RUN R -e "install.packages('<PACKAGE-NAME>', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"
RUN R -e "install.packages('<PACKAGE-NAME>', dependencies = TRUE, repos = 'https://cloud.r-project.org/')"

# REQUIRED
ENTRYPOINT []

COPY ./start_plumber.R /tmp/start_plumber.R 

CMD ["Rscript", "/tmp/start_plumber.R"]

修改文件以添加评分脚本所需的包。

plumber.R

重要

本部分介绍如何构造 plumber.R 脚本。 有关 plumber 包的详细信息,请参阅 plumber文档

文件 plumber.R 是 R 脚本,你将在其中定义评分函数。 此脚本还执行所需的任务,以使终结点能够正常运行。 脚本:

  • 从容器中的 AZUREML_MODEL_DIR 环境变量获取模型的装载路径。
  • carrier 包中加载使用 crate 函数创建的模型对象,该包在打包时保存为 crate.bin。
  • 取消序列化模型对象
  • 定义评分函数

提示

确保评分函数生成的任何内容都可以转换回 JSON。 某些 R 对象不容易转换。

# plumber.R
# This script will be deployed to a managed endpoint to do the model scoring

# REQUIRED
# When you deploy a model as an online endpoint, Azure Machine Learning mounts your model
# to your endpoint. Model mounting enables you to deploy new versions of the model without
# having to create a new Docker image.

model_dir <- Sys.getenv("AZUREML_MODEL_DIR")

# REQUIRED
# This reads the serialized model with its respecive predict/score method you 
# registered. The loaded load_model object is a raw binary object.
load_model <- readRDS(paste0(model_dir, "/models/crate.bin"))

# REQUIRED
# You have to unserialize the load_model object to make it its function
scoring_function <- unserialize(load_model)

# REQUIRED
# << Readiness route vs. liveness route >>
# An HTTP server defines paths for both liveness and readiness. A liveness route is used to
# check whether the server is running. A readiness route is used to check whether the 
# server's ready to do work. In machine learning inference, a server could respond 200 OK 
# to a liveness request before loading a model. The server could respond 200 OK to a
# readiness request only after the model has been loaded into memory.

#* Liveness check
#* @get /live
function() {
  "alive"
}

#* Readiness check
#* @get /ready
function() {
  "ready"
}

# << The scoring function >>
# This is the function that is deployed as a web API that will score the model
# Make sure that whatever you are producing as a score can be converted 
# to JSON to be sent back as the API response
# in the example here, forecast_horizon (the number of time units to forecast) is the input to scoring_function.  
# the output is a tibble
# we are converting some of the output types so they work in JSON


#* @param forecast_horizon 
#* @post /score
function(forecast_horizon) {
  scoring_function(as.numeric(forecast_horizon)) |> 
    tibble::as_tibble() |> 
    dplyr::transmute(period = as.character(yr_wk),
                     dist = as.character(logmove),
                     forecast = .mean) |> 
    jsonlite::toJSON()
}

start_plumber.R

文件 start_plumber.R 是在容器启动时运行的 R 脚本,它调用 plumber.R 脚本。 按原样使用以下脚本。

entry_script_path <- paste0(Sys.getenv('AML_APP_ROOT'),'/', Sys.getenv('AZUREML_ENTRY_SCRIPT'))

pr <- plumber::plumb(entry_script_path)

args <- list(host = '0.0.0.0', port = 8000); 

if (packageVersion('plumber') >= '1.0.0') {
  pr$setDocs(TRUE)
} else { 
  args$swagger <- TRUE 
} 

do.call(pr$run, args)

生成容器

这些步骤假设你有一个与工作区关联的 Azure 容器注册表,该容器注册表是在创建第一个自定义环境时创建的。 若要查看是否有自定义环境,请执行以下操作:

  1. 登录到 Azure 机器学习工作室
  2. 如果需要,请选择你的工作区。
  3. 在左侧导航栏中选择“环境”。
  4. 在顶部选择“自定义环境”。
  5. 如果看到了自定义环境,则不需要执行其他操作。
  6. 如果未看到任何自定义环境,请创建一个 R 环境或任何其他自定义环境。 (你将不会使用此环境进行部署,但将使用同时已创建的容器注册表。)

确认至少有一个自定义环境后,使用以下步骤生成容器。

  1. 打开终端窗口并登录到 Azure。 如果从 Azure 机器学习计算实例执行此操作,请使用:

    az login --identity
    

    如果你不在计算实例上,请省略 --identity 并按照提示打开浏览器窗口进行身份验证。

  2. 确保你拥有最新版本的 CLI 和 ml 扩展:

    az upgrade
    
  3. 如果你有多个 Azure 订阅,请将活动订阅设置为用于工作区的订阅。 (如果你只能访问单个订阅,则可以跳过此步骤。)将 <SUBSCRIPTION-NAME> 替换为订阅名称。 另请删除括号 <>

    az account set --subscription "<SUBSCRIPTION-NAME>"
    
  4. 设置默认工作区。 如果从计算实例执行此操作,可以按原样使用以下命令。 如果在任何其他计算机上操作,请将占位符替换为你的资源组和工作区名称。 (可以在 Azure 机器学习工作室中找到这些值。)

    az configure --defaults group=$CI_RESOURCE_GROUP workspace=$CI_WORKSPACE
    
  5. 确保在项目目录中操作。

    cd r-deploy-azureml
    
  6. 若要在云中生成映像,请在终端中执行以下 bash 命令。 将 <IMAGE-NAME> 替换为要为映像指定的名称。

    如果工作区位于虚拟网络中,请参阅启用 Azure 容器注册表 (ACR),了解将 --image-build-compute 添加到此代码最后一行中的 az acr build 命令的附加步骤。

    WORKSPACE=$(az config get --query "defaults[?name == 'workspace'].value" -o tsv)
    ACR_NAME=$(az ml workspace show -n $WORKSPACE --query container_registry -o tsv | cut -d'/' -f9-)
    IMAGE_TAG=${ACR_NAME}.azurecr.cn/<IMAGE-NAME>
    
    az acr build ./docker-context -t $IMAGE_TAG -r $ACR_NAME
    

重要

生成映像需要花费几分钟时间。 等待生成过程完成,然后继续阅读下一部分。 请不要关闭此终端,因为接下来需要使用它来创建部署。

az acr 命令会自动将 docker-context 文件夹(包含用于生成映像的项目)上传到云中生成映像并托管在 Azure 容器注册表中的位置。

部署模型

在本文的此部分,你将定义并创建一个终结点和部署,以将在前面步骤中生成的模型和映像部署到托管的联机终结点。

终结点是一个 HTTPS 终结点,客户端(例如应用程序)可以调用它来接收已训练的模型的评分输出。 提供以下功能:

  • 使用基于“密钥和令牌”的身份验证进行身份验证
  • SSL 终止
  • 稳定的评分 URI (endpoint-name.region.inference.ml.Azure.cn)

部署是一组资源,用于承载执行实际评分的模型。 单个终结点可以包含多个部署。 使用 Azure 机器学习托管终结点的负载均衡功能可将任意百分比的流量分配到每个部署。 使用流量分配可以通过在不同实例之间均衡请求来执行安全推出蓝/绿部署。

创建托管联机终结点

  1. 在项目目录中,使用以下代码添加 endpoint.yml 文件。 请将 <ENDPOINT-NAME> 替换为要为托管终结点指定的名称。

    $schema: https://azuremlschemas.azureedge.net/latest/managedOnlineEndpoint.schema.json
    name: <ENDPOINT-NAME>
    auth_mode: aml_token
    
  2. 使用生成映像的同一终端执行以下 CLI 命令以创建终结点:

    az ml online-endpoint create -f endpoint.yml
    
  3. 让终端保持打开状态,因为在下一部分仍要使用它。

创建部署

  1. 若要创建部署,请将以下代码添加到 deployment.yml 文件中。

    • <ENDPOINT-NAME> 替换为在 endpoint.yml 文件中定义的终结点名称

    • <DEPLOYMENT-NAME> 替换为要为部署指定的名称

    • <MODEL-URI> 替换为 azureml:modelname@latest 格式的已注册模型 URI

    • <IMAGE-TAG> 替换为来自以下位置的值:

      echo $IMAGE_TAG
      
    $schema: https://azuremlschemas.azureedge.net/latest/managedOnlineDeployment.schema.json
    name: <DEPLOYMENT-NAME>
    endpoint_name: <ENDPOINT-NAME>
    code_configuration:
      code: ./src
      scoring_script: plumber.R
    model: <MODEL-URI>
    environment:
      image: <IMAGE-TAG>
      inference_config:
        liveness_route:
          port: 8000
          path: /live
        readiness_route:
          port: 8000
          path: /ready
        scoring_route:
          port: 8000
          path: /score
    instance_type: Standard_DS2_v2
    instance_count: 1
    
  2. 接下来,在终端中执行以下 CLI 命令以创建部署(请注意,此处设置为将 100% 的流量发送到此模型):

    az ml online-deployment create -f deployment.yml --all-traffic --skip-script-validation
    

注意

部署服务可能需要几分钟时间。 等待部署完成,然后继续阅读下一部分。

测试

成功创建部署后,可以使用工作室或 CLI 测试终结点:

导航到 Azure 机器学习工作室,并从左侧菜单中选择“终结点”。 接下来,选择先前创建的“r-endpoint-iris”。

在“输入数据以测试实时终结点”文本框中输入以下 json:

{
    "forecast_horizon" : [2]
}

选择“测试”。 应会看到以下输出:

Screenshot shows results from testing a model.

清理资源

使用终结点成功评分后,可将其删除,以免持续产生费用:

az ml online-endpoint delete --name r-endpoint-forecast

后续步骤

有关将 R 与 Azure 机器学习配合使用的详细信息,请参阅 Azure 机器学习中的 R 功能概述