結果:マージ(2026-10-17 03:08、 llm-d/llm-d#2835). )は、実際にはGitHubのPR・レビュー・チェックの履歴、 llm-dのソース(PRのベースコミット
696b5e81)、vLLMのソース(リリースタグ)、llm-dオートスケーラーのソース(タグv0.9.0)、そして私たちが残した実測 生データから取得しました。時刻は韓国時間です。2026-10-17現在、この変更が含まれたllm-dのリリースはまだありません(最新はv0.10.0、2026-09-29)。
目次
- 一言まとめ
- 1. 何が問題だったのか:私たちが確認した現象
- 2. 原因:ソースのどの行か
- 3. 何を変更したのか:diffの要点
- 4. 反応:ボットもインラインコメントもなく2時間9分
- 5. 学んだこと:オープンソースコントリビューションのコツ
- リンク
一言まとめ
| PR | llm-d/llm-d#2835 docs: replace vLLM metric names that current vLLM no longer exports |
| 変更内容 | 2つのドキュメントと1つのダッシュボードJSONでのメトリック名のみ。6行追加、6行削除 |
| 反応 | レビューボット・インラインコメントなし。2つの承認(無言での承認が1回、 /lgtm が1回)、サイトプレビューボットのコメントが1つ |
| 結果 | PR公開 10-17 00:59 → マージ 03:08、約2時間9分。1つのコミットをスクワッシュしてマージ(私たちのアカウントが著者) |
1. 何が問題だったのか:私たちが確認した現象
まず率直に書きます。TT Labのクラスターにはllm-dはありません。今回の問題は運用の障害ではなく、学習の過程で遭遇しました。vLLMエンジンを 取り巻くプロジェクト(production-stack、LMCache、llm-d)のコードを読みながら、「エンジンが定義したメトリック名が他のリポジトリのクエリにどう 伝播していくか」を追いかけ、その内容は 「オープンソースの構造を読む」第4回にまとめました。
名前をドキュメントの文章だけで突合させないよう、PRを上げる直前にvLLM v0.31.0(vllm/vllm-openai イメージ、当時最新のリリース)を小規模クラスターのGPUノード1台(8GB級GPU)で使い捨てのPodとして起動し、 /metrics を取得しました。何も新しくダウンロードしないよう設定ファイルだけを作成した
ランダム重みモデル(Qwen2構造、2層、hidden 256、 --load-format dummy)をデプロイし、前半160トークンが同じリクエスト5個(各16トークン生成)を送信しました。その出力にllm-dのドキュメントが参照する名前はありませんでした。
| llm-dのドキュメントが参照する名前 | 場所 | v0.31.0 /metrics |
|---|---|---|
vllm:gpu_prefix_cache_hit_rate |
turn-profile-fairnessガイドの観測指標テーブル | なし |
vllm:time_per_output_token_seconds |
オートスケーラー(WVA)設計ドキュメント、指標リスト1行とクエリテーブル1行 | なし |
vllm:time_per_output_token_seconds_bucket |
DigitalOceanダッシュボードの「Time Per Output Token Latency」パネルの3つのクエリ | なし |
生データで2つの旧名で始まる行は0行であり、代わりに出力された値は次の通りです。
vllm:prefix_cache_queries_total{engine="0",model_name="tiny"} 805.0
vllm:prefix_cache_hits_total{engine="0",model_name="tiny"} 640.0
vllm:inter_token_latency_seconds_count{engine="0",model_name="tiny"} 75.0
数値はリクエストの形状と一致しています。リクエスト5個×161トークン=805回参照され、最初のリクエストはすべてミスし残りの4つが160トークンずつヒットして640となります
(ブロックサイズ16、同じ出力の cache_config_info)。16トークンずつ生成した5個のリクエストのトークン間隔は15×5=75です。ヒット率は640/805≈0.795となります。
存在しない名前で記述されたPromQLはエラーを出さずに空の結果を返します(Prometheusの一般的な動作)。ガイドに従ってクエリを実行した読者は 「何も表示されない」ことだけを確認し、その理由は自分で探さなければなりません。ダッシュボードパネルも空のように見えるはずですが、Grafanaにデプロイして確認はしていません(未実測)。
同じ方法でllm-d v0.10.0タグのドキュメント・ガイド全体をスキャンした結果も第4回にあります。 vllm: 71個の名前のうち40個は出力に存在し、
27個はオフロード・NIXLコネクターを有効にしなければ現れない条件付き指標であり、4個はv0.31.0のソースに定義がありませんでした。そのうち4個のうち3個が
time_per_output_token_seconds 系です。PRはmainブランチを基準としているため、v0.10.0にはまだ存在しないfairnessガイドが追加されています。
2. 原因:ソースのどの行か
llm-dの行番号はPRのベースコミット 696b5e81 を基準とし、
vLLMはリリースタグを基準としています。
エンジン側:名前は予告通り消えた
vLLMには指標を削除する際のルールがあります。 docs/usage/metrics.md の78–82行目
によると、X.Yで非推奨化を予告し、X.Y+1で非表示にし(--show-hidden-metrics-for-version=X.Y で復活可能)、X.Y+2で削除します。
vllm:gpu_prefix_cache_hit_rateはV0エンジンのゲージです。v0.9.0のvllm/engine/metrics.pyの119–128行目 には、「0.8で非推奨化、 V1ではルックアップ・ヒットカウンターに置き換え」、ビ「0.9で非表示、0.10で削除予定」というコメントと共に非表示の状態で存在し、v0.10.0の同ファイルには定義がありません。V1エンジンはヒット率の代わりに2つのカウンターvllm:prefix_cache_queries·vllm:prefix_cache_hitsを出力します。設計ドキュメント(docs/design/metrics.mdの437–447行目)はその理由を「ゲージで比率を固定せず、ユーザーがrate(…[5m])のように望む期間で比率を算出できるようにしよう」と説明しています。 注目すべき点は、fairnessガイドの冒頭の基準環境が vLLM 0.26 であるということです。ガイドが検証されたバージョンでもこのゲージはすでに存在しませんでした。vllm:time_per_output_token_secondsはV1エンジンのヒストグラムです。v0.11.0のvllm/v1/metrics/loggers.pyの387–388行目 のコメントが 「0.11で非推奨化、vllm:inter_token_latency_secondsに改名」と記載しており、v0.12.0(の689–692行目) では非表示に変更され「0.13.0で削除」というTODOが付与されます。実際にはv0.14.0(の718–721行目) まで非表示のまま残り、v0.15.0(2026-01-29リリース)の同ファイルには定義がありません。現在の名前はvllm:inter_token_latency_secondsです。
エンジンはルール通りに、時にはルールよりも余裕を持って名前を整理しました。問題は その名前を読み取る側が別のリポジトリにあるということです。
もう一つ、ソース内のカウンター名には _total はありませんが、 prometheus_client が出力時に付与するため、クエリには vllm:prefix_cache_hits_total
のように記述する必要があります。ソースをgrepして名前を移行する際によく間違えやすい箇所です。
消費者側:コードは追従したがドキュメントだけが残った
- オートスケーラーの設計ドキュメント
docs/architecture/autoscaling/wva.mdは144行目の指標リストと の210行目 のavg_itlクエリに旧名を記載していました。しかしこのドキュメントが説明するコレクターコード(リポジトリ名は現在llm-d-autoscaling)のv0.9.0のinternal/collector/registration/queueing_model.goの70行目 はすでにvllm:inter_token_latency_seconds_sum·_countを要求しています。 ドキュメントがコードと異なっていたのです。 - DigitalOceanダッシュボードJSONの「Time Per Output Token Latency」パネルは、p95・p90・p50のクエリ
(の1544行目,
の1559行目,
の1575行目)
がいずれも
vllm:time_per_output_token_seconds_bucketをhistogram_quantileに代入していました。 - fairnessガイドの観測テーブルの の663行目
は「戦略が最適化するメカニズム」として
vllm:gpu_prefix_cache_hit_rateを確認するように求めていました。
3. 何を変更したのか:diffの要点
名前だけを変更しました。文章、パネルのタイトル、クエリのその他の形状はそのまま維持しました。
# docs/architecture/autoscaling/wva.md
-- `vllm:time_per_output_token_seconds` -- ITL histogram (sum/count for average)
+- `vllm:inter_token_latency_seconds` -- ITL histogram (sum/count for average)
-| `avg_itl` | `rate(vllm:time_per_output_token_seconds_sum[1m]) / rate(..._count[1m])` | ...
+| `avg_itl` | `rate(vllm:inter_token_latency_seconds_sum[1m]) / rate(..._count[1m])` | ...
# docs/infrastructure/providers/digitalocean/monitoring/inference-gateway-dashboard.json (3곳)
-"expr": "histogram_quantile(0.95, sum by(le) (rate(vllm:time_per_output_token_seconds_bucket[$__rate_interval])))",
+"expr": "histogram_quantile(0.95, sum by(le) (rate(vllm:inter_token_latency_seconds_bucket[$__rate_interval])))",
# guides/turn-priority-fairness/README.md
-| `vllm:gpu_prefix_cache_hit_rate` | The mechanism the strategy is optimizing. |
+| `rate(vllm:prefix_cache_hits_total[5m]) / rate(vllm:prefix_cache_queries_total[5m])` | Prefix-cache hit ratio: the mechanism the strategy is optimizing. |
ヒット率の部分には、1つのゲージ名の代わりに2つのカウンターの比率式を挿入しました。置き換えるべき同名のゲージが存在しないためであり、vLLMの設計ドキュメントが推奨する形式でもあるためです。期間 [5m] は設計ドキュメントの例と同じにしました。
PRの本文にはファイル・旧名・新名・理由を1つのテーブルにまとめ、第1節の grep の出力3行と「旧名0行」をそのまま添付しました。「ダッシュボードJSONは依然としてパース可能であること、Grafanaにデプロイしてはいないこと、変更されたのは histogram_quantile の3つの式内の名前だけでありパネルのタイトルはそのまま残っていること」を明記したことも書き留めました。llm-dのCONTRIBUTINGには、AIの支援を受けたコントリビューションを他のコントリビューションと同等の基準で受け入れるが、投稿者が履歴上の著者として内容を直接説明できなければならないと記載されています。そのため、本文の最後にAIの支援を受けて作成し自身でレビューした旨の文言を追加しました。コミットは1つであり、リポジトリのルールであるDCO署名(Signed-off-by)とSSH署名を付与しました。チェック項目には署名されたコミットであるかを確認する項目も含まれています。
4. 反応:ボットもインラインコメントもなく2時間9分
| 時刻(10-17) | イベント |
|---|---|
| 00:45 | コミット(DCO署名・SSH署名)作成 |
| 00:59 | PR公開 |
| 00:59 ~ | 21個のチェック:成功12、スキップ9、失敗0 |
| 01:53 | ルートOWNERSの承認者1名が無言で承認 |
| 01:56 | サイトプレビューボットが「このコミットでサイトをビルドしました。ダウンロードして確認してください」とコメント |
| 03:08 | 別のメンテナーが /lgtm と共に承認、11秒後にスクワッシュマージ |
成功したチェックにはDCO、署名済みコミットの確認、pre-commit、ガイドチェック(CI Guides Check)、ガイドdry-run、サイトプレビュービルドが含まれます。スキップされた9個はイメージビルドなどのタスクであり、ドキュメントのみが変更されたPRであるためにスキップされたものとみられます。
第1回のSeaweedFSのようにレビューボットが付くことはなく、第2回のGrafanaチャートのように「Thanks!」の一言もありませんでした。インラインコメントも質問もなく2つの承認で終了しました。私たちが個別に対応すべき事項はありませんでした。マージコミット 2b0b8de7
の著者は私たちのアカウントであり、メッセージは私たちのコミットメッセージタイトルの末尾にPR番号が付いたものです。
これと同じ形状のPRがもう1つあります。production-stackのデフォルトダッシュボードも削除された vllm:gpu_prefix_cache_* の名前を参照していたため、
vllm-project/production-stack#1147 を送信し、2026-10-17現在進行中です。
5. 学んだこと:オープンソースコントリビューションのコツ
- 1つの名前は複数のリポジトリに伝播します。 エンジンは非推奨化の予告・非表示・削除をルール通りに行いましたが、そのルールはエンジンリポジトリ内でのみ守られます。
ガイド・設計ドキュメント・ダッシュボードJSONは別のリポジトリに存在しており、名前が間違っていてもエラーにならず空になるだけです。エンジンの
/metricsの1回と 消費者側のvllm:の名前リストの1回を確認すれば、このような箇所を見つけることができます。 - 代替名は推測せず、コードから見つけます。 WVAドキュメントの代替名は、そのドキュメントが説明するコレクターコードですでに使用されていました。 「ドキュメントがコードと異なっている」ことをコードの行で示せば、メンテナーが個別に確認すべきことはほとんどありません。
- 似たような名前に注意します。 v0.31.0には
vllm:request_time_per_output_token_secondsという別のヒストグラムがあります。同じ元データからtime_per_output_token_secondsの行頭を固定せずに grep すると 27 行ヒットし、^vllm:time_per_output_token_secondsで固定すると 0 行です。 さらにソースコードの説明は一方が「トークン間の遅延」、もう一方が「1 リクエストあたりの出力トークンにかかる時間」となっており、意味も異なります。「名前が似ているから これに置き換えよう」というのは間違った PR になりやすい箇所です。 - 測定できたものとできなかったものを同じ重みで記載します。 Grafana にアップロードしていないという一文が PR を弱くすることはありません。メンテナーは 何が確認されていて何が確認されていないかを見て判断します。
- ドキュメントの PR にも検証のパスがあります。 llm-d はドキュメントの変更だけでもサイトをビルドしてプレビューを提供し、ガイドのチェックと dry-run を実行します。 小さな PR であればあるほど、こうしたチェックがすべてグリーンであれば、レビュアーが見るべきなのは数行の diff だけです。
Tidbit の一言。 友人が名前を変えたのですが、アドレス帳には古い名前が残っていました。呼びかけても返事がないので、みんな「連絡がつかないな」で 済ませていました。直接声をかけてみて(0行!)、新しい名前を確認し(75!)、アドレス帳の3ヶ所を修正したところ、2時間で「いいね」のスタンプがつきました。 名前が似ている別の友人に間違えて電話をかけるのだけは気をつけようと思いました。
リンク
すべての資料は 2026-10-17 に閲覧しました。
- PR: llm-d/llm-d#2835 (マージコミット
2b0b8de7) - llm-d ソース(ベースコミット):
docs/architecture/autoscaling/wva.md,inference-gateway-dashboard.json,guides/turn-priority-fairness/README.md,CONTRIBUTING.md - オートスケーラーコレクター:
queueing_model.go(v0.9.0) - vLLM メトリクス廃止ルール:
docs/usage/metrics.md(v0.31.0)、 カウンターを選んだ理由:docs/design/metrics.md(v0.31.0) - vLLM メトリクス定義:
vllm/v1/metrics/loggers.py(v0.31.0)、 古い V0 ゲージvllm/engine/metrics.py(v0.9.0) - 同様の形の PR(進行中): vllm-project/production-stack#1147