跳到内容

指标

确保 v1 LLM 引擎暴露的指标是 v0 可用指标的超集。

目标

  • 实现 v0 和 v1 之间的指标对等。
  • 首要用例是通过 Prometheus 访问这些指标,因为我们预期这将在生产环境中使用。
  • 提供日志支持(即,将指标打印到信息日志中),用于更即兴的测试、调试、开发和探索性用例。

背景

vLLM 中的指标可分为以下几类:

  1. 服务器级别指标:跟踪 LLM 引擎状态和性能的全局指标。这些通常在 Prometheus 中作为 Gauges 或 Counters 暴露。
  2. 请求级别指标:跟踪单个请求特征(例如,大小和时间)的指标。这些通常在 Prometheus 中作为 Histograms 暴露,并且通常是 SRE 监控 vLLM 时会跟踪的 SLO。

思维模型是服务器级别指标有助于解释请求级别指标的值。

v0 指标

在 v0 中,以下指标通过 Prometheus 兼容的 /metrics 端点暴露,使用 vllm: 前缀:

  • vllm:num_requests_running (Gauge)
  • vllm:num_requests_swapped (Gauge)
  • vllm:num_requests_waiting (Gauge)
  • vllm:gpu_cache_usage_perc (Gauge)
  • vllm:cpu_cache_usage_perc (Gauge)
  • vllm:gpu_prefix_cache_hit_rate (Gauge)
  • vllm:cpu_prefix_cache_hit_rate (Gauge)
  • vllm:prompt_tokens_total (Counter)
  • vllm:generation_tokens_total (Counter)
  • vllm:request_success_total (Counter)
  • vllm:request_prompt_tokens (Histogram)
  • vllm:request_generation_tokens (Histogram)
  • vllm:time_to_first_token_seconds (Histogram)
  • vllm:time_per_output_token_seconds (Histogram)
  • vllm:e2e_request_latency_seconds (Histogram)
  • vllm:request_queue_time_seconds (Histogram)
  • vllm:request_inference_time_seconds (Histogram)
  • vllm:request_prefill_time_seconds (Histogram)
  • vllm:request_decode_time_seconds (Histogram)
  • vllm:request_max_num_generation_tokens (Histogram)
  • vllm:num_preemptions_total (Counter)
  • vllm:cache_config_info (Gauge)
  • vllm:lora_requests_info (Gauge)
  • vllm:tokens_total (Counter)
  • vllm:iteration_tokens_total (Histogram)
  • vllm:time_in_queue_requests (Histogram)
  • vllm:model_forward_time_milliseconds (Histogram)
  • vllm:model_execute_time_milliseconds (Histogram)
  • vllm:request_params_n (Histogram)
  • vllm:request_params_max_tokens (Histogram)
  • vllm:spec_decode_draft_acceptance_rate (Gauge)
  • vllm:spec_decode_efficiency (Gauge)
  • vllm:spec_decode_num_accepted_tokens_total (Counter)
  • vllm:spec_decode_num_draft_tokens_total (Counter)
  • vllm:spec_decode_num_emitted_tokens_total (Counter)

这些在推理和服务 -> 生产指标下有文档记录。

Grafana 仪表盘

vLLM 还提供了一个参考示例,说明如何使用 Prometheus 收集和存储这些指标,并使用 Grafana 仪表盘进行可视化。

Grafana 仪表盘中暴露的指标子集表明了哪些指标尤其重要:

  • vllm:e2e_request_latency_seconds_bucket - 端到端请求延迟,以秒为单位。
  • vllm:prompt_tokens_total - 提示词令牌数。
  • vllm:generation_tokens_total - 生成令牌数。
  • vllm:time_per_output_token_seconds - 令牌间延迟(每输出令牌时间,TPOT),以秒为单位。
  • vllm:time_to_first_token_seconds - 首令牌时间(TTFT)延迟,以秒为单位。
  • vllm:num_requests_running (以及 _swapped_waiting) - 处于 RUNNING、WAITING 和 SWAPPED 状态的请求数。
  • vllm:gpu_cache_usage_perc - vLLM 使用的缓存块百分比。
  • vllm:request_prompt_tokens - 请求提示长度。
  • vllm:request_generation_tokens - 请求生成长度。
  • vllm:request_success_total - 完成的请求数,按完成原因分类:生成了 EOS 令牌或达到最大序列长度。
  • vllm:request_queue_time_seconds - 队列时间。
  • vllm:request_prefill_time_seconds - 请求预填充时间。
  • vllm:request_decode_time_seconds - 请求解码时间。
  • vllm:request_max_num_generation_tokens - 序列组中的最大生成令牌数。

