mcpField
S
spark-memory-thermal-ops

spark-memory-thermal-ops

github.com/wshobsonクラウド・DevOps41.9k2.7k 回インストール2 週間前に更新
リポジトリ

spark-memory-thermal-ops について

DGX Spark GB10で学習するユーザー向けのスキルです。統合メモリの見積もり、OOMの切り分け、長時間実行時の熱監視に加え、学習と推論の同時実行による競合も扱います。

主な機能

  1. 01free -g によるメモリ余裕の算出
  2. 02段階的な UMA OOM 対処
  3. 03温度と電力の記録
  4. 04学習と推論の同時実行評価

活用シーン

  1. 01学習開始前のメモリ適合性の見積もり
  2. 02OOM発生後の段階的な対処
  3. 03長時間実行の低速化時に熱スロットリングを確認
  4. 04上限のない推論サーバーを停止するか判断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wshobson/agents --skill spark-memory-thermal-ops

インストール後、Claude Code で/spark-memory-thermal-opsを入力して読み込まれたか確認します。

同梱ファイルassets/thermal-sample.shreferences/uma-accounting.md

詳細

Spark メモリとサーマル運用

DGX Spark の GB10 チップには、CPU と GPU で共有される単一の 128GB 統合メモリ(UMA)プールがあり、持続可能な電力上限は定格値を大きく下回ります。どちらもディスクリート GPU の前提を覆します。ヘッドルームは nvidia-smi が報告する値ではなく、何も設定を誤っていなくても高速に始まった実行がジョブの途中で遅くなります。このスキルでは、メモリヘッドルームの計画、実際の OOM への対処、長時間ジョブにおけるサーマルの監視について扱います。起動時の障害モード(ABI の不一致、flash-attn、プレイブックの破損)については spark-training-gotchas を参照してください。このスキルはジョブが起動することを前提としています。

よくある問題クイックリファレンス

状況対処
起動前にヘッドルームを計画するnvidia-smi ではなく free -g を基準に予算を立てる — UMA メモリモデルを参照
統合メモリでジョブが OOM になるOOM ラダーを順番に進める: フラッシュ、次にバッチ/パック、次に手法のダウングレード
実行途中でスループットが低下する設定バグと決めつける前に電力/温度ログを確認する — サーマル監視を参照
トレーナーと推論サーバーの両方が必要一度に 1 つだけ実行する — 同時ワークロードを参照

このスキルを使う場面

  • 起動前に 128GB プールに対してトレーニング実行を見積もる — このモデル、手法、バッチ/パックの組み合わせが収まるかどうか。
  • 実行がロード中またはステップ中に OOM になり、対処の順序が重要 — 何を最初に、次に、その次に試すべきか。
  • 数時間に及ぶジョブの間、温度と電力を監視し、速度低下がサーマルスロットリングなのか別の何かなのかを判断する。
  • 同じマシン上でトレーナーと推論サーバー(vLLM、Ollama)を並行して実行する予定がある。

UMA メモリモデル

Spark には独立した GPU VRAM はありません — GPU と CPU が単一の 128GB プールを共有します。2 つの帰結があります:

  • nvidia-smi と cudaMemGetInfo はプレッシャーを過小報告する — あるいはまったく報告しない。 どちらも CUDA アロケーターから見えるメモリを報告しており、プールの実際の状態ではありません — アロケーターからは見えないページキャッシュと mmap されたページが同じプールを消費するため、nvidia-smi でヘッドルームが表示されていても OOM になることがあります。一部のドライバー/セットアップでは、メモリクエリは数値ではなく [N/A], [N/A] をそのまま返します — そこで数値を grep するスクリプトは何も得られませんが、誤解を招く過小カウントにはなりません(spark-training-gotchas の gotcha G3 を参照)。

  • モデルのロードは一時的なピークであり、定常状態ではありません。 safetensors の重みをロードするとファイルが mmap され、その後 CUDA テンソルにコピーされます — ロード中の一定期間、mmap されたページと CUDA コピーの両方が同時にプールを消費します。ヘッドルームをロード後のフットプリントではなく、この倍加した一時ピークに合わせて見積もっていると、トレーニング中は収まるモデルでもロード中に OOM になることがあります。

計画と診断には nvidia-smi ではなく free -g を使います:

free -g | awk 'NR==2 {print "free:", $4, "GB"}'

経験則: その空き容量の数値から OS/ドライバーのオーバーヘッド分を数 GB 差し引き、その結果を基準に予算を立てます — 128GB という仕様値を基準にしないでください。 references/uma-accounting.md のワークシートは、パラメーター数、dtype、手法を入力として受け取り、既知のアンカーと比較するためのメモリ見積もりを返します。

計画の手順

起動前に、次の順番で進めます:

  1. free -g を読み、OS/ドライバーのオーバーヘッドを差し引いて予算とします。
  2. references/uma-accounting.md から重み + オプティマイザー + 勾配 + アクティベーションを見積もります。
  3. 見積もり単独ではなく、最も近いアンカー(70B QLoRA、27B LoRA、9B フル FT)と比較します。
  4. 見積もりが予算に近い場合は、より短いパッキングまたはより小さなバッチで開始します — 実行途中で OOM ラダーに陥るより安上がりです。
