跳到內容

指標

vLLM 提供了一套豐富的指標,以支援 V1 引擎的可觀測性和容量規劃。

目標

  • 全面覆蓋引擎和請求級別的指標,以輔助生產環境的監控。
  • 優先整合 Prometheus,因為我們預計它將在生產環境中使用。
  • 提供日誌支援(即列印指標到 info 日誌),用於臨時測試、除錯、開發和探索性用例。

背景

vLLM 中的指標可以按如下方式分類:

  1. 伺服器級別指標:全域性指標,用於跟蹤 LLM 引擎的狀態和效能。這些通常在 Prometheus 中暴露為 Gauge 或 Counter。
  2. 請求級別指標:指標,用於跟蹤單個請求的特徵(例如大小和計時)。這些通常在 Prometheus 中暴露為 Histogram,並且通常是 SRE 監控 vLLM 時將跟蹤的 SLO。

其思想模型是,伺服器級別指標有助於解釋請求級別指標的值。

指標概覽

v1 指標

在 v1 中,透過 Prometheus 相容的 /metrics 端點公開了大量的指標,使用 vllm: 字首,例如:

  • vllm:num_requests_running (Gauge) - 當前執行的請求數量。
  • vllm:kv_cache_usage_perc (Gauge) - 已使用的 KV cache 塊的比例(0-1)。
  • vllm:prefix_cache_queries (Counter) - Prefix cache 查詢次數。
  • vllm:prefix_cache_hits (Counter) - Prefix cache 命中次數。
  • vllm:prompt_tokens_total (Counter) - 處理過的 Prompt tokens 總數。
  • vllm:generation_tokens_total (Counter) - 生成的 tokens 總數。
  • vllm:request_success_total (Counter) - 完成的請求數量(按結束原因)。
  • vllm:request_prompt_tokens (Histogram) - 輸入 Prompt token 數量的直方圖。
  • vllm:request_generation_tokens (Histogram) - 生成 token 數量的直方圖。
  • vllm:time_to_first_token_seconds (Histogram) - 到達第一個 token 的時間(TTFT)。
  • vllm:inter_token_latency_seconds (Histogram) - Token 之間的延遲。
  • vllm:e2e_request_latency_seconds (Histogram) - 端到端請求延遲。
  • vllm:request_prefill_time_seconds (Histogram) - 請求的預填充時間。
  • vllm:request_decode_time_seconds (Histogram) - 請求的解碼時間。

這些在 推理與服務 -> 生產指標 中有記錄。

Grafana Dashboard

vLLM 還提供了一個 參考示例,展示瞭如何使用 Prometheus 收集和儲存這些指標,並使用 Grafana 進行視覺化。

Grafana Dashboard 中顯示的指標子集表明了哪些指標特別重要。

  • vllm:e2e_request_latency_seconds_bucket - 端到端請求延遲(秒)。
  • vllm:prompt_tokens - Prompt tokens。
  • vllm:generation_tokens - Generation tokens。
  • 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:kv_cache_usage_perc - vLLM 使用的 cache 塊百分比。
  • vllm:request_prompt_tokens - 請求 Prompt 長度。
  • vllm:request_generation_tokens - 請求 Generation 長度。
  • vllm:request_success - 完成的請求數量(按其結束原因):生成了 EOS token 或達到了最大序列長度。
  • vllm:request_queue_time_seconds - 排隊時間。
  • vllm:request_prefill_time_seconds - 請求預填充時間。
  • vllm:request_decode_time_seconds - 請求解碼時間。
  • vllm:request_max_num_generation_tokens - 序列組的最大生成 token 數量。

請參閱 新增此 Dashboard 的 PR 以獲取有關此處所做選擇的有趣且有用的背景資訊。

Prometheus Client Library

Prometheus 支援最初是使用 aioprometheus 庫新增的,但很快切換到了 prometheus_client。理由在兩個連結的 PR 中都有討論。

在這些遷移過程中,我們短暫丟失了用於跟蹤 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

多程序模式

歷史上,指標是在引擎核心程序中收集的,並透過多程序模式使其在 API 伺服器程序中可用。請參閱 PR #7279

