跳转到内容

研究规格

研究规格是你发布研究时批准的那张公平对比表:各组在哪些设置上不同,每个 run 固定什么,什么可以调整。它是你能完整读懂的那一层,所以 CVSM 按每个 run 自己的记录对照它核对。

研究 #10 · 规格你读得懂 · 关口 01
  1. ### Arms各组之间仅有的不同
  2. full: model.adapter=none
  3. lora: model.adapter=lora model.lora.rank=8
  4. ### Controlled固定不变,各带理由
  5. optim.lr=3e-4# 论文 X 表 2
  6. train.effective_batch=256# 论文 X 表 2
  7. seed in 1,2,3# 同论文 X,用 3 个 seed
  8. ### Adaptable可以不同,守住各自的规则
  9. train.per_device_batch# 按显存调整,有效 batch 固定为 256
  10. train.accum# 跟随 per_device_batch
规格核对来自记录 · 6 个 run

规格核对:

  • ≠train.effective_batch=256 不成立:1 个 run,0330bc8a…(128)
  • ≠未声明的差异 train.precision:bf16(5 个 run)、fp16(1 个 run)
  • ·Adaptable train.per_device_batch:full 取 64(3 个 run);lora 取 64(2 个 run)、32(1 个 run)
  • ·Adaptable train.accum:full 取 4(3 个 run);lora 取 4(3 个 run)

scripts/results.py 的输出

它按事实列出

  1. 规格本身的问题:读不懂的行、没写理由的 Controlled 行、缺少的节、出现在多节的键
  2. 不满足某条 Controlled 的 run,或配置里没记录这个键的 run(未记录)
  3. 不属于任何 arm、或属于多个 arm 的 run
  4. 缺了某条 in 中某些取值的 arm
  5. 不在任何一节、取值却不同的键(未声明的差异)
  6. 没有 run 的 arm
  7. 每个 Adaptable 键在各 arm 取过的值

研究批准之后,规格下面的代码、配置和启动越来越多,多到没人读得完,设置上的差异也正是从这里冒出来的。规格只有几个变量,人一眼就能核对。把它当成合同,问题就从“agent 说它保证了公平吗?”变成了“记录和我批准的对得上吗?”。

规格是 study issue 里的三节,每行一项,行尾可加 # <注释>。

### Arms
full: model.adapter=none
lora: model.adapter=lora model.lora.rank=8
### Controlled
data.split=val # 留出的划分,来自 data.sha256
model.backbone=vit_b16 # 论文 X 表 2
optim.lr=3e-4 # 论文 X 表 2
train.epochs=30 # 论文 X 表 2
train.effective_batch=256 # 论文 X 表 2
seed in 1,2,3 # 同论文 X,用 3 个 seed
### Adaptable
train.per_device_batch # 按显存调整,有效 batch 固定为 256
train.accum # 跟随 per_device_batch
  • Arms(各组):各组之间仅有的不同。每行 <arm>: <键>=<值> ...。
  • Controlled(受控):每个 run 都要满足的设置。key=value # 理由 是每个 run 都要取的值;key in v1,v2,... # 理由 是每组都要跑遍的值,例如 seed 和调参网格。理由必填:一篇论文、一条记录或之前的一个结果。
  • Adaptable(可调整):可以因 run 而不同的工程设置,每行 key # 规则,规则保证对比不被破坏。这一节可以留空。

键是每个 run 解析后配置的点号键,也就是训练代码写的 config.json,run.py 把它记成 cfg.* 参数。一个键最多出现在一节里。值能按 JSON 解析(数字、true、false、null、列表)就按 JSON 比较,所以 1 和 1.0 相等;否则按字符串比较。

plan skill 在发布前和你一起推出规格,让它一开始就完整、有依据。它逐项过一遍常见的混杂因素,凡是适用的都固定下来:数据与划分、预处理与增强、模型与初始化、优化器与调度、有效 batch 与训练长度、精度、调参预算、评测协议与 checkpoint 选择、seed。代码暂时还不能通过配置设置的项,单开一个代码子 issue。

  • implement:规格里的每个键都经配置设置,把解析后的配置写进 $RUN_DIR/config.json,从不改 Controlled 设置,也不让各组的差异超出 Arms。
  • review:代码改动违反规格,就是阻断问题。
  • run:启动前确认 Runs 每行只跑一组,本 issue 跑到的每一组都跑遍每个 in 值。启动后马上做规格核对,停掉违反某条 Controlled key=value、没记录该键、或不属于任何一组或属于多组的 run。出现未声明的差异是卡点。Adaptable 设置只在规则内调整,每处调整都写下来。
  • 某个 Controlled 设置不改变对比就满足不了,是卡点:改实现、放宽规格,或放弃这个对比。

每条结果评论的最后都有一节 规格核对,由结果命令从记录生成:

终端窗口
gh issue view 10 --json body -q .body | python scripts/results.py --issue 12 --spec -

它对选中的 run(包括还在跑的)按事实列出:

  • 不满足某条 Controlled 的 run,或没记录这个键的 run(未记录);
  • 不属于任何一组、或属于多组的 run;
  • 缺了某条 in 中某些值的组;
  • 不在任何一节、取值却不同的键(未声明的差异);
  • 没有 run 的组;
  • 规格本身的问题:读不懂的行、没写理由的 Controlled 行、缺少 Arms 或 Controlled 节、同一个键出现在多节;
  • 每个 Adaptable 键在各组取过的值。

没给规格或没有偏差时,这一节也会写明。

下面是上面这份规格的六个玩具 run,直接用 run.py 启动。其中一个 lora run 用了更小的每卡 batch 和 fp16;按 run skill,它在启动后就会被停掉。

规格核对:
- `train.effective_batch=256` 不成立:1 个 run,0330bc8a46094e03a875e72c6dfd0872(128)
- 未声明的差异 `train.precision`:bf16(5 个 run)、fp16(1 个 run)
- Adaptable `train.per_device_batch`:full 取 64(3 个 run);lora 取 64(2 个 run)、32(1 个 run)
- Adaptable `train.accum`:full 取 4(3 个 run);lora 取 4(3 个 run)

参考实现 results.py 输出的文字是中文;项目要用别的语言,就改 results.py。