debug について
ML トレーニングの障害を、証拠収集、制御されたスモークテスト、不確実性の明示を通じて調べるスキルです。原因を断定する前にツール出力で裏付ける必要がある、実行診断向けのエージェントを対象とします。
主な機能
- 01証拠を優先する5段階の手順
- 02プロセス、システム、GPU、ディスク、ログの確認
- 03制御されたスモークテストと単一変数の対照実験
- 04根拠に基づく結論または不確実性の報告
活用シーン
- 01NaN、OOM、停止、低速な学習の診断
- 02損失や GPU 使用率の異常の調査
- 03修正案の前にログとチェックポイントを確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ fcakyon/ phd-skills --skill debugインストール後、Claude Code で/debugを入力して読み込まれたか確認します。
詳細
デバッグ:証拠を先に集めてから調査する
ML のデバッグで最もコストの高いミスは、もっともらしさだけを根拠に原因を断定し、実際の問題を覆い隠す「修正」を試みることです。このスキルでは、probe → hypothesis → smoke → controls → claim の順序を守ります。
エージェントの Stop フックは、アシスタントがツール出力の裏付けなしに原因を主張した場合、reason からここにルーティングします。
実行するタイミング
ユーザーが次のいずれかを直前に述べた場合:
- 「X が失敗する/発散する/NaN になる/OOM になる/ハングする/遅い/クラッシュするのはなぜ?」
- 「損失が増えている」、「メトリクスがおかしい」、「GPU 使用率が 0」
- 「これをデバッグして」、「診断して」、「トラブルシューティングして」、「この実行を調査して」
- 何がおかしいのか尋ねながらログの抜粋を貼り付けた
5 ステップのプロトコル
ステップ 1:手軽なプローブ
仮説を立てる前に、手軽に集められる証拠を収集します。これらに数秒以上かかるものはありません。
プロセスの状態:
ps aux | grep -E '(python|train|torchrun|accelerate)' | grep -v grep
プロセスはまだ実行中ですか?ゾンビ状態ですか?終了済みですか?複数のインスタンスがありませんか?
カーネル/システムイベント:
dmesg | tail -100 # OOM kills, hardware errors, NFS errors
journalctl -xe --since "1 hour ago" | tail -50
GPU の状態:
nvidia-smi
nvidia-smi --query-gpu=utilization.gpu,memory.used,temperature.gpu --format=csv
GPU は実際に使われていますか?「トレーニング」中に GPU がアイドル状態なら、プロセスがデータの読み込みでブロックされているか、すでに終了しています。
ディスク/ファイルシステム:
df -h /path/to/run-dir
du -sh /path/to/run-dir/*
ディスク容量が不足していませんか?チェックポイントが書き込まれていませんか?
ログのスクロールバック: トレーニングログの末尾数百行を読みます。ユーザーの要約を鵜呑みにしないでください。読み飛ばしている可能性があります。次の点を確認します:
- 例外のトレースバック
- 「loss=NaN」や「grad_norm=Inf」の繰り返し
- 早期停止の通知(実行が正常に完了している可能性があります)
- 最後に成功したエポック/ステップ(どこで進行が止まったか)
チェックポイントの状態:
ls -la /path/to/run-dir/checkpoints/
最後にチェックポイントが書き込まれたのはいつですか?サイズから何が推測できますか?空の .pt と、途中で書き込みが止まった 2GB のファイルは異なります。
ステップ 2:仮説(仮説であることを明示)
プローブの後、何が起きている_可能性があるか_を、仮説として明示して述べます:
「仮説:3 分前に dmesg に
oom-killが表示されており、プロセスも消えているため、この実行は OOM になっています。まだ除外できていない別の仮説:(a)NFS 書き込みのタイムアウト、(b)同じグループの別プロセスによる明示的な kill。」
「原因は X です」とすぐに断定してはいけません。仮説として示すことで、まだ分かっていないことを明確にします。
ステップ 3:スモーク実行
仮説を確認または否定する最も手軽な方法は、条件を制御して、失敗時と同じ状況を再現することです:
- OOM 仮説:
batch_size=1で 1 ステップ再実行します。成功するなら OOM が確認でき、同じように失敗するなら OOM ではありません。 - データ仮説:インメモリの合成データセットで再実行します。動作するなら、データの経路に問題がある可能性があります。
- モデル仮説:
eval()モードで単一バッチの forward pass のみを実行します。損失は有限ですか?出力は妥当ですか? - オプティマイザー仮説:
lr=0で再実行します。それでも損失が爆発するなら、オプティマイザーではなく損失自体に問題があります。 - 分散処理の仮説:1 GPU で再実行します。動作するなら、DDP/NCCL に問題がある可能性があります。
30 秒のスモーク実行は、30 分かけて再起動し、祈るよりも効果的です。
ステップ 4:対照実験
スモーク実行で判断できない場合は、対照実験を行います。失敗する設定から変数を 1 つだけ変更し、スモーク実行を再度行います。違いを比べることで、原因となる仕組みを絞り込めます。
よく使う対照軸(一度に 1 つだけ変更):
- 単一ソースのデータと複数ソースのデータ
- デフォルトのワーカー数と調整後のワーカー数
- 混合精度のオンとオフ
- 勾配チェックポイントのオンとオフ
- torch.compile のオンとオフ
ステップ 5:原因の主張
プローブ、スモーク実行、対照実験を経て、証拠が積み上がってから初めて原因を断定します。主張には、それを裏付ける具体的なツール出力を引用します:
「根本原因:NFS 書き込みのタイムアウト。証拠:dmesg に 14:23 に
nfs server X not respondingと表示されており(最後のチェックポイントが書き込まれたのと同じ分)、batch=1のスモーク実行でもタイムアウトが再現します。推奨する修正:チェックポイント用のローカルなスクラッチディレクトリをバインドマウントし、エポックの終わりに NFS に rsync します。」
証拠が積み上がっていない場合は、仮説を原因として断定しないでください。「まだ分かりません」と伝え、次に行うプローブを提案します。
避けること
- 「おそらく X です。Y を試してみます」→ いいえ。まず調査してください。
- 診断のために小さな変更を加えて実行を再開すること。まずスモークテストを行い、その後、意図的に再開してください。
- 根拠としてユーザーの説明だけを引用すること。実際のログを読み直してください。
- 成果物が矛盾を示しているのに、もっともらしい最初の原因で調査を打ち切ること。
出力
簡潔な診断レポート: (1)調査で判明したこと、(2)仮説、(3)スモークテストの結果、(4)原因が特定できたか不確かかの判定、(5)推奨する次のアクション。各主張には、その根拠となるツール出力を引用してください。