Skip to content

第 3 章 配置覆盖、类型检查与执行边界 ​

3.1 一次运行为什么会有三份“配置” ​

train.py 开头先定义普通 Python 全局变量,随后执行 configurator.py,最后把选中的全局值收集成 config 字典。配置不是独立对象:脚本后面直接使用 batch_size、learning_rate 等名字。默认值、配置文件、命令行参数依次覆盖,顺序决定最终结果。configurator.py

例如:

sh
python train.py config/train_shakespeare_char.py --batch_size=12 --device=cpu --dtype=float32 --compile=False

先载入默认 batch_size=12,配置文件改为 64,末尾参数又改回 12。如果把同一个参数放在配置文件之前,后读的配置文件会覆盖它。这里没有“命令行永远优先”的特殊层级,只有从左到右执行。

config_keys 在执行配置之前,从全局变量中挑选非下划线开头、类型属于整数、浮点数、布尔或字符串的键。之后建立的 config 是这些键的快照。配置文件新引入的变量未必被记录;DDP 稍后再修改的每进程累积次数也不会反写这个快照。日志中的原始设置和运行时派生值有意分开,但读 checkpoint 时要知道自己看的是哪一个。

3.2 命令行的类型检查到底检查了什么 ​

包含等号的参数必须以 -- 开头,随后 key, val = arg.split('=')。literal_eval 尝试把字符串变成 Python 字面值;失败时才保留原字符串。最后检查 type(attempt) == type(globals()[key])。

输入若原值类型如下实际结果
--batch_size=3int通过,得到整数 3
--batch_size=3.0intAssertionError
--compile=Falsebool通过
--compile=falsebool小写不是 Python 布尔字面值,成为字符串,类型不符
--unknown=3键不存在ValueError
--start=a=bstr拆成三段,解包失败

表中反例已由 examples/verify_mechanics.py 执行,不是按理想解析器推测。外层 shell 去掉引号以后,参数里依然包含第二个等号,因此简单加引号不能修复最后一行;提示中需要等号时可使用 FILE: 文件方式。

类型检查不是范围检查。batch_size=-1、temperature=0.0、top_k=0 都可能通过各自的类型关,却在后续分配或采样时失败。也不是安全校验:配置文件走的是 exec,可以导入模块、写文件或执行任意 Python。literal_eval 只约束单个命令行值,不能给配置文件提供沙箱。只运行可信、审查过的配置;来自网页或陌生仓库的“配置”应按代码处理。

3.3 把开关按它真正影响的东西分类 ​

组别源码字段谁使用它
数据与批次dataset, batch_size, block_size, gradient_accumulation_steps文件路径、取窗、模型长度、累积循环
模型n_layer, n_head, n_embd, dropout, bias新建模型;恢复时部分被 checkpoint 覆盖
优化器learning_rate, weight_decay, beta1, beta2, grad_clipAdamW、学习率和梯度裁剪
日程max_iters, decay_lr, warmup_iters, lr_decay_iters, min_lr停止条件和逐步学习率
评估与保存out_dir, eval_interval, eval_iters, eval_only, always_save_checkpoint, init_from初始化、验证与 checkpoint
系统backend, device, dtype, compile分布式、设备、自动混合精度和编译
在线日志wandb_log, wandb_project, wandb_run_name仅启用时导入和连接 W&B

dtype='float32' 在本书 CPU 测试中是明确配置。原脚本 CPU 路径使用 nullcontext(),不会因为选择了 bfloat16 就自动把模型变成 BF16。默认 dtype 是根据 CUDA 支持情况决定的;没有 CUDA 时默认落入 float16,随后 GradScaler 可能给出禁用警告。把设备、dtype 和编译开关一起明确写出,比靠默认值猜行为容易审计。

3.4 七份配置,各自省略了什么 ​

字符训练配置把层数、头数、宽度设为 6、6、384,长度 256,批次 64,累积 1,dropout 0.2;学习率 10−3,最小 10−4,warmup 100,训练上限与衰减终点都是 5000,beta2=0.99。它每 250 步评估,200 个批次估计损失,每 10 步打印,只在验证改善时保存。bias、优化器其他字段仍从主脚本继承,因此不能把配置文件单独当作完整实验说明。

GPT-2 训练配置设 gradient_accumulation_steps=40、B=12,T=1024,600000 的训练与衰减终点,每 1000 步评估,评估 200 批,每 10 步打印,权重衰减 0.1。它主动启用 W&B,读者运行前若不想外联必须追加 --wandb_log=False。第 10 章解释 40 如何在 8 卡下变成每进程 5 次。

