创建和管理无服务器实时推理终结点

重要

  • 本文档已过时,将来可能不会更新。 本内容中提及的产品、服务或技术不再受支持。
  • 本文中的指南适用于模型服务功能(以前称为无服务器实时推理)的预览版本。 Databricks 建议将模型服务工作流迁移到正式版功能。 请参阅 Azure Databricks 中的模型服务

重要

此功能目前以公共预览版提供。

本文介绍如何创建和管理使用 Azure Databricks 无服务器实时推理的终结点。

重要

  • 公共预览版期间,API 定义和工作流可能发生更改。
  • 如果依赖于 Anaconda,请查看服务条款通知,了解详细信息。

要求

  • 无服务器实时推理仅适用于在 MLflow 模型注册表中进行注册的基于 Python 的 MLflow 模型。 必须在 conda 环境或要求文件中声明所有模型依赖项。
    • 如果没有注册模型,请参阅笔记本示例,了解可用于启动和运行无服务器实时推理终结点的预打包模型。
  • 必须针对无服务器实时推理启用工作区。 若要使用无服务器实时推理启用模型服务,必须具有群集创建权限
  • 如果将自定义库或来自专用镜像服务器的库与模型配合使用,请在创建模型终结点之前,参阅将自定义 Python 库与模型服务配合使用

创建模型服务终结点

可以使用 Databricks 机器学习 API 或 Databricks 机器学习 UI 为模型服务创建无服务器实时推理终结点。 终结点可为任何在模型注册表中注册的 Python MLflow 模型提供服务。

使用 API

可以使用“启用服务 API”为模型服务创建终结点。 在以下示例中,ElasticNet 是已注册的模型的名称。

POST https://<databricks-instance>/api/2.0/preview/mlflow/endpoints-v2/enable

{
   "registered_model_name": "ElasticNet"
}

使用 UI

可以从 Databricks 机器学习 UI 中的注册模型页启用模型以提供服务。

  1. 单击“服务”选项卡。如果模型尚未启用服务,则会显示“启用无服务器实时推理”按钮。
  2. 单击“启用无服务器实时推理”。 将显示“服务”选项卡,其中的“状态”为“挂起”。 几分钟后,“状态”更改为“就绪”。

修改终结点的计算配置

启用模型终结点后,可以根据需要使用 API 或 UI 设置计算配置。 如果需要模型的其他资源,此配置将尤其有用。 在为模型服务分配哪些资源方面,工作负载大小和计算配置起着关键作用。 详细了解 WorkloadConfigSpec 对象

使用 API

可以在终结点版本状态config_update_status 字段中跟踪配置更新的状态。

PUT /preview/model-serving-api/endpoints-v2/update-compute-config

在下面的示例中,用 WorkloadConfigSpec 属性填充 desired_workload_config_spec

{
  "registered_model_name": "ElasticNet",
  "stage": "Staging|Production",
  "desired_workload_config_spec": {"WorkloadConfigSpec"}
}

使用 UI

启用模型终结点后,可以在“计算设置”选项卡上设置所需的计算配置。可以为“暂存”和“生产”模型版本设置单独的配置。

可以从几个工作负载大小中进行选择,并且自动缩放会在工作负载大小内自动配置。 如果希望终结点纵向缩减到零,则可以选中标题为“缩减到零”的复选框。

对模型终结点评分

若要对已部署的模型进行评分,可以向模型 URL 发送 REST API 请求或使用 UI。

应通过调用其阶段 API 来调用模型。 例如,如果版本 1 处于“生产”阶段,则可以使用以下 URI 对其进行评分:

https://<databricks-instance>/model-endpoint/iris-classifier/Production/invocations

可用模型 URI 的列表显示在“服务”选项卡上的“模型版本”选项卡顶部。

请求格式

应通过使用以下键之一和与输入格式对应的 JSON 对象来构造 JSON,从而发送请求。