最近,指標是在 API 伺服器程序中收集的,並且僅在 --api-server-count > 1 時使用多程序模式。請參閱 PR #17546API 伺服器橫向擴充套件的詳細資訊。

內建 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

因此,當 --api-server-count > 1 時,這些指標將不可用。這些指標的相關性值得懷疑,因為它們沒有彙總構成 vLLM 例項的所有程序的這些統計資訊。

指標設計

"Even Better Observability" 功能中,其中大部分指標設計都在此進行了規劃。例如,請參閱 詳細路線圖

舊版 PR

為了幫助理解指標設計的背景,以下是一些添加了原始、現在已棄用指標的相關 PR:

指標實現 PR

作為背景,以下是與指標實現相關的 PR: Issue #10582

指標收集

在 v1 中,我們希望將計算和開銷移出引擎核心程序,以最大限度地減少每次前向傳遞之間的時間。

V1 EngineCore 設計的整體思路是:

  • EngineCore 是內部迴圈。效能在此處最為關鍵。
  • AsyncLLM 是外部迴圈。它與 GPU 執行(理想情況下)重疊,因此如果可能,任何“開銷”都應該在此處。因此,如果可能,AsyncLLM.output_handler_loop 是指標簿記的理想位置。

我們將透過在前端 API 伺服器中收集指標來實現這一點,並根據從引擎核心程序返回給前端的 EngineCoreOutputs 中收集的資訊來確定這些指標。

時間間隔計算

我們的許多指標是處理請求過程中各種事件之間的時間間隔。最佳實踐是使用基於“單調時間”(time.monotonic())而不是“掛鐘時間”(time.time())的時間戳來計算時間間隔,因為前者不受系統時鐘更改(例如 NTP 引起)的影響。

同樣重要的是要注意,單調時鐘在程序之間是不同的——每個程序都有自己的參考點。因此,比較來自不同程序的單調時間戳是沒有意義的。

因此,為了計算時間間隔,我們必須比較同一程序中的兩個單調時間戳。

排程器統計資訊

引擎核心程序將從排程器收集一些關鍵統計資訊——例如,在上一個排程器傳遞後已排程或等待的請求數量——並將這些統計資訊包含在 EngineCoreOutputs 中。

Engine Core 事件

引擎核心還將記錄某些每個請求事件的時間戳,以便前端可以計算這些事件之間的時間間隔。

事件是:

  • 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 的時間(time-to-first-token)和預填充間隔。

Interval calculations - preempted prefill

前端統計資訊收集

當前端處理單個 EngineCoreOutputs(即來自單個引擎核心迭代的輸出)時,它會收集與該迭代相關的各種統計資訊:

  • 此迭代中生成的新 token 總數。
  • 此迭代中完成的預填充所處理的 prompt token 總數。
  • 此迭代中安排的任何請求的佇列間隔。
  • 此迭代中完成的任何請求的預填充間隔。
  • 此迭代中包含的所有請求的 token 之間間隔(每輸出 token 時間,TPOT)。
  • 此迭代中完成預填充的任何請求的到達第一個 token 的時間(TTFT)。然而,我們計算此時間間隔是相對於請求首次由前端接收(arrival_time)的時間,以考慮輸入處理時間。

對於在給定迭代中完成的任何請求,我們還記錄:

  • 推理和解碼間隔 - 相對於上述的排程和第一個 token 事件。
  • 端到端延遲 - 前端 arrival_time 到前端接收最後一個 token 之間的時間間隔。

KV Cache 駐留指標

我們還輸出了一個直方圖集,描述了取樣的 KV cache 塊的駐留時間以及它們被重用的頻率。取樣(--kv-cache-metrics-sample)可以使開銷微乎其微;當選擇一個塊時,我們記錄:

  • lifetime – 分配 ⟶ 驅逐
  • idle before eviction – 最後一次觸碰 ⟶ 驅逐
  • reuse gaps – 當塊被重用時,觸碰之間的暫停時間

這些直接對映到 Prometheus 指標:

  • vllm:kv_block_lifetime_seconds – 每個取樣塊存在的時間。
  • vllm:kv_block_idle_before_evict_seconds – 最後一次訪問後的空閒尾部。
  • vllm:kv_block_reuse_gap_seconds – 連續觸碰之間的時間。