请参阅 添加此仪表盘的 PR,了解关于此处选择的有趣且有用的背景信息。

Prometheus 客户端库

Prometheus 支持最初是 使用 aioprometheus 库添加的,但很快就切换到了 prometheus_client。理由在两个链接的 PR 中都有讨论。

切换到 aioprometheus 后,我们失去了用于跟踪 HTTP 指标的 MetricsMiddleware,但这已通过 prometheus_fastapi_instrumentator 恢复。

$ curl http://0.0.0.0:8000/metrics 2>/dev/null  | grep -P '^http_(?!.*(_bucket|_created|_sum)).*'
http_requests_total{handler="/v1/completions",method="POST",status="2xx"} 201.0
http_request_size_bytes_count{handler="/v1/completions"} 201.0
http_response_size_bytes_count{handler="/v1/completions"} 201.0
http_request_duration_highr_seconds_count 201.0
http_request_duration_seconds_count{handler="/v1/completions",method="POST"} 201.0

多进程模式

在 v0 中,指标在引擎核心进程中收集,我们使用多进程模式使其在 API 服务器进程中可用。请参阅 拉取请求 #7279

内置 Python/进程指标

以下指标是 prometheus_client 默认支持的,但在使用多进程模式时不暴露:

  • python_gc_objects_collected_total
  • python_gc_objects_uncollectable_total
  • python_gc_collections_total
  • python_info
  • process_virtual_memory_bytes
  • process_resident_memory_bytes
  • process_start_time_seconds
  • process_cpu_seconds_total
  • process_open_fds
  • process_max_fds

这之所以相关,是因为如果我们在 v1 中放弃多进程模式,我们将重新获得这些指标。然而,如果它们不能聚合组成 vLLM 实例的所有进程的统计信息,那么这些指标的相关性就值得怀疑。

v0 PRs 和 Issues

作为背景,以下是一些添加 v0 指标的相关 PR:

另请注意 “更好的可观测性”功能,其中例如 详细路线图已制定

v1 设计

v1 PRs

作为背景,以下是与 v1 指标问题相关的 v1 PRs: 问题 #10582

指标收集

在 v1 中,我们希望将计算和开销从引擎核心进程中移出,以最小化每次正向传播之间的时间。

v1 EngineCore 设计的总体思路是:

  • EngineCore 是内循环。性能在此处最关键。
  • AsyncLLM 是外循环。这与 GPU 执行重叠(理想情况下),因此任何“开销”都应该尽可能放在这里。因此,AsyncLLM.output_handler_loop 是指标记账的理想位置(如果可能的话)。

我们将通过在前端 API 服务器中收集指标来实现这一点,并将这些指标基于我们从引擎核心进程返回到前端的 EngineCoreOutputs 中获取的信息。

间隔计算

我们的许多指标都是请求处理过程中各种事件之间的时间间隔。最佳实践是使用基于“单调时间”(time.monotonic())而不是“挂钟时间”(time.time())的时间戳来计算间隔,因为前者不受系统时钟变化(例如,来自 NTP)的影响。

同样重要的是要注意,单调时钟在不同进程之间是不同的——每个进程都有自己的参考点。因此,比较来自不同进程的单调时间戳是没有意义的。

因此,为了计算间隔,我们必须比较来自同一进程的两个单调时间戳。

调度器统计

引擎核心进程将从调度器收集一些关键统计信息——例如,在上次调度器通过后调度或等待的请求数量——并将这些统计信息包含在 EngineCoreOutputs 中。

引擎核心事件

引擎核心还将记录某些请求事件的时间戳,以便前端可以计算这些事件之间的时间间隔。

事件包括:

  • QUEUED - 请求被引擎核心接收并添加到调度器队列时。
  • SCHEDULED - 请求首次被调度执行时。
  • PREEMPTED - 请求已被放回等待队列,以便为其他请求完成腾出空间。它将在未来重新调度并重新启动其预填充阶段。
  • NEW_TOKENS - EngineCoreOutput 中包含的输出生成时。由于这对于给定迭代中的所有请求都是通用的,因此我们在 EngineCoreOutputs 上使用单个时间戳来记录此事件。