根据用例,输入 JSON 有以下四种格式:

  • dataframe_splitsplit 方向的 JSON 序列化 Pandas 数据帧。

    {
      "dataframe_split": {
        "index": [0, 1],
        "columns": ["sepal length (cm)", "sepal width (cm)", "petal length (cm)", "petal width (cm)"],
        "data": [[5.1, 3.5, 1.4, 0.2], [4.9, 3.0, 1.4, 0.2]]
      }
    }
    
  • dataframe_recordsrecords 方向的 JSON 序列化 Pandas 数据帧。

    注意

    此格式不保证保留列顺序,split 格式优于 records 格式。

    {
      "dataframe_records": [
      {
         "sepal length (cm)": 5.1,
         "sepal width (cm)": 3.5,
         "petal length (cm)": 1.4,
         "petal width (cm)": 0.2
      },
      {
         "sepal length (cm)": 4.9,
         "sepal width (cm)": 3,
         "petal length (cm)": 1.4,
         "petal width (cm)": 0.2
       },
       {
         "sepal length (cm)": 4.7,
         "sepal width (cm)": 3.2,
         "petal length (cm)": 1.3,
         "petal width (cm)": 0.2
       }
      ]
    }
    
  • instances 是一种基于张量的格式,可接受行格式的张量。 如果所有输入张量都具有相同的第 0 维,则使用此格式。 从概念上讲,实例列表中的每个张量都可以与列表其余部分中的其他同名张量联接,从而构建模型的完整输入张量(只有在所有张量都具有相同的第 0 维时才有可能实现)。

      {"instances": [ "a", "b", "c" ]}
    

    下面的示例中有三个维度,因此每个输入张量中恰好有三个维度。

    {
    "instances": [
      {
       "t1": "a",
       "t2": [1, 2, 3, 4, 5],
       "t3": [[1, 2], [3, 4], [5, 6]]
      },
      {
       "t1": "b",
       "t2": [6, 7, 8, 9, 10],
       "t3": [[7, 8], [9, 10], [11, 12]]
      }
    ]
    }
    
  • inputs 通过以列格式的张量发送查询。 此请求不同,由于 t2 (3) 的张量实例的数量实际上与 t1t3 不同,因此不可能用 instances 格式表示这个输入。

    {
    "inputs": {
      "t1": ["a", "b"],
      "t2": [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]],
      "t3": [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]
    }
    }
    

响应格式

终结点的响应采用以下格式。 模型的输出包装在“预测”键中。

{
  "predictions": "<JSON output from model>"
}

使用 UI

使用 UI 发送请求是测试模型最简单、最快速的方法。 你可以插入 JSON 格式的模型输入数据,并单击“发送请求”。 如果已使用输入示例记录了模型(如上图所示),请单击“显示示例”来加载输入示例。

使用 API

你可以使用标准 Databricks 身份验证通过 REST API 发送评分请求。 下面的示例演示了如何使用个人访问令牌进行身份验证。

注意

作为安全最佳做法,在使用自动化工具、系统、脚本和应用进行身份验证时,Databricks 建议使用属于服务主体(而不是工作区用户)的个人访问令牌。 若要为服务主体创建令牌,请参阅管理服务主体的令牌

对于给定的 MODEL_VERSION_URI(例如 https://<databricks-instance>/model/iris-classifier/Production/invocations,其中,<databricks-instance>Databricks 实例的名称)和名为 DATABRICKS_API_TOKEN 的 Databricks REST API 令牌,以下是如何对服务模型评分的示例片段。

Bash

对接受数据帧记录输入格式的模型进行评分。

curl -X POST -u token:$DATABRICKS_API_TOKEN $MODEL_VERSION_URI \
  -H 'Content-Type: application/json' \
  -d '{"dataframe_records": [
    {
      "sepal_length": 5.1,
      "sepal_width": 3.5,
      "petal_length": 1.4,
      "petal_width": 0.2
    }
  ]}'

对接受张量输入的模型进行评分。 应该根据 TensorFlow 服务的 API 文档中所述设置张量输入的格式。

curl -X POST -u token:$DATABRICKS_API_TOKEN $MODEL_VERSION_URI \
   -H 'Content-Type: application/json' \
   -d '{"inputs": [[5.1, 3.5, 1.4, 0.2]]}'

Python

import numpy as np
import pandas as pd
import requests

def create_tf_serving_json(data):
  return {'inputs': {name: data[name].tolist() for name in data.keys()} if isinstance(data, dict) else data.tolist()}

