GPU 4枚の実測で遊んでいるカードを判定する
目標
GPU4枚の実測3時間分で、「このカードはアイドルか」を判定し、その判定の根拠を、レポートとして残します。最後に、vLLM形式のサービングメトリクスから、最初のトークンまでの遅延を求めます。
なぜ重要なのか
GPUは高価で、なかなか増やせないので、容量の判定を間違えると、すぐにお金と時間が漏れ出ます。ところが、使用率だけを見ると、必ず間違えます。使用率0のカードがメモリ13.7 GiBを確保していれば、そのカードはアイドルであると同時に、埋まってもいます。しかも、どのPodが使っているのかを教えてくれる帰属ラベルは、ノードの構成によっては、まるごと空になることがあり、「誰が使っているのかわからないGPU」が、実際に生まれます。このラボは、その2つをメトリクスで判定する練習です。
データについて
- GPU・コンテナ・ノードのメトリクスは、このサイトを動かしている7ノードのクラスターの実測です。
vllm:で始まる時系列だけは、実測ではありません。このクラスターのvLLMのデプロイは、現在停止していて、メトリクスがありません。形式だけを似せた合成サンプルで、すべての時系列にsource="synthetic"ラベルが付いています。- ウィンドウは固定された3時間です。
lab-realdataで確認し、promq-atでクエリしてください。 - 公開形式の原文は
/opt/lab/realdata/expo/に、出典の説明は同じディレクトリのREADME.mdにあります。
ステップ
- DCGMが報告するGPUの個数を数えるクエリを、
/root/pca-gpu/01-inventory.promqlに書きます。 - ウィンドウのあいだずっと使用率が0で、フレームバッファーを最も多く確保しているGPUのノード名を、
/root/pca-gpu/02-idle.txtに1行で書きます。 - そのGPUの
DCGM_FI_DEV_FB_USEDを出すクエリを、/root/pca-gpu/03-fbused.promqlに書きます。 exported_podラベルが空のGPUのノード名を、/root/pca-gpu/04-attribution.txtに1行で書きます。nuc1のGPUの累積エネルギーのカウンターから、平均電力(W)を出すクエリを、/root/pca-gpu/05-energy.promqlに書きます。- ウィンドウ全体で見て、使用率が一度も0を超えなかったGPUの個数を数えるクエリを、
/root/pca-gpu/06-idle-window.promqlに書きます。 - サービングのサンプルの、最初のトークンまでの遅延のp95を求めるクエリを、
/root/pca-gpu/07-ttft.promqlに書きます。 - 2つの判定と根拠、そして何が実測で何がサンプルなのかを、
/root/pca-gpu/08-report.mdに300文字以上で書きます。
参考
promq-at 'DCGM_FI_DEV_GPU_UTIL'のように投げると、ラベルがそのまま見えます。ノード名はnodeラベルにあります。- よくあるミス1:
max_over_timeを使わずに、瞬間値で判定してしまうことです。忙しいカードにも、たまたま0の瞬間があります。 - よくあるミス2:
FB_USEDをバイトに換算してしまうことです。このメトリクスの単位はMiBです。
DCGMが報告するGPUを数える
DCGMは、GPU1枚ごとに時系列を1つ出力します。count()で数えればよいです。クエリはpromq-atで投げてください。今の時刻で投げると、ウィンドウの外なので、空の結果が返ります。
メモリは確保しているのに、ウィンドウのあいだずっとアイドルのGPUを探す
瞬間値1つで判定すると、忙しいカードも、たまたま0の瞬間に引っかかります。max_over_time(...[3h])で、ウィンドウ全体の最大値が0のGPUを選び、その中でFB_USEDが最も大きいものを、topkで探してください。答えはnodeラベルの値です。
そのGPUが確保しているフレームバッファーを測る
DCGM_FI_DEV_FB_USEDの単位はMiBです。前のステップで見つけたノードに絞ってください。バイトに換算すると、基準値とずれます。メトリクスが返す単位のまま答えてください。
誰が使っているのかわからないGPUを探す
dcgm-exporterは、exported_namespace・exported_pod・exported_containerラベルで、どのPodがそのGPUを使っているかを教えてくれます。ところが、ノードの構成によっては、このラベルが空のことがあります。空のラベルは、{exported_pod=""}で選びます。
累積エネルギーのカウンターから平均電力を導き出す
DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTIONは累積エネルギーで、単位はmJです。rateで微分するとmWになり、1000で割るとWになります。ノードはnuc1です。同じ時刻のPOWER_USAGEゲージと比べて、値がほぼ同じであれば正常です。
ウィンドウ全体でアイドルのGPUの個数を数える
瞬間値で数えると、忙しいGPUも、たまたま0の瞬間に引っかかります。max_over_timeでウィンドウ全体の最大値を求めてから、== 0で絞って、数えてください。
サービングメトリクスから、最初のトークンまでの遅延のp95を求める
vllm:で始まる時系列は、実測ではなく、形式を似せた合成サンプルです(source="synthetic"ラベルが付いています)。ヒストグラムなので、バケットにrateをかけて、leで集計してから、histogram_quantileをかけます。leを捨てて集計すると、値が無意味になります。
判定と根拠を、何が実測かとあわせて書く
レポートには、2つの判定(メモリだけ確保してアイドルのGPUのノード、帰属がわからないGPUのノード)と、その根拠として使ったメトリクスの名前を入れる必要があります。そして、vllm:の時系列が、実測ではなく合成サンプルであるという事実も、あわせて書いてください。300文字以上です。