-
Notifications
You must be signed in to change notification settings - Fork 422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
不是Issue,一点个人训练minimind的记录 #26
Comments
这个效果的话,一个是26M规模有些小,再一个sft跑到5轮以后会好点,现在的瞎编现象比较严重。 谢谢你的分享,非常详细,比我写的清晰很多hhhh 中秋节快乐!!!✨ |
记录的很好! 可以发个教程了。 |
赞!学习了! |
谢谢大佬,十分具有参考意义,新建环境也遇到了大佬们遇到的坑,flash-attn真的难装啊,https://github.com/bdashore3/flash-attention后面是通过这里下载安装才行,windows系统 |
感谢大佬分享 |
项目文件说明
imagesReadme里的图片目录。 model模型文件夹。 model/minimind_tokenizer项目自定义的Tokenizer模型文件。
注:分词器训练代码可见 model/dataset.py数据集定义文件,该文件定义了两个继承自Dataset的数据集类,分别是 PretrainDataset 和 SFTDataset,它们分别用于预训练任务和微调任务的数据加载和处理。 model/LMConfig.py模型配置文件,定义 LMConfig 类,继承自 PretrainedConfig。如果想修改模型参数,可以在这个文件里改。 主要包括如下内容:
以下是 MOE(Mixture of Experts)的特定配置当 use_moe 为 False 时,以下配置无效
model/model.py模型文件,定义了模型结构,包括多个子模块如 FeedForward、RMSNorm、MoEGate、MOEFeedForward、TransformerBlock 等,实现了前向传播计算、损失函数计算和通过逐步生成方式进行文本生成。 主要内容总结:
主要功能:
0-eval_pretrain.py测试预训练模型的接龙效果。 1-pretrain.py功能概述预训练脚本,执行预训练。 使用、配置及功能说明以下是该脚本的使用、配置和功能说明: 单机多卡使用
参数配置
数据加载
训练循环
模型的保存频率在训练过程中,模型的权重会每迭代1000步保存一次模型,以便后续检查点或恢复训练。 使用已有权重再训练的说明如果你已经有一个预训练模型的权重文件(例如
注意,这部分是脚本中是注释掉的。 如果你想用已有权重继续训练,需要在脚本中找到上述代码,解除注释,才能使用现有的模型进行训练。 2-eval.py测试模型的对话效果。通过加载预训练后的模型,并让模型来回答内置在脚本中的一系列问题,以评估模型的对话效果。 ckp = f'./out/full_sft_{lm_config.dim}{moe_path}.pth' 其中 3-full_sft.py执行指令微调训练 配置参数代码中可以配置的参数有:
然后按Readme的描述运行脚本即可。 4-lora_sft.py执行lora微调训练 5-dpo_train.py执行DPO训练 chat_openai_api.py实现与OpenAI API类似的接口 CODE_OF_CONDUCT.md贡献者公约 data_process.py处理数据集,例如pretrain数据提前进行token-encoder、sft数据集抽离qa到csv文件 eval_ceval.py评估模型在ceval数据集上的表现 export_model.py可以导出模型到transformers格式,推送到huggingface。 fast_infenence.py使用 Streamlit 框架构建的交互式聊天应用程序,主要内容和功能的概述如下:
实现的功能
LICENSE项目使用Apache License许可证。 my_openai_api.py使用Flask框架构建的API服务器,用于处理与聊天模型相关的请求,包括生成聊天响应和计算文本的嵌入向量。 README_en.md项目说明文件(英语)。 README.md项目说明文件。 requirements.txtpython环境依赖文件,列出了运行该项目所需的Python包及其版本。 train_tokenizer.py用于分词器训练。 |
步骤2 数据集处理 |
@AirGHub 1-pretrain updated on 27th. |
请问一张4090能预训练嘛 |
可以,足够 |
|
请问最低配置是多少,游戏本32G内存,4060(8G)可以预训练吗? |
可以,但很慢,得耐心等了 |
minimind训练记录
0. 环境安装
conda新建的环境下,直接按照上面的命令安装时出现了两个问题,一个是
flash_attn==2.5.0
下载时依赖torch,一直报错,另一个是torch==2.1.2+cu121
没有找到该版本,只有torch==2.1.2
。第一个问题,可能是连接github时的网络问题,变成了编译安装。
所以先单独安装了torch,再安装的flash_attn。此时依然报错,调整网络环境后,直接pip安装成功。
第二个问题,直接
pip install torch==2.1.2
。1. 数据集下载
参考Readme,在项目根目录下新建了
dataset
文件夹,并从如下地址下载数据集到./dataset/
目录下:其中,
【tokenizer训练集】
、【Pretrain数据】
下载自百度网盘;【SFT数据】来自modelscope。【DPO数据1】
(huozi_rlhf_data.json)、【DPO数据2】
(test-00000-of-00001-8ecd46436fadcf7f.parquet、train-00000-of-00001-789dc5dece0f1fc1.parquet)来自hugginface(上不了hugginface,可以试试hf-mirror),放在了dataset\dpo
目录下。【Pretrain数据】
的百度网盘地址内容很全,包括如下文件:其中的tokenizer_train.jsonl文件与【tokenizer训练集】是同一个文件。
mobvoi_seq_monkey_general_open_corpus.zip是mobvoi_seq_monkey_general_open_corpus.jsonl的压缩文件。
【tokenizer训练集】
的HuggingFace地址下的内容跟【Pretrain数据】
百度网盘 的内容基本一致,跟【Pretrain数据】
的HuggingFace 地址是同一个。2. 数据集处理
按Readme中的步骤进行操作:
终端输出如下:
运行上述命令后,处理数据集,在
dataset
目录下生成了pretrain_data.bin
和clean_seq_monkey.bin
两个文件。经md5校验,这两个文件与【Pretrain数据】中的
pretrain_data_6400.bin
完全一致。md5sum dataset/*.bin
可见大佬已经把数据处理好并上传到百度网盘和HuggingFace了。
结合Readme的说明,可以得知pretrain_data_32000.bin是基于mistral tokenizer作为分词器预训练的,而pretrain_data_6400.bin(也是通过
python data_process.py
自己生成的pretrain_data.bin)是基于自定义Tokenizer模型(见model/minimind_tokenizer
)预训练的。3. 模型训练
训练环境:
Intel i9-13900k + 128G DDR5-4800 + NIVIDA RTX 4090 × 2,Driver Version: 550.54.14,CUDA Version: 12.4。
训练过程
预训练
按Readme中的说明,单机多卡训练可以使用deepspeed,但项目的requirements中并没有deepspeed。需要手动安装:
安装成功后,执行如下命令进行了单机多卡训练:
训练的同时开启nvidia-smi实时监控显卡资源占用情况:
单显卡显存占用量13000MiB左右,双卡共占用约26000MiB,两颗GPU占用均在99-100%。
通过
htop
监测CPU和内存占用情况,其中CPU有两个线程占用在100%左右,另有两个核心占用在22%左右,内存占用在6-7GB左右。Epoch0
第一个Epoch约用时1个小时左右。
loss值变化:
Epoch:[0/20]
0/23047, loss:8.867 ;
9400/23047,loss:2.853;
之后从2.8左右,缓慢下降至2.651。
Epoch1
第二个Epoch约用时1个小时左右。
loss值变化:
Epoch:[1/20]
(0/23047) loss:2.645;
(9500/23047) loss:2.557;
(19700/23047) loss:2.641
一直在2.5-2.7左右波动。
Epoch2
第三个Epoch没有训练完,强制结束了。
loss值变化:
在2.4-2.7左右波动。
Epoch:[2/20]
(0/23047) loss:2.533
(9500/23047) loss:2.483
结束前最后一个保存点:
Epoch:2/20 loss:2.572 lr:0.0000965 epoch_Time:29.0min:
单轮对话任务微调
采用sft_data_single.csv数据集进行任务微调。
刚开始遇到两处错误,一处是
NameError: name '加完班回到家窝在沙发里' is not defined
,经与大佬咨询,更用新代码跳过了个别这种所谓的“非法Python标识符的字符串”异常数据;另一处是TypeError: can only concatenate str (not "float") to str
,通过修改model/dataset.py
中SFTDataset
类的__getitem__
方法,强制转化为字符串,跑通了训练。详细情况可以见项目Issues预测微调训练的时间为98min,实际时间相当,与Readme中2个小时比较接近,但按Reame的说法,应该远远小于预训练才对,可能是用torchrun的性能发挥比不上deepspeed。
实际nvidia-smi监测显卡的情况,两个显卡显存占用均在17000MiB以上,GPU占用率87~93%,均未发挥到100%。
Epoch0
loss值变化:
初始迅速下降至2.6左右,然后继续缓慢下降,至第一个Epoch结束,loss下降至1.8~2.0。
Epoch1
第二个Epoch训练至第3000轮强制结束。
Epoch:1/19 loss:1.843 lr:0.00019871 epoch_Time:321.0min:
Epoch:1/19 loss:1.977 lr:0.00019870 epoch_Time:96.0min:
Epoch:1/19 loss:2.030 lr:0.00019869 epoch_Time:95.0min:
Epoch:1/19 loss:2.023 lr:0.00019868 epoch_Time:93.0min:
Epoch:1/19 loss:1.923 lr:0.00019867 epoch_Time:93.0min:
Epoch:1/19 loss:1.794 lr:0.00019866 epoch_Time:93.0min:
Epoch:1/19 loss:1.999 lr:0.00019864 epoch_Time:92.0min:
Epoch:1/19 loss:1.916 lr:0.00019863 epoch_Time:92.0min:
Epoch:1/19 loss:1.881 lr:0.00019862 epoch_Time:91.0min:
Epoch:1/19 loss:2.007 lr:0.00019861 epoch_Time:91.0min:
Epoch:1/19 loss:2.018 lr:0.00019860 epoch_Time:92.0min:
Epoch:1/19 loss:1.846 lr:0.00019859 epoch_Time:91.0min:
Epoch:1/19 loss:2.004 lr:0.00019858 epoch_Time:91.0min:
Epoch:1/19 loss:2.062 lr:0.00019857 epoch_Time:89.0min:
Epoch:1/19 loss:1.944 lr:0.00019856 epoch_Time:89.0min:
Epoch:1/19 loss:1.887 lr:0.00019855 epoch_Time:89.0min:
Epoch:1/19 loss:1.731 lr:0.00019854 epoch_Time:88.0min:
Epoch:1/19 loss:1.982 lr:0.00019852 epoch_Time:88.0min:
Epoch:1/19 loss:1.815 lr:0.00019851 epoch_Time:88.0min:
Epoch:1/19 loss:1.956 lr:0.00019850 epoch_Time:87.0min:
Epoch:1/19 loss:2.041 lr:0.00019849 epoch_Time:87.0min:
Epoch:1/19 loss:1.966 lr:0.00019848 epoch_Time:86.0min:
Epoch:1/19 loss:2.006 lr:0.00019847 epoch_Time:86.0min:
Epoch:1/19 loss:2.039 lr:0.00019846 epoch_Time:86.0min:
Epoch:1/19 loss:1.965 lr:0.00019845 epoch_Time:85.0min:
Epoch:1/19 loss:1.977 lr:0.00019843 epoch_Time:85.0min:
Epoch:1/19 loss:2.057 lr:0.00019842 epoch_Time:85.0min:
Epoch:1/19 loss:1.935 lr:0.00019841 epoch_Time:84.0min:
Epoch:1/19 loss:1.851 lr:0.00019840 epoch_Time:84.0min:
Epoch:1/19 loss:1.779 lr:0.00019839 epoch_Time:83.0min:
Epoch:1/19 loss:1.982 lr:0.00019838 epoch_Time:83.0min:
deepspeed任务微调
经测试,deepspeed单机多卡微调训练速度与torchrun相当,显卡资源占用率相当。
多轮对话任务微调
修改3-full_sft.py中第178行的csv文件路径,如下:
同时修改第93行,ckp的保存文件名,如下:
的在预训练的base模型上直接进行多轮对话任务微调。
训练一轮后强制结束
4.模型测试
因为测试脚本的
2-eval.py
里的ckp地址取的是./out/single_chat
下的模型,所以需要在out
下新建一个single_chat
文件夹,然后把生成的full_sft_512.pth文件移动进去。然后执行测试
结果有好有坏的,具体如下:
许是训练轮次不够的问题吧。
5.后记
多轮对话未见测试脚本,此处未做测试。
DPO训练还没有做,待中秋节后吧。
不过整个语言模型的预训练和任务微调的路线算是跑通了。
路漫漫其修远兮,吾将上下而求索。
最后特别感谢jingyaogong大佬!!!
中秋节快乐!!
The text was updated successfully, but these errors were encountered: