使用部署模板管理模型

本文介绍如何将部署模板发布到Azure 机器学习注册表并将其固定到已注册的模型。 完成这些步骤后,使用者无需自行指定环境或基础结构设置即可将模型部署到托管联机终结点。

注释

本文档中详细介绍的 YAML 语法基于最新版本的 ML CLI v2 扩展的 JSON 架构。 此语法必定仅适用于最新版本的 ML CLI v2 扩展。 可以在 https://azuremlschemasprod.azureedge.net/ 上查找早期扩展版本的架构。

先决条件

步骤 1:在工作区中创建环境

创建供部署模板使用的环境。 将以下 YAML 保存为 environment.yml,并编辑 image 的值以引用你的推理镜像。

$schema: https://azuremlschemas.azureedge.net/latest/environment.schema.json
name: my-inference-env
version: 1
image: <your-acr>.azurecr.io/my-inference-image:1

示例(TF 服务): TensorFlow 服务发布可直接使用的公共容器映像。 使用它可按照本文的其余部分对已知 half_plus_two 测试模型进行端到端操作。

$schema: https://azuremlschemas.azureedge.net/latest/environment.schema.json
name: tfs-env
version: 1
image: docker.io/tensorflow/serving:latest

使用 环境版本 - 创建或更新 操作创建环境版本。

获取Azure 资源管理器的访问令牌:

TOKEN=$(az account get-access-token --resource https://management.chinacloudapi.cn --query accessToken -o tsv)

将请求正文另存为 environment-version.json。 对于自带容器镜像,请设置 imageosType

{
  "properties": {
    "image": "docker.io/tensorflow/serving:latest",
    "osType": "Linux"
  }
}

PUT 请求发送到工作区环境版本路径:

curl -X PUT \
  "https://management.chinacloudapi.cn/subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>/providers/Microsoft.MachineLearningServices/workspaces/<your-workspace>/environments/my-inference-env/versions/1?api-version=2024-04-01" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @environment-version.json

注释

如果要直接在注册表中创建环境版本(并跳过步骤 2),请使用 注册表环境版本 - 针对注册表路径创建或更新 操作。

步骤 2:将环境共享到注册表中

部署模板的 environment 字段必须指向注册表范围内的环境。 将步骤 1 中创建的工作区环境共享到注册表。

共享操作会将工作区环境复制到注册表。 这是针对注册表的资源提供程序主机运行的注册表数据平面操作,可以使用一次性 发现 调用进行查找。

首先,查找注册表的数据平面主机。 获取用于 Azure 资源管理器 的 Microsoft Entra 令牌(你可以重复使用步骤 1 中的 $TOKEN),然后从发现响应中读取 primaryRegionResourceProviderUri。 在 <your-region> 中使用该注册表的主区域。

TOKEN=$(az account get-access-token --resource https://management.chinacloudapi.cn --query accessToken -o tsv)

RP_HOST=$(curl -s \
  "https://<your-region>.api.azureml.ms/registrymanagement/v1.0/registries/<your-registry>/discovery?api-version=v1.0" \
  -H "Authorization: Bearer $TOKEN" | jq -r '.primaryRegionResourceProviderUri')

sourceAssetId 使用工作区的不可变 ID(GUID)和区域,而不是工作区名称。 从 az ml workspace showworkspace_idlocation 字段)或从工作区 GET 请求中获取这两者。

将请求正文另存为 share-environment.json

{
  "properties": {
    "referenceType": "Id",
    "destinationName": "my-inference-env",
    "destinationVersion": "1",
    "sourceAssetId": "azureml://locations/<workspace-location>/workspaces/<workspace-guid>/environments/my-inference-env/versions/1"
  }
}

使用 POST 将副本提交到位于已发现主机上的注册表 import 端点。 共享是一项长时间运行的操作,因此响应为 202 Accepted,并带有一个 Azure-AsyncOperation 标头,你需要轮询该标头,直到复制完成:

curl -X POST \
  "${RP_HOST%/}/mferp/managementfrontend/subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>/providers/Microsoft.MachineLearningServices/registries/<your-registry>/import?api-version=2021-10-01-dataplanepreview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @share-environment.json

步骤 3:在注册表中创建部署模板

编写部署模板负载并将其发布到注册表。 替换 <your-registry> 和环境引用值,使其与您的环境相匹配,并根据您的模型调整 default_instance_typeallowed_instance_typesenvironment_variables、评分路径、端口以及探针。

将以下 JSON 保存为 deployment-template.json 用作步骤 4 中的请求正文。 请注意 camelCase 属性名称和 ISO 8601 持续时间(例如, PT50S 为 50 秒)。

{
  "name": "my-deployment-template",
  "version": "1",
  "type": "deploymenttemplates",
  "description": "Deployment template for my-model",
  "deploymentTemplateType": "Managed",
  "environmentId": "azureml://registries/<your-registry>/environments/my-inference-env/versions/1",
  "environmentVariables": {
    "EXAMPLE_VAR": "example-value"
  },
  "instanceCount": 1,
  "defaultInstanceType": "Standard_DS3_v2",
  "allowedInstanceType": [
    "Standard_DS3_v2",
    "Standard_DS4_v2",
    "Standard_DS5_v2"
  ],
  "scoringPath": "/score",
  "scoringPort": 5001,
  "requestSettings": {
    "requestTimeout": "PT50S",
    "maxConcurrentRequestsPerInstance": 2
  },
  "livenessProbe": {
    "initialDelay": "PT30S",
    "period": "PT10S",
    "timeout": "PT2S",
    "failureThreshold": 30,
    "successThreshold": 1
  },
  "readinessProbe": {
    "initialDelay": "PT30S",
    "period": "PT10S",
    "timeout": "PT2S",
    "failureThreshold": 30,
    "successThreshold": 1
  }
}

通过向注册表的部署模板资源路径发出一个 POST 请求来创建部署模板。 使用注册表的主要区域(创建注册表时指定的区域 <your-region> );有关详细信息,请参阅 “创建和管理注册表”。 获取用于 Azure 资源管理器 的 Microsoft Entra 令牌,并将部署模板有效负载放在请求正文中发送。

TOKEN=$(az account get-access-token --resource https://management.chinacloudapi.cn --query accessToken -o tsv)

curl -X POST \
  "https://<your-region>.api.azureml.ms/genericasset/v2.0/subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>/providers/Microsoft.MachineLearningServices/registries/<your-registry>/my-deployment-template/versions/1?api-version=2024-04-01-preview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @deployment-template.json

示例(TF 服务):TF 服务需求MODEL_BASE_PATHMODEL_NAME环境变量,侦听端口 8501,并提供 REST 预测终结点。/v1/models/<model-name>:predict 以下部署模板捕获所有这些设置,以便使用者无需知道这些设置。

{
  "name": "tfs-deployment-template",
  "version": "1",
  "type": "deploymenttemplates",
  "description": "TF Serving deployment template",
  "deploymentTemplateType": "Managed",
  "environmentId": "azureml://registries/<your-registry>/environments/tfs-env/versions/1",
  "environmentVariables": {
    "MODEL_BASE_PATH": "/var/azureml-app",
    "MODEL_NAME": "half_plus_two"
  },
  "modelMountPath": "/var/azureml-app",
  "instanceCount": 1,
  "defaultInstanceType": "Standard_F2s_v2",
  "allowedInstanceType": [
    "Standard_F2s_v2",
    "Standard_F4s_v2"
  ],
  "scoringPath": "/v1/models/half_plus_two:predict",
  "scoringPort": 8501,
  "requestSettings": {
    "requestTimeout": "PT50S",
    "maxConcurrentRequestsPerInstance": 2
  },
  "livenessProbe": {
    "initialDelay": "PT5M",
    "period": "PT10S",
    "timeout": "PT2S",
    "failureThreshold": 30,
    "successThreshold": 1,
    "scheme": "http",
    "httpMethod": "GET",
    "path": "/v1/models/half_plus_two",
    "port": 8501
  },
  "readinessProbe": {
    "initialDelay": "PT5M",
    "period": "PT10S",
    "timeout": "PT2S",
    "failureThreshold": 30,
    "successThreshold": 1,
    "scheme": "http",
    "httpMethod": "GET",
    "path": "/v1/models/half_plus_two",
    "port": 8501
  }
}
TOKEN=$(az account get-access-token --resource https://management.chinacloudapi.cn --query accessToken -o tsv)

curl -X POST \
  "https://<your-region>.api.azureml.ms/genericasset/v2.0/subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>/providers/Microsoft.MachineLearningServices/registries/<your-registry>/tfs-deployment-template/versions/1?api-version=2024-04-01-preview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @deployment-template.json

步骤 4:管理部署模板版本

使用以下命令检查、更新、存档或还原注册表中的部署模板版本。

使用与步骤 3 中相同的 genericasset 数据平面路径。 先获取 https://management.chinacloudapi.cn 的令牌。 所有请求都采用 api-version=2024-04-01-preview 查询参数。

TOKEN=$(az account get-access-token --resource https://management.chinacloudapi.cn --query accessToken -o tsv)

BASE="https://<your-region>.api.azureml.ms/genericasset/v2.0/subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>/providers/Microsoft.MachineLearningServices/registries/<your-registry>"

显示特定版本。 读取请求的路径中包含 deploymenttemplates 资产类型段:

curl -X GET "$BASE/deploymenttemplates/my-deployment-template/versions/1?api-version=2024-04-01-preview" \
  -H "Authorization: Bearer $TOKEN"

列出注册表中的所有部署模板:

curl -X GET "$BASE/deploymenttemplates?api-version=2024-04-01-preview&listViewType=ActiveOnly" \
  -H "Authorization: Bearer $TOKEN"

创建新版本(将 -d @ 指向一个具有 deployment-template.json"version": "2")。 资产类型来自 "type": "deploymenttemplates" 正文中的字段,因此创建 POST 路径省略资产类型段:

curl -X POST "$BASE/my-deployment-template/versions/2?api-version=2024-04-01-preview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @deployment-template.json

genericasset 数据平面仅提供 GET(显示和列出)和 POST(创建或更新)操作。 因此,更新、存档和还原是客户端读写操作: GET 版本、更改返回的对象中的相关字段,然后将 POST 整个对象返回到同一 versions URL。

更新某个版本的可修改字段。 GET该版本,在已保存对象中编辑该字段(例如,description),然后将其POST回去:

curl -X GET "$BASE/deploymenttemplates/my-deployment-template/versions/1?api-version=2024-04-01-preview" \
  -H "Authorization: Bearer $TOKEN" -o deployment-template.json

# Edit deployment-template.json, then POST the full object back.
curl -X POST "$BASE/my-deployment-template/versions/1?api-version=2024-04-01-preview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @deployment-template.json

通过在对象中设置 "isArchived": true 并将其 POST 回去来归档一个版本:

curl -X POST "$BASE/my-deployment-template/versions/1?api-version=2024-04-01-preview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @deployment-template.json

通过在对象中设置 "isArchived": false 并将其 POST 回去来还原已归档的版本:

curl -X POST "$BASE/my-deployment-template/versions/1?api-version=2024-04-01-preview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @deployment-template.json

步骤 5:创建用于固定部署模板的模型

编写模型负载并将其发布到注册表。 default_deployment_template当使用者在不重写的情况下部署模型时,将应用该值。 该 allowed_deployment_templates 列表是供作者参考的指引,建议使用者将哪些部署模板用作覆盖项——即一组经过筛选且已验证的模板。 不强制实施:平台不会阻止不在列表中的替代。

模型创建使用与步骤 2 相同的注册表数据平面主机进行。 重用来自$RP_HOST$TOKEN,并确保你的模型构件已上传到可访问的 Blob 存储;将modelUri设置为该位置。 (Azure CLI 和 Python SDK 会为你上传项目文件;如果使用原始 REST,则需要提供现有的 modelUri。)若要获取用于上传的可写 Blob 位置,请调用 注册表模型版本 - 创建或获取开始挂起上传 操作,将模型文件上传到返回的位置,然后将 modelUri 设置为该位置。

将以下 JSON 保存为 model.json 用作请求正文。 该 allowedDeploymentTemplates 列表是供作者参考的指南——一组经过验证并精心整理的覆盖模板,平台不会强制执行:

{
  "properties": {
    "modelType": "custom_model",
    "modelUri": "<blob-uri-for-model-artifacts>",
    "defaultDeploymentTemplate": {
      "assetId": "azureml://registries/<your-registry>/deploymenttemplates/my-deployment-template/versions/1"
    },
    "allowedDeploymentTemplates": [
      { "assetId": "azureml://registries/<your-registry>/deploymenttemplates/my-deployment-template/labels/latest" },
      { "assetId": "azureml://registries/<your-registry>/deploymenttemplates/my-deployment-template2/labels/latest" }
    ]
  }
}

通过向注册表的模型版本路径发出一个 PUT 请求来创建该模型。 模型名称和版本位于 URL 中。 响应为 202 Accepted,并带有一个 Azure-AsyncOperation 标头,你需要轮询该标头,直到创建完成:

curl -X PUT \
  "${RP_HOST%/}/mferp/managementfrontend/subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>/providers/Microsoft.MachineLearningServices/registries/<your-registry>/models/my-model/versions/1?api-version=2021-10-01-dataplanepreview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @model.json

示例(TF 服务): 固定前面创建的 TF 服务部署模板作为模型的默认模板。 path 指向一个 TF Serving SavedModel 目录(例如 half_plus_two/00000123/)。

{
  "properties": {
    "modelType": "custom_model",
    "modelUri": "<blob-uri-for-tfs-model-artifacts>",
    "defaultDeploymentTemplate": {
      "assetId": "azureml://registries/<your-registry>/deploymenttemplates/tfs-deployment-template/versions/1"
    }
  }
}
curl -X PUT \
  "${RP_HOST%/}/mferp/managementfrontend/subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>/providers/Microsoft.MachineLearningServices/registries/<your-registry>/models/tfs-model/versions/1?api-version=2021-10-01-dataplanepreview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @model.json

注释

default_deployment_template.asset_id 必须使用 版本控制 的资产 ID 格式(.../deploymenttemplates/<name>/versions/<n>),以便将默认值固定到特定版本。 allowed_deployment_templates[].asset_id 使用 标签/最新 格式(.../deploymenttemplates/<name>/labels/latest),它指向命名部署模板的任何当前版本。