def score_model(model_uri, databricks_token, data):
  headers = {
    "Authorization": f"Bearer {databricks_token}",
    "Content-Type": "application/json",
  }
  data_json = json.dumps({'dataframe_records': data.to_dict(orient='records')}) if isinstance(data, pd.DataFrame) else create_tf_serving_json(data)
  response = requests.request(method='POST', headers=headers, url=model_uri, json=data_json)
  if response.status_code != 200:
      raise Exception(f"Request failed with status {response.status_code}, {response.text}")
  return response.json()

# Scoring a model that accepts pandas DataFrames
data =  pd.DataFrame([{
  "sepal_length": 5.1,
  "sepal_width": 3.5,
  "petal_length": 1.4,
  "petal_width": 0.2
}])
score_model(MODEL_VERSION_URI, DATABRICKS_API_TOKEN, data)

# Scoring a model that accepts tensors
data = np.asarray([[5.1, 3.5, 1.4, 0.2]])
score_model(MODEL_VERSION_URI, DATABRICKS_API_TOKEN, data)

PowerBI

可以使用以下步骤在 Power BI Desktop 中为数据集评分:

  1. 打开要评分的数据集。

  2. 转到“转换数据”。

  3. 右键单击左侧面板,然后选择“创建新查询”。

  4. 转到“视图高级编辑器”。

  5. 填写适当的 DATABRICKS_API_TOKENMODEL_VERSION_URI 后,将查询主体替换为下面的代码片段。

    (dataset as table ) as table =>
    let
      call_predict = (dataset as table ) as list =>
      let
        apiToken = DATABRICKS_API_TOKEN,
        modelUri = MODEL_VERSION_URI,
        responseList = Json.Document(Web.Contents(modelUri,
          [
            Headers = [
              #"Content-Type" = "application/json",
              #"Authorization" = Text.Format("Bearer #{0}", {apiToken})
            ],
            Content = {"dataframe_records": Json.FromValue(dataset)}
          ]
        ))
      in
        responseList,
      predictionList = List.Combine(List.Transform(Table.Split(dataset, 256), (x) => call_predict(x))),
      predictionsTable = Table.FromList(predictionList, (x) => {x}, {"Prediction"}),
      datasetWithPrediction = Table.Join(
        Table.AddIndexColumn(predictionsTable, "index"), "index",
        Table.AddIndexColumn(dataset, "index"), "index")
    in
      datasetWithPrediction
    
  6. 将查询命名为所需的模型名称。

  7. 打开你的数据集的高级查询编辑器,并应用模型函数。

有关如何使用 Python 模型测试无服务器实时推理终结点的示例,请参阅以下笔记本:

测试无服务器实时推理终结点笔记本

获取笔记本

更新模型终结点提供的模型版本

模型版本必须位于模型注册表中的“暂存”或“生产”阶段,然后才能将其提供给终结点。

使用 API

若要将新模型版本转换为“服务”,可以使用模型注册表将要提供的模型版本转换为相应的阶段。

以下代码示例将模型 ElasticNet 版本 2 转换为“暂存”。 将 archive_existing_versions 设置为 true 后将存档所有现有模型版本,这会导致暂存 URL 在新模型版本准备好提供服务后指向新模型版本。 新版本准备就绪之前,暂存终结点会提供旧模型版本,因此转换过程不会导致停机。


POST /mlflow/databricks/model-versions/transition-stage

{
   "name": "ElasticNet",
   "version": "2",
   "stage": "Staging",
   "archive_existing_versions": true,
   "comment": "Deploying version 1 to Staging endpoint!"
}

将多个版本保留在一个阶段

还可以选择在“暂存”阶段中保留先前的暂存版本。 模型的多个版本可以处于同一阶段。 在这种情况下,会同时提供两个版本,但暂存 URL 仅指向最新版本。 旧版本仍可通过其版本 URL 进行访问。

如果想在暂存终结点上尝试新版本,可以执行与上述相同的操作,但需将 archive_existing_versions 设置为 false 才可确保不会存档先前的暂存版本。

POST /mlflow/databricks/model-versions/transition-stage

{
...
   "archive_existing_versions": false,
...
}

使用 UI

使用 Databricks 机器学习 UI 将模型版本转换为“暂存”或“生产”:

  1. 选择边栏中的 “模型图标”模型”。
  2. 标识并选择要更新的已注册模型。
  3. 选择要转换为“暂存”或“生产”的模型版本。 链接将打开模型版本的详细信息页。
  4. 使用右上角的“阶段”下拉菜单,将模型版本转换为“暂存”或“生产”。

获取模型终结点的状态

使用 API

Databricks 提供以下内容来检查终结点的状态。 详细了解 EndpointStatus 对象

GET /preview/mlflow/endpoints-v2/get-status
{
  "registered_model_name": "ElasticNet"
}

这将返回 EndpointStatus 对象属性:

{
  "endpoint_status": {"EndpointStatus"}
}

使用 UI

在 UI 中,可以通过“服务”选项卡顶部的“状态指示器”检查终结点的状态。

获取模型终结点版本的状态

可以获取已部署的特定终结点版本的状态。 此操作可让你:

  • 跟踪提供的版本。
  • 跟踪这些版本的状态。
  • 验证特定模型版本是否可供使用。

使用 API

Databricks 提供两个 API 来检查终结点版本的状态。 若要检查特定注册模型的所有终结点版本的状态,可以使用 ListVersions。 详细了解 EndpointVersionStatus 对象

GET /preview/mlflow/endpoints-v2/list-versions
{
  "registered_model_name": "ElasticNet"
}

这将返回 EndpointVersionStatus 对象属性:

{
  "endpoint_statuses": ["EndpointVersionStatus"]
}

或者,如果已经知道想要了解其状态的特定版本,则可以使用 GetVersions

GET /preview/mlflow/endpoints-v2/get-version-status
{
  "registered_model_name": "ElasticNet",
  "endpoint_version_name": "1"
}

这将返回 EndpointVersionStatus 对象属性:

{
  "endpoint_status": {"EndpointVersionStatus"}
}

获取某个阶段的状态

还可以获取特定阶段的状态。 为此,首先需要确定当前服务于“阶段”的终结点版本。 若要检索该信息,可以使用 ListVersionAliases

GET /preview/mlflow/endpoints-v2/list-version-aliases
{
  "registered_model_name": "ElasticNet"
}

这样会返回:

{
  "aliases": [
   {
      "alias": "Staging",
      "endpoint_version_name": "2"
   },
   {
      "alias": "Production",
      "endpoint_version_name": "1"
   }
  ]
}

在此处,可以使用上述操作获取特定终结点版本的状态。

使用 UI

在 UI 的“服务”选项卡中,可以在左侧看到每个终结点版本及其专属的选项卡。 选择每个选项卡时,将显示有关特定版本的详细信息。 可以通过终结点版本上的“暂存”或“生产”标签查看当前服务于某个阶段的版本。

禁用模型服务

使用 API

可以使用 API 禁用模型注册表中存在的任何已注册模型的模型服务。

若要禁用模型的模型服务,请使用禁用服务 API:

POST /preview/mlflow/endpoints-v2/disable

{
   "registered_model_name": "ElasticNet"
}

使用 UI

可以从已注册模型页为模型禁用服务。

  1. 单击“服务”选项卡。如果模型尚未启用服务,则会显示“启用无服务器实时推理”按钮。
  2. 单击“禁用服务”。

调试模型终结点

备注

只能通过 UI 调试模型终结点。

通过在 Databricks 机器学习 UI 的终结点版本选项卡上查看模型日志,可以调试和排查终结点问题。 模型的所有副本日志均将合并到“所有副本”选项卡中。

除模型日志之外,还可以在“模型事件”选项卡中查看与模型相关的重要服务事件。

核心 API 对象

本部分包含无服务器实时推理的核心 API 对象的设计模式和语法。

重要

公共预览版期间,API 定义可能发生更改。

工作负载配置

WorkloadConfigSpec 描述用于缩放特定阶段的计算的配置。

  "WorkloadConfigSpec":
  {
   "workload_size_id": "Small|Medium|Large",
   "scale_to_zero_enabled": false
  }

ComputeConfig 表示用于缩放特定阶段的计算以及随附元数据的配置。

在下面的示例中,通过将 "WorkloadConfigSpec" 替换为 WorkloadConfigSpec 对象的先前定义的属性来填充 workload_spec

  "ComputeConfig":
  {
   "stage":  "Staging|Production",
   "creation_timestamp": 12345678,
   "user_id": "first.last@databricks.com",
   "workload_spec": {"WorkloadConfigSpec"}
  }

终结点状态

