All systems operationalAI Agent Automation Platform
English
Language简体中文EnglishSelected

Choose your language

ChatLM-mini-Chinese

charent/ChatLM-mini-Chinese

Publishercharent

Download access requirementsModelScope source

中文对话0.2B小模型 ChatLM-Chinese-0.2B 最新的readme文档请移步Github仓库ChatLM-mini-Chinese 现在的大语言模型的参数往往较大,消费级电脑单纯做推理都比较慢,更别说想自己从头开始训练一个模型了。本项目的目标是从0开始训练一个生成式语言模型,包括数据清洗、tokenizer训练、模型预训练、SFT指令微调、RLHF优化等。

Text Chat
Model details

模型介绍

中文整理

中文对话0.2B小模型 ChatLM-Chinese-0.2B

中文 English

最新的readme文档请移步Github仓库ChatLM-mini-Chinese

一、👋介绍

现在的大语言模型的参数往往较大,消费级电脑单纯做推理都比较慢,更别说想自己从头开始训练一个模型了。本项目的目标是从0开始训练一个生成式语言模型,包括数据清洗、tokenizer训练、模型预训练、SFT指令微调、RLHF优化等。

ChatLM-mini-Chinese为中文对话小模型,模型参数只有0.2B(算共享权重约210M),可以在最低4GB显存的机器进行预训练( batch size=1 , fp16 或者 bf16 ), float16 加载、推理最少只需要512MB显存。

公开所有预训练、SFT指令微调、DPO偏好优化数据集来源。

使用 Huggingface NLP框架,包括 transformers 、 accelerate 、 trl 、 peft 等。

自实现 trainer ,支持单机单卡、单机多卡进行预训练、SFT微调。训练过程中支持在任意位置停止,及在任意位置继续训练。

预训练:整合为端到端的 Text-to-Text 预训练,非 mask 掩码预测预训练。

  • 开源所有数据清洗(如规范化、基于mini hash的文档去重等)、数据集构造、数据集加载优化等流程;
  • tokenizer多进程词频统计,支持 sentencepiece 、 huggingface tokenizers 的tokenizer训练;
  • 预训练支持任意位置断点,可从断点处继续训练;
  • 大数据集(GB级别)流式加载、支持缓冲区数据打乱,不利用内存、硬盘作为缓存,有效减少内存、磁盘占用。配置 batch size=1, max len=320 下,最低支持在16GB内存+4GB显存的机器上进行预训练;
  • 训练日志记录。

SFT微调:开源SFT数据集及数据处理过程。

  • 自实现 trainer 支持prompt指令微调, 支持任意断点继续训练;
  • 支持 Huggingface trainer 的 sequence to sequence 微调;
  • 支持传统的低学习率,只训练decoder层的微调。

RLHF偏好优化:使用DPO进行全量偏好优化。

  • 支持使用 peft lora 进行偏好优化;
  • 支持模型合并,可将 Lora adapter 合并到原始模型中。

支持下游任务微调:finetune examples给出**三元组信息抽取任务**的微调示例,微调后的模型对话能力仍在。

如果需要做基于小模型的检索增强生成(RAG),可以参考我的另一个项目Phi2-mini-Chinese,代码见rag with langchain.ipynb

🟢**最近更新**

2024-01-30

模型文件更新到魔搭modelscope,可以通过 snapshot download 快速下载。

2024-01-07

添加数据清洗过程中基于mini hash实现的文档去重(在本项目中其实是数据集的样本去重),防止模型遇到多次重复数据后,在推理时吐出训练数据。

添加 DropDatasetDuplicate 类实现对大数据集的文档去重。

2023-12-29

更新模型代码(权重不变),可以直接使用 AutoModelForSeq2SeqLM.from pretrained(...) 加载模型使用。

更新readme文档。

2023-12-18

补充利用 ChatLM-mini-0.2B 模型微调下游三元组信息抽取任务代码及抽取效果展示 。

更新readme文档。

2023-12-14

更新SFT、DPO后的模型权重文件。

