うちのラボでは、生成AIエージェントの一団が24時間体制でパイプラインを回しています。Wikipedia由来の記事を読み、要約し、知識基盤に積んでいく——止まらないことが前提の仕組みです。この1週間、その足元で同じGPU障害が2回起きました。1回目の停止時間は16時間。2回目は34分でした。しかも2回目は、人間もAIも、誰も復旧作業をしていません。
間に何を変えたのか。実際のタイムラインと数字で記録します。
一度目:GPUは16時間「無言で」止まっていた
最初の障害は、監視の敗北でした。GPUノードで生成処理がハングしたのですが、監視系は全員「正常」と言い続けたのです。
- nvidia-smi:正常。GPUは見えているし、温度も電力も平常値
- モデルサーバのヘルスチェック(モデル一覧API):正常応答
- プロセス監視:プロセスは生きている
実際には、推論ランナーがハングしてCUDAが応答しなくなっていました。状態を尋ねる系の監視は、この種の故障では全部嘘をつきます。管理APIは生きているからです。結局16時間、パイプラインは1件も処理していませんでした。機会損失はおよそ2,500記事分です。
この障害で唯一嘘をつかなかった値がひとつだけありました。処理済みカウントの増分です。処理が止まれば、ゼロ増は隠しようがない。ここから、うちのラボの監視原則がひとつ生まれました。
「状態ではなく、進捗を監視せよ」
復旧そのものは再起動で済みました。そこで再発に備えて、「生成処理はハングしているのに状態APIは正常応答する」という故障シグネチャを条件に、検知から自動再起動までを行う仕組みを監視に組み込みました。
二度目:34分後、気づいた時には直っていた
その仕組みができた2日後、同じシグネチャの故障がもう一度来ました。実測のタイムラインがこちらです。
- 17:30 — GPUノードで再発(生成ハング × 状態API正常。前回と同一シグネチャ)
- 18:00 — 進捗監視が「30分間ゼロ増」を検知、通知を発報
- 18:01 — シグネチャ照合が一致、対象ノードの自動再起動が発動
- 18:04 — パイプライン側がドライバを自動で再投入
- 18:09 — 両GPUノードで処理再開を確認(エラー0件、毎時225記事ペースに復帰)
発生から処理再開まで34分。この間、人間もAIエージェントも一切介在していません。所長が通知に気づいて状況を確認した時には、復旧はすでに終わっていました。
巻き添えでエラー計上された10,372件の処理も、チェックポイントに未記録のままだったため全件が自動で再キューされ、データ損失はゼロでした。
ひとつ正直に書いておくと、「34分で直した」という言い方は少し盛っています。34分の内訳は、30分が検知閾値(ゼロ増30分で停止と判定する設計値)の待ち時間で、自動化そのものの応答は検知後1〜4分です。正確には「30分で気づき、4分で直る仕組みが勝手に動いた」です。検知を速くしたければ閾値を詰めればよいのですが、短くしすぎると一時的な処理の谷を「停止」と誤判定して再起動を誤爆させます。閾値は「何分の停止まで許容するか」を先に決めて、そこから逆算する値だと考えています。
同じ日にもうひとつ:メモリ98.3%とOOMの30分
実は二度目のGPU障害とほぼ同時刻に、別のノードでも障害が起きていました。エージェント群が住んでいるコンテナのメモリが張り付いたのです。ホスト側の資源ログ(sar)とカーネルログで追った経過です。
- 17:30→17:40 — メモリ使用率 21% → 98.3%。ファイルキャッシュは 9.4GB → 26MB まで圧殺
- この間、CPUも100%近くに見えたが、実体は %system + %iowait(メモリ回収のスラッシング)で、計算負荷ではない
- 17:44 — コンテナのメモリ上限(16GB)で OOM kill が発動
- 17:50 — 使用率19%へ回復
犯人はカーネルログで特定できました。エージェントの1プロセスが、起動から十数分で13.28GBまで膨らんでいました。
ここで問題だったのはプロセス単体ではなく構造です。当時、エージェント全員が管理用の常駐サービスと同じcgroup(Linuxの資源管理の世帯)に同居していました。つまり1匹の暴走が、サービスユニットごと巻き込んで倒す配置だったのです。冗長構成のつもりが共倒れする、監視系と被監視系が同じ世帯にいる——家庭ラボでやりがちな相部屋問題でした。
対策は世帯分離です。エージェント群を専用のcgroup(MemoryHigh 22GB / MemoryMax 24GB)へ移し、暴走してもその世帯の中でOOMが完結して管理系を巻き込まないようにしました。コンテナ自体のメモリも16GBから32GBへ増やしています。次に誰かが13GB食べても、爆風はエージェント世帯の中で収まります。
まとめ:障害対応の成果物は「直したこと」ではない
1回目と2回目の差は、担当者の頑張りではありません。16時間の障害から「状態ではなく進捗を監視する」「故障シグネチャを条件に自動復旧する」という仕組みを残したことが、2回目の34分を作りました。
障害対応の成果物は「直したこと」ではなく、「次から直さなくていい仕組み」だと考えています。同じ障害が三度目に来ても、うちのラボでは誰も何もしない予定です。
確かめきれていないこと(caveat)
- 数字はすべてこのラボの実測(資源ログ・カーネルログ・パイプラインの進捗ファイル)で、環境が違えば再現しません。
- 13GBまで膨らんだプロセスを「何が」起動したかは、ログ不足で特定しきれていません。スポナー側のログ整備が宿題です。
- 自動再起動は誤爆すると被害が出ます。シグネチャを狭く絞る・再起動対象を故障ノードに限定する・再起動後の再開確認まで自動化する、の3点をそろえてから有効化することをおすすめします。
この検証を回している環境
この検証は、自宅の常設ラボ(使い捨てVM/LXCを回す母艦+GPU+VLAN分離ネットワーク)で動かしています。使っている機材と選定理由、全体構成は1本にまとめています。
ラボ構成のまとめを見る →