run-experiment について
run-experimentは、プロジェクトのCLAUDE.mdに記された環境設定に基づき、機械学習実験をデプロイして起動するスキルです。ローカル、SSH経由のリモート、Vast.ai、Modalの実行手順と起動確認に対応します。
主な機能
- 01ローカル・リモート・Vast.ai・Modalの判別
- 02起動前のGPU使用状況確認
- 03リモートマシンへのコード同期
- 04ログを保存してジョブを起動
- 05実験プロセスの起動確認
活用シーン
- 01設定済みのリモートGPUで学習を実行
- 02Vast.aiインスタンスで実験を起動
- 03ModalでサーバーレスGPU実行を開始
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wanshuiyin/ auto-claude-code-research-in-sleep --skill run-experimentインストール後、Claude Code で/run-experimentを入力して読み込まれたか確認します。
詳細
実験を実行
ML 実験をデプロイして実行します:$ARGUMENTS
ワークフロー
ステップ 1:環境を検出する
プロジェクトの CLAUDE.md を読み、実験環境を特定します。
- ローカル GPU(
gpu: local):ローカルの CUDA/MPS 設定情報を確認します - リモートサーバー(
gpu: remote):SSH エイリアス、conda 環境、コードディレクトリを確認します - Vast.ai(
gpu: vast):プロジェクトのルートにvast-instances.jsonがあるか確認します。実行中のインスタンスがあれば、それを使用します。また、CLAUDE.mdに## Vast.aiセクションがあるか確認します。 - Modal(
gpu: modal):Modal 経由のサーバーレス GPU です。SSH も Docker も不要で、自動的にスケール・トゥ・ゼロになります。/serverless-modalに委任します。
Modal の検出: CLAUDE.md に gpu: modal または ## Modal セクションがある場合、デプロイ全体を /serverless-modal が処理します。**ステップ 4:デプロイ(Modal)**に進みます。ステップ 2~3 は不要です(Modal がコード同期と GPU 割り当てを自動的に処理します)。
環境の契約(../shared-references/compute-env-contract.md):環境を構築または信頼する前に、プロバイダーの環境台帳(.aris/compute/<provider>.md)を読みます。仕様ハッシュに変更がなければウォーム再利用し、変更があれば再構築します。新しい環境では、まず宣言的な仕様を記述し、それをこのプロバイダーの形式に合わせてレンダリングします。インポートの成功だけを根拠に準備完了と判断してはいけません。シード済みのカーネル検証を実行し、再構築またはドキュメント編集の後は、エージェントによるドキュメント追従テストを実行します(新しいサブエージェントが、記載された呼び出し手順をそのまま実行し、ドキュメントと実際の動作の不一致を報告します)。
Vast.ai の検出優先順位:
CLAUDE.mdにgpu: vastまたは## Vast.aiセクションがある場合:vast-instances.jsonが存在し、実行中のインスタンスがあれば、そのインスタンスを使用します- 実行中のインスタンスがなければ、
/vast-gpu provisionを呼び出します。タスクを分析し、コストを最適化した GPU の選択肢を提示したうえで、ユーザーの選択したものを借ります
CLAUDE.mdにサーバー情報が見つからない場合は、ユーザーに確認します。
ステップ 2:実行前チェック
対象マシンで GPU が利用可能か確認します。
リモート(SSH):
ssh <server> nvidia-smi --query-gpu=index,memory.used,memory.total --format=csv,noheader
リモート(Vast.ai):
ssh -p <PORT> root@<HOST> nvidia-smi --query-gpu=index,memory.used,memory.total --format=csv,noheader
(vast-instances.json から ssh_host と ssh_port を読み取るか、vastai ssh-url <INSTANCE_ID> を実行します。ssh://root@HOST:PORT が返されます)
ローカル:
nvidia-smi --query-gpu=index,memory.used,memory.total --format=csv,noheader
# or for Mac MPS:
python -c "import torch; print('MPS available:', torch.backends.mps.is_available())"
空き GPU とは、memory.used < 500 MiB の状態です。
ステップ 3:コードを同期する(リモートのみ)
プロジェクトの CLAUDE.md で code_sync の設定を確認します。指定がない場合は、デフォルトで rsync を使用します。
オプション A:rsync(デフォルト)
データ、チェックポイント、大容量ファイルは除き、必要なファイルのみ同期します。
rsync -avz --include='*.py' --exclude='*' <local_src>/ <server>:<remote_dst>/
オプション B:git(CLAUDE.md で code_sync: git が設定されている場合)
ローカルの変更をリモートリポジトリにプッシュしてから、サーバーでプルします。
# 1. Push from local
git add -A && git commit -m "sync: experiment deployment" && git push
# 2. Pull on server
ssh <server> "cd <remote_dst> && git pull"
メリット:バージョン管理され、1 回のプッシュで複数サーバーと同期でき、rsync の include/exclude ルールも不要です。
オプション C:Vast.ai インスタンス
vast.ai インスタンスにコードを同期します(常に rsync を使用し、コードディレクトリは /workspace/project/ です)。
rsync -avz -e "ssh -p <PORT>" \
--include='*.py' --include='*.yaml' --include='*.yml' --include='*.json' \
--include='*.txt' --include='*.sh' --include='*/' \
--exclude='*.pt' --exclude='*.pth' --exclude='*.ckpt' \
--exclude='__pycache__' --exclude='.git' --exclude='data/' \
--exclude='wandb/' --exclude='outputs/' \
./ root@<HOST>:/workspace/project/
環境の契約に従って依存関係をインストールします(順序付きフェーズ:最初にバージョンを固定し、フェーズごとに pip install を 1 回実行します。../shared-references/compute-env-contract.md を参照してください)。
ssh -p <PORT> root@<HOST> "pip install -q torch==<pinned>" # phase 1: pins
ssh -p <PORT> root@<HOST> "pip install -q <remaining packages>" # phase 2+
レガシーな代替手段 — 環境仕様がなく、requirements.txt のみの場合:1 つのフェーズとしてインストールし、バージョンの競合が発生したら、順序付きフェーズに切り替える合図として扱います。
scp -P <PORT> requirements.txt root@<HOST>:/workspace/
ssh -p <PORT> root@<HOST> "pip install -q -r /workspace/requirements.txt"
ステップ 3.5:W&B 連携(CLAUDE.md で wandb: true の場合)
CLAUDE.md で wandb が設定されていないか、false に設定されている場合は、このステップ全体をスキップしてください。
デプロイする前に、実験スクリプトで W&B のログ記録が行われることを確認してください。
-
スクリプトに wandb がすでに含まれているか確認します —
import wandbまたはwandb.initを探してください。含まれている場合は、ステップ 4 に進みます。 -
含まれていない場合は、トレーニングスクリプトに W&B のログ記録を追加します:
import wandb wandb.init(project=WANDB_PROJECT, name=EXP_NAME, config={...hyperparams...}) # Inside training loop: wandb.log({"train/loss": loss, "train/lr": lr, "step": step}) # After eval: wandb.log({"eval/loss": eval_loss, "eval/ppl": ppl, "eval/accuracy": acc}) # At end: wandb.finish() -
記録するメトリクス(実験に該当するものを追加します):
train/loss— ステップごとのトレーニング損失train/lr— 学習率eval/loss、eval/ppl、eval/accuracy— エポックごとの評価メトリクスgpu/memory_used— GPU メモリ(torch.cuda.max_memory_allocated()を使用)speed/samples_per_sec— スループット- 実験ですでに計算されているカスタムメトリクス
-
対象マシンで wandb にログインできることを確認します:
ssh <server> "wandb status" # should show logged in # If not logged in: ssh <server> "wandb login <WANDB_API_KEY>"
W&B プロジェクト名と API キーは
CLAUDE.mdから取得します(以下の例を参照)。実験名は、スクリプト名とタイムスタンプから自動生成されます。
ステップ 4:デプロイ
リモート(SSH + screen 経由)
各実験用に、GPU を割り当てた専用の screen セッションを作成します:
ssh <server> "screen -dmS <exp_name> bash -c '\
eval \"\$(<conda_path>/conda shell.bash hook)\" && \
conda activate <env> && \
CUDA_VISIBLE_DEVICES=<gpu_id> python <script> <args> 2>&1 | tee <log_file>'"
Vast.ai インスタンス
conda は不要です — Docker イメージに環境が含まれています。作業ディレクトリには /workspace/project/ を使用します:
ssh -p <PORT> root@<HOST> "screen -dmS <exp_name> bash -c '\
cd /workspace/project && \
CUDA_VISIBLE_DEVICES=<gpu_id> python <script> <args> 2>&1 | tee /workspace/<log_file>'"
起動後、このインスタンスの vast-instances.json にある experiment フィールドを更新します。
Modal(サーバーレス)
gpu: modal が検出された場合は、/serverless-modal に処理を委任します:
- タスクを分析する — VRAM の必要量を判断し、GPU を選択して、コストを見積もります
- ランチャーを生成する — コードには
modal.Mount.from_local_dir、結果にはmodal.Volumeを使用してトレーニングスクリプトをラップするmodal_launcher.pyを作成します - 実行する —
modal run modal_launcher.py(ローカルで実行し、GPU はリモートで動作します) - 結果を収集する — 結果は Volume または stdout 経由で返されるため、手動でダウンロードする必要はありません
CLAUDE.md で設定する主な Modal の項目:
modal_gpu:GPU の上書き設定(デフォルト:VRAM 分析に基づいて自動選択)modal_timeout:最大秒数(デフォルト:21600 = 6 時間)modal_volume:結果を永続化するための名前付きボリューム
SSH、コード同期、screen セッションは不要です。Modal がすべて処理します。
ローカル
# Linux with CUDA
CUDA_VISIBLE_DEVICES=<gpu_id> python <script> <args> 2>&1 | tee <log_file>
# Mac with MPS (PyTorch uses MPS automatically)
python <script> <args> 2>&1 | tee <log_file>
ローカルで長時間実行するジョブでは、会話の応答性を保つため、run_in_background: true を使用します。
ステップ 5:起動を確認する
リモート(SSH):
ssh <server> "screen -ls"
リモート(Vast.ai):
ssh -p <PORT> root@<HOST> "screen -ls"
Modal:
modal app list # Check app is running
modal app logs <app> # Stream logs
ローカル: プロセスが実行中で、GPU が割り当てられていることを確認します。
ステップ 6:Feishu 通知(設定されている場合)
デプロイの確認後、~/.claude/feishu.json を確認します:
experiment_done通知を送信します:起動した実験、使用する GPU、推定所要時間を通知します- 設定ファイルが存在しない場合、またはモードが
"off"の場合は、何もせずスキップします
ステップ 7:Vast.ai インスタンスを自動破棄する(gpu: vast かつ auto_destroy: true の場合)
vast.ai を使用していない場合、または auto_destroy が false の場合は、このステップをスキップしてください。
実験の完了後(/monitor-experiment または screen セッションの終了によって検出):
-
インスタンスから結果をダウンロードします:
rsync -avz -e "ssh -p <PORT>" root@<HOST>:/workspace/project/results/ ./results/ -
ログをダウンロードします:
scp -P <PORT> root@<HOST>:/workspace/*.log ./logs/ -
課金を停止するため、インスタンスを破棄します:
vastai destroy instance <INSTANCE_ID> -
vast-instances.jsonを更新します — ステータスをdestroyedに設定します。 -
コストを報告します:
Vast.ai instance <ID> auto-destroyed. - Duration: ~X.X hours - Estimated cost: ~$X.XX - Results saved to: ./results/
これにより、アイドル状態のインスタンスに対してユーザーが課金されることを防げます。
auto_destroy: true(デフォルト)の場合、ライフサイクル全体(レンタル → セットアップ → 実行 → 収集 → 破棄)が自動化されます。
主なルール
- 必ず最初に GPU の利用可否を確認してください。GPU を盲目的に割り当てないでください(自動的に割り当てを管理する Modal を除く)。
- 各実験には、それぞれ専用の screen セッションと GPU(リモートの場合)、またはバックグラウンドプロセス(ローカルの場合)を割り当ててください。
- 後でログを確認できるよう、
teeを使ってログを保存してください。 - 会話の応答性を保つため、デプロイコマンドは
run_in_background: trueを指定して実行してください。 - 実行内容を報告してください。使用する GPU、screen セッションまたはプロセス、コマンド、推定所要時間を含めてください。
- 複数の実験を実行する場合は、異なる GPU で並列に開始してください。
- Vast.ai のコストに関する注意:
gpu: vastを使用する場合は、必ず実行中のコストを報告してください。auto_destroy: trueの場合は、そのインスタンス上のすべての実験が完了したら、すぐにインスタンスを破棄してください。 - Modal のコストに関する注意:実行前に必ずコストを見積もって表示してください。Modal は自動的にゼロまでスケールするため、アイドル時の課金も手動でのクリーンアップも不要です。
CLAUDE.md の例
ユーザーは、プロジェクトの CLAUDE.md にサーバー情報を追加してください。
## Remote Server
- gpu: remote # use pre-configured SSH server
- SSH: `ssh my-gpu-server`
- GPU: 4x A100 (80GB each)
- Conda: `eval "$(/opt/conda/bin/conda shell.bash hook)" && conda activate research`
- Code dir: `/home/user/experiments/`
- code_sync: rsync # default. Or set to "git" for git push/pull workflow
- wandb: false # set to "true" to auto-add W&B logging to experiment scripts
- wandb_project: my-project # W&B project name (required if wandb: true)
- wandb_entity: my-team # W&B team/user (optional, uses default if omitted)
## Vast.ai
- gpu: vast # rent on-demand GPU from vast.ai
- auto_destroy: true # auto-destroy after experiment completes (default: true)
- max_budget: 5.00 # optional: max total $ to spend per experiment
## Modal
- gpu: modal # serverless GPU via Modal (no SSH, auto scale-to-zero)
- modal_gpu: A100-80GB # optional: override GPU selection (default: auto-select)
- modal_timeout: 21600 # optional: max seconds (default: 6 hours)
- modal_volume: my-results # optional: named volume for results persistence
## Local Environment
- gpu: local # use local GPU
- Mac MPS / Linux CUDA
- Conda env: `ml` (Python 3.10 + PyTorch)
Vast.ai のセットアップ:
pip install vastai && vastai set api-key YOUR_KEYを実行します。SSH 公開鍵を https://cloud.vast.ai/manage-keys/ にアップロードします。CLAUDE.mdにgpu: vastを設定すると、/run-experimentがインスタンスを自動的にレンタルし、実験を実行して、完了後に破棄します。
Modal のセットアップ:
pip install modal && modal setupを実行します。https://modal.com/settings で支払い方法を登録します(CLI からは絶対に登録しないでください)。これにより、月額 30 ドルの無料枠をすべて利用できます(カードを登録しない場合は月額 5 ドルのみ)。誤った請求を防ぐため、ワークスペースの利用上限を設定してください。CLAUDE.mdにgpu: modalを設定します。ローカル GPU がなく、コードのデバッグや小規模なテストの実行が必要なユーザーに最適です。
W&B のセットアップ:サーバーで一度
wandb loginを実行するか、WANDB_API_KEY環境変数を設定します。このスキルはCLAUDE.mdからプロジェクトとエンティティを読み取り、トレーニングスクリプトにwandb.init()とwandb.log()を自動的に追加します。ダッシュボード:https://wandb.ai/<entity>/<project>。