如何将已注册的 R 模型部署到联机(实时)终结点
本文介绍如何将 R 模型部署到托管终结点 (Web API),使应用程序可以准实时地根据模型对新数据进行评分。
必备条件
- 一个 Azure 机器学习工作区。
- 已安装 Azure CLI 和 ml 扩展。 或者在工作区中使用预安装了 CLI 的计算实例。
- 至少一个与工作区关联的自定义环境。 创建一个 R 环境或任何其他自定义环境(如果没有)。
- 了解 R
plumber
包 - 一个已训练的模型,该模型已通过
crate
打包并已注册到工作区
创建一个具有此结构的文件夹
为项目创建此文件夹结构:
📂 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 容器注册表,该容器注册表是在创建第一个自定义环境时创建的。 若要查看是否有自定义环境,请执行以下操作:
- 登录到 Azure 机器学习工作室。
- 如果需要,请选择你的工作区。
- 在左侧导航栏中选择“环境”。
- 在顶部选择“自定义环境”。
- 如果看到了自定义环境,则不需要执行其他操作。
- 如果未看到任何自定义环境,请创建一个 R 环境或任何其他自定义环境。 (你将不会使用此环境进行部署,但将使用同时已创建的容器注册表。)
确认至少有一个自定义环境后,启动终端并设置 CLI:
打开终端窗口并登录到 Azure。 如果使用 Azure 机器学习计算实例,请使用:
az login --identity
如果你不在计算实例上,请省略
--identity
并按照提示打开浏览器窗口进行身份验证。确保你拥有最新版本的 CLI 和
ml
扩展:az upgrade
如果你有多个 Azure 订阅,请将活动订阅设置为用于工作区的订阅。 (如果你只能访问单个订阅,则可以跳过此步骤。)将
<YOUR_SUBSCRIPTION_NAME_OR_ID>
替换为你的订阅名称或订阅 ID。 另请删除括号<>
。
### TESTED
# <az_extension_list>
az extension list
# </az_extension_list>
# <az_ml_install>
az extension add -n ml
# </az_ml_install>
# <list_defaults>
az configure -l -o table
# </list_defaults>
apt-get install sudo
# <az_extension_install_linux>
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az extension add -n ml -y
# </az_extension_install_linux>
# <az_ml_update>
az extension update -n ml
# </az_ml_update>
# <az_ml_verify>
az ml -h
# </az_ml_verify>
# <az_extension_remove>
az extension remove -n azure-cli-ml
az extension remove -n ml
# </az_extension_remove>
# <git_clone>
git clone --depth 1 https://github.com/Azure/azureml-examples
cd azureml-examples/cli
# </git_clone>
# <az_version>
az version
# </az_version>
### UNTESTED
exit
# <az_account_set>
az account set -s "<YOUR_SUBSCRIPTION_NAME_OR_ID>"
# </az_account_set>
# <az_login>
az login
# </az_login>
设置默认工作区。 如果使用计算实例,可以按原样使用以下命令。 如果在任何其他计算机上操作,请将占位符替换为你的资源组和工作区名称。 (可以在 Azure 机器学习工作室中找到这些值。)
az configure --defaults group=$CI_RESOURCE_GROUP workspace=$CI_WORKSPACE
设置 CLI 后,使用以下步骤生成容器。
确保在项目目录中操作。
cd r-deploy-azureml
若要在云中生成映像,请在终端中执行以下 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 机器学习托管终结点的负载均衡功能可将任意百分比的流量分配到每个部署。 使用流量分配可以通过在不同实例之间均衡请求来执行安全推出蓝/绿部署。
创建托管联机终结点
在项目目录中,使用以下代码添加 endpoint.yml 文件。 请将
<ENDPOINT-NAME>
替换为要为托管终结点指定的名称。$schema: https://azuremlschemas.azureedge.net/latest/managedOnlineEndpoint.schema.json name: <ENDPOINT-NAME> auth_mode: aml_token
使用生成映像的同一终端执行以下 CLI 命令以创建终结点:
az ml online-endpoint create -f endpoint.yml
让终端保持打开状态,因为在下一部分仍要使用它。
创建部署
若要创建部署,请将以下代码添加到 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
接下来,在终端中执行以下 CLI 命令以创建部署(请注意,此处设置为将 100% 的流量发送到此模型):
az ml online-deployment create -f deployment.yml --all-traffic --skip-script-validation
注意
部署服务可能需要几分钟时间。 等待部署完成,然后继续阅读下一部分。
测试
成功创建部署后,可以使用工作室或 CLI 测试终结点:
导航到 Azure 机器学习工作室,并从左侧菜单中选择“终结点”。 接下来,选择先前创建的“r-endpoint-iris”。
在“输入数据以测试实时终结点”文本框中输入以下 json:
{
"forecast_horizon" : [2]
}
选择“测试”。 应会看到以下输出:
清理资源
使用终结点成功评分后,可将其删除,以免持续产生费用:
az ml online-endpoint delete --name r-endpoint-forecast
后续步骤
有关将 R 与 Azure 机器学习配合使用的详细信息,请参阅 Azure 机器学习中的 R 功能概述