关于 compare
面向 Claude Code 的机器学习实验对比技能,可从指标跟踪器和本地文件中读取运行结果。它按相同步数对齐指标,并区分代理指标与下游目标,避免产生误导性比较。
主要功能
- 01自动检测指标跟踪器
- 02获取完整指标历史
- 03按相同步数对齐基线
- 04区分代理指标与目标指标
- 05多运行排名与消融分析
- 06生成实验报告并监控训练
适用场景
- 01将进行中的运行与基线比较
- 02检查不同运行的收敛曲线
- 03按指标和资源用量排列运行
- 04为实验报告分析消融结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fcakyon/ labrat --skill compare安装后在 Claude Code 中输入/compare确认已加载。
详细介绍
比较:跨跟踪器的同一训练轮次运行对比
最常见的比较错误,是在运行 A 处于 100 个训练轮次中的第 11 轮时,根据基线第 100 轮的数据报告“运行 A 落后基线 4 个百分点”。学生仍在训练中,这种比较毫无意义。此技能会确保按相同训练轮次对齐。
当助手报告差值却未对齐运行时,Agentic Stop 钩子会从 reason 路由到此处。
如果问题是“为什么 X 失败/发散/表现不佳”,请先转到 /labrat:debug。
自动检测跟踪器
按以下顺序检查:
- 已设置
WANDB_API_KEY环境变量,或项目中可导入wandb,或存在包含 wandb 键的*.yaml配置 → wandb - 已设置
NEPTUNE_API_TOKEN环境变量,或存在包含 neptune 键的*.yaml配置 → neptune - 已设置
MLFLOW_TRACKING_URI环境变量,或存在mlruns/目录 → mlflow - 存在
runs/或lightning_logs/目录 → tensorboard - 运行目录中存在
*results*.json/*meta*.json/eval*.csv文件 → 本地文件格式:读取一个样例文件,并编写适用于该格式的分析代码,而不是使用硬编码脚本
如果都没有,请先询问用户指标存放在哪里,再做判断。
流程
1. 确认运行
获取完整名称(不要使用简称)。如果用户说“run-b 和基线对比”,请确认:
- 指的是哪个
run-b运行(项目 + 实体 + 运行 ID) - 指的是哪个基线(完整运行名称;基线通常有多个变体)
2. 获取指标历史记录(而不只是最终值)
你需要的是完整曲线,而不是最后报告的值。只比较最终值会掩盖收敛动态。
对于 wandb:
import wandb
api = wandb.Api()
run = api.run("entity/project/run-id")
history = run.history(samples=10000) # full history, not just summary
对于 tensorboard,解析事件文件(tensorboard.backend.event_processing.event_accumulator.EventAccumulator)。
对于 neptune/mlflow,使用各自的 API。
3. 找出学生当前步数
学生指仍在进行中的运行(或正在评估的运行)。从最新的历史记录行中获取其当前训练轮次/步数。
4. 截取基线在相同步数的数据
这是关键一步。基线可能一直训练到(比如)第 100 轮,而学生处于第 11 轮。提取基线在第 11 轮时的指标,而不是 第 100 轮的指标。
student_step = student_history['epoch'].max()
baseline_at_same_step = baseline_history[baseline_history['epoch'] == student_step]
如果基线没有完全匹配的步数,请进行插值或选取最接近的步数,并说明采用了哪种方式。
5. 区分代理指标与下游指标
大多数 ML 流水线都有一个_代理指标_(计算成本低,在训练期间计算,例如特征上的 kNN 准确率、损失、困惑度)和一个_目标下游指标_(计算成本高,定期或仅在结束时计算,例如微调后的线性探测准确率、下游任务 F1)。
代理指标用于跟踪收敛情况;目标指标才是项目实际优化的指标。只报告代理指标可能会造成误导:某个运行在 kNN 上落后,可能会在下游微调中缩小差距。请分别报告两者:
| student (ep 11) | baseline (ep 11) | delta |
| proxy (kNN top-1) | 36.4% | 38.9% | -2.5 |
| downstream (linear) | not yet | 42.1% | n/a |
如果用户只有代理指标数据,请明确说明。切勿仅凭代理指标判定胜者。
6. 输出中的运行名称
报告的每一行都要使用完整运行名称。不要写 run-a vs run-b;应写 imagenet-resnet50-baseline-bs256 vs imagenet-resnet50-distill-from-vit-l。未来的你看到这里时,可能已经不记得这些简称。
反模式
- “X 落后基线 4 个百分点”:未说明_在哪个步数_。几乎总是错误的。
- “X 已收敛”:却不展示曲线最后 5 个训练轮次的数据。
- “最佳运行是 Y”:依据的指标在不同运行中的记录方式不同(归约方式不同,评估集也不同)。
- 将单个随机种子的比较当作定论。已知方差时注明;否则标记为单随机种子结果。
输出
按指标对(代理指标 + 下游指标)提供简洁的比较表。每行都对齐到学生当前的步数。每个单元格都应能追溯到具体的跟踪器运行 ID 和步数。最后用一两句话解读比较结果;“根据当前斜率,预计学生会在第 N 步追上”是一种实用的表述;在收敛之前,很少有理由断言“学生正在获胜/落败”。
超过两个运行:排名、报告、消融、监控
对大量运行进行排名
跨多个指标比较运行结果,而不只看主要指标:
- 主要指标(准确率、F1、损失)
- 训练动态(收敛速度、稳定性)
- 资源用量(GPU 小时数、内存、成本)
- 超参数差异
将它们填入下方实验报告的结果表,并找出:
- 综合表现最佳的运行
- 各项指标表现最佳的运行
- 效率最高的运行(每 GPU 小时的指标最佳)
- 崩溃或出现异常的运行
消融分析
- 找出基线运行
- 对每项消融,计算与基线的差值
- 按影响幅度排序
- 检查交互效应(A+B != A 和 B 的单独效果之和)
- 要选择纳入论文的消融实验,请将这些差值交给
/labrat:rebuttal中的 Ablation Selection
实验报告
当用户请求报告或摘要时:
## Experiment Report
### Overview
- Total runs: N
- Date range: start to end
- Best result: [metric] = [value] (run [name])
### Results Table
| Run | Step | Config Diff | Proxy | Downstream | GPU Hours | Status |
|-----|------|-------------|-------|------------|-----------|--------|
### Key Findings
1. [Finding with evidence]
2. [Finding with evidence]
### Recommendations
1. [Next experiment to try, with justification]
确保结果表中的每一行对齐到相同步数,并像上方输出那样将代理指标与下游指标分开。
训练监控
设置定期监控:
- 检查训练是否仍在运行(GPU 利用率、日志新鲜度)
- 跟踪指标变化
- 发现异常时发出警报(损失激增、NaN、OOM)
- 在训练完成时通知
在 */10 * * * * 上创建一个 CronCreate 任务,将 {"title", "message"} JSON 对象传递给插件通知器;它会将通知转发到 /labrat:setup 配置的目标(ntfy、Slack 或电子邮件):
echo "{\"title\": \"Training check\", \"message\": \"GPU util: $(nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader)\"}" | ${CLAUDE_PLUGIN_ROOT}/scripts/notify.sh