nvidia-smiが正常でもGPUハングを検知する進捗監視

NAS・ストレージを描いたアイキャッチ画像

ローカルLLMを自宅や小規模ラボで回していると、監視の最初の関心は「落ちていないか」になりがちです。プロセスが生きているか。ポートが開いているか。GPUが見えているか。そこまでは自然です。

ただし、AI処理の無人運用では、それだけでは足りません。

某所ラボのGPUノードでは、RTX 4090クラスのGPUを使ったローカルLLM実行系が、16時間にわたって何も処理していない状態になりました。にもかかわらず、状態系の監視はほぼすべて正常に見えていました。nvidia-smi相当の確認でも、GPU管理APIであるNVMLは生きており、APIの疎通チェックも通りました。

嘘をつかなかったのは、処理カウントだけです。16時間、成果物が1件も増えていませんでした。

これは「死活監視が不要」という話ではありません。むしろ逆です。以前のUptime Kumaの死活監視はDownと通知失敗を作って見るでは、サービスがDownしたときに気づけるかを確認しました。今回の話は、その次の段階です。死んでいないのに働いていないものを、どう検知するかです。

目次

nvidia-smiが正常でも処理が止まった

観測された症状は単純でした。

  • ローカルLLM実行系のランナーがハングした
  • CUDA側が壊れた状態になった
  • GPU管理APIは正常応答を返し続けた
  • APIのモデル一覧などの疎通チェックも通った
  • 生成リクエストだけが永遠に返らなかった
  • 16時間、成果物が1件も増えなかった

状態監視だけを見ると、かなり厄介です。プロセスは落ちていない。GPUも見えている。APIも返る。典型的な「監視上は正常」です。

しかし、利用者から見ると何も動いていません。キューに仕事を投げても生成が返らず、成果物も増えない。実運用上は停止です。

損害は、16時間の停止と、およそ2,500処理分の機会損失でした。自宅運用でも、これは小さくありません。特に夜間や外出中に処理を積ませる構成では、朝になって「何も進んでいない」と分かるのが一番悪い発見の仕方です。

状態監視・疎通監視・進捗監視の違い

今回の教訓は、監視対象を3層に分けると見えやすくなります。

監視の種類 見ているもの 今回どう見えたか 検知できる異常
状態監視 プロセス、GPU、ポートなど 正常に見えた 明確な停止、プロセス終了、GPU未認識
疎通監視 API応答、モデル一覧など 正常に見えた API停止、ネットワーク断、応答不能
進捗監視 成果物数、処理完了数、キュー消化 16時間ゼロ増 ハング、処理停滞、働いていない正常状態

状態監視は「存在しているか」を見ます。疎通監視は「返事があるか」を見ます。進捗監視は「仕事が進んでいるか」を見ます。

AI処理の無人運用で本当に痛いのは、三つ目が止まることです。

nvidia-smiが正常でも安心できない理由

nvidia-smi相当の確認が正常だからといって、生成処理が正常に進むとは限りません。今回のケースでは、GPU管理APIは生きていました。つまり、GPUが見えることと、CUDAを使った実処理が完走することは別です。

これはGPU監視でよくある落とし穴です。

  • GPUが認識されている
  • メモリ使用量が見える
  • プロセスが残っている
  • APIがモデル一覧を返す

これらは重要な情報ですが、生成が返ることを保証しません。実際には、生成だけが永遠に返らない状態が成立しました。

今回、確実に異常を示していたのは、単位時間あたりの処理完了数でした。16時間、処理カウントが増えていない。これだけが運用上の真実でした。

復旧と再発対策

図解: 復旧と再発対策(GPUが怪しい / 正常な長時間処理 / 生成がハングしている / API疎通は正常 / 処理カウントが一定時間増えない / 自動reboot)
図解: 復旧と再発対策(AI生成)

復旧は最終的にrebootでした。ランナーやAPIの表面的な応答が残っていても、壊れている層がCUDA側に寄っている場合、部分的な再起動だけでは戻らないことがあります。今回の公開可能な素材から断定できる復旧手段は、rebootです。

再発対策としては、次のシグネチャを検知するようにしました。

  • 生成がハングしている
  • しかしAPI疎通は正常
  • 処理カウントが一定時間増えない

この条件に一致した場合、自動rebootまで進めます。以後、この系統の異常は最大35分で検知できるようになりました。

