Triton 客户端库和示例#
为了简化与 Triton 的通信,Triton 项目提供了几个客户端库以及如何使用这些库的示例。在 Triton 主 问题页面 中提问或报告问题。
提供的客户端库包括
C++ 和 Python API,使您可以轻松地从 C++ 或 Python 应用程序与 Triton 通信。使用这些库,您可以向 Triton 发送 HTTP/REST 或 GRPC 请求,以访问其所有功能:推理、状态和健康状况、统计信息和指标、模型仓库管理等。这些库还支持使用系统和 CUDA 共享内存来传递输入到 Triton 和从 Triton 接收输出。
Java API(由 阿里云 PAI 团队 贡献),使您可以轻松地从 Java 应用程序使用 HTTP/REST 请求与 Triton 通信。目前,仅支持有限的功能子集。
protoc 编译器 可以生成多种编程语言的 GRPC API。
有关 Go 编程语言 的示例,请参阅 src/grpc_generated/go。
有关 Java 和 Scala 编程语言的示例,请参阅 src/grpc_generated/java。
有关 JavaScript 编程语言的示例,请参阅 src/grpc_generated/javascript。
还有许多示例应用程序展示了如何使用这些库。许多这些示例使用来自 示例模型仓库 的模型。
image_client 的 C++ 和 Python 版本,这是一个示例应用程序,它使用 C++ 或 Python 客户端库在 Triton 上执行图像分类模型。请参阅 图像分类示例。
几个简单的 C++ 示例 展示了如何使用 C++ 库与 Triton 通信以执行推理和其他任务。演示 HTTP/REST 客户端的 C++ 示例以 simple_http_ 为前缀命名,演示 GRPC 客户端的示例以 simple_grpc_ 为前缀命名。请参阅 简单示例应用程序。
几个简单的 Python 示例 展示了如何使用 Python 库与 Triton 通信以执行推理和其他任务。演示 HTTP/REST 客户端的 Python 示例以 simple_http_ 为前缀命名,演示 GRPC 客户端的示例以 simple_grpc_ 为前缀命名。请参阅 简单示例应用程序。
几个简单的 Java 示例 展示了如何使用 Java API 与 Triton 通信以执行推理和其他任务。
一些 Python 示例,这些示例使用由 protoc 编译器 生成的 Python GRPC API 与 Triton 通信。grpc_client.py 是一个简单的示例,展示了简单的 API 用法。grpc_image_client.py 在功能上与 image_client 等效,但它使用生成的 GRPC 客户端存根与 Triton 通信。
获取客户端库和示例#
获取 Python 客户端库的最简单方法是 使用 pip 安装 tritonclient 模块。您还可以从 Triton GitHub 发布版本 下载 C++、Python 和 Java 客户端库,或者从 NGC 下载包含客户端库的预构建 Docker 镜像,NVIDIA GPU Cloud (NGC)。
也可以使用 cmake 构建客户端库。
使用 Python 包安装程序 (pip) 下载#
GRPC 和 HTTP 客户端库作为 Python 包提供,可以使用最新版本的 pip 安装。
$ pip install tritonclient[all]
使用 all 会同时安装 HTTP/REST 和 GRPC 客户端库。有两个可选包可用,grpc 和 http,可用于专门安装对协议的支持。例如,要仅安装 HTTP/REST 客户端库,请使用:
$ pip install tritonclient[http]
还有另一个可选包,即 cuda,必须安装该包才能使用 cuda_shared_memory 实用程序。all 规范默认将安装 cuda 包,但在其他情况下,需要显式指定 cuda 以安装支持 cuda_shared_memory 的客户端。
$ pip install tritonclient[http, cuda]
安装包的组件包括
http
grpc [
service_pb2
,service_pb2_grpc
,model_config_pb2
]utils [ Linux 发行版将包含
shared_memory
和cuda_shared_memory
]
从 GitHub 下载#
可以从与您感兴趣的版本对应的 Triton GitHub 发布页面 下载客户端库。客户端库位于发布页面的“Assets”部分,在一个以发布版本和操作系统命名的 tar 文件中,例如,v2.3.0_ubuntu2004.clients.tar.gz。
预构建的库可以在相应的宿主机系统上使用,或者您可以将它们安装到 Triton 容器中,以便在同一容器中同时拥有客户端和服务器。
$ mkdir clients
$ cd clients
$ wget https://github.com/triton-inference-server/server/releases/download/<tarfile_path>
$ tar xzf <tarfile_name>
安装后,库可以在 lib/ 中找到,头文件在 include/ 中,Python wheel 文件在 python/ 中,jar 文件在 java/ 中。bin/ 和 python/ 目录包含已构建的示例,您可以在下面了解更多信息。
从 NGC 下载 Docker 镜像#
包含客户端库和示例的 Docker 镜像可从 NVIDIA GPU Cloud (NGC) 获取。在尝试拉取容器之前,请确保您有权访问 NGC。有关分步说明,请参阅 NGC 入门指南。
使用 docker pull 从 NGC 获取客户端库和示例容器。
$ docker pull nvcr.io/nvidia/tritonserver:<xx.yy>-py3-sdk
其中 <xx.yy> 是您要拉取的版本。在容器内,客户端库位于 /workspace/install/lib 中,相应的头文件位于 /workspace/install/include 中,Python wheel 文件位于 /workspace/install/python 中。镜像还将包含已构建的客户端示例。
重要提示: 当使用 Docker 容器运行服务器或客户端并使用 CUDA 共享内存功能 时,您需要在启动容器时添加 --pid host
标志。原因是 CUDA IPC API 要求导出的指针的源和目标的 PID 不同。否则,Docker 启用 PID 命名空间可能会导致源和目标 PID 相等。当两个容器都以非交互模式启动时,将始终观察到该错误。
使用 CMake 构建#
客户端库构建是使用 CMake 执行的。要构建具有所有功能的客户端库和示例,请首先将目录更改为此仓库的根目录,并检出您要构建的分支的发布版本(如果您要构建正在开发中的版本,则检出 main 分支)。
$ git checkout main
如果构建 Java 客户端,您必须首先安装 Maven 和适用于您操作系统的 JDK。例如,对于 Ubuntu,您应该安装 default-jdk
包
$ apt-get install default-jdk maven
在 Windows 与非 Windows 上构建需要不同的调用,因为 Windows 上的 Triton 尚不支持所有构建选项。
非 Windows#
使用 cmake 配置构建。您应该根据您正在使用的 Triton 客户端组件以及您想要构建的组件来调整标志。
如果您正在发布分支上构建(或基于发布分支的开发分支上构建),则还必须使用额外的 cmake 参数来指向客户端构建所依赖的仓库的该发布分支。例如,如果您正在构建 r21.10 客户端分支,则需要使用以下额外的 cmake 标志
-DTRITON_COMMON_REPO_TAG=r21.10
-DTRITON_THIRD_PARTY_REPO_TAG=r21.10
-DTRITON_CORE_REPO_TAG=r21.10
然后使用 make 构建客户端和示例。
$ make cc-clients python-clients java-clients
构建完成后,库和示例可以在 install 目录中找到。
Windows#
要构建客户端,您必须安装适当的 C++ 编译器和构建所需的其他依赖项。最简单的方法是创建 Windows min Docker 镜像 并在从该镜像启动的容器中执行构建。
> docker run -it --rm win10-py3-min powershell
对于构建,没有必要使用 Docker 或 win10-py3-min 容器,但如果您不使用,则必须将适当的依赖项安装到您的宿主机系统上。
接下来,使用 cmake 配置构建。如果您不是在 win10-py3-min 容器中构建,那么您可能需要调整以下命令中的 CMAKE_TOOLCHAIN_FILE 位置。
$ mkdir build
$ cd build
$ cmake -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_TOOLCHAIN_FILE='/vcpkg/scripts/buildsystems/vcpkg.cmake' -DCMAKE_INSTALL_PREFIX=install -DTRITON_ENABLE_CC_GRPC=ON -DTRITON_ENABLE_PYTHON_GRPC=ON -DTRITON_ENABLE_GPU=OFF -DTRITON_ENABLE_EXAMPLES=ON -DTRITON_ENABLE_TESTS=ON ..
如果您正在发布分支上构建(或基于发布分支的开发分支上构建),则还必须使用额外的 cmake 参数来指向客户端构建所依赖的仓库的该发布分支。例如,如果您正在构建 r21.10 客户端分支,则需要使用以下额外的 cmake 标志
-DTRITON_COMMON_REPO_TAG=r21.10
-DTRITON_THIRD_PARTY_REPO_TAG=r21.10
-DTRITON_CORE_REPO_TAG=r21.10
然后使用 msbuild.exe 进行构建。
$ msbuild.exe cc-clients.vcxproj -p:Configuration=Release -clp:ErrorsOnly
$ msbuild.exe python-clients.vcxproj -p:Configuration=Release -clp:ErrorsOnly
构建完成后,库和示例可以在 install 目录中找到。
客户端库 API#
C++ 客户端 API 公开了一个基于类的接口。注释接口在 grpc_client.h、http_client.h、common.h 中提供。
Python 客户端 API 提供了与 C++ API 类似的功能。注释接口在 grpc 和 http 中提供。
Java 客户端 API 提供了与 Python API 类似的功能,具有类似的类和方法。有关更多信息,请参阅 Java 客户端目录。
HTTP 选项#
SSL/TLS#
客户端库允许使用 HTTPS 协议通过安全通道进行通信。仅设置这些 SSL 选项并不能确保安全通信。Triton 服务器应在 https://
代理(例如 nginx)后面运行。然后,客户端可以与代理建立安全通道。服务器仓库中的 qa/L0_https
演示了如何实现这一点。
对于 C++ 客户端,请参阅 HttpSslOptions
结构,该结构在 http_client.h 中封装了这些选项。
对于 Python 客户端,请在 http/__init__.py 中查找以下选项
ssl
ssl_options
ssl_context_factory
insecure
压缩#
客户端库为 HTTP 事务启用在线压缩。
对于 C++ 客户端,请参阅 http_client.h 中 Infer
和 AsyncInfer
函数中的 request_compression_algorithm
和 response_compression_algorithm
参数。默认情况下,该参数设置为 CompressionType::NONE
。
类似地,对于 Python 客户端,请参阅 http/__init__.py 中 infer
和 async_infer
函数中的 request_compression_algorithm
和 response_compression_algorithm
参数。
Python AsyncIO 支持(Beta 版)#
此功能目前处于 Beta 版,可能会发生更改。
高级用户可以通过 async
和 await
语法调用 Python 客户端。infer 示例演示了如何使用 AsyncIO 进行推理。
如果将 SSL/TLS 与 AsyncIO 结合使用,请在 http/aio/__init__.py 中查找 ssl
和 ssl_context
选项
Python 客户端插件 API(Beta 版)#
此功能目前处于 Beta 版,可能会发生更改。
Triton 客户端插件 API 允许您注册自定义插件以添加或修改请求标头。如果您在 Triton 服务器前面有网关,该网关需要每个请求的额外标头(例如 HTTP 授权),这将非常有用。通过注册插件,您的网关将与 Python 客户端一起工作,而无需额外的配置。请注意,Triton 服务器不实现身份验证或授权机制,同样,Triton 服务器也不是额外标头的直接使用者。
插件必须实现 __call__
方法。__call__
方法的签名应如下所示
class MyPlugin:
def __call__(self, request):
"""This method will be called for every HTTP request. Currently, the only
field that can be accessed by the request object is the `request.headers`
field. This field must be updated in-place.
"""
request.headers['my-header-key'] = 'my-header-value'
插件实现完成后,您可以通过在 InferenceServerClient
对象上调用 register
来注册插件。
from tritonclient.http import InferenceServerClient
client = InferenceServerClient(...)
# Register the plugin
my_plugin = MyPlugin()
client.register_plugin(my_plugin)
# All the method calls will update the headers according to the plugin
# implementation.
client.infer(...)
要注销插件,您可以调用 client.unregister_plugin()
函数。
基本身份验证#
您可以注册实现 基本身份验证 的 BasicAuth
插件。
from tritonclient.grpc.auth import BasicAuth
from tritonclient.grpc import InferenceServerClient
basic_auth = BasicAuth('username', 'password')
client = InferenceServerClient('...')
client.register_plugin(basic_auth)
上面的示例显示了如何为 gRPC 客户端注册插件。BasicAuth
插件可以为 HTTP 和 AsyncIO 客户端进行类似地注册。
GRPC 选项#
SSL/TLS#
客户端库允许使用 gRPC 协议通过安全通道进行通信。
对于 C++ 客户端,请参阅 SslOptions
结构,该结构在 grpc_client.h 中封装了这些选项。
对于 Python 客户端,请在 grpc/__init__.py 中查找以下选项
ssl
root_certificates
private_key
certificate_chain
C++ 和 Python 示例演示了如何在客户端使用 SSL/TLS 设置。有关相应的服务器端参数的信息,请参阅 服务器文档
压缩#
客户端库还公开了用于 gRPC 事务的在线压缩选项。
对于 C++ 客户端,请参阅 grpc_client.h 中 Infer
、AsyncInfer
和 StartStream
函数中的 compression_algorithm
参数。默认情况下,该参数设置为 GRPC_COMPRESS_NONE
。
类似地,对于 Python 客户端,请参阅 grpc/__init__.py 中 infer
、async_infer
和 start_stream
函数中的 compression_algorithm
参数。
GRPC KeepAlive#
Triton 公开了 GRPC KeepAlive 参数,客户端和服务器的默认值在 此处 描述。
您可以在 C++ 和 Python 客户端库中找到封装这些参数的 KeepAliveOptions
结构/类。
还有一个 C++ 和 Python 示例,演示了如何在客户端设置这些参数。有关相应的服务器端参数的信息,请参阅 服务器文档
自定义 GRPC 通道参数#
高级用户可能需要特定的客户端 GRPC 通道参数,这些参数目前 Triton 没有通过直接方式公开。为了支持这一点,Triton 允许用户在创建 GRPC 客户端时传递自定义通道参数。当使用此选项时,用户有责任传递适用于其用例的有效参数组合;Triton 无法切实测试每种可能的通道参数组合。
有一个 C++ 和 Python 示例,演示了如何在创建 GRPC 客户端时构造和传递这些自定义参数。
您可以在 此处 找到可能的 GRPC 通道参数的完整列表。
Python AsyncIO 支持(Beta 版)#
此功能目前处于 Beta 版,可能会发生更改。
高级用户可以通过 async
和 await
语法调用 Python 客户端。infer 和 stream 示例演示了如何使用 AsyncIO 进行推理。
请求取消#
从 r23.10 开始,triton python gRPC 客户端可以向正在进行的请求发出取消。这可以通过在 async_infer()
API 返回的 CallContext 对象上调用 cancel()
来完成。
ctx = client.async_infer(...)
ctx.cancel()
对于流式请求,可以将 cancel_requests=True
发送到 stop_stream()
API,以终止通过此流发送的所有正在进行的请求。
client.start_stream()
for _ in range(10):
client.async_stream_infer(...)
# Cancels all pending requests on stream closure rather than blocking until requests complete
client.stop_stream(cancel_requests=True)
有关这些 API 的更多详细信息,请参阅 grpc/_client.py。
对于 gRPC AsyncIO 请求,可以安全地取消包装 infer()
协程的 AsyncIO 任务。
infer_task = asyncio.create_task(aio_client.infer(...))
infer_task.cancel()
对于 gRPC AsyncIO 流式请求,可以在 stream_infer()
API 返回的异步迭代器上调用 cancel()
。
responses_iterator = aio_client.stream_infer(...)
responses_iterator.cancel()
有关这些 API 的更多详细信息,请参阅 grpc/aio/_init_.py。
有关服务器端如何处理此问题的更多信息,请参阅服务器用户指南中的 request_cancellation。如果您使用您选择的语言编写自己的 gRPC 客户端,请查阅 gRPC 指南中的 取消。
GRPC 状态码#
从 24.08 版本开始,Triton 服务器为所有客户端的流模式引入了 gRPC 错误代码支持,从而增强了错误报告功能。启用此功能后,Triton 服务器将返回标准 gRPC 错误代码,并在传递错误后关闭流。此功能是可选的,可以通过添加带有 triton_grpc_error
键和 true
值的标头来启用。有关服务器端如何处理此问题的更多信息,请参阅服务器中的 grpc 错误代码。有关更多详细信息,请参阅 gRPC 指南中的 状态码。以下是启用此功能的 Python 代码片段。如果没有此标头,Triton 服务器将在默认模式下继续流式传输,并在提供的回调中的 InferenceServerException
对象中返回错误消息和状态。
triton_client = grpcclient.InferenceServerClient(triton_server_url)
# New added header key value
metadata = {"triton_grpc_error": "true"}
triton_client.start_stream(
callback=partial(callback, user_data), headers=metadata
)
简单示例应用程序#
本节介绍几个简单的示例应用程序以及它们说明的功能。
字节/字符串数据类型#
某些框架支持张量,其中张量中的每个元素都是可变长度的二进制数据。每个元素可以保存字符串或任意字节序列。在客户端,此数据类型为 BYTES(有关支持的数据类型的信息,请参阅 数据类型)。
Python 客户端库使用 numpy 来表示输入和输出张量。对于 BYTES 张量,numpy 数组的 dtype 应为 'np.object_',如示例所示。为了向后兼容以前版本的客户端库,'np.bytes_' 也可用于 BYTES 张量。但是,不建议使用 'np.bytes_',因为使用此 dtype 将导致 numpy 从每个数组元素中删除所有尾随零。因此,以零结尾的二进制序列将无法正确表示。
C++ 示例应用程序 simple_http_string_infer_client.cc 和 simple_grpc_string_infer_client.cc 中演示了 BYTES 张量。Python 示例应用程序 simple_http_string_infer_client.py 和 simple_grpc_string_infer_client.py 中演示了字符串张量。
用于有状态模型的客户端 API#
当使用有状态模型执行推理时,客户端必须识别哪些推理请求属于同一序列,以及序列何时开始和结束。
每个序列都使用序列 ID 标识,该 ID 在发出推理请求时提供。创建唯一序列 ID 由客户端负责。对于每个序列,第一个推理请求应标记为序列的开始,最后一个推理请求应标记为序列的结束。
C++ 示例应用程序 simple_grpc_sequence_stream_infer_client.cc 演示了序列 ID 以及开始和结束标志的用法。Python 示例应用程序 simple_grpc_sequence_stream_infer_client.py 演示了序列 ID 以及开始和结束标志的用法。
图像分类示例#
使用 C++ 客户端 API 的图像分类示例位于 src/c++/examples/image_client.cc。Python 版本的图像分类客户端位于 src/python/examples/image_client.py。
要使用 image_client(或 image_client.py),您必须首先运行一个 Triton,它正在服务一个或多个图像分类模型。image_client 应用程序要求模型具有单个图像输入并产生单个分类输出。如果您没有包含图像分类模型的模型仓库,请参阅 快速入门 以获取有关如何创建一个的说明。
一旦 Triton 运行,您可以使用 image_client 应用程序发送推理请求。您可以指定单个图像或包含图像的目录。在这里,我们为来自 qa/images 的图像的 inception_graphdef 模型发送请求。
$ image_client -m inception_graphdef -s INCEPTION qa/images/mug.jpg
Request 0, batch size 1
Image 'qa/images/mug.jpg':
0.754130 (505) = COFFEE MUG
Python 版本的应用程序接受相同的命令行参数。
$ python image_client.py -m inception_graphdef -s INCEPTION qa/images/mug.jpg
Request 0, batch size 1
Image 'qa/images/mug.jpg':
0.826384 (505) = COFFEE MUG
image_client 和 image_client.py 应用程序使用客户端库与 Triton 通信。默认情况下,image_client 指示客户端库使用 HTTP/REST 协议,但您可以使用 GRPC 协议,方法是提供 -i 标志。您还必须使用 -u 标志指向 Triton 上的 GRPC 端点。
$ image_client -i grpc -u localhost:8001 -m inception_graphdef -s INCEPTION qa/images/mug.jpg
Request 0, batch size 1
Image 'qa/images/mug.jpg':
0.754130 (505) = COFFEE MUG
默认情况下,客户端打印图像的最可能分类。使用 -c 标志可查看更多分类。
$ image_client -m inception_graphdef -s INCEPTION -c 3 qa/images/mug.jpg
Request 0, batch size 1
Image 'qa/images/mug.jpg':
0.754130 (505) = COFFEE MUG
0.157077 (969) = CUP
0.002880 (968) = ESPRESSO
-b 标志允许您发送一批图像进行推理。image_client 应用程序将从您指定的图像或多个图像中形成批次。如果批次大于图像数量,则 image_client 将只重复图像以填充批次。
$ image_client -m inception_graphdef -s INCEPTION -c 3 -b 2 qa/images/mug.jpg
Request 0, batch size 2
Image 'qa/images/mug.jpg':
0.754130 (505) = COFFEE MUG
0.157077 (969) = CUP
0.002880 (968) = ESPRESSO
Image 'qa/images/mug.jpg':
0.754130 (505) = COFFEE MUG
0.157077 (969) = CUP
0.002880 (968) = ESPRESSO
提供目录而不是单个图像以对目录中的所有图像执行推理。
$ image_client -m inception_graphdef -s INCEPTION -c 3 -b 2 qa/images
Request 0, batch size 2
Image '/opt/tritonserver/qa/images/car.jpg':
0.819196 (818) = SPORTS CAR
0.033457 (437) = BEACH WAGON
0.031232 (480) = CAR WHEEL
Image '/opt/tritonserver/qa/images/mug.jpg':
0.754130 (505) = COFFEE MUG
0.157077 (969) = CUP
0.002880 (968) = ESPRESSO
Request 1, batch size 2
Image '/opt/tritonserver/qa/images/vulture.jpeg':
0.977632 (24) = VULTURE
0.000613 (9) = HEN
0.000560 (137) = EUROPEAN GALLINULE
Image '/opt/tritonserver/qa/images/car.jpg':
0.819196 (818) = SPORTS CAR
0.033457 (437) = BEACH WAGON
0.031232 (480) = CAR WHEEL
grpc_image_client.py 应用程序的行为与 image_client 相同,不同之处在于它没有使用客户端库,而是使用 GRPC 生成的库与 Triton 通信。
集成图像分类示例应用程序#
与上面的图像分类示例相比,此示例使用图像预处理模型的集成,该模型实现为 DALI 后端 和 TensorFlow Inception 模型。集成模型允许您在请求中发送原始图像二进制文件,并接收分类结果,而无需在客户端上预处理图像。
要尝试此示例,您应遵循 DALI 集成示例说明。