例: 70B QLoRA 実行の見積もり

ワークシートの式を ≈40GB のアンカーに対してサニティチェックします:

params = 70e9
weights_gb = params * 0.5 / 1e9      # NF4, step 1
adapter_gb = 0.5                     # step 5, negligible
total_gb = weights_gb + adapter_gb   # + activations
print(f"{total_gb:.0f}GB before activations")

重みだけで ≈40GB のアンカー付近に収まります — 同じモデルクラスに対してこれをはるかに超える見積もりをする計画は、dtype と手法を再確認するシグナルです。

OOM のはしご

統合メモリ上でジョブが OOM になったときは、この はしごを順番にたどってください。各ステップは前の ステップよりも影響が大きくなります — 先に進みすぎ ないでください: バッチサイズの削減がステップ 1 になることは 決してありません。

  1. バッファキャッシュをフラッシュする。 前回の 実行や大規模データセットの読み込みによるページ キャッシュが、「失われた」ヘッドルームの GB 単位 のかなりの部分を占めていることがよくあります。 これには再実行以外のコストはかからず、ジョブの 設定にも触れません:

    sync; echo 3 > /proc/sys/vm/drop_caches
    

    ルート権限が必要です。実行の合間のリセットで あり、トレーニング途中のステップではありません。 このステップの背景にある完全な診断については spark-training-gotchas(gotcha G3)を参照して ください。

  2. バッチサイズまたはパッキング長を削減する。 フラッシュで十分なヘッドルームが解放されなかった 場合にのみ、バッチサイズまたはパッキング長を削減 します — 実行の内容を変える最初のステップです。 まずパッキング長を優先してください。長いコンテキスト では、こちらのほうがアクティベーションのフット プリントに直接影響します。

  3. メソッドをダウングレードする: QLoRA より先に bf16 LoRA。 フラッシュとバッチ/パックの縮小でも まだ OOM になる場合は、メソッドを 1 段階下げます — 次は bf16 LoRA であり、その逆ではありません。 QLoRA の bitsandbytes 逆量子化バッファは一時的な CUDA 側の割り当てで、QLoRA の定常状態のフット プリントがより小さくても、同等の bf16 LoRA 実行 なら OOM にならないようなケースで OOM になる ことがあります。QLoRA の OOM は、モデルが収まら ない証拠にはなりません。

さらにフォールバックする(より小さなモデル、マルチ Spark)のは、3 つのステップをすべて試してもジョブが まだ収まらない場合だけにしてください。

熱モニタリング

数時間にわたる実行は、定格値をはるかに下回る Spark の持続電力上限に達します — これは想定される プラットフォームの挙動であり、言い訳をすべき症状 ではありません:

  • 温度と電力を、トレーニングログと並行して サンプリングしてください。遅延に気づいてからでは ありません — 30〜60 秒ごとであれば、スループット 低下と熱イベントを関連付けられます。 assets/thermal-sample.sh が書き出す CSV 出力形式 を維持して、タイムスタンプがログと一致するように してください:

    bash assets/thermal-sample.sh 30 thermal.log
    
  • 約 100W の持続的な電力消費はプラットフォームの 上限であり、設定のバグではありません。 負荷時に ハードウェアが正常に動作しているだけのプラトーを 「修正」しようとして、バッチサイズや精度を再調整 しないでください。定格 240W を下回る値で電力が 横ばいのまま温度が上昇するなら、それが認識すべき 兆候です。

  • スロットリングイベントは、実行が記録されないまま 静かに遅くなるのに任せず、明示的にログに記録して ください。2 時間の時点で 1 ステップあたりの時間が 2 倍になった実行は、そのタイムスタンプの熱サンプル と突き合わせて、ログにそれが表れるはずです。完全な スロットリング診断: spark-training-gotchas (gotcha G4)。

同時ワークロード

128GB のプールはグローバルであるため、どちらの プロセスのログにも OOM が表示されないままエビクション が発生します:

  • 1 つの重いジョブというルールは、上限なしまたは 上限ぎりぎりのワークロードに適用されます — 上限なしのトレーナーと推論サーバー(vLLM、Ollama)は 同じプールを奪い合います。小規模で上限付きの ワークロードはそうではありません: 4GB 未満の LoRA ファインチューニングは、gpu-memory-utilization<=0.5 に上限設定された vLLM と問題なく共存します — 停止する前に、もう一方のプロセスの存在だけでなく 上限を確認してください。

  • 推論サーバーは、上限なし/上限ぎりぎりの競合下で トレーナーのページを静かにエビクションし、その逆も 同様です — どちらもエラーをログに記録しないため、 実行の遅さや KV キャッシュの消失は、確認すべき 競合の症状です。長時間またはプール全体を使う実行の 前には、無関係な上限なしのサーバーを停止して ください。

まず GPU 上に常駐するプロセスを確認してください:

ps aux | grep -E 'vllm|ollama|trl|axolotl' | grep -v grep

この手順は spark-training-gotchas(gotcha G3、G4、G6) を補完します — あちらのスキルは起動時の失敗を扱い、 こちらは実行中のジョブを扱います。

メモリ計算のワークシート: references/uma-accounting.md。

コメント