ここで重要なのは、「GPUが怪しいから即reboot」ではないことです。状態だけで判断すると、正常な長時間処理や一時的な待ち時間まで巻き込む可能性があります。見るべきなのは、生成ハングと疎通正常の組み合わせ、そして処理カウントの停滞です。

監視範囲ごとの検知能力と死角

小規模なローカルLLM運用で、監視をどこまで作るかは迷うところです。少なくとも、次の比較はしておいた方がよいです。

方針 検知できる範囲 残る死角 採用条件
状態監視だけ 作りやすい。Downには気づきやすい 生きているが働いていない状態を見逃す 手動確認が多く、停止時の損失が小さい人
状態監視+疎通監視 API停止やネットワーク断に強い 生成ハングは残る サービス公開や家庭内API利用をしている人
状態監視+疎通監視+進捗監視 実際の処理停止に近い異常を拾える 成果物や処理完了数を記録する設計が必要 夜間・外出中・無人でAI処理を回す人
手動確認中心 実装コストが低い 気づくまで止まり続ける 実験用途で、失敗しても困りにくい人

向かない人もいます。進捗監視は、何を成果物として数えるかを決める必要があります。処理完了数、保存ファイル数、ジョブ完了フラグ、キュー消化数など、運用ごとに基準が違います。そこを設計したくない場合は、まず死活監視と通知の確実性を固める方が現実的です。

一方で、無人でGPUを使うなら、進捗監視を避け続けるのはおすすめしません。GPUは高価な計算資源です。動いているように見えるだけで16時間空転する構成は、静かに損失を積みます。

進捗監視を追加する確認項目

最後に、手元の環境で確認する観点を置いておきます。

  • プロセスが落ちたときに通知されるか
  • GPUが見えなくなったときに通知されるか
  • APIが応答しないときに通知されるか
  • APIは応答するが生成だけ返らない状態を検知できるか
  • 一定時間、成果物や処理完了数が増えない状態を検知できるか
  • 検知後に、人手で復旧するのか、自動rebootまで進めるのかを決めているか

最初の三つは状態と疎通です。後半三つが進捗です。

死活監視は、サービスが明確にDownしたときの土台です。そこをまだ試していない場合は、先にDownと通知失敗を実際に作っておく方がよいです。その上で、GPUやローカルLLMのように「生きているが働いていない」系の処理には、進捗監視を足します。

GPU処理は成果物の増分で監視する

今回のGPUハングでは、状態系の監視は正常を返し続けました。APIの疎通も正常でした。nvidia-smi相当の確認でも、異常は見えませんでした。

しかし、成果物は1件も増えていませんでした。

AI処理の無人運用で見るべき最終指標は、プロセスの生存ではありません。ポートの開閉でもありません。単位時間に成果物が増えたか、処理が完了したか、キューが進んだかです。

状態ではなく進捗を監視する。

少し冷たい言い方をすると、動いているように見える機械を信用しすぎない方がよいです。所長も、その点では一度きれいに裏切られました。ただし、裏切られた後に見る指標を変えれば、次は最大35分で気づけます。無人運用では、この差がそのまま睡眠時間と処理結果を守ります。

nvidia-smiと成果物カウンタを同じ時刻に記録する

検証環境はRTX 4090クラスのGPUとローカルLLM実行系です。状態確認だけでなく、処理件数を時間差で2回読み、増分を検査します。

nvidia-smi --query-gpu=timestamp,name,utilization.gpu,memory.used \
  --format=csv,noheader
before=$(cat "$COMPLETED_COUNT_FILE")
sleep "$PROGRESS_WINDOW_SECONDS"
after=$(cat "$COMPLETED_COUNT_FILE")
printf 'completed_before=%s completed_after=%s\n' "$before" "$after"
test "$after" -gt "$before"
今回の障害: NVML正常 / API疎通正常 / 16時間で成果物0件増
機会損失: 約2,500処理分
対策後: 同じ型を最大35分で検知

GPU利用率が低いだけでは待機と故障を分けられません。逆に利用率が出ていても成果物が増えないことがあります。キューが空なら進捗停止を異常にしない、といった業務条件と組み合わせて判定します。

この検証を回している環境

この検証は、自宅の常設ラボ(使い捨てVM/LXCを回す母艦+GPU+VLAN分離ネットワーク)で動かしています。使っている機材と選定理由、全体構成は1本にまとめています。

ラボ構成のまとめを見る →
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次