mcpField
R
run-experiment

run-experiment

github.com/wanshuiyin云与 DevOps18.2k530 次安装4 天前更新
代码仓库

关于 run-experiment

run-experiment 是用于部署和启动机器学习实验的技能,会依据项目的 CLAUDE.md 配置选择运行环境。它涵盖本地、SSH 远程、Vast.ai 和 Modal 流程,并检查环境及确认任务启动。

主要功能

  1. 01识别本地、远程、Vast.ai 或 Modal 环境
  2. 02启动前检查 GPU 可用情况
  3. 03向远程机器同步代码
  4. 04启动任务并保存日志
  5. 05验证实验进程状态

适用场景

  1. 01在已配置的远程 GPU 上运行训练任务
  2. 02在 Vast.ai 实例上启动实验
  3. 03通过 Modal 启动无服务器 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)——规格哈希未变表示可复用预热环境,哈希已变则表示需要重建。新环境 → 先编写声明式规格,再根据此提供商的配置形式进行渲染;仅凭导入成功绝不能认定环境已就绪:运行已植入种子的内核验证;任何重建或文档编辑之后,都要运行“Agent 遵循文档”检查(由一个全新的子 Agent 原样执行文档中的调用方式,并报告文档与实际情况的差异)。

Vast.ai 检测优先级:

  1. 如果 CLAUDE.md 中包含 gpu: vast 或 ## Vast.ai 章节:
    • 如果 vast-instances.json 存在且有正在运行的实例 → 使用该实例
    • 如果没有正在运行的实例 → 调用 /vast-gpu provision,它会分析任务、提供经过成本优化的 GPU 选项,并租用用户选择的实例
  2. 如果未在 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"

优点:有版本跟踪,一次推送即可同步到多台服务器,无需设置 rsync 包含/排除规则。

选项 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;参见 ../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,没有环境规格:作为一个阶段安装, 任何版本冲突都表明需要转换为有序阶段:

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 日志记录:

  1. 检查脚本中是否已有 wandb——查找 import wandb 或 wandb.init。如果存在,则跳到步骤 4。

  2. 如果不存在,则在训练脚本中添加 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()
    
  3. 要记录的指标(添加适用于该实验的指标):

    • train/loss — 每个步骤的训练损失
    • train/lr — 学习率
    • eval/loss、eval/ppl、eval/accuracy — 每个 epoch 的评估指标
    • gpu/memory_used — GPU 内存(通过 torch.cuda.max_memory_allocated() 获取)
    • speed/samples_per_sec — 吞吐量
    • 实验已计算的任何自定义指标
  4. 验证目标机器上的 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)

为每个实验创建一个专用的 screen 会话,并绑定 GPU:

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 处理:

  1. 分析任务——确定 VRAM 需求、选择 GPU、估算费用
  2. 生成启动器——创建 modal_launcher.py,使用 modal.Mount.from_local_dir 挂载代码,并使用 modal.Volume 保存结果,以此封装训练脚本
  3. 运行——modal run modal_launcher.py(在本地运行,GPU 在远程执行)
  4. 收集结果——结果通过 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:飞书通知(如果已配置)

确认部署后,检查 ~/.claude/feishu.json:

  • 发送 experiment_done 通知:说明已启动的实验、使用的 GPU 和预计耗时
  • 如果配置文件不存在或模式为 "off":则完全跳过(不执行任何操作)
步骤 7:自动销毁 Vast.ai 实例(当 gpu: vast 且 auto_destroy: true 时)

如果未使用 vast.ai 或 auto_destroy 为 false,则跳过此步骤。

实验完成后(通过 /monitor-experiment 检测到完成,或 screen 会话结束):

  1. 从实例下载结果:

    rsync -avz -e "ssh -p <PORT>" root@<HOST>:/workspace/project/results/ ./results/
    
  2. 下载日志:

    scp -P <PORT> root@<HOST>:/workspace/*.log ./logs/
    
  3. 销毁实例以停止计费:

    vastai destroy instance <INSTANCE_ID>
    
  4. 更新 vast-instances.json——将状态标记为 destroyed。

  5. 报告费用:

    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。在 https://cloud.vast.ai/manage-keys/ 上传 SSH 公钥。在 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>。

评论

支持 Markdown