更新预训练、SFT及DPO脚本。

更新 tokenizer 为 PreTrainedTokenizerFast 。

重构 dataset 代码,支持动态最大长度,每个批次的最大长度由该批次的最长文本决定,节省显存。

补充 tokenizer 训练细节。

2023-12-04

更新 generate 参数及模型效果展示。

更新readme文档。

2023-11-28

更新dpo训练代码及模型权重。

2023-10-19

项目开源, 开放模型权重供下载。

二、🛠️ChatLM-0.2B-Chinese模型训练过程

  • 1 预训练数据集

所有数据集均来自互联网公开的**单轮对话**数据集,经过数据清洗、格式化后保存为parquet文件。数据处理过程见 utils/raw data process.py 。主要数据集包括:

  • 社区问答json版webtext2019zh-大规模高质量数据集,见:nlp chinese corpus。共410万,清洗后剩余260万。
  • baike qa2019百科类问答,见:,共140万,清醒后剩余130万。
  • 中国医药领域问答数据集,见:Chinese-medical-dialogue-data,共79万,清洗后剩余79万。
  • ~~金融行业问答数据,见:,共77万,清洗后剩余52万。~~**数据质量太差,未采用。**
  • 知乎问答数据,见:Zhihu-KOL,共100万行,清洗后剩余97万行。
  • belle开源的指令训练数据,介绍:BELLE,下载:BelleGroup,仅选取 Belle open source 1M 、 train 2M CN 、及 train 3.5M CN 中部分回答较短、不含复杂表格结构、翻译任务(没做英文词表)的数据,共370万行,清洗后剩余338万行。
  • 维基百科(Wikipedia)词条数据,将词条拼凑为提示语,百科的前 N 个词为回答,使用 202309 的百科数据,清洗后剩余119万的词条提示语和回答。Wiki下载:zhwiki,将下载的bz2文件转换为wiki.txt参考:WikiExtractor。

数据集总数量1023万:Text-to-Text预训练集:930万,评估集:2.5万(因为解码较慢,所以没有把评估集设置太大)。~~测试集:90万。~~

SFT微调和DPO优化数据集见下文。

  • 2 模型

T5模型(Text-to-Text Transfer Transformer),详情见论文: Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer。

模型源码来自huggingface,见:T5ForConditionalGeneration。

模型配置见model config.json,官方的 T5-base : encoder layer 和 decoder layer 均为为12层,本项目这两个参数修改为10层。

模型参数:0.2B。词表大小:29298,仅包含中文和少量英文。

  • 3 训练过程

硬件:

  • **tokenizer 训练**: 现有 tokenizer 训练库遇到大语料时存在OOM问题,故全量语料按照类似 BPE 的方法根据词频合并、构造词库,运行耗时半天。
  • **Text-to-Text 预训练**:学习率为 1e-4 到 5e-3 的动态学习率,预训练时间为8天。训练损失:
  • **prompt监督微调(SFT)**:使用 belle 指令训练数据集(指令和回答长度都在512以下),学习率为 1e-7 到 5e-5 的动态学习率,微调时间2天。微调损失:
  • **dpo直接偏好优化(RLHF)**:数据集alpaca-gpt4-data-zh作为 chosen 文本,步骤 2 中SFT模型对数据集中的prompt做批量 generate ,得到 rejected 文本,耗时1天,dpo全量偏好优化,学习率 le-5 ,半精度 fp16 ,共 2 个 epoch ,耗时3h。dpo损失:
  • 4 对话效果展示
  • 4.1 stream chat

默认使用 huggingface transformers 的 TextIteratorStreamer 实现流式对话,只支持 greedy search ,如果需要 beam sample 等其他生成方式,请将 cli demo.py 的 stream chat 参数修改为 False 。

  • 4.2 对话展示

存在问题:预训练数据集只有900多万,模型参数也仅0.2B,不能涵盖所有方面,会有答非所问、废话生成器的情况。

三、📑使用说明

  • 1 快速开始:

如果无法连接huggingface,请使用 modelscope.snapshot download 从modelscope下载模型文件。

  • 2 从克隆仓库代码开始

[!CAUTION]

本项目模型为 TextToText 模型,在预训练、SFT、RLFH阶段的 prompt 、 response 等字段,请务必加上 [EOS] 序列结束标记。

  • 2.1 克隆项目:
  • 2.2 安装依赖

本项目推荐使用 python 3.10 ,过老的python版本可能不兼容所依赖的第三方库。

pip安装:

如果pip安装了CPU版本的pytorch,可以通过下面的命令安装CUDA版本的pytorch:

conda安装:

  • 2.3 下载预训练模型及模型配置文件

用 git 命令从 Hugging Face Hub 下载模型权重及配置文件,需要先安装Git LFS,然后运行:

也可以直接从 Hugging Face Hub 仓库ChatLM-Chinese-0.2B手工下载,将下载的文件移动到 model save 目录下即可。

  • 3 Tokenizer训练

原本打算直接用现成的 tokenizer 库训练的(如 sentencepiece ),但是数据集一大就容易OOM。另外预训练数据集各个领域的语料不平衡,会产生很多不必要的合并。最后使用 jieba 分词对所有的预训练语料切词后统计词频,只保留出现1500次以上的字、词,参照 PreTrainedTokenizerFast 的 BPE model 的保存格式,构造 tokenzier ,最后转换为 PreTrainedTokenizerFast 。核心代码如下,详细的处理过程见 utils/train tokenizer.py 。

该方法不是严谨的merge方法,忽略了词频信息及有不该合并的词也合并了,是针对小于16G机器的折中办法,如果要做预训练,建议使用 train tokenizer.ipynb 的代码重新训练。**

本项目还提供了使用预训练模型自带的 tokenizer 根据自己的语料重新训练 tokenizer 的例子,见 train tokenizer.ipynb 。注意,重新训练 tokenizer 后,预训练模型的权重将无法使用,需要重新训练模型权重,因为 token 对应的 id 变了。

  • 4 Text-to-Text 预训练
  • 预训练数据集示例
  • jupyter-lab 或者 jupyter notebook:

见文件 train.ipynb ,推荐使用jupyter-lab,避免考虑与服务器断开后终端进程被杀的情况。

  • 控制台:

控制台训练需要考虑连接断开后进程被杀的,推荐使用进程守护工具 Supervisor 或者 screen 建立连接会话。

首先要配置 accelerate ,执行以下命令, 根据提示选择即可,参考 accelerate.yaml ,*注意:DeepSpeed在Windows安装比较麻烦*。

开始训练,如果要使用工程提供的配置请在下面的命令 accelerate launch 后加上参数 --config file ./accelerate.yaml ,*该配置按照单机2xGPU配置。*

  • 预训练有两个脚本,本项目实现的trainer对应 train.py ,huggingface实现的trainer对应 pre train.py ,用哪个都可以,效果一致。本项目实现的trainer训练信息展示更美观、更容易修改训练细节(如损失函数,日志记录等),均支持断点继续训练,本项目实现的trainer支持在任意位置断点后继续训练,按 ctrl+c 退出脚本时会保存断点信息。*

单机单卡:

单机多卡:

2 为显卡数量,请根据自己的实际情况修改。

从断点处继续训练:

  • 5 SFT微调

SFT数据集全部来自BELLE大佬的贡献,感谢。SFT数据集分别为:generated chat 0.4M、train 0.5M CN和train 2M CN,清洗后剩余约137万行。

sft指令微调数据集示例:

参考 data 目录下的示例 parquet 文件制作自己的数据集,数据集格式: parquet 文件分两列,一列 prompt 文本,表示提示语,一列 response 文本,表示期待的模型输出。

微调细节见 model/trainer.py 下的 train 方法, is finetune 设置为 True 时,将进行微调,微调默认会冻结embedding层和encoder层,只训练decoder层。如需要冻结其他参数,请自行调整代码。