终结点的运行状况反映了是可以对任何阶段进行评分,还是需要针对特定模型版本生成资源。

在下面的 EndpointStatus 对象中,通过重用 ComputeConfig 对象的先前定义的属性和任何其他属性作为数组来填充 compute_config

  "EndpointStatus":
  {
   "registered_model_name": "ElasticNet",
   "state": "PENDING|READY|FAILED",
   "state_message": "State message",
   "compute_config": ["ComputeConfig and additional properties as an array"]
  }

终结点版本状态

终结点版本具有可以查询的特定 URI。 URI 代表正在提供服务的单个模型版本,其计算由为其阶段设置的计算配置进行配置。

在以下 EndpointVersionStatus 对象中,通过将 "ComputeConfig" 替换为 ComputeConfig 对象的先前定义的属性,填充 service_statusconfig_update_status 这两个 config 字段。

  "EndpointVersionStatus":
  {
   "registered_model_name": "ElasticNet",
   "endpoint_version_name": "1",
   "service_status": {
      "state": "SERVICE_STATE_UNKNOWN|SERVICE_STATE_PENDING|SERVICE_STATE_READY|SERVICE_STATE_UNKNOWN",
      "message": "Ready",
      "config": {"ComputeConfig"}
   },
   "config_update_status": {
      "state": "SERVICE_STATE_UNKNOWN|SERVICE_STATE_PENDING|SERVICE_STATE_READY|SERVICE_STATE_UNKNOWN",
      "message": "Pending",
      "config": {"ComputeConfig"}
    }
  }

笔记本示例

以下笔记本包含可用于启动和运行无服务器实时推理终结点的各种模型。 可以按照导入笔记本中的说明将模型示例导入工作区。 从其中一个示例中选择并创建模型后,在 MLflow 模型注册表中注册它,然后按照 UI 工作流步骤实现模型服务。

为模型服务笔记本训练和注册 scikit-learn 模型

获取笔记本

为模型服务笔记本训练和注册 Pytorch 模型

获取笔记本

为模型服务笔记本训练和注册 HuggingFace 模型

获取笔记本

在终结点笔记本中托管多个模型

获取笔记本

Anaconda 许可更新

以下通知适用于依赖 Anaconda 的客户。

重要

Anaconda Inc. 为 anaconda.org 通道更新了其服务条款。 根据新的服务条款,如果依赖 Anaconda 的打包和分发,则可能需要商业许可证。 有关详细信息,请参阅 Anaconda Commercial Edition 常见问题解答。 对任何 Anaconda 通道的使用都受其服务条款的约束。

v1.18(Databricks Runtime 8.3 ML 或更低版本)之前记录的 MLflow 模型默认以 conda defaults 通道 (https://repo.anaconda.com/pkgs/) 作为依赖项进行记录。 由于此许可证更改,Databricks 已停止对使用 MLflow v1.18 及更高版本记录的模型使用 defaults 通道。 记录的默认通道现在为 conda-forge,它指向社区管理的 https://conda-forge.org/

如果在 MLflow v1.18 之前记录了一个模型,但没有从模型的 conda 环境中排除 defaults 通道,则该模型可能依赖于你可能没有预期到的 defaults 通道。 若要手动确认模型是否具有此依赖项,可以检查与记录的模型一起打包的 conda.yaml 文件中的 channel 值。 例如,具有 conda.yaml 通道依赖项的模型 defaults 可能如下所示:

channels:
- defaults
dependencies:
- python=3.8.8
- pip
- pip:
    - mlflow
    - scikit-learn==0.23.2
    - cloudpickle==1.6.0
      name: mlflow-env

由于 Databricks 无法确定是否允许你根据你与 Anaconda 的关系使用 Anaconda 存储库来与模型交互,因此 Databricks 不会强制要求其客户进行任何更改。 如果允许你根据 Anaconda 的条款通过 Databricks 使用 Anaconda.com 存储库,则你不需要采取任何措施。

若要更改模型环境中使用的通道,可以使用新的 conda.yaml 将模型重新注册到模型注册表。 为此,可以在 log_model()conda_env 参数中指定该通道。

有关 log_model() API 的详细信息,请参阅所用模型风格的 MLflow 文档,例如用于 scikit-learn 的 log_model

有关 conda.yaml 文件的详细信息,请参阅 MLflow 文档