计算出的间隔是:

  • 队列间隔 - 在 QUEUED 和最近的 SCHEDULED 之间。
  • 预填充间隔 - 在最近的 SCHEDULED 和随后的第一个 NEW_TOKENS 之间。
  • 解码间隔 - 在第一个(在最近的 SCHEDULED 之后)和最后一个 NEW_TOKENS 之间。
  • 推理间隔 - 在最近的 SCHEDULED 和最后一个 NEW_TOKENS 之间。
  • 令牌间间隔 - 在连续的 NEW_TOKENS 之间。

换句话说:

Interval calculations - common case

我们探讨了让前端使用前端可见事件的时间来计算这些间隔的可能性。然而,前端无法看到 QUEUEDSCHEDULED 事件的时间,而且,由于我们需要根据来自同一进程的单调时间戳计算间隔……我们需要引擎核心记录所有这些事件的时间戳。

间隔计算与抢占

当在解码期间发生抢占时,由于任何已生成的令牌都将被重用,我们将抢占视为影响令牌间、解码和推理间隔。

Interval calculations - preempted decode

当在预填充期间发生抢占时(假设此类事件可能发生),我们将抢占视为影响首令牌时间和预填充间隔。

Interval calculations - preempted prefill

前端统计收集

当前端处理单个 EngineCoreOutputs——即单个引擎核心迭代的输出——它会收集与该迭代相关的各种统计信息:

  • 本次迭代中生成的新令牌总数。
  • 本次迭代中完成预填充的预填充所处理的提示令牌总数。
  • 本次迭代中调度的任何请求的队列间隔。
  • 本次迭代中完成预填充的任何请求的预填充间隔。
  • 本次迭代中包含的所有请求的令牌间间隔(每输出令牌时间,TPOT)。
  • 本次迭代中完成预填充的任何请求的首令牌时间(TTFT)。然而,我们计算此间隔是相对于请求首次被前端接收的时间(arrival_time),以考虑输入处理时间。

对于给定迭代中完成的任何请求,我们还记录:

  • 推理和解码间隔 - 相对于调度和首令牌事件,如上所述。
  • 端到端延迟 - 前端 arrival_time 与前端接收到最终令牌之间的时间间隔。

指标发布 - 日志

LoggingStatLogger 指标发布器每 5 秒输出一个日志 INFO 消息,其中包含一些关键指标:

  • 当前运行/等待请求的数量
  • 当前 GPU 缓存使用情况
  • 过去 5 秒内每秒处理的提示令牌数量
  • 过去 5 秒内每秒生成的新令牌数量
  • 最近 1k kv-缓存块查询的前缀缓存命中率

指标发布 - Prometheus

PrometheusStatLogger 指标发布器通过 /metrics HTTP 端点以 Prometheus 兼容的格式提供指标。然后可以配置 Prometheus 实例来轮询此端点(例如,每秒),并在其时间序列数据库中记录这些值。Prometheus 通常通过 Grafana 使用,允许这些指标随时间绘制图表。

Prometheus 支持以下指标类型:

  • Counter(计数器):一个随时间增加、永不减少的值,通常在 vLLM 实例重启时重置为零。例如,实例生命周期内生成的令牌总数。
  • Gauge(仪表):一个可升可降的值,例如当前调度执行的请求数量。
  • Histogram(直方图):度量样本的计数,记录在桶中。例如,TTFT <1ms、<5ms、<10ms、<20ms 等的请求数量。

Prometheus 指标也可以进行标记,允许根据匹配的标签组合指标。在 vLLM 中,我们为每个指标添加一个 model_name 标签,其中包含该实例服务的模型名称。

示例输出

