给定一个经过训练的模型,我如何使用 Triton 推理服务器以最佳配置大规模部署它? 本文档旨在帮助回答这个问题。
对于那些喜欢高级概述的人,下面是大多数用例的通用流程。
对于那些希望直接进入的人,请跳到端到端示例。
有关其他材料,请参阅 Triton 概念指南教程。
我的模型与 Triton 兼容吗?
如果您的模型属于 Triton 支持的后端之一,那么我们可以简单地尝试按照快速入门指南中的描述部署该模型。 对于 ONNXRuntime、TensorFlow SavedModel 和 TensorRT 后端,可以使用 Triton 的自动完成功能从模型中推断出最小模型配置。 这意味着可能仍会提供 config.pbtxt,但不是必需的,除非您想明确设置某些参数。 此外,通过 --log-verbose=1 启用详细日志记录,您可以在服务器日志输出中看到 Triton 在内部看到的完整配置。 对于其他后端,请参阅入门所需的最小模型配置。
如果您的模型不是来自受支持的后端,您可以查看 Python 后端或编写自定义 C++ 后端来支持您的模型。 Python 后端提供了一个简单的接口来通过通用 python 脚本执行请求,但性能可能不如自定义 C++ 后端。 根据您的用例,Python 后端性能可能是实现简单性的充分折衷。
我可以在我的服务模型上运行推理吗?
# NOTE: "my_model" represents a model currently being served by Triton
$ perf_analyzer -m my_model
...
Inferences/Second vs. Client Average Batch Latency
Concurrency: 1, throughput: 482.8 infer/sec, latency 12613 usec
这为我们提供了一个完整性测试,我们能够成功地形成输入请求并接收输出响应以通过 Triton API 与模型后端进行通信。
如果 Perf Analyzer 无法发送请求并且从错误中不清楚如何继续,那么您可能需要完整性检查您的模型 config.pbtxt 输入/输出是否与模型预期的相匹配。 如果配置正确,请直接使用其原始框架检查模型是否成功运行。 如果您没有自己的脚本或工具来执行此操作,Polygraphy 是一个有用的工具,可以通过各种框架在您的模型上运行样本推理。 目前,Polygraphy 支持 ONNXRuntime、TensorRT 和 TensorFlow 1.x。
“表现良好”的定义可能因用例而异。 一些常见指标是吞吐量、延迟和 GPU 利用率。 有许多变量可以在您的模型配置 (config.pbtxt) 中进行调整以获得不同的结果。
随着模型、配置或用例的发展,Perf Analyzer 是快速验证模型功能和性能的绝佳工具。
如何提高我的模型性能?
为了进一步了解您可以为您的用例提供给 Triton 的最佳模型配置,Triton 的模型分析器工具可以提供帮助。 模型分析器可以自动或手动搜索配置组合,以找到满足您的约束条件的最佳 triton 配置。 在运行模型分析器为您的模型/用例找到最佳配置后,您可以将生成的配置文件传输到您的模型存储库。 Model Analyzer 提供了一个快速入门指南,其中包含一些示例。
使用模型分析器找到的新优化配置文件为模型提供服务并再次运行 Perf Analyzer 后,与默认配置相比,您应该期望在大多数情况下找到更好的性能数字。
一些可以为模型调整的参数可能不会暴露给模型分析器的自动搜索,因为它们并不适用于所有模型。 例如,后端可以公开特定于后端的配置选项,这些选项也可以进行调整。 例如,ONNXRuntime 后端有几个参数会影响在模型上执行推理时的并行化级别。 如果默认值不能提供足够的性能,这些特定于后端的选项可能值得研究。 为了调整自定义参数集,模型分析器支持手动配置搜索。
要了解有关模型配置进一步优化的更多信息,请参阅优化文档。
我的模型在首次被 Triton 加载时执行缓慢(冷启动惩罚),我该怎么办?
为什么我的模型在 GPU 上的执行速度没有显着提高?
Triton 支持的大多数官方后端都针对 GPU 推理进行了优化,应该在开箱即用的 GPU 上表现良好。
Triton 为您提供了在 GPU 上进一步优化模型的选项。 Triton 的 Framework Specific Optimizations 进一步详细介绍了这个主题。
将您的模型完全转换为完全针对 GPU 推理优化的后端(例如 TensorRT)可能会提供更好的结果。 您可以在 TensorRT 后端找到更多关于 TensorRT 的特定于 Triton 的详细信息。
如果以上都不能帮助您的模型获得足够的 GPU 加速性能,则该模型可能更适合 CPU 执行,而 OpenVINO 后端可能有助于进一步优化您的 CPU 执行。
注意如果您以前从未使用过 Triton,您可能有兴趣先查看快速入门示例。 对 Triton 的一些基本了解可能对下一节有用,但这个示例意味着在没有经验的情况下足够简单。
让我们以 ONNX 模型为例,因为 ONNX 被设计为一种可以从大多数其他框架轻松导出的格式。
# Create model repository with placeholder for model and version 1
mkdir -p ./models/densenet_onnx/1
# Download model and place it in model repository
wget -O models/densenet_onnx/1/model.onnx
https://contentmamluswest001.blob.core.windows.net/content/14b2744cf8d6418c87ffddc3f3127242/9502630827244d60a1214f250e3bbca7/08aed7327d694b8dbaee2c97b8d0fcba/densenet121-1.2.onnx
在 ./models/densenet_onnx/config.pbtxt
的模型存储库中为 densenet_onnx 模型创建最小模型配置。
注意这是另一个示例配置的稍微简化的版本,它使用了本示例不需要的其他模型配置功能。
name: "densenet_onnx"
backend: "onnxruntime"
max_batch_size: 0
input: [
{
name: "data_0",
data_type: TYPE_FP32,
dims: [ 1, 3, 224, 224]
}
]
output: [
{
name: "prob_1",
data_type: TYPE_FP32,
dims: [ 1, 1000, 1, 1 ]
}
]
注意 从 22.07 版本开始,Triton 和模型分析器都支持完全自动完成支持它的后端的配置文件。 因此,对于 ONNX 模型,除非您想显式设置某些参数,否则可以跳过此步骤。
在后台启动服务器和客户端容器
这些容器可以以交互方式启动,但为了演示,更清楚的是在后台启动这些容器,并根据需要执行以下步骤的 docker exec 到它们中。
# Start server container in the background
docker run -d --gpus=all --network=host -v $PWD:/mnt --name triton-server nvcr.io/nvidia/tritonserver:23.05-py3
# Start client container in the background
docker run -d --gpus=all --network=host -v $PWD:/mnt --name triton-client nvcr.io/nvidia/tritonserver:23.05-py3-sdk
注意 -v $PWD:/mnt
将主机上的当前目录挂载到容器内的 /mnt
目录中。 因此,如果您在 $PWD/models
中创建了模型存储库,您将在 /mnt/models
的容器中找到它。 您可以根据需要更改这些路径。 有关其工作原理的更多信息,请参阅 docker volume 文档。
使用 Triton 为模型服务
为了服务我们的模型,我们将使用我们已经启动的服务器容器,它预装了一个 tritonserver 二进制文件。
# Enter server container interactively
docker exec -ti triton-server bash
# Start serving your models
tritonserver --model-repository=/mnt/models
要检查模型是否加载成功,我们希望在上一个命令的输出中看到我们的模型处于 READY 状态:
...
I0802 18:11:47.100537 135 model_repository_manager.cc:1345] successfully loaded 'densenet_onnx' version 1
...
+---------------+---------+--------+
| Model | Version | Status |
+---------------+---------+--------+
| densenet_onnx | 1 | READY |
+---------------+---------+--------+
...
验证模型可以运行推理
为了验证我们的模型可以执行推理,我们将使用我们已经启动的 triton-client 容器,它预装了 perf_analyzer。
在一个单独的 shell 中,我们使用 Perf Analyzer 来完整性检查我们是否可以运行推理并获得我们期望从该模型获得的性能的基线。
在下面的示例中,Perf Analyzer 正在向同一台机器上服务的模型发送请求(通过 --network=host
来自服务器容器的 localhost)。 但是,您也可以通过设置 -u 标志(例如 perf_analyzer -m densenet_onnx -u 127.0.0.1:8000
)来测试在某些
远程服务的模型。
# Enter client container interactively
docker exec -ti triton-client bash
# Benchmark model being served from step 3
perf_analyzer -m densenet_onnx --concurrency-range 1:4
...
Inferences/Second vs. Client Average Batch Latency
Concurrency: 1, throughput: 265.147 infer/sec, latency 3769 usec
Concurrency: 2, throughput: 890.793 infer/sec, latency 2243 usec
Concurrency: 3, throughput: 937.036 infer/sec, latency 3199 usec
Concurrency: 4, throughput: 965.21 infer/sec, latency 4142 usec
运行模型分析器为我们的模型找到最佳配置
虽然模型分析器预安装在 SDK(客户端)容器中,并支持连接到 Triton 服务器的各种模式,但为简单起见,我们将在我们的服务器容器中安装模型分析器以使用本地(默认)模式。 要了解有关将模型分析器连接到正在运行的 Triton 服务器的其他方法的更多信息,请参阅 --triton-launch-mode
模型分析器标志。
# Enter server container interactively
docker exec -ti triton-server bash
# Stop existing tritonserver process if still running
# because model-analyzer will start its own server
SERVER_PID=`ps | grep tritonserver | awk '{ printf $1 }'`
kill ${SERVER_PID}
# Install model analyzer
pip install --upgrade pip
pip install triton-model-analyzer wkhtmltopdf
# Profile the model using local (default) mode
# NOTE: This may take some time, in this example it took ~10 minutes
model-analyzer profile \
--model-repository=/mnt/models \
--profile-models=densenet_onnx \
--output-model-repository-path=results
# Summarize the profiling results
model-analyzer analyze --analysis-models=densenet_onnx
示例模型分析器输出摘要:
在 6 种配置的 51 次测量中,densenet_onnx_config_3 提供了最佳吞吐量:323 infer/sec。
在给定的约束下,这比默认配置(168 次推断/秒)提高了 92%。
在上表中,我们看到将 GPU 实例计数设置为 4 可以让我们在该系统上实现最高的吞吐量和几乎最低的延迟。
另请注意,此 densenet_onnx 模型具有在输入/输出 dims 的第一个维度中明确指定的固定批量大小,因此 max_batch_size 参数设置为 0,如此处所述。 对于支持动态批量大小的模型,模型分析器还会调整 max_batch_size 参数。
警告 这些结果特定于运行 Triton 服务器的系统,因此,例如,在较小的 GPU 上,我们可能看不到增加 GPU 实例数带来的改进。 通常,在具有不同硬件(CPU、GPU、RAM 等)的系统上运行相同的配置可能会提供不同的结果,因此在准确反映您将在何处部署模型以供使用的系统上分析您的模型非常重要。
从模型分析器结果中提取最佳配置
在我们上面的示例中,densenet_onnx_config_3 是最佳配置。 因此,让我们提取 config.pbtxt 并将其放回我们的模型存储库中以备将来使用。
# (optional) Backup our original config.pbtxt (if any) to another directory
cp /mnt/models/densenet_onnx/config.pbtxt /tmp/original_config.pbtxt
# Copy over the optimal config.pbtxt from Model Analyzer results to our model repository
cp ./results/densenet_onnx_config_3/config.pbtxt /mnt/models/densenet_onnx/
现在我们有了优化的模型配置,我们已准备好将我们的模型用于部署。 如需进一步手动调整,请阅读模型配置和优化文档以了解有关 Triton 完整功能集的更多信息。
在这个例子中,我们碰巧从相同的配置中获得了最高的吞吐量和几乎最低的延迟,但在某些情况下,这是必须做出的权衡。 某些模型或配置可能会实现更高的吞吐量,但也会导致更高的延迟。 值得全面检查模型分析器生成的报告,以确保您的模型性能满足您的要求。