从头训练小模型: 预训练(Pretrain)
从头训练小模型: 预训练(Pretrain):
简介!
从头训练小模型是我个人对大语言模型(LLM)学习中的重要部分。
通过对一个小规模模型的最小化复现实践,我不仅能够深入理解模型训练的基本流程,还可以系统地学习其中的核心原理和实际运行机制。这种实践性的学习方法让我能够直观地感受模型训练的每个环节,同时掌握相关的技术细节和实现方式。
目前的工作中,确实存在某些任务是有这种小模型的需求, 也在学习过程中理解运作逻辑, 力求用最小的资源消耗情况下,实现某些子任务的最小模型实现.
ALL in AI
代码已经上传 https://github.com/godzeo/miniGPT
那么这个系列第一部就是 pretrain
预训练(Pretrain)
我理解训练模型的第一步就是学习知识。
LLM首先要学习的并非直接与人交流,就像学生需要先掌握基础知识一样,AI也需要大量"阅读"各种资料来学习。它会阅读维基百科、新闻和书籍,从中学习知识和规律。这个学习过程是自主的,不需要老师(人类)在旁边指导。
AI的主要任务很简单:学会"接下文"。比如当看到"天王盖地虎"时,它能自动接上"宝塔镇河妖"。这就像我们在玩接龙游戏一样,AI通过阅读大量文本来学会这种接龙能力。
小模型
那么对于小型语言模型,合理优化 tokenizer 很重要,但不仅仅是简单的"压缩"问题:
- 参数量与词表大小的平衡:小模型的参数量有限,过大的词表会占用太多参数在 token embedding 层上,tokenizer 影响整个训练过程和模型能力的上限
tokenizer 这部分内容需要进一步深入研究。我计划使用相同的数据集和模型架构,仅调整 tokenizer 的配置参数来对比效果。目前这块内容主要参考了前人的经验,后续需要更系统地学习
我一开始找了一个 6400 超小词表的训练,发现效果一般
我租了一个 4090 * 2 的来训练
torchrun --nproc_per_node=2 pretrain.py \--output_dir ../outputs/pretrain_full_test \--data_file /root/autodl-fs/data/pretrain_hq.jsonl \--tokenizer_path ../tokenizer \--batch_size 64 \--num_epochs 1 \--fp16
于是预算换了 mistralai_tokenizer 之后
4090 * 4 预训练 不到2小时
主要代码
https://github.com/godzeo/miniGPT/blob/main/scripts/pretrain.py
- 主要功能
- 加载预训练的tokenizer
- 创建或加载模型
- 准备预训练数据集
- 设置训练参数
- 创建Trainer并开始训练
- 支持断点续训和异常处理
重要训练参数说明
- 基础训练参数
batch_size
: 每个设备的训练批次大小, 就像厨师每次炒菜放的食材量。数字越大,每次处理的数据越多,主要是看显存,超过就直接就炸了.gradient_accumulation_steps
: 梯度累积步数,相当于分多次称重食材,最后一次性调整配方。当显存不足时,用这个方法模拟大锅炒菜的效果。num_epochs
: 训练轮数, 类似学生反复刷真题的次数。类似学生反复刷真题的次数。但要注意过多会导致死记硬背(过拟合),过少则学不会。learning_rate
: 学习率(模型学习时的步长调整参数)- (高学习率)容易漏学细节
- (低学习率)学得扎实但费时间
weight_decay
: 权重衰减,通过正则化来防止模型过拟合warmup_ratio
: 预热比例,让学习率从零开始逐步提升到设定值
上面是场景的训练参数, 目前只是理解其中含义, 但是实际效果应该怎么设置, 目前没有一个明确的值, 大多数都是实验之后才知道, 所以我目前都是使用一些默认的值, 直接使用前人总结的大多数较好的参数.
data_limit
: 用于限制训练数据量(测试数据的时候,少了测试跑通流程用的)
训练注意事项
- 断点续训
- 支持从checkpoint恢复训练
- 会自动检查checkpoint的完整性
- 训练中断时会自动保存当前状态
训练效果:
我们加载一下模型看一下这个效果, 现在这个模型是只会普通的成语接龙的,
一轮的结果
{‘train_runtime’: 6075.9813, ‘train_samples_per_second’: 232.572, ‘train_steps_per_second’: 0.227, ‘train_loss’: 3.2094810264697973, ‘epoch’: 1.0}
于是预算换了 mistralai_tokenizer 之后
4090 * 4 预训练 不到2小时
主要代码
https://github.com/godzeo/miniGPT/blob/main/scripts/pretrain.py
- 主要功能
- 加载预训练的tokenizer
- 创建或加载模型
- 准备预训练数据集
- 设置训练参数
- 创建Trainer并开始训练
- 支持断点续训和异常处理
重要训练参数说明
- 基础训练参数
batch_size
: 每个设备的训练批次大小, 就像厨师每次炒菜放的食材量。数字越大,每次处理的数据越多,主要是看显存,超过就直接就炸了.gradient_accumulation_steps
: 梯度累积步数,相当于分多次称重食材,最后一次性调整配方。当显存不足时,用这个方法模拟大锅炒菜的效果。num_epochs
: 训练轮数, 类似学生反复刷真题的次数。类似学生反复刷真题的次数。但要注意过多会导致死记硬背(过拟合),过少则学不会。learning_rate
: 学习率(模型学习时的步长调整参数)- (高学习率)容易漏学细节
- (低学习率)学得扎实但费时间
weight_decay
: 权重衰减,通过正则化来防止模型过拟合warmup_ratio
: 预热比例,让学习率从零开始逐步提升到设定值
上面是场景的训练参数, 目前只是理解其中含义, 但是实际效果应该怎么设置, 目前没有一个明确的值, 大多数都是实验之后才知道, 所以我目前都是使用一些默认的值, 直接使用前人总结的大多数较好的参数.
data_limit
: 用于限制训练数据量(测试数据的时候,少了测试跑通流程用的)
训练注意事项
- 断点续训
- 支持从checkpoint恢复训练
- 会自动检查checkpoint的完整性
- 训练中断时会自动保存当前状态
训练效果:
我们加载一下模型看一下这个效果, 现在这个模型是只会普通的成语接龙的,
一轮的结果
{‘train_runtime’: 6075.9813, ‘train_samples_per_second’: 232.572, ‘train_steps_per_second’: 0.227, ‘train_loss’: 3.2094810264697973, ‘epoch’: 1.0}