$ curl http://0.0.0.0:8000/metrics
# HELP vllm:num_requests_running Number of requests in model execution batches.
# TYPE vllm:num_requests_running gauge
vllm:num_requests_running{model_name="meta-llama/Llama-3.1-8B-Instruct"} 8.0
...
# HELP vllm:generation_tokens_total Number of generation tokens processed.
# TYPE vllm:generation_tokens_total counter
vllm:generation_tokens_total{model_name="meta-llama/Llama-3.1-8B-Instruct"} 27453.0
...
# HELP vllm:request_success_total Count of successfully processed requests.
# TYPE vllm:request_success_total counter
vllm:request_success_total{finished_reason="stop",model_name="meta-llama/Llama-3.1-8B-Instruct"} 1.0
vllm:request_success_total{finished_reason="length",model_name="meta-llama/Llama-3.1-8B-Instruct"} 131.0
vllm:request_success_total{finished_reason="abort",model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.0
...
# HELP vllm:time_to_first_token_seconds Histogram of time to first token in seconds.
# TYPE vllm:time_to_first_token_seconds histogram
vllm:time_to_first_token_seconds_bucket{le="0.001",model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.0
vllm:time_to_first_token_seconds_bucket{le="0.005",model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.0
vllm:time_to_first_token_seconds_bucket{le="0.01",model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.0
vllm:time_to_first_token_seconds_bucket{le="0.02",model_name="meta-llama/Llama-3.1-8B-Instruct"} 13.0
vllm:time_to_first_token_seconds_bucket{le="0.04",model_name="meta-llama/Llama-3.1-8B-Instruct"} 97.0
vllm:time_to_first_token_seconds_bucket{le="0.06",model_name="meta-llama/Llama-3.1-8B-Instruct"} 123.0
vllm:time_to_first_token_seconds_bucket{le="0.08",model_name="meta-llama/Llama-3.1-8B-Instruct"} 138.0
vllm:time_to_first_token_seconds_bucket{le="0.1",model_name="meta-llama/Llama-3.1-8B-Instruct"} 140.0
vllm:time_to_first_token_seconds_count{model_name="meta-llama/Llama-3.1-8B-Instruct"} 140.0

注意

选择最能为广泛用例用户提供帮助的直方图桶并非易事,需要随着时间的推移进行完善。

缓存配置信息

prometheus_client 支持信息指标 (Info metrics),它等同于一个值永久设置为 1 的 Gauge,但通过标签暴露有趣的键/值对信息。这用于实例中不变的信息——因此只需要在启动时观察——并允许在 Prometheus 中进行实例间比较。

我们将此概念用于 vllm:cache_config_info 指标:

# HELP vllm:cache_config_info Information of the LLMEngine CacheConfig
# TYPE vllm:cache_config_info gauge
vllm:cache_config_info{block_size="16",cache_dtype="auto",calculate_kv_scales="False",cpu_offload_gb="0",enable_prefix_caching="False",gpu_memory_utilization="0.9",...} 1.0

然而,prometheus_client 从未在多进程模式下支持信息指标——原因 不明。我们简单地使用一个设置为 1 的 Gauge 指标,并使用 multiprocess_mode="mostrecent" 代替。

LoRA 指标

vllm:lora_requests_info Gauge 有些类似,只是值是当前的挂钟时间,并且每迭代更新一次。

使用的标签名称是:

  • running_lora_adapters: 每个适配器上运行的使用该适配器的请求计数,格式为逗号分隔的字符串。
  • waiting_lora_adapters: 类似,但计数的是等待调度的请求。
  • max_lora - 静态的“单个批次中最大 LoRA 数量”配置。

将多个适配器的运行/等待计数编码为逗号分隔的字符串似乎相当误导——我们可以使用标签来区分每个适配器的计数。这应该重新审视。

请注意,使用了 multiprocess_mode="livemostrecent"——使用最新的指标,但仅来自当前运行的进程。

这在 拉取请求 #9477 中添加,并且至少有一位已知用户。如果我们重新审视这个设计并弃用旧指标,我们应该通过在 v0 中也进行更改并要求该项目迁移到新指标来减少长时间弃用期的需要。

前缀缓存指标

问题 #10582 中关于添加前缀缓存指标的讨论提出了一些有趣的观点,可能与我们未来如何处理指标相关。

每次查询前缀缓存时,我们都会记录查询的令牌数量以及缓存中存在的查询令牌数量(即命中)。

然而,我们感兴趣的指标是命中率——即每次查询的命中次数。

在日志记录的情况下,我们期望用户通过计算最近固定数量查询的命中率来获得最佳服务(目前间隔固定为最近 1k 次查询)。

但在 Prometheus 的情况下,我们应该利用 Prometheus 的时间序列特性,允许用户计算他们选择的间隔内的命中率。例如,一个 PromQL 查询来计算过去 5 分钟的命中间隔:

rate(cache_query_hit[5m]) / rate(cache_query_total[5m])

为了实现这一点,我们应该将查询和命中记录为 Prometheus 中的计数器,而不是将命中率记录为仪表。

已弃用指标

如何弃用

弃用指标不应轻率。用户可能没有注意到指标已被弃用,当指标突然(从他们的角度看)被移除时,即使有等效指标可用,也可能会给他们带来不便。

例如,请看 vllm:avg_prompt_throughput_toks_per_s 是如何被 弃用(代码中有注释),然后被 移除,然后被 用户注意到

通常来说:

  1. 我们应该谨慎弃用指标,尤其难以预测其对用户的影响。
  2. 我们应该在 /metrics 输出的帮助字符串中包含醒目的弃用通知。
  3. 我们应该在用户文档和发布说明中列出已弃用的指标。
  4. 我们应该考虑将弃用的指标隐藏在一个 CLI 参数后面,以便在删除它们之前给管理员提供一段时间的“逃生舱口”

请参阅弃用策略,了解项目范围的弃用策略。

未实现 - vllm:tokens_total

拉取请求 #4464 添加,但显然从未实现。这可以直接移除。

重复 - 队列时间

vllm:time_in_queue_requests 直方图指标由 拉取请求 #9659 添加,其计算方式是:

    self.metrics.first_scheduled_time = now
    self.metrics.time_in_queue = now - self.metrics.arrival_time

两周后, 拉取请求 #4464 添加了 vllm:request_queue_time_seconds,导致我们有了:

if seq_group.is_finished():
    if (seq_group.metrics.first_scheduled_time is not None and
            seq_group.metrics.first_token_time is not None):
        time_queue_requests.append(
            seq_group.metrics.first_scheduled_time -
            seq_group.metrics.arrival_time)
    ...
    if seq_group.metrics.time_in_queue is not None:
        time_in_queue_requests.append(
            seq_group.metrics.time_in_queue)

这似乎是重复的,其中一个应该被移除。后者被 Grafana 仪表盘使用,因此我们应该弃用或移除 v0 中的前者。

前缀缓存命中率

见上文——我们现在暴露的是“查询”和“命中”计数器,而不是“命中率”仪表。

KV 缓存卸载

两个 v0 指标与 v1 中不再相关的“交换”抢占模式有关:

  • vllm:num_requests_swapped
  • vllm:cpu_cache_usage_perc

在这种模式下,当请求被抢占时(例如,为了在 KV 缓存中为其他请求腾出空间),我们将 KV 缓存块交换到 CPU 内存。这也被称为“KV 缓存卸载”,并通过 --swap-space--preemption-mode 进行配置。

在 v0 中, vLLM 长期支持束搜索。SequenceGroup 封装了 N 个序列共享相同提示 kv 块的想法。这使得请求之间可以共享 KV 缓存块,并使用写时复制进行分支。CPU 交换旨在用于这些类似束搜索的情况。

后来,引入了前缀缓存的概念,它允许隐式共享 KV 缓存块。事实证明,这比 CPU 交换是更好的选择,因为块可以按需缓慢逐出,并且已逐出的提示部分可以重新计算。

SequenceGroup 已在 V1 中移除,尽管“并行采样”(n>1)需要替换。在 V0 中, 束搜索已移出核心。有很多复杂的代码用于一个非常不常见的功能。

在 V1 中,由于前缀缓存更好(零开销)并且默认开启,因此抢占和重新计算策略应该更好地工作。

未来工作

并行采样

一些 v0 指标仅与“并行采样”相关。这是指请求中的 n 参数用于从同一提示请求多个完成。

作为在 拉取请求 #10980 中添加并行采样支持的一部分,我们还应该添加这些指标。

  • vllm:request_params_n (Histogram)

观察每个已完成请求的“n”参数值。

  • vllm:request_max_num_generation_tokens (Histogram)

观察每个已完成序列组中所有序列的最大输出长度。在没有并行采样的情况下,这等同于 vllm:request_generation_tokens

推测解码

一些 v0 指标特定于“推测解码”。这是指我们使用更快、近似的方法或模型生成候选令牌,然后使用更大的模型验证这些令牌。

  • vllm:spec_decode_draft_acceptance_rate (Gauge)
  • vllm:spec_decode_efficiency (Gauge)
  • vllm:spec_decode_num_accepted_tokens_total (Counter)
  • vllm:spec_decode_num_draft_tokens_total (Counter)
  • vllm:spec_decode_num_emitted_tokens_total (Counter)

有一个 PR 正在审核中( 拉取请求 #12193),旨在向 v1 添加“提示查找(ngram)”推测解码。其他技术将随之而来。我们应该在此背景下重新审视 v0 指标。

注意

我们可能应该将接受率暴露为单独的接受计数器和草稿计数器,就像我们对前缀缓存命中率所做的那样。效率可能也需要类似的处理。

自动扩缩和负载均衡

我们指标的一个常见用例是支持 vLLM 实例的自动化扩缩。

有关来自 Kubernetes 服务工作组的相关讨论,请参阅:

这是一个不容忽视的话题。考虑一下 Rob 的评论:

我认为这个指标应该着重于尝试估计最大并发量,这将导致平均请求长度 > 每秒查询量……因为这才是真正会“饱和”服务器的原因。

一个明确的目标是,我们应该暴露检测此饱和点所需的指标,以便管理员可以根据这些指标实施自动扩缩规则。然而,为了做到这一点,我们需要清楚地了解管理员(和自动化监控系统)应该如何判断实例何时接近饱和:

为了识别模型服务器计算的饱和点(即在更高请求率下无法获得更高吞吐量,但会开始产生额外延迟的拐点),我们如何才能有效地自动扩缩?

指标命名

我们命名指标的方法可能值得重新审视:

  1. 在指标名称中使用冒号似乎与“冒号保留用于用户自定义记录规则”相悖。
  2. 我们的大多数指标都遵循以单位结尾的约定,但并非所有都如此。
  3. 我们的一些指标名称以 _total 结尾:

    如果指标名称中带有 _total 后缀,它将被移除。当暴露计数器的时间序列时,将添加 _total 后缀。这是为了 OpenMetrics 和 Prometheus 文本格式之间的兼容性,因为 OpenMetrics 要求使用 _total 后缀。

添加更多指标

新的指标构想层出不穷:

我们应该谨慎对待添加新指标。虽然指标通常相对容易添加,但:

  1. 它们可能难以移除——请参阅上文的弃用部分。
  2. 启用时可能会对性能产生显著影响。而且,除非可以默认在生产环境中启用,否则指标的使用价值非常有限。
  3. 它们对项目的开发和维护产生影响。添加到 v0 的每个指标都使得这项 v1 工作更加耗时,而且并非所有指标都值得持续投入维护。

追踪 - OpenTelemetry

指标提供了系统性能和健康状况随时间变化的聚合视图。另一方面,追踪则跟踪单个请求在不同服务和组件之间的移动。两者都属于“可观测性”这一更广泛的范畴。

v0 支持 OpenTelemetry 追踪:

OpenTelemetry 设有一个生成式 AI 工作组

鉴于指标本身是一个足够大的话题,我们将把 v1 中追踪的话题单独处理。

OpenTelemetry 模型正向传播与执行时间

在 v0 中,我们有以下两个指标:

  • vllm:model_forward_time_milliseconds (直方图) - 此请求在批处理中时,模型正向传播所花费的时间。
  • vllm:model_execute_time_milliseconds (直方图) - 模型执行函数所花费的时间。这将包括模型正向传播、跨工作器的块/同步、CPU-GPU 同步时间和采样时间。

这些指标仅在启用 OpenTelemetry 追踪且使用 --collect-detailed-traces=all/model/worker 时才启用。此选项的文档指出:

收集指定模块的详细追踪。这可能涉及使用耗时或阻塞操作,因此可能对性能产生影响。

这些指标由 拉取请求 #7089 添加,并作为 OpenTelemetry 追踪中的内容:

-> gen_ai.latency.time_in_scheduler: Double(0.017550230026245117)
-> gen_ai.latency.time_in_model_forward: Double(3.151565277099609)
-> gen_ai.latency.time_in_model_execute: Double(3.6468167304992676)

我们已经有了 inference_timedecode_time 指标,因此问题是更高分辨率的时间是否有足够常见的用例来证明其开销是合理的。

由于我们将单独处理 OpenTelemetry 支持的问题,因此我们将把这些特定指标纳入该主题下。