跳至内容

指标

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

目标

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

背景

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

  1. 服务器级别指标:这些是跟踪 LLM 引擎状态和性能的全局指标。它们通常在 Prometheus 中作为 Gauge 或 Counter 暴露。
  2. 请求级别指标:这些是跟踪单个请求特征(例如大小和时间)的指标。它们通常在 Prometheus 中作为 Histogram 暴露,并且通常是 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 - 提示词 Token
  • vllm:generation_tokens_total - 生成 Token
  • vllm:time_per_output_token_seconds - Token 间延迟(每输出 Token 时间,TPOT),单位为秒。
  • vllm:time_to_first_token_seconds - 首个 Token 时间(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 Token,或达到了最大序列长度
  • vllm:request_queue_time_seconds - 队列时间
  • vllm:request_prefill_time_seconds - 请求预填充时间
  • vllm:request_decode_time_seconds - 请求解码时间
  • vllm:request_max_num_generation_tokens - 序列组中的最大生成 Token

请参阅添加此面板的拉取请求,了解此处选择的有趣且有用的背景信息。

Prometheus 客户端库

Prometheus 支持最初是使用 aioprometheus 库添加的,但很快切换到了 prometheus_client。原因在两个链接的拉取请求中都有讨论。

切换到 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 拉取请求和议题

作为背景信息,以下是一些添加了 v0 指标的相关拉取请求

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

v1 设计

v1 拉取请求

作为背景信息,以下是与 v1 指标问题相关的 v1 拉取请求 议题 #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 之间。
  • Token 间间隔 - 在连续的 NEW_TOKENS 之间。

换句话说

Interval calculations - common case

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

间隔计算对比抢占

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

Interval calculations - preempted decode

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

Interval calculations - preempted prefill

前端统计收集

当前端处理单个 EngineCoreOutputs(即单个引擎核心迭代的输出)时,它会收集与该迭代相关的各种统计数据

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

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

  • 推理和解码间隔——相对于调度和第一个 Token 事件,如上所述。
  • 端到端延迟——前端 arrival_time 与前端接收到最后一个 Token 之间的间隔。

指标发布 - 日志记录

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

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

指标发布 - Prometheus

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

Prometheus 支持以下指标类型

  • Counter(计数器):一个随时间增加的值,永不减少,通常在 vLLM 实例重新启动时重置为零。例如,实例生命周期内生成的 Token 数量。
  • 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 指标,它等同于一个值永久设置为 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 在多进程模式下从未支持 Info 指标——原因不明。我们只是改用一个值设置为 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 中的讨论提出了一些有趣的观点,这些观点可能与我们未来如何处理指标有关。

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

然而,我们关注的指标是命中率——即每次查询的命中数量。

在日志记录的情况下,我们期望通过计算固定数量的最近查询的命中率来最好地服务用户(目前间隔固定为最近 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 Histogram 指标由 拉取请求 #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 指标是“推测解码”特有的。这是指我们使用更快、近似的方法或模型生成候选 Token,然后使用更大的模型验证这些 Token。

  • 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)

有一个正在审查中的拉取请求( 拉取请求 #12193) 旨在为 v1 添加“提示词查找(ngram)”推测解码。其他技术也将陆续推出。我们应该在此背景下重新审视 v0 指标。

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

自动扩缩容和负载均衡

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

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

这是一个非简单的话题。考虑一下 Rob 的这条评论

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

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

为了确定,模型服务器计算的饱和点是什么(即在更高的请求速率下无法获得更多吞吐量,但开始产生额外延迟的拐点),以便我们能够有效地进行自动扩缩容?

指标命名

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

  1. 在指标名称中使用冒号似乎与“冒号保留给用户定义的记录规则”相悖
  2. 我们的大多数指标遵循以单位结尾的约定,但并非全部如此。
  3. 我们的一些指标名称以 _total 结尾
If there is a suffix of `_total` on the metric name, it will be removed. When
exposing the time series for counter, a `_total` suffix will be added. This is
for compatibility between OpenMetrics and the Prometheus text format, as OpenMetrics
requires the `_total` suffix.

添加更多指标

关于新指标的想法源源不断

我们在添加新指标时应保持谨慎。虽然添加指标通常相对直接

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

跟踪 - OpenTelemetry

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

v0 支持 OpenTelemetry 跟踪

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

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

OpenTelemetry 模型前向对比执行时间

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

  • vllm:model_forward_time_milliseconds (Histogram) - 当此请求在批次中时,模型前向传播所花费的时间。
  • vllm:model_execute_time_milliseconds (Histogram) - 模型执行函数中花费的时间。这包括模型前向传播、跨 workers 的块/同步、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 支持的问题,因此会将这些特定指标包含在该主题下。