Triton 服务器跟踪#
Triton 包含为单个推理请求生成详细跟踪的功能。通过运行 tritonserver 可执行文件时的命令行参数启用跟踪。
Triton 中的 --trace-config
命令行选项可用于指定全局和跟踪模式特定的配置设置。此标志的格式为 --trace-config <mode>,<setting>=<value>
,其中 <mode>
是 triton
或 opentelemetry
。默认情况下,跟踪模式设置为 triton
,服务器将使用 Triton 的跟踪 API。对于 opentelemetry
模式,服务器将使用 OpenTelemetry 的 API 来为单个推理请求生成、收集和导出跟踪。
要指定全局跟踪设置(级别、速率、计数或模式),格式为 --trace-config <setting>=<value>
。
一个示例用法,它调用 Triton 的跟踪 API
$ tritonserver \
--trace-config triton,file=/tmp/trace.json \
--trace-config triton,log-frequency=50 \
--trace-config rate=100 \
--trace-config level=TIMESTAMPS \
--trace-config count=100 ...
跟踪设置#
全局设置#
下表显示了可传递给 --trace-config
的可用全局跟踪设置
设置 | 默认值 | 描述 |
---|---|---|
rate |
1000 | 指定采样率。与已弃用的 --trace-rate 相同。例如,值 1000 指定每 1000 个推理 请求将被跟踪。 |
level |
OFF | 指示应收集的跟踪详细程度,并且 可以多次指定以跟踪多个信息。 与已弃用的 --trace-level 相同。选项为 TIMESTAMPS 和 TENSORS 。注意, opentelemetry 模式当前不支持 TENSORS 级别。 |
count |
-1 | 指定要收集的剩余跟踪数。 默认值 -1 指定永不停止收集跟踪。 值为 100 时,Triton 将在跟踪 100 个请求后 停止跟踪请求。 与已弃用的 --trace-count 相同。 |
mode |
triton | 指定使用哪个跟踪 API 来收集跟踪。 选项为 triton 或 opentelemetry 。 |
Triton 跟踪 API 设置#
下表显示了 --trace-config triton,<setting>=<value>
的可用 Triton 跟踪 API 设置。
设置 | 默认值 | 描述 |
---|---|---|
file |
空字符串 | 指示应将跟踪输出写入到哪里。 与已弃用的 --trace-file 相同。 |
log-frequency |
0 | 指定将跟踪写入文件的速率。 例如,值 50 指定 Triton 将每收集 50 个跟踪 记录到文件。 与已弃用的 --trace-log-frequency 相同。 |
除了命令行中的跟踪配置设置外,您还可以使用 跟踪协议 修改跟踪配置。当跟踪模式设置为 opentelemetry
时,当前不支持此选项。
注意:以下标志已被弃用
--trace-file
选项指示应将跟踪输出写入到哪里。--trace-rate
选项指定采样率。在此示例中,每 100 个推理请求将被跟踪。--trace-level
选项指示应收集的跟踪详细程度。--trace-level
选项可以多次指定以跟踪多个信息。--trace-log-frequency
选项指定将跟踪写入文件的速率。在此示例中,Triton 将每收集 50 个跟踪记录到文件。--trace-count
选项指定要收集的剩余跟踪数。在此示例中,Triton 将在收集 100 个跟踪后停止跟踪更多请求。使用 --help
选项获取更多信息。
支持的跟踪级别选项#
TIMESTAMPS
:跟踪每个请求的执行时间戳。TENSORS
:跟踪执行期间的输入和输出张量。
JSON 跟踪输出#
跟踪输出是具有以下模式的 JSON 文件。
[
{
"model_name": $string,
"model_version": $number,
"id": $number,
"request_id": $string,
"parent_id": $number
},
{
"id": $number,
"timestamps": [
{ "name" : $string, "ns" : $number }
]
},
{
"id": $number
"activity": $string,
"tensor":{
"name": $string,
"data": $string,
"shape": $string,
"dtype": $string
}
},
...
]
每个跟踪都分配了一个“id”,指示推理请求的模型名称和版本。如果跟踪来自作为集成模型一部分运行的模型,“parent_id”将指示包含集成模型的“id”。例如
[
{
"id": 1,
"model_name": "simple",
"model_version": 1
},
...
]
每个 TIMESTAMPS
跟踪将具有一个或多个“timestamps”,每个时间戳都有一个名称和以纳秒 (“ns”) 为单位的时间戳。例如
[
{"id": 1, "timestamps": [{ "name": "HTTP_RECV_START", "ns": 2356425054587444 }] },
{"id": 1, "timestamps": [{ "name": "HTTP_RECV_END", "ns": 2356425054632308 }] },
{"id": 1, "timestamps": [{ "name": "REQUEST_START", "ns": 2356425054785863 }] },
{"id": 1, "timestamps": [{ "name": "QUEUE_START", "ns": 2356425054791517 }] },
{"id": 1, "timestamps": [{ "name": "INFER_RESPONSE_COMPLETE", "ns": 2356425057587919 }] },
{"id": 1, "timestamps": [{ "name": "COMPUTE_START", "ns": 2356425054887198 }] },
{"id": 1, "timestamps": [{ "name": "COMPUTE_INPUT_END", "ns": 2356425057152908 }] },
{"id": 1, "timestamps": [{ "name": "COMPUTE_OUTPUT_START", "ns": 2356425057497763 }] },
{"id": 1, "timestamps": [{ "name": "COMPUTE_END", "ns": 2356425057540989 }] },
{"id": 1, "timestamps": [{ "name": "REQUEST_END", "ns": 2356425057643164 }] },
{"id": 1, "timestamps": [{ "name": "HTTP_SEND_START", "ns": 2356425057681578 }] },
{"id": 1, "timestamps": [{ "name": "HTTP_SEND_END", "ns": 2356425057712991 }] }
]
每个 TENSORS
跟踪将包含一个“activity”和一个“tensor”。“activity”指示张量的类型,目前包括 “TENSOR_QUEUE_INPUT” 和 “TENSOR_BACKEND_OUTPUT”。“tensor”具有张量的详细信息,包括其 “name”、“data” 和 “dtype”。例如
[
{
"id": 1,
"activity": "TENSOR_QUEUE_INPUT",
"tensor":{
"name": "input",
"data": "0.1,0.1,0.1,...",
"shape": "1,16",
"dtype": "FP32"
}
}
]
跟踪摘要工具#
可以使用示例 跟踪摘要工具 来汇总从 Triton 收集的一组跟踪。基本用法是
$ trace_summary.py <trace file>
这将生成文件中所有跟踪的摘要报告。HTTP 和 GRPC 推理请求将分别报告。
File: trace.json
Summary for simple (-1): trace count = 1
HTTP infer request (avg): 403.578us
Receive (avg): 20.555us
Send (avg): 4.52us
Overhead (avg): 24.592us
Handler (avg): 353.911us
Overhead (avg): 23.675us
Queue (avg): 18.019us
Compute (avg): 312.217us
Input (avg): 24.151us
Infer (avg): 244.186us
Output (avg): 43.88us
Summary for simple (-1): trace count = 1
GRPC infer request (avg): 383.601us
Send (avg): 62.816us
Handler (avg): 392.924us
Overhead (avg): 51.968us
Queue (avg): 21.45us
Compute (avg): 319.506us
Input (avg): 27.76us
Infer (avg): 227.844us
Output (avg): 63.902us
注意:“接收(平均)”指标未包含在 gRPC 摘要中,因为 gRPC 库未提供任何非侵入式钩子来检测从线路读取消息所花费的时间。跟踪 HTTP 请求将提供从网络读取请求所花费时间的准确测量值。
使用 -t 选项获取文件中每个跟踪的摘要。此摘要显示推理请求处理过程中不同点之间的时间(以微秒为单位)。例如,以下输出显示从开始处理请求到请求在调度队列中排队花费了 15 微秒。
$ trace_summary.py -t <trace file>
...
simple (-1):
request handler start
15us
queue start
20us
compute start
266us
compute end
4us
request handler end
19us
grpc send start
77us
grpc send end
...
如果文件中有 TENSORS
跟踪,则该脚本还可以显示第一个请求的数据流。如果 TENSORS
跟踪来自集成模型,则将显示数据流以及每个模型的依赖关系。
...
Data Flow:
==========================================================
Name: ensemble
Version:1
QUEUE_INPUT:
input: [[0.705676 0.830855 0.833153]]
BACKEND_OUTPUT:
output: [[1. 2. 7. 0. 4. 7. 9. 3. 4. 9.]]
==========================================================
==================================================
Name: test_trt1
Version:1
QUEUE_INPUT:
input: [[0.705676 0.830855 0.833153]]
BACKEND_OUTPUT:
output1: [[1. 1. ...]]
==================================================
==================================================
Name: test_trt2
Version:1
QUEUE_INPUT:
input: [[0.705676 0.830855 0.833153]]
BACKEND_OUTPUT:
output2: [[2. 2. ...]]
==================================================
==================================================
Name: test_py
Version:1
QUEUE_INPUT:
output1: [[1. 1. ...]]
QUEUE_INPUT:
output2: [[2. 2. ...]]
BACKEND_OUTPUT:
output: [[1. 2. 7. 0. 4. 7. 9. 3. 4. 9.]]
==================================================
...
跟踪时间戳的含义是
HTTP 请求接收:仅针对使用 HTTP 协议的推理请求收集。从网络读取推理请求所需的时间。
发送:发送推理响应所需的时间。
开销:HTTP 端点中处理推理请求和响应所需的额外时间。
处理程序:处理推理请求所花费的总时间,不包括 HTTP 和 GRPC 请求/响应处理。
队列:推理请求在调度队列中花费的时间。
计算:推理请求执行实际推理所花费的时间。此时间包括复制输入和输出张量所花费的时间。如果 –trace-level=TIMESTAMPS,则将提供计算时间的细分,如下所示
输入:推理框架/后端复制输入张量数据所需的时间。这包括将输入张量数据复制到 GPU 的时间。
推理:执行模型以执行推理所花费的时间。
输出:推理框架/后端复制输出张量数据所需的时间。这包括将输出张量数据从 GPU 复制出来的时间。
开销:请求处理所需的额外时间,不包括队列或计算时间。
数据流:第一个请求的数据流。它包含执行的每个部分的输入和输出张量。
名称:模型名称。
版本:模型版本。
QUEUE_INPUT:进入后端队列等待调度的张量。
BACKEND_OUTPUT:后端响应中的张量。
BLS 模型的跟踪#
默认情况下,Triton 不会收集从 BLS 模型调用的子模型的跟踪。
要将子模型包含到收集的跟踪中,用户需要提供 trace
参数(如下例所示),在构造 InferenceRequest 对象时。这有助于 Triton 将子模型与父模型的跟踪(request.trace()
)关联起来。
import triton_python_backend_utils as pb_utils
class TritonPythonModel:
...
def execute(self, requests):
...
for request in requests:
...
inference_request = pb_utils.InferenceRequest(
model_name='model_name',
requested_output_names=['REQUESTED_OUTPUT_1', 'REQUESTED_OUTPUT_2'],
inputs=[<pb_utils.Tensor object>], trace = request.trace())
OpenTelemetry 跟踪支持#
Triton 提供了一个选项,可以使用 OpenTelemetry API 和 SDK 生成和导出跟踪。
要为跟踪指定 OpenTelemetry 模式,请按如下方式指定 --trace-config
标志
$ tritonserver --trace-config mode=opentelemetry \
--trace-config opentelemetry,url=<endpoint> ...
Triton 的 OpenTelemetry 跟踪模式使用 批次 Span 处理器,它批量处理已结束的 span 并批量发送它们。批处理有助于数据压缩并减少传输数据所需的传出连接数。此处理器支持基于大小和基于时间的批处理。基于大小的批处理由 2 个参数控制:bsp_max_export_batch_size
和 bsp_max_queue_size
,而基于时间的批处理由 bsp_schedule_delay
控制。当批次大小达到 bsp_max_export_batch_size
时,或自上次导出以来的延迟达到 bsp_schedule_delay
时(以先到者为准),将导出收集的 span。此外,用户应确保 bsp_max_export_batch_size
始终小于 bsp_max_queue_size
,否则,过多的 span 将被丢弃,并且跟踪数据将丢失。
批次 Span 处理器的默认参数在 OpenTelemetry 跟踪 API 设置
中提供。作为一般建议,请确保 bsp_max_queue_size
足够大以容纳所有收集的 span,并且 bsp_schedule_delay
不会导致频繁导出,这将影响 Triton 服务器的延迟。最小的 Triton 跟踪由 3 个 span 组成:顶级 span、模型 span 和计算 span。
顶级 span:顶级 span 收集请求被 Triton 接收以及响应何时发送的时间戳。任何 Triton 跟踪仅包含 1 个顶级 span。
模型 span:模型 span 收集信息,包括何时为此模型的请求启动、何时将其放入队列以及何时结束。最小的 Triton 跟踪包含 1 个模型 span。
计算 span:计算 span 记录计算时间戳。最小的 Triton 跟踪包含 1 个计算 span。
span 的总数量取决于模型的复杂性。一般规则是任何基本模型(执行计算的单个模型)都会生成 1 个模型 span 和 1 个计算 span。对于集成模型,除了集成的 1 个模型 span 外,每个组成模型都会生成模型和计算 span。BLS 模型生成的模型 span 和计算 span 的数量与 BLS 请求中涉及的模型总数相同,包括主 BLS 模型。
与 Triton 的跟踪 输出 的跟踪内容差异#
OpenTelemetry API 生成 span,它们收集与 Triton 的跟踪 API 相同的时间戳。每个 span 还包括 model_name
、model_version
、request_id
和 parent_id
作为 属性。
span 收集 TIMESTAMPS
,它由名称和以纳秒为单位的时间戳组成,这与 Triton 跟踪 API 类似。但是,OpenTelemetry 依赖于系统的时钟来获取事件时间戳,该时钟基于系统的实时时钟。另一方面,Triton 跟踪 API 使用稳定时钟报告时间戳,稳定时钟是一个单调时钟,可确保时间始终向前移动。此时钟与挂钟时间无关,例如,可以测量自上次重启以来的时间。
OpenTelemetry 跟踪 API 设置#
下表显示了 --trace-config opentelemetry,<setting>=<value>
的可用 OpenTelemetry 跟踪 API 设置。
设置 | 默认值 | 描述 |
---|---|---|
url |
https://127.0.0.1:4318/v1/traces |
接收器将接收跟踪数据的 host:port 。 |
resource |
service.name=triton-inference-server |
用作资源属性的键值对。 应按照提供的模板指定 --trace-config opentelemetry,resource=< 例如 --trace-config opentelemetry,resource=service.name=triton --trace-config opentelemetry,resource=service.version=1 或者,可以通过以下方式指定键值属性 OTEL_RESOURCE_ATTRIBUTES 环境变量。 |
批次 Span 处理器 | ||
bsp_max_queue_size |
2048 | 最大队列大小。 此设置也可以通过以下方式指定 OTEL_BSP_MAX_QUEUE_SIZE 环境变量。 |
bsp_schedule_delay |
5000 | 两次连续导出之间的延迟间隔(以毫秒为单位)。 此设置也可以通过以下方式指定 OTEL_BSP_SCHEDULE_DELAY 环境变量。 |
bsp_max_export_batch_size |
512 | 最大批次大小。必须小于或等于 bsp_max_queue_size 。此设置也可以通过以下方式指定 OTEL_BSP_MAX_EXPORT_BATCH_SIZE 环境变量。 |
OpenTelemetry 上下文传播#
从 24.01 版本开始,Triton 在 OpenTelemetry 模式下支持 上下文传播。请注意,每个具有传播的 OpenTelemetry 上下文的请求都将被跟踪,而与 rate
和 count
跟踪设置无关。如果用户希望仅跟踪那些在客户端注入了 OpenTelemetry 上下文的请求,请使用 --trace-config rate=0
启动 Triton
$ tritonserver \
--trace-config rate=0 \
--trace-config level=TIMESTAMPS \
--trace-config count=-1 \
--trace-config mode=opentelemetry
请注意,此选项在未来版本中可能会更改。
如何在客户端注入 OpenTelemetry 上下文#
对于 C++ 客户端,请参阅 gRPC 和 HTTP 示例。
对于 Python 客户端,请确保安装 OpenTelemetry Python。然后,您可以使用 opentelemetry.propagate.inject
方法来准备要与请求一起传递的标头,如 此处 所示。然后,您可以在 infer
方法中指定标头。有关参考,请查看我们的 测试,例如 http 上下文传播测试。
自定义后端跟踪#
如果需要在后端跟踪自定义活动,请使用 TRITONSERVER_InferenceTraceReportActivity
API。有关示例,请参阅 identity 后端。
在 openTelemetry
跟踪模式下,如果希望启动新的 span,请确保您的自定义活动的名称以 _START
结尾。要结束新的 span,请确保相应的活动以 _END
结尾。例如,在 identity 后端中,我们通过 报告 CUSTOM_ACTIVITY_START
事件来启动 CUSTOM_ACTIVITY
span;我们通过 报告 CUSTOM_ACTIVITY_END
事件来关闭此 span。
请注意,用户有责任确保所有自定义启动的 span 都已正确结束。
限制#
Windows 系统不支持 OpenTelemetry 跟踪模式。
Triton 仅支持 OTLP/HTTP Exporter,并且仅允许通过
--trace-config
为此导出器指定 url。其他选项和相应的默认值可以在 此处 找到。Triton 不支持在 Triton 运行期间配置 opentelemetry 跟踪设置,并且 opentelemetry 特定设置不能通过 Triton 的跟踪扩展 进行检索。