快捷方式

⚠️ 注意:有限维护

本项目不再积极维护。现有版本仍然可用,但没有计划中的更新、错误修复、新功能或安全补丁。用户应注意漏洞可能不会得到解决。

管理 API

TorchServe 提供了以下 API,允许您在运行时管理模型

  1. 注册模型

  2. 增加/减少特定模型的 worker 数量

  3. 描述模型的状态

  4. 注销模型

  5. 列出已注册的模型

  6. 设置模型的默认版本

  7. 刷新 token 以进行 token 授权

管理 API 默认监听 8081 端口,并且只能从 localhost 访问。要更改默认设置,请参阅 TorchServe 配置

用于注册和删除模型的管理 API 默认处于禁用状态。在运行 TorchServe 时,向命令行添加 --enable-model-api 以启用这些 API 的使用。有关更多详细信息和启用方法,请参阅 模型 API 控制

对于所有管理 API 请求,TorchServe 要求包含正确的管理 token,否则必须禁用 token 授权。有关更多详细信息,请参阅 token 授权文档

推理 API 类似,管理 API 提供 API 描述,用于使用 OpenAPI 3.0 规范描述管理 API。

或者,如果您想使用 KServe,TorchServe 同时支持 v1 和 v2 API。有关更多详细信息,请参阅此 kserve 文档

注册模型

此 API 遵循 ManagementAPIsService.RegisterModel gRPC API。

TorchServe 启动后要使用此 API,必须启用模型 API 控制。在启动 TorchServe 时,向命令行添加 --enable-model-api 以启用此 API 的使用。有关更多详细信息,请参阅 模型 API 控制

POST /models

  • url - 模型归档文件下载 URL。支持以下位置:

    • 本地模型归档文件 (.mar);文件必须位于 model_store 文件夹中(不能在子文件夹中)。

    • 使用 HTTP(s) 协议的 URI。TorchServe 可以从互联网下载 .mar 文件。

  • model_name - 模型名称;此名称将在其他 API 中用作路径的一部分 {model_name}。如果此参数不存在,将使用 MANIFEST.json 中的 modelName

  • handler - 推理处理器的入口点。如果存在,此值将覆盖 MANIFEST.json 中的 handler注意:请确保给定的 handler 位于 PYTHONPATH 中。handler 的格式为 module_name:method_name

  • runtime - 模型自定义服务代码的运行时。如果存在,此值将覆盖 runtime 在 MANIFEST.json。默认值为 PYTHON

  • batch_size - 推理批量大小。默认值为 1

  • max_batch_delay - 批量聚合的最大延迟。默认值为 100 毫秒。

  • initial_workers - 创建的初始 worker 数量。默认值为 0。TorchServe 在至少分配一个 worker 之前不会运行推理。

  • synchronous - worker 的创建是否是同步的。默认值为 false。TorchServe 将创建新的 worker,而无需等待确认上一个 worker 已在线。

  • response_timeout - 如果模型的后端 worker 在此超时期间内未响应推理响应,则该 worker 将被视为无响应并重新启动。单位为秒。默认值为 120 秒。

  • startup_timeout - 如果模型的后端 worker 在此超时期间内未加载模型,则该 worker 将被视为无响应并重新启动。单位为秒。默认值为 120 秒。

curl -X POST  "http://localhost:8081/models?url=https://torchserve.pytorch.org/mar_files/squeezenet1_1.mar"

{
  "status": "Model \"squeezenet_v1.1\" Version: 1.0 registered with 0 initial workers. Use scale workers API to add workers for the model."
}

加密模型服务

如果您想提供加密模型服务,则需要使用以下环境变量设置 S3 SSE-KMS

  • AWS_ACCESS_KEY_ID

  • AWS_SECRET_ACCESS_KEY

  • AWS_DEFAULT_REGION

并在 HTTP 请求中设置 “s3_sse_kms=true”。

例如:模型 squeezenet1_1 在 您自己的私有账户下的 S3 上加密。模型在 S3 上的 http URL 是 https://torchserve.pytorch.org/sse-test/squeezenet1_1.mar

  • 如果 torchserve 将在 EC2 实例上运行(例如 操作系统:ubuntu)

  1. 为 EC2 实例添加 IAM 角色 (AWSS3ReadOnlyAccess)

  2. 运行 ts_scripts/get_aws_credential.sh 导出 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY

  3. 导出 AWS_DEFAULT_REGION=您的_s3_桶区域

  4. 启动 torchserve

  5. 在 curl 命令中设置 s3_sse_kms=true 注册加密模型 squeezenet1_1。

curl -X POST  "http://localhost:8081/models?url=https://torchserve.pytorch.org/sse-test/squeezenet1_1.mar&s3_sse_kms=true"