引擎核心僅透過 SchedulerStats 傳送原始的驅逐事件;前端會消耗它們,將其轉換為 Prometheus 觀測值,並在日誌記錄開啟時透過 LLM.get_metrics() 公開相同資料。檢視生命週期和空閒時間圖表可以輕鬆發現滯留的 cache 或需要長時間解碼才能固定 Prompt 的工作負載。

指標釋出 - 日誌記錄

LoggingStatLogger 指標釋出器每 5 秒輸出一個 INFO 級別的日誌訊息,包含一些關鍵指標:

  • 當前執行/等待的請求數量。
  • 當前 GPU 快取使用情況。
  • 過去 5 秒內的每秒 Prompt tokens 處理量。
  • 過去 5 秒內的每秒新 token 生成量。
  • 最近 1k kv-cache 塊查詢的 Prefix 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

注意

選擇對使用者在廣泛用例中最有用的直方圖桶並非易事,需要隨著時間的推移進行完善。

Cache 配置資訊

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 中新增,並且有一個 至少有一位已知使用者。如果我們重新審視此設計並棄用舊指標,我們應與下游使用者協調,以便他們在移除之前進行遷移。

字首快取指標

問題 #10582 中關於新增字首快取指標的討論產生了一些有趣的觀點,這些觀點可能與我們處理未來指標的方式有關。

每次查詢字首快取時,我們都會記錄查詢的 token 數量以及快取中存在的查詢 token 數量(即命中數)。

然而,我們感興趣的指標是命中率——即每次查詢的命中數。

在日誌記錄的情況下,我們期望使用者最好透過計算最近 N 次查詢(目前固定為 1k 次最近查詢的間隔)的命中率來獲得最佳服務。

但在 Prometheus 的情況下,我們應該利用 Prometheus 的時間序列特性,允許使用者計算他們選擇的間隔內的命中率。例如,一個計算過去 5 分鐘命中間隔的 PromQL 查詢

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

為了實現這一點,我們應該將查詢和命中記錄為 Prometheus 中的計數器,而不是將命中率記錄為 gauge。

已棄用指標

如何棄用

棄用指標不應輕視。使用者可能沒有注意到某個指標已被棄用,並且當它突然(從他們的角度來看)被移除時,即使有等效的指標供他們使用,也會造成很大的不便。

例如,請參閱 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 面板使用,所以我們應該棄用或移除前者。

字首快取命中率

見上文——我們現在暴露的是“queries”和“hits”計數器,而不是“hit rate”gauge。

KV 快取解除安裝

兩個舊指標與已不再相關的“已交換”搶佔模式有關 v1

  • vllm:num_requests_swapped
  • vllm:cpu_cache_usage_perc

在此模式下,當請求被搶佔時(例如,為完成其他請求騰出 KV 快取空間),我們會將 kv 快取塊交換到 CPU 記憶體。這也被稱為“KV 快取解除安裝”,並透過 --swap-space--preemption-mode 進行配置。

歷史上, vLLM 很早就支援束搜尋。SequenceGroup 封裝了共享相同提示 kv 塊的 N 個序列的想法。這使得請求之間可以共享 KV 快取塊,並使用寫時複製進行分支。CPU 交換的目的是為了這些類似束搜尋的場景。

後來,引入了字首快取的概念,它允許 KV 快取塊被隱式共享。事實證明,這比 CPU 交換更好(開銷為零),因為塊可以按需緩慢地逐出,並且被逐出的提示部分可以重新計算。

SequenceGroup 在 V1 中被移除,儘管需要一個替代品來支援“並行取樣”(n>1)。 束搜尋已移出核心。有很多複雜程式碼是為了一個非常不常見的特性。

在 V1 中,隨著字首快取變得更好(零開銷)並且因此預設啟用,搶佔和重新計算策略應該工作得更好。

未來工作

並行取樣

一些舊指標僅與“並行取樣”相關。這是請求中的 n 引數用於從同一提示請求多個完成。

