多功能大语言模型训练测试工具包
llms_tool是一个基于HuggingFace的大语言模型工具包,支持多种模型的训练、测试和部署。它提供预训练、指令微调、奖励模型训练和RLHF等功能,支持全参数和低参数量训练。工具包集成WebUI和终端预测界面,以及DeepSpeed分布式训练。涵盖ChatGLM、LLaMA、Bloom等主流模型,提供多种训练方法和量化选项。
这是一个基于🤗HuggingFace开发的大语言模型训练和测试工具。它支持不同模型的网页界面和终端预测,支持各种模型的低参数量及全参数模型的预训练、奖励模型训练以及RLHF训练(包括PPO和DPO两种方法)。同时还支持deepspeed分布式训练。
作者习惯于将配置和任务都写在一个配置文件中,然后以一个主函数作为入口直接运行,因此才有了这个项目。喜欢使用命令行的朋友们可以将其改回去使用。
日期 | 详情 |
---|---|
2023-10-30 | 通过attention_sinks支持StreamingLLM |
2023-10-25 | 基于sentencepiece实现词表扩充功能 |
2023-10-24 | 支持使用NEFTune对LLM进行噪声调优 |
2023-10-09 | 增加扩充词表后Embedding初始化方式 |
2023-10-08 | LLama和Falcon两类模型支持Flash Attention2 |
2023-09-26 | 支持模型预训练 |
2023-09-11 | 集成多轮对话的Firefly的loss训练函数 |
2023-09-04 | 支持部分可以从配置修改使用NTK的模型 |
2023-08-24 | 支持deepspeed-ZeRo2分布式训练 |
2023-08-23 | RLHF的DPO方法对各个模型的训练支持 |
2023-08-21 | RLHF的PPO方法对各个模型的训练支持 |
2023-08-08 | 奖励模型训练 |
2023-07-25 | 初始仓库 |
几个重要的环境要求:
其它环境要求请参见requirements.txt 目前FlashAttention的作者未主动兼容和测试Windows操作环境问题,若在Windows上使用,则不需要安装flash-attn这个包。
大模型经过SFT(然后进行RLHF)之后可用于对话任务Chat。面世的Chat大部分都没有重新训练基座,或者是基于同样的基座结构用数据重新预训练了一个基座。下表列出了经过验证并被此项目支持的基座模型,相应地也支持同样结构的衍生和Chat模型。
模型 | 规模 | 系列 |
---|---|---|
ChatGLM1 | 6B | chatglm1 |
ChatGLM2 | 6B | chatglm2 |
ChatGLM3 | 6B | chatglm3 |
Qwen | 1.8B、7B、14B | Qwen |
Bloom | 560M、9B、7B1M | bloom、bloomz |
LLama1 | 3B、7B、13B | openllama、chinese-alpaca、ziya |
LLama2 | 7B、13B | llama2、orca-2 |
Baichuan | 7B、13B | baichuan |
Baichuan2 | 7B、13B | baichuan2 |
Falcon | 7B | falcon、Orca-2 |
Aquila | 7B | aquila |
Aquila2 | 7B | aquila |
InternLM | 7B、20B | internlm |
MOSS | 16B | MOSS |
XVERSE | 13B | XVERSE |
Mistral | 7B | Mistral |
Yi | 6B | Yi |
由于许多训练者都是基于上述基础模型或对话模型进行进一步训练,但他们采用了不同的模板提示词,因此在下载相关模型后,需要根据这些模型的要求添加与之匹配的模板提示词。除了加载这些模型官方要求的模板提示词外,本项目还提供了一些模板提示词,如ziya、openbuddy等的模板。
模板提示词 | 网站 |
---|---|
chatglm | chatglm2 |
chatglm3 | chatglm3 |
alpaca | Chinese-LLaMA-Alpaca |
vicuna | Chinese-Vicuna |
belle | BELLE |
ziya | Ziya |
aquila | AquilaChat |
firefly | Firefly |
openbuddy | OpenBuddy |
internlm | Internlm |
baichuan | Baichuan |
baichuan2 | Baichuan2 |
qwen | Qwen |
moss | MOSS |
linksoul | LinkSoul |
xverse | XVERSE |
tigerbot | TigerBot |
flagalpha | FlagAlpha |
orca-2 | Orca-2 |
yi | yi |
方法 | 是否支持 |
---|---|
全参数训练 | ✅ |
Lora | ✅ |
AdaLora | ✅ |
QLora | ✅ |
提示词微调 | ✅ |
P-tuning | ✅ |
前缀微调 | ✅ |
quantization: Optional[str] = field(
default='bnb',
metadata={
# 如果使用qlora只能选择bnb,两种量化方式区别不大。
'help': '要使用的具体模型版本(可以是分支名、标签名或提交ID)。',
'choices': ['cpm', 'bnb'],
}
)
quantization_bit: Optional[int] = field(
default=None,
metadata={
# 使用8位量化还是4位量化?
'help': '量化模型的位数。',
'choices': [4, 8],
}
)
两种量化方式分别是基于bitsandbytes的bnb和基于cpm_kernels组件的cpm,其中cpm量化脚本来自quantization.py。
在不同的训练阶段运行测试集时,会输出以下一些常规的生成模型评估结果。这些结果仅供参考,目前对大模型的事实性评估没有更好的方法,各个模型提供方或评测机构都是在各个维度上制作数据集进行评测,相对比较主观。
指标 | 是否支持 | 训练阶段 |
---|---|---|
Rouge-1 | ✅ | SFT训练 |
Rouge-2 | ✅ | SFT训练 |
Rouge-l | ✅ | SFT训练 |
ppl | ✅ | 预训练、SFT训练 |
accuracy | ✅ | PPO-RM训练 |
在开始之前,需要确定要实验的模型,并从Hugging Face上下载整个模型文件,完成以下两步:
model_type: str = field(
default='internlm',
metadata={
# 模型类型
'help': '模型类型。',
'choices': ['chatglm', 'qwen', 'llama', 'falcon', 'baichuan', 'aquila', 'internlm', 'moss', 'bloom', 'rwkv'],
}
)
model_path: str = field(
default='/home/XXXXX/llm_models/internLM/intern-chat-7b',
metadata={
# 从huggingface.co/models上下载的模型保存到本地的路径。
'help': '预训练模型的本地路径或huggingface.co/models上的模型标识符。'
}
)
checkpoint_dir: Optional[str] = field(
default=None,
metadata={
# 保存下载的或者自己训练的adapter增量模型的地方。
'help': '自动保存(增量)模型检查点以及配置的路径。',
}
)
prompt_template: Optional[str] = field(
default='internlm',
metadata={
# 选择对应模型的模板prompt,一般Chat模型的出品方都会有一个固定的prompt。
'help': '用于在训练和推理中构建提示的模板。'
}
)
这里提供两种预测方式,分别是基于Gradio的WebUI预测和终端预测。需要在config.py中相应地修改mode,然后运行main.py。
模式 | 推理类型 |
---|---|
web_inference | WebUI |
terminal_inference | 终端 |
目前原生配置就能支持NTK方法的有chatglm2-6b-32k、LLama系列、Falcon系列和Qwen-7B-Chat:
模型 | 位置编码器 | 支持的NTK类型 |
---|---|---|
chatglm2-6b-32k | Rope | Linear |
Qwen-7B-Chat | Rope | Dynamic |
LLama系列 | Rope | Dynamic、Linear |
Falcon系列 | Rope | Dynamic、Linear |
预训练数据参考datasets/pretrain/example/train下的文件,数据以txt格式存储。制作数据集时最好能与示例类似,每行一句话,但不要超过模型接收的最大token长度。然后将数据路径填写到DataTrainingArguments配置中:
train_file_dir: Optional[str] = field(
default='datasets/pretrain/example/train',
metadata={
# 训练集保存路径。
'help': '训练json数据文件夹。'
}
)
validation_file_dir: Optional[str] = field(
default='datasets/pretrain/example/train',
metadata={
# 验证集保存路径。
'help': '评估json文件夹。'
}
)
开始训练时,需要在config.py中将mode改为pretrain,然后运行main.py。
指令微调数据参考datasets/finetune/example/train下的文件,数据由instruction、input、output和history四个字段组成。
[
{
"instruction": "10乘以10等于多少?",
"input": "",
"output": "10乘以10等于100。",
"history": [
"你好呀。",
"你好,请问您有什么需要帮助的吗?",
"好的,我想问下你是谁?",
"我是一个AI模型,能够解决你提出的问题。"
]
},
...
]
如上所示,history字段需要按一问一答的格式存储对话历史,用于模型训练。如果没有历史对话,history应为空列表:
[
{
"instruction": "你身份是什么?",
"input": "",
"output": "我是一个AI智能助手,由XX公司训练,我将力所能及的帮助你解决问题。",
"history": []
},
...
]
使用时将数据路径填写到DataTrainingArguments配置中:
train_file_dir: Optional[str] = field(
default='datasets/finetune/example/train',
metadata={
# 训练集保存路径。
'help': '训练json数据文件夹。'
}
)
validation_file_dir: Optional[str] = field(
default='datasets/finetune/example/eval',
metadata={
# 验证集保存路径。
'help': '评估json文件夹。'
}
)
开始训练时,需要在config.py中将mode改为sft_train,然后在TrainingArguments中配置好各项训练参数,运行main.py。
框架支持测试SFT训练效果。测试前在DataTrainingArguments中配置test_file为测试数据集路径,然后在config.py中将mode改为sft_batch_test,运行main.py。
test_file: Optional[str] = field(
default='datasets/finetune/test',
metadata={
# 测试集保存路径。
'help': '测试文件。'
}
)
奖励模型训练数据参考datasets/rm/example/train下的文件,数据由instruction、input、output三个字段组成。output是一个两元素列表,第一个元素是采纳的答案,第二个是拒绝的答案。使用时将训练奖励模型的数据同样填写到DataTrainingArguments配置中。然后需要在config.py中将mode改为rm_train,在TrainingArguments中配置好各项训练参数,运行main.py。
train_file_dir: Optional[str] = field(
default='datasets/rm/example/train',
metadata={
# 训练集保存路径。
'help': '训练json数据文件夹。'
}
)
validation_file_dir: Optional[str] = field(
default='datasets/rm/example/eval',
metadata={
# 验证集保存路径。
'help': '评估json文件夹。'
}
)
框架支持测试奖励模型训练效果。首先需要在DataTrainingArguments中配置test_file为测试数据集路径,然后在config.py中将mode改为rm_batch_test,运行main.py。奖励模型测试只会输出模型的准确率。
在进行基于PPO模型的RLHF训练之前,需要一个奖励模型和一个需要被RLHF微调的SFT模型,需要把它们配置到ModelArguments中如下:
checkpoint_dir: Optional[str] = field(
default='checkpoint/sft',
metadata={
# 保存下载的或者自己训练的adapter增量模型的地方,在RLHF时候,此处需要填写指令微调后模型所在的文件地址。
'help': '自动保存(增量)模型检查点和配置的路径。',
}
)
reward_model_checkpoint: str = field(
default='checkpoint/rm',
metadata={
# 在RLHF时候,此处需要填写奖励模型所在的文件地址
'帮助': '奖励模型的检查点。'
}
)
PPO方法对模型进行强化学习训练的数据和SFT阶段训练的数据的格式是一致的,此外使用的时候还需要在TrainingArguments中把PPO的配置 填写好,在config.py中将mode修改为ppo_train,然后运行main.py。训练的结果将会通过wandb的格式记录在训练输出的文件夹中。
在进行基于DPO模型的RLHF训练之前,只需要一个被RLHF微调的SFT模型,如果是基于adapter的模型还需要把adapter配置到ModelArguments中如下:
model_path: str = field(
default='/home/XXX/ChatGLM/ChatGLM2-6B-32k',
metadata={
# 从huggingface.co/models上下载的模型保存到本地的路径或者自己的模型。
'help': '从huggingface.co/models下载的预训练模型的本地路径或模型标识符。'
}
)
checkpoint_dir: Optional[str] = field(
default='checkpoint/sft',
metadata={
# 保存下载的或者自己训练的adapter增量模型的地方,在RLHF时候,此处需要填写指令微调后模型所在的文件地址。
'help': '自动保存(增量)模型检查点和配置的路径。',
}
)
DPO方法对模型进行强化学习训练的数据和奖励模型的数据是一致的,在config.py中将mode修改为dpo_train,然后运行main.py。训练的结果将会通过wandb的格式记录在训练输出的文件夹中。
常用的一些参数如下:
参数 | 描述 |
---|---|
fine_tuning_type | 训练方式 |
use_firefly_loss | 使用Firefly loss训练模型 |
output_dir | 训练结果输出的文件夹 |
num_train_epochs | 训练的轮次 |
gradient_accumulation_steps |