{
  "status": "Model \"squeezenet_v1.1\" Version: 1.0 registered with 0 initial workers. Use scale workers API to add workers for the model."
}
  • 如果 torchserve 将在本地运行(例如 操作系统:macOS)

  1. 找到您的 AWS 访问密钥和秘密密钥。如果您忘记了密钥,可以重置它们

  2. 导出 AWS_ACCESS_KEY_ID=您的_aws_访问密钥

  3. 导出 AWS_SECRET_ACCESS_KEY=您的_aws_秘密密钥

  4. 导出 AWS_DEFAULT_REGION=您的_s3_桶区域

  5. 启动 torchserve

  6. 在 curl 命令中设置 s3_sse_kms=true 注册加密模型 squeezenet1_1(与 EC2 示例步骤 5 相同)。

您可能希望在注册期间创建 worker。因为创建初始 worker 可能需要一些时间,您可以选择同步或异步调用以确保初始 worker 正确创建。

异步调用在尝试创建 worker 之前返回 HTTP 代码 202。

curl -v -X POST "http://localhost:8081/models?initial_workers=1&synchronous=false&url=https://torchserve.pytorch.org/mar_files/squeezenet1_1.mar"

< HTTP/1.1 202 Accepted
< content-type: application/json
< x-request-id: 4dc54158-c6de-42aa-b5dd-ebcb5f721043
< content-length: 47
< connection: keep-alive
<
{
  "status": "Processing worker updates..."
}

同步调用在所有 worker 已调整后返回 HTTP 代码 200。

curl -v -X POST "http://localhost:8081/models?initial_workers=1&synchronous=true&url=https://torchserve.pytorch.org/mar_files/squeezenet1_1.mar"

< HTTP/1.1 200 OK
< content-type: application/json
< x-request-id: ecd2e502-382f-4c3b-b425-519fbf6d3b85
< content-length: 89
< connection: keep-alive
<
{
  "status": "Model \"squeezenet1_1\" Version: 1.0 registered with 1 initial workers"
}

扩缩 worker

此 API 遵循 ManagementAPIsService.ScaleWorker gRPC API。它返回 ModelServer 中模型的状态。

PUT /models/{model_name}

  • min_worker - (可选)worker 进程的最小数量。TorchServe 将尝试为指定模型维持此最小值。默认值为 1

  • max_worker - (可选)worker 进程的最大数量。TorchServe 为指定模型创建的 worker 数量不会超过此值。默认值与 min_worker 的设置相同。

  • synchronous - 调用是否是同步的。默认值为 false

  • timeout - 为 worker 完成所有待处理请求指定的等待时间。如果超出,worker 进程将被终止。使用 0 可立即终止后端 worker 进程。使用 -1 可无限等待。默认值为 -1

使用扩缩 Worker API 动态调整模型任意版本的 worker 数量,以更好地服务不同的推理请求负载。

此 API 有两种不同类型:同步和异步。

异步调用将立即返回 HTTP 代码 202

curl -v -X PUT "http://localhost:8081/models/noop?min_worker=3"

< HTTP/1.1 202 Accepted
< content-type: application/json
< x-request-id: 42adc58e-6956-4198-ad07-db6c620c4c1e
< content-length: 47
< connection: keep-alive
<
{
  "status": "Processing worker updates..."
}

同步调用在所有 worker 已调整后返回 HTTP 代码 200。

curl -v -X PUT "http://localhost:8081/models/noop?min_worker=3&synchronous=true"

< HTTP/1.1 200 OK
< content-type: application/json
< x-request-id: b72b1ea0-81c6-4cce-92c4-530d3cfe5d4a
< content-length: 63
< connection: keep-alive
<
{
  "status": "Workers scaled to 3 for model: noop"
}

要扩缩模型的特定版本的 worker,请使用 URI : /models/{model_name}/{version} PUT /models/{model_name}/{version}

以下同步调用将在模型“noop”的版本“2.0”的所有 worker 都调整完毕后返回 HTTP 代码 200。

curl -v -X PUT "http://localhost:8081/models/noop/2.0?min_worker=3&synchronous=true"

< HTTP/1.1 200 OK
< content-type: application/json
< x-request-id: 3997ccd4-ae44-4570-b249-e361b08d3d47
< content-length: 77
< connection: keep-alive
<
{
  "status": "Workers scaled to 3 for model: noop, version: 2.0"
}

描述模型

此 API 遵循 ManagementAPIsService.DescribeModel gRPC API。它返回 ModelServer 中模型的状态。

GET /models/{model_name}

使用描述模型 API 获取模型的默认版本的详细运行时状态