运行SFT微调:

  • 6 RLHF(强化学习人类反馈优化方法)

偏好方法这里介绍常见的两种:PPO和DPO,具体实现请自行搜索论文及博客。

  • PPO方法(近似偏好优化,Proximal Policy Optimization)

步骤1:使用微调数据集做有监督微调(SFT, Supervised Finetuning)。

步骤2:使用偏好数据集(一个prompt至少包含2个回复,一个想要的回复,一个不想要的回复。多个回复可以按照分数排序,最想要的分数最高)训练奖励模型(RM, Reward Model)。可使用 peft 库快速搭建Lora奖励模型。

步骤3:利用RM对SFT模型进行有监督PPO训练,使得模型满足偏好。

  • 使用DPO(直接偏好优化,Direct Preference Optimization)微调(**本项目采用DPO微调方法,比较节省显存**)

在获得SFT模型的基础上,无需训练奖励模型,取得正向回答(chosen)和负向回答(rejected)即可开始微调。微调的 chosen 文本来自原数据集alpaca-gpt4-data-zh,拒绝文本 rejected 来自SFT微调1个epoch后的模型输出,另外两个数据集:huozi rlhf data json和rlhf-reward-single-round-trans chinese,合并后共8万条dpo数据。

dpo数据集处理过程见 utils/dpo data process.py 。

DPO偏好优化数据集示例:

运行偏好优化:

  • 7 推理

确保 model save 目录下有以下文件,这些文件都可以在 Hugging Face Hub 仓库ChatLM-Chinese-0.2B中找到:

  • 控制台运行:
  • API调用

API调用示例:

  • 8 下游任务微调

这里以文本中三元组信息为例,做下游微调。该任务的传统深度学习抽取方法见仓库pytorch IE model。抽取出一段文本中所有的三元组,如句子 《写生随笔》是冶金工业2006年出版的图书,作者是张来亮 ,抽取出三元组 (写生随笔,作者,张来亮) 和 (写生随笔,出版社,冶金工业) 。

原始数据集为:百度三元组抽取数据集。加工得到的微调数据集格式示例:

可以直接使用 sft train.py 脚本进行微调,脚本finetune IE task.ipynb里面包含详细的解码过程。训练数据集约 17000 条,学习率 5e-5 ,训练epoch 5 。微调后其他任务的对话能力也没有消失。

微调效果:

将 百度三元组抽取数据集 公开的 dev 数据集作为测试集,对比传统方法pytorch IE model。

模型 F1分数 精确率P 召回率R

:--- :----: :---: :---:

ChatLM-Chinese-0.2B微调 0.74 0.75 0.73

ChatLM-Chinese-0.2B无预训练 0.51 0.53 0.49

传统深度学习方法 0.80 0.79 80.1

备注: ChatLM-Chinese-0.2B无预训练 指直接初始化随机参数,开始训练,学习率 1e-4 ,其他参数和微调一致。

四、🎓引用

如果你觉得本项目对你有所帮助,欢迎引用。

五、🤔其他事项

本项目不承担开源模型和代码导致的数据安全、舆情风险或发生任何模型被误导、滥用、传播、不当利用而产生的风险和责任。

优先采用原作者提供的中文模型卡片;仅有英文说明时由闲社AI翻译整理。重要参数、许可证和商用范围请以原文为准。

你将获得什么

完整仓库方式包含该固定版本中的权重、配置、分词器及说明文件;指定版本方式只下载所选文件或整组分片。多模态模型的投影文件、配置等依赖,请按作者说明配齐。

完整仓库可能包含多个权重格式,因此需要的磁盘空间可能大于单一格式的模型大小。下载文件不等于完成模型部署。

使用前须知

运行环境

运行模型需要的设备、工具与依赖,以原作者说明为准。

授权范围

是否允许商用、修改和分发,请查看模型许可证。

闲社提供资料与镜像下载方法,不代表已运行模型或完成安全审计。下载的代码应先检查,再执行。

Back to top