四份评估配置只有模型型号不同:gpt2、gpt2-medium、gpt2-large、gpt2-xl;共同设批次 8、评估 500 批、eval_only=True、关闭 W&B。它们没有指定数据目录,继承默认 OWT。微调配置指定 Shakespeare BPE、gpt2-xl、批次 1、累积 32、最多 20、固定学习率 3×10−5,每 5 步评估 40 批,只保存改善的模型。它没有把 dropout 改成 0.1,仍继承默认 0.0。注释建议与实际赋值应分开读。配置目录

3.5 练习:写出最终值,而不是凭文件名判断 ​

补充练习。 执行 python train.py --batch_size=4 config/train_shakespeare_char.py --n_embd=128 后,批次、宽度和头数各是多少?能开始模型前向吗?

答案。 批次 64、宽度 128、头数 6。配置文件覆盖了先前批次,最后参数只覆盖宽度。128 不能被 6 整除,注意力初始化断言失败。修复时应连同头数调整,例如 4;配置正确解析不代表结构有效。

3.6 默认值逐项参考 ​

下面是固定 train.py 的全部 33 项默认配置,读者可用它补齐覆盖文件中没写出的值。它们是源码事实,不是面向任意硬件的推荐参数。相同字段在 sample.py、bench.py 有各自默认值,不能跨入口推断。

字段固定源码默认值含义及边界
out_dir'out'checkpoint 目录;复用旧目录前先确认 init_from
eval_interval2000相邻评估的迭代间隔;影响开销、保存和 RNG
log_interval1打印间隔;过密日志会增加同步与 I/O
eval_iters200每个 split 的抽样批次数;精度与耗时折中
eval_onlyFalse仅在 iter_num=0 的原版分支退出,见 9.3
always_save_checkpointTrue每次评估都可保存;best 字段语义见 9.3
init_from'scratch'scratch、resume 或 gpt2*;控制权重及优化器来源
wandb_logFalse启用会外联日志服务;本书始终关闭
wandb_project'owt'在线日志项目名;关闭日志时不使用
wandb_run_name'gpt2'在线日志运行名;不决定本地输出目录
dataset'openwebtext'data 下的子目录名;编码必须与模型一致
gradient_accumulation_steps5 * 8DDP 分配前的总累积数 A;必须整除 W
batch_size12每进程每微步序列数;不是全局 batch
block_size1024每序列长度;限制窗口和位置表
n_layer12block 数;主干成本近似线性增长
n_head12注意力头数;宽度须能整除它
n_embd768残差宽度 C;主矩阵成本约按 C 平方增长
dropout0.0训练态随机丢弃比例;评估态关闭
biasFalseLinear/LN 是否带偏置;GPT-2 导入强制 True
learning_rate0.0006最大或固定学习率;每步写入所有参数组
max_iters600000原版是更新后检查 >;有多执行一步边界
weight_decay0.1矩阵参数组的 AdamW 解耦衰减
beta10.9Adam 一阶矩平滑系数
beta20.95Adam 二阶矩平滑系数
grad_clip1.0全局梯度范数阈值;0.0 关闭裁剪
decay_lrTrue是否调用 warmup+cosine;False 用固定值
warmup_iters2000warmup 分支终点;首步不是零
lr_decay_iters600000余弦终点;须大于 warmup
min_lr6e-05衰减结束后保持的学习率
backend'nccl'进程组后端;改 gloo 不自动支持 CPU DDP
device'cuda'单进程设备;DDP 会改为本地 CUDA 卡
dtype支持 CUDA BF16 则 bfloat16,否则 float16自动混合精度选择;CPU 不使用 autocast
compileTrue是否 torch.compile;本书关闭,不测编译收益

七份配置的在线日志字符串也只是标签:字符训练使用项目 shakespeare-char、运行名 mini-gpt、输出 out-shakespeare-char;GPT-2 训练使用 owt、gpt2-124M,输出仍继承 out;微调使用 shakespeare、由当前时间拼出的 ft-...、输出 out-shakespeare。时间戳只改变日志名,不设随机 seed。四份评估文件不定义输出路径和项目名,继续继承默认。逐项赋值、行号及原表达式见配套 research/author/coverage.json 的 config_assignments,可以核对是否遗漏继承项。

本章来源 ​

保留各书来源与许可 · 示例运行条件以正文为准