curl http://localhost:8081/models/noop
[
    {
      "modelName": "noop",
      "modelVersion": "1.0",
      "modelUrl": "noop.mar",
      "engine": "Torch",
      "runtime": "python",
      "minWorkers": 1,
      "maxWorkers": 1,
      "batchSize": 1,
      "maxBatchDelay": 100,
      "workers": [
        {
          "id": "9000",
          "startTime": "2018-10-02T13:44:53.034Z",
          "status": "READY",
          "gpu": false,
          "memoryUsage": 89247744
        }
      ],
      "jobQueueStatus": {
        "remainingCapacity": 100,
        "pendingRequests": 0
      }
    }
]

GET /models/{model_name}/{version}

使用描述模型 API 获取模型的特定版本的详细运行时状态

curl http://localhost:8081/models/noop/2.0
[
    {
      "modelName": "noop",
      "modelVersion": "2.0",
      "modelUrl": "noop_2.mar",
      "engine": "Torch",
      "runtime": "python",
      "minWorkers": 1,
      "maxWorkers": 1,
      "batchSize": 1,
      "maxBatchDelay": 100,
      "workers": [
        {
          "id": "9000",
          "startTime": "2018-10-02T13:44:53.034Z",
          "status": "READY",
          "gpu": false,
          "memoryUsage": 89247744
        }
      ],
      "jobQueueStatus": {
        "remainingCapacity": 100,
        "pendingRequests": 0
      }
    }
]

GET /models/{model_name}/all

使用描述模型 API 获取模型所有版本的详细运行时状态

curl http://localhost:8081/models/noop/all
[
    {
      "modelName": "noop",
      "modelVersion": "1.0",
      "modelUrl": "noop.mar",
      "engine": "Torch",
      "runtime": "python",
      "minWorkers": 1,
      "maxWorkers": 1,
      "batchSize": 1,
      "maxBatchDelay": 100,
      "workers": [
        {
          "id": "9000",
          "startTime": "2018-10-02T13:44:53.034Z",
          "status": "READY",
          "gpu": false,
          "memoryUsage": 89247744
        }
      ],
      "jobQueueStatus": {
        "remainingCapacity": 100,
        "pendingRequests": 0
      }
    },
    {
      "modelName": "noop",
      "modelVersion": "2.0",
      "modelUrl": "noop_2.mar",
      "engine": "Torch",
      "runtime": "python",
      "minWorkers": 1,
      "maxWorkers": 1,
      "batchSize": 1,
      "maxBatchDelay": 100,
      "workers": [
        {
          "id": "9000",
          "startTime": "2018-10-02T13:44:53.034Z",
          "status": "READY",
          "gpu": false,
          "memoryUsage": 89247744
        }
      ],
      "jobQueueStatus": {
        "remainingCapacity": 100,
        "pendingRequests": 0
      }
    }
]

GET /models/{model_name}/{model_version}?customized=trueGET /models/{model_name}?customized=true

使用描述模型 API 获取模型某个版本的详细运行时状态和自定义元数据

  • 实现函数 describe_handle。例如:

    def describe_handle(self):
        """Customized describe handler
        Returns:
            dict : A dictionary response.
        """
        output_describe = None

        logger.info("Collect customized metadata")

        return output_describe
  • 如果 handler 没有继承自 BaseHandler,则实现函数 _is_describe。然后,在 handle 中调用 _is_describe 和 describe_handle。

    def _is_describe(self):
        if self.context and self.context.get_request_header(0, "describe"):
            if self.context.get_request_header(0, "describe") == "True":
                return True
        return False

    def handle(self, data, context):
        if self._is_describe():
            output = [self.describe_handle()]
        else:
            data_preprocess = self.preprocess(data)

            if not self._is_explain():
                output = self.inference(data_preprocess)
                output = self.postprocess(output)
            else:
                output = self.explain_handle(data_preprocess, data)

        return output
  • 在 handle 中调用函数 _is_describe 和 describe_handle。例如:

def handle(self, data, context):
        """Entry point for default handler. It takes the data from the input request and returns
           the predicted outcome for the input.
        Args:
            data (list): The input data that needs to be made a prediction request on.
            context (Context): It is a JSON Object containing information pertaining to
                               the model artifacts parameters.
        Returns:
            list : Returns a list of dictionary with the predicted response.
        """

        # It can be used for pre or post processing if needed as additional request
        # information is available in context
        start_time = time.time()

        self.context = context
        metrics = self.context.metrics

        is_profiler_enabled = os.environ.get("ENABLE_TORCH_PROFILER", None)
        if is_profiler_enabled:
            output, _ = self._infer_with_profiler(data=data)
        else:
            if self._is_describe():
                output = [self.describe_handle()]
            else:
                data_preprocess = self.preprocess(data)

                if not self._is_explain():
                    output = self.inference(data_preprocess)
                    output = self.postprocess(output)
                else:
                    output = self.explain_handle(data_preprocess, data)

        stop_time = time.time()
        metrics.add_time('HandlerTime', round(
            (stop_time - start_time) * 1000, 2), None, 'ms')
        return output
  • 这是一个示例。“customizedMetadata”显示了来自用户模型的元数据。这些元数据可以解码为字典。

