前言
经过前面的努力,已经完成了训练前的所有准备。回顾下我们的模型代码MiniLlmsModel.py,主要包括几个关键部分:
- Token Embedding:将输入的文字(Token ID)转换成模型能理解的高维向量。
- Positional Encoding:给每个词添加位置信息,让模型知道词语的先后顺序。
- Decoder Blocks:这是模型的核心,由多个“积木块”堆叠而成。每个积木块里都有两个大杀器:
- Causal Self-Attention:让模型在预测下一个词时,只关注前面已经出现过的词,防止“未卜先知”。
- Feed-Forward Network:一个简单的前馈网络,用来进一步处理信息。
- Output Layer:最后,将模型处理完的向量,映射回整个词汇表,得到每个词的概率分数。
整个结构就像一个高效的信息处理流水线,专门为生成文本而设计。
训练总结:一次分两步走的“炼丹之旅”
我们的训练脚本train_opt.py是整个过程的总指挥。这次,我们采用了两阶段训练的策略。第一阶段为0 ~ 12.5k步阶段,第二阶段为12.5k步之后。
阶段一:高歌猛进的“余弦退火” (0 ~ 12.5k 步)
在训练的初期,模型就像一个什么都不懂的学生,需要一位严厉又聪明的老师快速引导。这个老师,就是我们的学习率调度器。
第一阶段,我们使用了 余弦退火(Cosine Annealing) 策略。
看图说话:
上图的左半部分(0到约12.5k步)就是余弦退火学习率的变化曲线。它有几个特点:
- 热身(Warmup):刚开始,学习率从一个很小的值慢慢爬升到顶峰(5.0e-4)。这就像运动员赛前热身,让模型慢慢适应,防止一开始步子迈太大“扯着蛋”。
- 快速下降:达到峰值后,学习率像余弦函数一样平滑地下降,几乎降到了0。这就像老师在初期用很大的声音划重点,帮助学生快速掌握基础知识;随着学生水平提高,老师的声音也逐渐变小,让学生自己去领悟和微调。
那么,这个策略效果如何呢?我们来看损失(Loss)和困惑度(Perplexity)的变化。
看图说话:
- 训练/验证损失(Loss):可以看到,在这一阶段,无论是训练损失(上图,更抖动)还是验证损失(中图,更平滑),都出现了断崖式下降!这说明模型在大学习率的驱动下,正在疯狂地吸收知识,从一个随机网络迅速成长,学习到了语言的基本结构和模式。
- 困惑度(Perplexity):困惑度可以通俗地理解为模型对下一个词的“惊讶程度”,值越低越好。下图显示,困惑度也随之快速降低,证明模型预测下一个词的能力在飞速提升。
第一阶段非常成功!模型已经从“小白”变成了“初中生”。
阶段二:稳扎稳打的“精细打磨” (12.5k 步之后)
在模型掌握了基础知识后,再用很高的学习率可能会让它在最优解附近“反复横跳”,难以收敛到最佳点。因此,我从第12.5k步的checkpoint断点续训,并切换到了第二种策略:恒定低学习率。
看图说话:
- 回到学习率曲线图,在12.5k步的位置,学习率突然“跳”到了一个较低的恒定值(1.5e-4),并一直保持不变。
- 这就像把教学方式从“大声划重点”切换到了“小声辅导”。我们希望模型能在这个更小的学习率下,对知识进行精细的打磨和微调。
观察损失和困惑度曲线的后半段:
- 损失(Loss):下降趋势明显变缓了,但依然在持续、稳定地下降。这完全符合预期!这表明模型正在从“粗通”走向“精通”,在已经很低的基础上,一点点地优化自己,寻找更优的解。
- 困惑度(Perplexity):同样,困惑度的下降也变得平缓,但仍在稳步降低,最终达到了40以下。对于我们这个规模的迷你模型来说,这是一个还算过得去的成绩!
这次两阶段的训练策略,完美地展示了如何张弛有度地训练一个模型:先用大学习率快速收敛,再用小学习率精细调优。
学有所成:用best_model.pt来一次真正的“创作”
经过了漫长的训练和调优,我们得到了一个在验证集上表现最好的模型——best_model.pt。现在,是时候让它“毕业”并展示一下学习成果了!
我们给模型出了一道开放题:以“machine learning”作为开头,让它自由发挥,续写大约500个词。这就像是它的毕业论文答辩!
上图就是我们迷你模型的“答卷”。乍一看,非常惊艳!
- 流畅度和相关性:模型生成了一段非常流畅、语法通顺的英文。而且,内容紧紧围绕着“machine learning”展开,讨论了学术论文、研究方法、预测事件影响等话题,充满了“学术范儿”。这证明,我们的模型确实学到了语言的统计规律和特定文体(学术文章)的风格。
- 一本正经地“胡说八道”:仔细阅读你会发现,它提到的“芝加哥大学学生在《自然》杂志上发表的论文”、“耶鲁大学经济学院的首席研究员”等信息,全都是它自己编造的!这就是我们常说的“模型幻觉”。它并没有真正的知识和记忆,只是根据训练数据中学到的模式,生成了“看起来最像那么回事”的文本。它知道论文通常由某大学发表在某期刊,但具体是哪个,它只能靠统计概率去“猜”。
- 小瑕疵:在文本的最后,出现了一些重复性的短语,比如 "learning during learning during learning"。这是小模型在长文本生成中常见的问题,说明它在生成到后面时,可能会陷入某种局部模式,忘记了前面已经说过什么。
- 总结:这次推理还算是成功的!它证明了我们从零开始的训练是有效的,那些下降的损失曲线最终转化为了模型实实在在的生成能力。虽然它还远非完美,会“说谎”,会犯错,但这正是这类自回归语言模型的本质体现。
它不是一个知识库,而是一个能用的文本模式生成器。
总结:总结的几点启示
回顾这次完整的训练过程,我想和各位分享几点心得:
- 学习率是“炼丹”的灵魂:它不是一成不变的数字。通过精心设计的学习率策略(如热身、退火),我们可以更高效、更稳定地训练模型。
- 训练是迭代和调整的过程:对于我们的模型,训练了这么久,感觉一次性把所有参数设对几乎是不可能的。像我这次一样,分阶段训练、从断点恢复、调整超参数(比如学习率策略),不断的尝试都是模型训练的常态。
- 损失(Loss)和困惑度(Perplexity)是你的指南针:它们是衡量模型好坏最直接的量化标准。你的目标,就是想尽办法,让它们稳步下降。
- 我们当前的模型是“统计模仿家”,而非“事实查询机”:通过推理我们可以看到,我们的模型学会的是语言的模式,而不是事实。它会为了生成最“通顺”的句子而编造信息。
希望这篇训练日记能帮你拨开语言模型训练的迷雾,感受到其中的逻辑和乐趣。这只是一个开始,背后还有更广阔的世界等待我们去探索。
关注我的公众号不走丢
附录
GitHub链接:github.com/JimmysAIPG/…