作為在 拉取請求 #10980 中新增並行取樣支援的一部分,我們也應該新增這些指標。

  • vllm:request_params_n (Histogram)

觀察每個已完成請求的 'n' 引數值。

  • vllm:request_max_num_generation_tokens (Histogram)

觀察每個已完成序列組中所有序列的最大輸出長度。在沒有並行取樣的情況下,這等同於 vllm:request_generation_tokens

推斷式解碼

一些舊指標特定於“推斷式解碼”。這是我們使用更快、近似的方法或模型生成候選 token,然後用更大的模型驗證這些 token。

  • vllm:spec_decode_draft_acceptance_rate (Gauge)
  • vllm:spec_decode_efficiency (Gauge)
  • vllm:spec_decode_num_accepted_tokens (Counter)
  • vllm:spec_decode_num_draft_tokens (Counter)
  • vllm:spec_decode_num_emitted_tokens (Counter)

有一個正在審查的 PR ( 拉取請求 #12193) 來為 v1 新增“提示查詢(ngram)”推斷式解碼。其他技術將隨後跟進。我們應該在此上下文中重新審視這些指標。

注意

我們可能應該將接受率暴露為單獨的已接受和草稿計數器,就像我們處理字首快取命中率一樣。效率可能也需要類似的待遇。

自動縮放和負載均衡

我們指標的一個常見用例是支援 vLLM 例項的自動縮放。

有關 Kubernetes 服務工作組 的相關討論,請參閱

這是一個不平凡的話題。考慮 Rob 的評論

我認為這個指標應該專注於嘗試估計什麼將導致平均請求長度大於每秒查詢次數的最大併發度……因為這才是真正會“飽和”伺服器的。

一個明確的目標是,我們應該公開檢測到這種飽和點所需的指標,以便管理員可以基於這些指標實施自動縮放規則。然而,為了做到這一點,我們需要清楚地瞭解管理員(和自動化監控系統)應如何判斷一個例項接近飽和。

為了識別模型伺服器計算的飽和點(即我們無法透過更高的請求速率獲得更多吞吐量,但開始產生額外延遲的轉折點),以便我們有效地進行自動縮放?

指標命名

我們對指標命名的處理可能值得重新審視

  1. 在指標名稱中使用冒號似乎與 “冒號為使用者定義的記錄規則保留” 相悖。
  2. 我們的大多數指標都遵循以單位結尾的約定,但並非所有指標都如此。
  3. 我們的一些指標名稱以 _total 結尾

    如果指標名稱中存在 _total 字尾,則會將其移除。在暴露計數器的時間序列時,會新增 _total 字尾。這是為了相容 OpenMetrics 和 Prometheus 文字格式,因為 OpenMetrics 要求 _total 字尾。

新增更多指標

關於新指標的創意不乏

在新增新指標的方法上,我們應該謹慎。雖然指標通常相對容易新增

  1. 但移除它們可能很困難——請參閱上面的棄用部分。
  2. 啟用它們可能會產生顯著的效能影響。並且指標通常用途非常有限,除非預設啟用並且可以在生產環境中使用。
  3. 它們對專案的開發和維護有影響。隨著時間的推移新增的每個指標都使這項工作更加耗時,而且也許並非所有指標都值得在維護上進行持續的投資。

跟蹤 - OpenTelemetry

指標提供了系統性能和健康狀況隨時間的聚合檢視。另一方面,跟蹤則跟蹤單個請求在不同服務和元件之間的移動。兩者都屬於更廣泛的“可觀察性”範疇。

vLLM 支援 OpenTelemetry 跟蹤

OpenTelemetry 有一個 Gen AI 工作組

由於指標本身就是一個很大的話題,我們認為跟蹤話題與指標是分開的。

OpenTelemetry 模型前向與執行時間

當前實現公開了以下兩個指標

  • vllm:model_forward_time_milliseconds (Histogram) - 當此請求在批次中時,模型前向傳遞所花費的時間。
  • vllm:model_execute_time_milliseconds (Histogram) - 模型執行函式所花費的時間。這包括模型前向、跨工作節點的塊/同步、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 支援的問題單獨處理,因此我們將這些特定指標歸入該主題。