curl http://localhost:8081/models/noop-customized/1.0?customized=true
[
    {
        "modelName": "noop-customized",
        "modelVersion": "1.0",
        "modelUrl": "noop-customized.mar",
        "runtime": "python",
        "minWorkers": 1,
        "maxWorkers": 1,
        "batchSize": 1,
        "maxBatchDelay": 100,
        "loadedAtStartup": false,
        "workers": [
          {
            "id": "9010",
            "startTime": "2022-02-08T11:03:20.974Z",
            "status": "READY",
            "memoryUsage": 0,
            "pid": 98972,
            "gpu": false,
            "gpuUsage": "N/A"
          }
        ],
        "jobQueueStatus": {
          "remainingCapacity": 100,
          "pendingRequests": 0
        },
        "customizedMetadata": "{\n  \"data1\": \"1\",\n  \"data2\": \"2\"\n}"
     }
]
  • 在客户端解码 customizedMetadata。例如:

import requests
import json

response = requests.get('http://localhost:8081/models/noop-customized/?customized=true').json()
customizedMetadata = response[0]['customizedMetadata']
print(customizedMetadata)

注销模型

此 API 遵循 ManagementAPIsService.UnregisterModel gRPC API。它返回 ModelServer 中模型的状态。

TorchServe 启动后要使用此 API,必须启用模型 API 控制。在启动 TorchServe 时,向命令行添加 --enable-model-api 以启用此 API 的使用。有关更多详细信息,请参阅 模型 API 控制

DELETE /models/{model_name}/{version}

使用注销模型 API 通过从 TorchServe 注销模型的特定版本来释放系统资源

curl -X DELETE http://localhost:8081/models/noop/1.0

{
  "status": "Model \"noop\" unregistered"
}

列出模型

此 API 遵循 ManagementAPIsService.ListModels gRPC API。它返回 ModelServer 中模型的状态。

GET /models

  • limit - (可选)返回的最大项目数。它作为查询参数传递。默认值为 100

  • next_page_token - (可选)查询下一页。它作为查询参数传递。此值由先前的 API 调用返回。

使用 Models API 查询当前注册模型的默认版本

curl "http://localhost:8081/models"

此 API 支持分页

curl "http://localhost:8081/models?limit=2&next_page_token=2"

{
  "nextPageToken": "4",
  "models": [
    {
      "modelName": "noop",
      "modelUrl": "noop-v1.0"
    },
    {
      "modelName": "noop_v0.1",
      "modelUrl": "noop-v0.1"
    }
  ]
}

API 描述

OPTIONS /

要查看推理和管理 API 的完整列表,您可以使用以下命令:

# To view all inference APIs:
curl -X OPTIONS http://localhost:8080

# To view all management APIs:
curl -X OPTIONS http://localhost:8081

输出是 OpenAPI 3.0.1 json 格式。您可以使用它来生成客户端代码,详细信息请参阅 swagger codegen

推理和管理 API 的示例输出

设置默认版本

此 API 遵循 ManagementAPIsService.SetDefault gRPC API。它返回 ModelServer 中模型的状态。

PUT /models/{model_name}/{version}/set-default

要将模型的任何已注册版本设置为默认版本,请使用

curl -v -X PUT http://localhost:8081/models/noop/2.0/set-default

输出是 OpenAPI 3.0.1 json 格式。您可以使用它来生成客户端代码,详细信息请参阅 swagger codegen

Token 授权 API

TorchServe 现在默认强制执行 token 授权。查看以下文档了解更多信息:Token 授权

此 API 用于生成新密钥以替换管理或推理密钥。

管理示例

curl localhost:8081/token?type=management -H "Authorization: Bearer {API Token}"

将用新密钥替换 key_file 中的当前管理密钥,并更新过期时间。

推理示例

curl localhost:8081/token?type=inference -H "Authorization: Bearer {API Token}"

将用新密钥替换 key_file 中的当前推理密钥,并更新过期时间。

文档

查阅 PyTorch 的全面开发者文档

查看文档

教程

获取面向初学者和高级开发者的深度教程

查看教程

资源

查找开发资源并获取问题解答

查看资源