Early Stopping 在大模型训练中还有用吗?数据量和参数量都很大时的策略

我第一次在BERT上跑微调,验证集在第三个epoch到92%,第四个epoch跌回91%。我立刻停了训练,把权重回滚到之前的最佳点——这是早停教给我的第一课。后来,我在8卡A100集群上预训练一个7B模型,盯着验证loss看了两天,它一路向下,没有拐点,没有回升。我甚至怀疑验证集是不是写错了。早停在大模型训练中难道失灵了?

AI technology illustration

先回到早停的逻辑:每训练几步,就在验证集上测一次性能;如果连续多轮没有提升(甚至开始下降),就停下来,用之前保存的最佳权重。它是个简单粗暴的正则化手段,核心在于防止模型在训练数据上“背答案”而失去泛化能力。

但在大模型预训练里,这个逻辑明显不太对。下面我说说原因。

预训练为什么等不到那个“过拟合拐点”?

第一,数据几乎没有机会被“背”第二遍。预训练语料动辄几千亿token,模型在一个epoch内已经遍历了海量数据,很少重复二次。当每个样本只被看到一次的时候,模型根本来不及记住它,训练loss和验证loss几乎同步下降,不存在经典的分叉曲线。

第二,当前普遍的观点是,大模型预训练的主要矛盾是欠拟合,而不是过拟合。《Scaling Laws for Neural Language Models》指出,模型性能随着参数量、数据量、计算量呈幂律增长。训练不足时,验证loss会一直高于应有水平,但不会出现U型回转。

第三,现代训练中真正控制收敛的是学习率调度,不是早停。以最常用的cosine schedule为例:训练前你就定了总步数,学习率从warmup后一路余弦衰减到0。最后的迭代步恰好对应最低验证loss。如果你在90%步数时早停,学习率还没来得及降到最低区间,模型不仅没有“预防过拟合”,反而变成了“欠拟合”。

但即使如此,仍有朋友说:我见过预训练时验证loss升上去啊。这种情况确实存在,尤其当数据被重复使用多次(multi-epoch)时。可是,DeepMind的Chinchilla论文发现,重复数据带来的收益非常低,最优做法是在固定计算预算下同时调整参数量和训练token数,而不是靠早停来把握时机。

Chinchilla:把“什么时候停”变成一个计算问题

Chinchilla有一个简洁的结论:对于固定总计算量,最优的训练token数大约为模型参数量的20倍。也就是说,7B模型在140B token附近就应该停下;LLaMA系列实际训练了1.4T token,是因为他们额外增加了数据量来换取推理性能,而非因为“验证集还在下降”。

Chinchilla不是简单拍脑袋,他们训练了70多个不同规模的语言模型,拟合出一个损失与参数量N和数据量D之间的幂律关系,然后求导得到给定算力下的最优分配。翻译成人话就是:你的预训练步数应该由算力和目标损失共同决定,而不是由一张浮动的验证曲线决定。

早停还会踩到“双重下降”的坑

另一个有意思的现象叫“双重下降”(double descent):随着模型规模或训练步数增加,模型先过拟合、后泛化,性能曲线会再次变好。如果沿用早停“验证集变差就停”的逻辑,你会在第一次峰值就撤了,错过后面更好的解。这个现象在深度学习中已被反复观察到。

所以我后来想通了:预训练里,我不再关心“要不要停”,我关心的是“我有多少算力、计划训练多少步、用什么调度、数据要不要重复”。早停在这里几乎无关。

微调场景里,早停依然是救命稻草

但如果你今天要在某个预训练模型上做下游任务,比如用一万条医疗QA微调一个7B模型,那我强烈建议你用早停。为什么?因为微调时数据集小,模型容量大,一个epoch后模型就开始“背”训练集了。不早停的话,验证集F1会像过山车一样往下掉。

Hugging Face的Trainer里就内置了EarlyStoppingCallback,常见做法是保存最佳checkpoint,设置patience为2或3轮。即使是LoRA这类参数高效微调,也逃不过早停——因为新增的那几个adapter权重同样会过拟合。别以为只训练几百个adapter参数就安全,它们依然能记住那几千条样本。

早停的适用边界:一张表说清

场景 早停有用? 推荐策略
小型模型,中等数据量(经典ML) 非常有用 验证集监控 + patience
大型模型,从零预训练 基本无用 计算预算 + cosine调度 + scaling law
预训练模型在下游任务微调 非常有用 early stopping + 保存最佳checkpoint
大规模分布式训练,周期性评估 需谨慎 固定步数,恢复时用完整状态,避免中途停止

FAQ:关于早停和预训练的常见疑问

我的预训练验证loss一直在降,是不是应该无限训练下去?
不是。如果数据只过一次,loss会在某个点收敛,但之后继续过数据,迟早进入过拟合。更合理的方式是用scaling law估算所需步数,然后按计划训练。
早停能避免训练崩溃(loss spike)吗?
不能。loss spike一般是优化问题,比如学习率过大、数据异常。你需要的操作是降低学习率并回滚,不是“停”。
微调时用了早停,为什么效果反而不稳定?
很可能是patience设置太小,验证集噪声导致误停。建议每次评估后保存最佳状态,而不是一有下降就终止。

我最早觉得,早停是训练中万能的安全网,无论模型多大、数据多少,看着验证集总没错。直到自己跑过一次真实预训练才发现,在几万步的过程里,验证loss的曲线几乎是一条单调下降的直线。所谓的“拐点”根本不存在。真正让我做出停止决定的,是预先制定的训练总步数和学习率计划。

所以,最后的建议是:预训练,请忘掉早停,用预算和调度来规划;微调,请继续依赖早停,它仍然是成本最低、效果最稳的正则化手段。理解这两者的区别,比机械地套用“要不要停”的直觉重要得多。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/517.html

(0)
上一篇 2天前
下一篇 2天前

相关推荐