2. 训练参数概述:超参数、模型参数、环境参数

做AI训练的同学应该都有这种体会——明明代码没改,跑出来的结果就是不一样。差别在哪?多半是参数没锁住。今天我就跟你聊聊训练里的三类核心参数:超参数、模型参数、环境参数。搞懂它们,你才能真的把实验“钉死”。

2.1 超参数

超参数,说白了就是你在训练开始前就必须定好的那些旋钮。学习率、批次大小、训练轮数、优化器的动量系数……统统归它管。这些值不是模型自己学出来的,是靠人一次次试出来的。

我个人习惯是这样的:拿到一个新任务,先把学习率范围扫一遍。我见过太多新手上来就把学习率设成 0.1,结果 loss 直接飞了。嗯,其实调超参数没那么玄乎,你只要用对数尺度扫几轮,基本就能找到感觉。

常见超参数速查表

参数典型范围影响
学习率1e-5 ~ 1e-1收敛速度与稳定性
批次大小8 ~ 512梯度噪声与内存占用
Epoch 数10 ~ 500欠拟合/过拟合
优化器动量0.8 ~ 0.999逃离局部最优能力

这里要注意,超参数之间是会互相影响的。比如你调大了批次大小,学习率一般也得跟着调。我以前有个项目,batch size 从 32 调到 128,忘了改学习率,结果训练了两天发现精度还不如 baseline。从那以后我就养成了习惯——改一个参数,必须连带检查相关参数。

2.2 模型参数

模型参数和超参数最大的区别在哪?模型参数是训练过程中自己学出来的。权重矩阵、偏置向量、Embedding 层的词向量……这些都是。你给模型喂数据,它通过反向传播一点一点更新这些值。

你想想看,一个 7B 的模型,参数数量是 70 亿。这么多参数,每次训练完都要保存下来。如果你不锁版本,下一次重训出来的参数可能完全不同。哪怕你用的是同样的数据和同样的超参数,因为随机种子和初始化不同,最终模型参数也会有差异。

一个小技巧:每次训练结束后,除了保存模型权重,我还会把优化器的状态字典一起存下来。这样如果想从某个中间状态继续训练,能保证完全一致。

模型参数的版本锁定,核心是锁住那个“检查点文件”。我个人推荐用统一的命名规范,比如:

model_bert-base_epoch-10_lr-3e-5_bs-32_seed-42.pt

这样你看到文件名,就能大概知道这个模型是怎么训出来的。别小看这个习惯,关键时刻能救命。

2.3 环境参数

环境参数是最容易被忽视的一类。CUDA 版本、cuDNN 版本、Python 解释器版本、PyTorch 或 TensorFlow 的版本、甚至操作系统的内核版本——这些统统算环境参数。

为什么会这样?因为底层库的差异会直接影响浮点运算的顺序和精度。举个例子,CUDA 11.7 和 CUDA 11.8 在同一个 GPU 上跑同一个模型,结果可能就差那么几个点。你别小看这几个点,在论文复现或者生产部署时,这就是天壤之别。

我曾经就因为 CUDA 版本没锁,浪费了整整一周。当时帮同事复现一个实验,代码一模一样,结果就是不对。后来查了三天才发现,他用的 CUDA 11.6,我用的 11.7。从那以后,我只要开始一个新项目,第一件事就是写一个 environment.yml 或者 requirements.txt,把环境参数钉死。

一个典型的环境参数记录文件大概长这样:

# 环境锁文件
cuda_version: 11.7
cudnn_version: 8.5.0.96
python_version: 3.9.16
pytorch_version: 1.13.1
torchvision_version: 0.14.1
cuda_visible_devices: "0,1"
random_seed: 42

嗯,你可能觉得麻烦。但相信我,等到你要复现三个月前的实验时,你会感谢现在记下这些的你。

2.4 三类参数对比

我把这三类参数放在一起做个对比,你一看就明白:

对比维度超参数模型参数环境参数
定义训练前人工设定训练中自动学习运行环境决定
来源人工调优/搜索反向传播更新安装的软件栈
典型示例学习率、batch size权重矩阵、偏置CUDA、Python 版本
是否需要锁定是,每次实验记录是,保存检查点是,锁定环境配置
变化频率实验间变化训练中持续更新一般不变化

你看,三类参数的角色完全不同。但它们有一个共同点——都需要被版本化地管理起来。

训练参数分类全景图 训练参数 超参数 模型参数 环境参数 学习率 批次大小 权重矩阵 偏置向量 CUDA版本 随机种子 三类参数共同决定了训练的可复现性 任何一类没锁住,复现都可能失败

2.5 参数锁定的核心意义

你可能会问:参数锁定到底图个啥?就一个字——准。实验可复现,结果可对比,模型可回滚。这三个“可”是 AI 工程化的基石。

在我参与过的项目里,至少有一半的线上故障最终都指向了参数版本不一致。要么是训练时的超参数和生产环境不一致,要么是环境库版本对不上。嗯,说实话,这些问题其实都可以通过一个简单的参数锁文件来避免。

我的建议:从项目第一天就建立参数版本管理习惯。不要等到跑出好结果了再回头去记参数。那个时刻你大概率已经记不全了。边跑边记,用版本控制工具把参数锁定,这才是专业做法。

一把锁住三类参数,你的训练才真正有了“根”。以后不管是谁、在什么机器上、什么时间点,都能原封不动地复现你的实验。