研究规格
研究规格是你发布研究时批准的那张公平对比表:各组在哪些设置上不同,每个 run 固定什么,什么可以调整。它是你能完整读懂的那一层,所以 CVSM 按每个 run 自己的记录对照它核对。
### Arms各组之间仅有的不同full: model.adapter=nonelora: model.adapter=lora model.lora.rank=8### Controlled固定不变,各带理由optim.lr=3e-4# 论文 X 表 2train.effective_batch=256# 论文 X 表 2seed in 1,2,3# 同论文 X,用 3 个 seed### Adaptable可以不同,守住各自的规则train.per_device_batch# 按显存调整,有效 batch 固定为 256train.accum# 跟随 per_device_batch
规格核对:
- ≠
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 的输出
它按事实列出
- 规格本身的问题:读不懂的行、没写理由的 Controlled 行、缺少的节、出现在多节的键
- 不满足某条 Controlled 的 run,或配置里没记录这个键的 run(未记录)
- 不属于任何 arm、或属于多个 arm 的 run
- 缺了某条 in 中某些取值的 arm
- 不在任何一节、取值却不同的键(未声明的差异)
- 没有 run 的 arm
- 每个 Adaptable 键在各 arm 取过的值
为什么要规格
Section titled “为什么要规格”研究批准之后,规格下面的代码、配置和启动越来越多,多到没人读得完,设置上的差异也正是从这里冒出来的。规格只有几个变量,人一眼就能核对。把它当成合同,问题就从“agent 说它保证了公平吗?”变成了“记录和我批准的对得上吗?”。
规格是 study issue 里的三节,每行一项,行尾可加 # <注释>。
### Armsfull: model.adapter=nonelora: model.adapter=lora model.lora.rank=8
### Controlleddata.split=val # 留出的划分,来自 data.sha256model.backbone=vit_b16 # 论文 X 表 2optim.lr=3e-4 # 论文 X 表 2train.epochs=30 # 论文 X 表 2train.effective_batch=256 # 论文 X 表 2seed in 1,2,3 # 同论文 X,用 3 个 seed
### Adaptabletrain.per_device_batch # 按显存调整,有效 batch 固定为 256train.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 相等;否则按字符串比较。
规格怎么定出来
Section titled “规格怎么定出来”plan skill 在发布前和你一起推出规格,让它一开始就完整、有依据。它逐项过一遍常见的混杂因素,凡是适用的都固定下来:数据与划分、预处理与增强、模型与初始化、优化器与调度、有效 batch 与训练长度、精度、调参预算、评测协议与 checkpoint 选择、seed。代码暂时还不能通过配置设置的项,单开一个代码子 issue。
各个角色怎么守住规格
Section titled “各个角色怎么守住规格”- implement:规格里的每个键都经配置设置,把解析后的配置写进
$RUN_DIR/config.json,从不改 Controlled 设置,也不让各组的差异超出 Arms。 - review:代码改动违反规格,就是阻断问题。
- run:启动前确认 Runs 每行只跑一组,本 issue 跑到的每一组都跑遍每个
in值。启动后马上做规格核对,停掉违反某条 Controlledkey=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。