文章目录
Baichuan-13B介绍
2023年7月11日,百川智能发布Baichuan-13B!
github地址:https://github.com/baichuan-inc/Baichuan-13B
Baichuan-13B特点
Baichuan-13B 是由百川智能继 Baichuan-7B 之后开发的包含 130 亿参数的开源可商用的大规模语言模型,在权威的中文和英文 benchmark 上均取得同尺寸最好的效果。本次发布包含有预训练 (Baichuan-13B-Base) 和对齐 (Baichuan-13B-Chat) 两个版本。Baichuan-13B 有如下几个特点:
- 更大尺寸、更多数据:Baichuan-13B 在 Baichuan-7B 的基础上进一步扩大参数量到 130 亿,并且在高质量的语料上训练了 1.4 万亿 tokens,超过 LLaMA-13B 40%,是当前开源 13B 尺寸下训练数据量最多的模型。支持中英双语,使用 ALiBi 位置编码,上下文窗口长度为 4096。
- 同时开源预训练和对齐模型:预训练模型是适用开发者的『 基座 』,而广大普通用户对有对话功能的对齐模型具有更强的需求。因此本次开源我们同时发布了对齐模型(Baichuan-13B-Chat),具有很强的对话能力,开箱即用,几行代码即可简单的部署。
- 更高效的推理:为了支持更广大用户的使用,我们本次同时开源了 int8 和 int4 的量化版本,相对非量化版本在几乎没有效果损失的情况下大大降低了部署的机器资源门槛,可以部署在如 Nvidia 3090 这样的消费级显卡上。
- 开源免费可商用:Baichuan-13B 不仅对学术研究完全开放,开发者也仅需邮件申请并获得官方商用许可后,即可以免费商用。
Baichuan-13B效果
Baichuan-13B在 C-Eval 上排名Rank10!
CMMLU 榜单上Baichuan-13B模型在 five-shot 和 zero-shot 下的表现如下:
Five-shot
模型 | STEM | 人文学科 | 社会科学 | 其他 | 中国特定主题 | 平均分 |
---|---|---|---|---|---|---|
Baichuan-13B | 42.38 | 61.61 | 60.44 | 59.26 | 56.62 | 55.82 |
ChatGLM2-6B | 42.55 | 50.98 | 50.99 | 50.80 | 48.37 | 48.80 |
Baichuan-7B | 35.25 | 48.07 | 47.88 | 46.61 | 44.14 | 44.43 |
ChatGLM-6B | 32.35 | 39.22 | 39.65 | 38.62 | 37.70 | 37.48 |
BatGPT-15B | 34.96 | 35.45 | 36.31 | 42.14 | 37.89 | 37.16 |
Chinese-LLaMA-13B | 27.12 | 33.18 | 34.87 | 35.10 | 32.97 | 32.63 |
MOSS-SFT-16B | 27.23 | 30.41 | 28.84 | 32.56 | 28.68 | 29.57 |
Chinese-GLM-10B | 25.49 | 27.05 | 27.42 | 29.21 | 28.05 | 27.26 |
Zero-shot
模型 | STEM | 人文学科 | 社会科学 | 其他 | 中国特定主题 | 平均分 |
---|---|---|---|---|---|---|
Baichuan-13B | 42.04 | 60.49 | 59.55 | 56.60 | 55.72 | 54.63 |
ChatGLM2-6B | 41.28 | 52.85 | 53.37 | 52.24 | 50.58 | 49.95 |
Baichuan-7B | 32.79 | 44.43 | 46.78 | 44.79 | 43.11 | 42.33 |
ChatGLM-6B | 32.22 | 42.91 | 44.81 | 42.60 | 41.93 | 40.79 |
BatGPT-15B | 33.72 | 36.53 | 38.07 | 46.94 | 38.32 | 38.51 |
Chinese-LLaMA-13B | 26.76 | 26.57 | 27.42 | 28.33 | 26.73 | 27.34 |
MOSS-SFT-16B | 25.68 | 26.35 | 27.21 | 27.92 | 26.70 | 26.88 |
Chinese-GLM-10B | 25.57 | 25.01 | 26.33 | 25.94 | 25.81 | 25.80 |
可见,Baichuan-13B模型在中文上的表现还是非常好的。
Baichuan-13B模型参数
模型名称 | 隐藏层维度 | 层数 | 注意力头数 | 词表大小 | 总参数量 | 训练数据(tokens) | 位置编码 | 最大长度 |
---|---|---|---|---|---|---|---|---|
Baichuan-7B | 4,096 | 32 | 32 | 64,000 | 7,000,559,616 | 1.2 万亿 | RoPE | 4,096 |
Baichuan-13B | 5,120 | 40 | 40 | 64,000 | 13,264,901,120 | 1.4 万亿 | ALiBi | 4,096 |
推理和部署
模型下载
推理所需的模型权重、源码、配置已发布在 Hugging Face:Baichuan-13B-Base 和 Baichuan-13B-Chat。
可以使用下面命令将模型下载到本地,方便使用时直接加载(/data/sim_chatgpt/)。
git clone https://huggingface.co/baichuan-inc/Baichuan-13B-Base
git clone https://huggingface.co/baichuan-inc/Baichuan-13B-Chat
模型推理
这里直接用 LLaMA-Efficient-Tuning 仓库中的环境
conda activate baichuan-7b
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation.utils import GenerationConfig
tokenizer = AutoTokenizer.from_pretrained("/data/sim_chatgpt/Baichuan-13B-Chat", use_fast=False, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained("/data/sim_chatgpt/Baichuan-13B-Chat", torch_dtype=torch.float16, trust_remote_code=True)
model = model.quantize(4).cuda()
model.generation_config = GenerationConfig.from_pretrained("/data/sim_chatgpt/Baichuan-13B-Chat")
messages = []
messages.append({"role": "user", "content": "世界上第二高的山峰是哪座"})
response = model.chat(tokenizer, messages)
print(response)
由于GPU显存只有16G,因此我们直接使用 int4 量化,但由于取消了device_map=‘auto’,模型加载到了CPU上,所以速度非常慢,而且还出现报错。
RuntimeError: CUDA Error: no kernel image is available for execution
on the device
这个报错应该是和GPU型号有关系,待解决,参考
https://github.com/baichuan-inc/Baichuan-13B/issues/56
如果上面是硬件的问题,我们可以考虑直接加载Baichuan-13B的量化版:Baichuan-13B-Chat-8bit,并用git clone命令下载。
git clone https://huggingface.co/trillionmonster/Baichuan-13B-Chat-8bit
使用 int8 推理代码如下:
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation.utils import GenerationConfig
tokenizer = AutoTokenizer.from_pretrained("/data/sim_chatgpt/Baichuan-13B-Chat-8bit", use_fast=False, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained("/data/sim_chatgpt/Baichuan-13B-Chat-8bit", device_map="auto", trust_remote_code=True)
model.generation_config = GenerationConfig.from_pretrained("/data/sim_chatgpt/Baichuan-13B-Chat-8bit")
messages = []
messages.append({"role": "user", "content": "世界上第二高的山峰是哪座"})
response = model.chat(tokenizer, messages)
print(response)
使用 int4 推理只需修改一行代码如下:
(区别在于加上 load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained("/data/sim_chatgpt/Baichuan-13B-Chat-8bit", device_map="auto",load_in_4bit=True,trust_remote_code=True)
推理效果如下:
基于LoRA 微调Baichuan-13B-Chat过程(单轮)
本次微调参考:LLaMA-Efficient-Tuning
下载仓库
git clone https://github.com/hiyouga/LLaMA-Efficient-Tuning.git
配置环境
# 这里使用和 baichuan-7b 相同的环境
conda create -n baichuan-7b python=3.10
conda activate baichuan-7b
cd LLaMA-Efficient-Tuning
pip install -r requirements.txt
微调数据
这里直接使用 alpaca_gpt4_zh,也就是由GPT4生成的中文alpaca数据,在仓库的data目录下。
数据格式如下:
instruction:任务指令,不能为空。
input:任务输入,可为空。如果不为空,项目内部处理训练数据时,会将 instruction、input 拼接在一起作为任务的输入。
output:任务输出,不能为空。
数据示例如下:
[ {
“instruction”: “保持健康的三个提示。”,
“input”: “”,
“output”: “以下是保持健康的三个提示:\n\n1. 保持身体活动。每天做适当的身体运动,如散步、跑步或游泳,能促进心血管健康,增强肌肉力量,并有助于减少体重。\n\n2.
均衡饮食。每天食用新鲜的蔬菜、水果、全谷物和脂肪含量低的蛋白质食物,避免高糖、高脂肪和加工食品,以保持健康的饮食习惯。\n\n3.
睡眠充足。睡眠对人体健康至关重要,成年人每天应保证 7-8 小时的睡眠。良好的睡眠有助于减轻压力,促进身体恢复,并提高注意力和记忆力。”
}, {
“instruction”: “三原色是什么?”,
“input”: “”,
“output”: “三原色通常指的是红色、绿色和蓝色(RGB)。它们是通过加色混合原理创建色彩的三种基础颜色。在以发光为基础的显示设备中(如电视、计算机显示器、智能手机和平板电脑显示屏),
三原色可混合产生大量色彩。其中红色和绿色可以混合生成黄色,红色和蓝色可以混合生成品红色,蓝色和绿色可以混合生成青色。当红色、绿色和蓝色按相等比例混合时,可以产生白色或灰色。\n\n此外,在印刷和绘画中,三原色指的是以颜料为基础的红、黄和蓝颜色(RYB)。这三种颜色用以通过减色混合原理来创建色彩。不过,三原色的具体定义并不唯一,不同的颜色系统可能会采用不同的三原色。”
},
微调过程
微调方法采用 LoRA 方法。
微调过程命令如下:
CUDA_VISIBLE_DEVICES=0 nohup python src/train_bash.py \
--do_train \
--model_name_or_path /data/sim_chatgpt/Baichuan-13B-Chat \
--template baichuan \
--dataset alpaca_gpt4_zh \
--output_dir baichuan_lora_checkpoint \
--max_source_length 256 \
--max_target_length 512 \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 1 \
--lr_scheduler_type cosine \
--logging_steps 10 \
--save_steps 10000 \
--learning_rate 5e-5 \
--num_train_epochs 1.0 \
--plot_loss \
--fp16 \
--lora_target W_pack \
--lora_rank 8 \
--padding_side right \
--quantization_bit 4 \
>> qlora_log.out 2>&1 &
各个参数说明如下:
- CUDA_VISIBLE_DEVICES=0: 单卡运行。
- do_train: 是否执行训练。
- model_name_or_path: 预训练模型路径。
- dataset: 训练数据集名称,可在 data/dataset_info.json 中增加自定义数据集。
- output_dir: 微调后的模型保存路径。
- source_prefix: 训练时每个输入序列添加的前缀,可为空。
- max_source_length: 输入序列的最大长度,即 source_prefix + instruction + input 的长度。
- max_target_length: 输出序列的最大长度,即 output 的长度。
- per_device_train_batch_size: 用于训练的批处理大小。可根据 GPU 显存大小自行设置。
- gradient_accumulation_steps: 梯度累加次数。
- logging_steps: 多少步输出一次 log。
- save_steps: 多少步保存一次参数。
- learning_rate: AdamW 优化器的初始学习率。
- num_train_epochs: 训练轮数(若非整数,则最后一轮只训练部分数据)
- plot_loss: 微调后绘制损失函数曲线,图片保存在 output_dir 中 。
- fp16: 使用半精度(混合精度)训练。
- lora_target: 大模型内将要进行 LoRA 微调的模块名称。
- lora_rank: LoRA 微调中的秩大小。
- padding_side: pad对齐方式,左对齐或者右对齐。
- quantization_bit:量化,4bit。
显存占用约9个G,运行时间大概60小时。
微调后生成的日志文件。
在 baichuan_lora_checkpoint 路径下会生成微调后的模型文件,如下:
使用微调后的模型进行推理
python src/cli_demo.py \
--model_name_or_path /data/sim_chatgpt/Baichuan-13B-Chat \
--template baichuan \
--finetuning_type lora \
--checkpoint_dir baichuan_lora_checkpoint \
--quantization_bit 4
界面可以正常打开,但输入句子进行推理时报错:RuntimeError: “addmm_impl_cpu_” not implemented for ‘Half’。
解决尝试一(未成功)
参考:https://github.com/hiyouga/LLaMA-Efficient-Tuning/issues/114
尝试了几种方法均未解决。
解决尝试二(未成功)
在阿里云A10的GPU上尝试成功,过程和前面基本没有变化,需要注意的一点是–quantization_bit 4,改为–quantization_bit 8,显存占用为16G。但微调成功(机器显存24G,微调占用显存为16G)后,推理会有乱码问题。**参考:https://github.com/hiyouga/LLaMA-Efficient-Tuning/issues/271
解决尝试三(未成功)
因为这里用的是阿里云免费试用的V100,GPU上显存只有16G,如果–quantization_bit 8,则会out of memory,使用因此选择尝试–quantization_bit 4,微调占用显存约为9G。微调完成后推理仍是报错:RuntimeError: mat1 and mat2 shapes cannot be multiplied,放弃。
解决尝试4(成功解决)
最后考虑尝试显存32G的V100,这里用的是AutoDL平台,由于模型文件较大,且还要考虑微调生成的模型文件,因此在选卡的的时候需要找能够扩容的卡,以免在使用过程中内存不足(我这里扩容了50G)。
下面再详细描述下在该平台上的详细步骤。
1、创建新实例:建议选择北京A区,有空闲GPU的V100-32G,且注意下数据盘是否支持扩容,选择支持扩容的机器。
2、使用提供的ssh命令登录,登录后进入数据盘目录。
cd /root/autodl-tmp
3、安装git-lfs
# 安装apt-get源
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
# 安装git-lfs
sudo apt-get install git-lfs
# 初始化git-lfs
git lfs install
4、下载模型
git clone https://huggingface.co/baichuan-inc/Baichuan-13B-Chat
5、下载LLaMA-Efficient-Tuning仓库,并安装环境依赖
git clone https://github.com/hiyouga/LLaMA-Efficient-Tuning.git
cd LLaMA-Efficient-Tuning
pip install -r requirements.txt
pip install bitsandbytes==0.38.1
pip install transformers_stream_generator
6、
由于显存有32G,因此可以不用量化(去掉–quantization_bit参数),同时可以将batch_size调为2,执行微调命令如下:
CUDA_VISIBLE_DEVICES=0 nohup python src/train_bash.py \
--do_train \
--model_name_or_path ../Baichuan-13B-Chat \
--template baichuan \
--dataset alpaca_gpt4_zh \
--output_dir baichuan_lora_checkpoint \
--max_source_length 256 \
--max_target_length 512 \
--per_device_train_batch_size 2 \
--gradient_accumulation_steps 1 \
--lr_scheduler_type cosine \
--logging_steps 10 \
--save_steps 5000 \
--learning_rate 5e-5 \
--num_train_epochs 1.0 \
--plot_loss \
--fp16 \
--lora_target W_pack \
--lora_rank 8 \
--padding_side right \
>> qlora_log.out 2>&1 &
代码可以正常运行,显存占用为28G。
而和之前几个卡的区别是,该卡的训练速度也非常快,之前可能需要60个小时,这里4个小时就可以搞定。
微调结束后,loss降到1.1左右。
使用微调后的模型进行推理,代码如下:
python src/cli_demo.py \
--model_name_or_path ../Baichuan-13B-Chat \
--template baichuan \
--finetuning_type lora \
--checkpoint_dir baichuan_lora_checkpoint
就可以和微调后的Baichuan-13B正常对话了。
推理显存占用28G。
这里简单说下AutoDL的使用体验。
优点:性价比比较高,操作简单,GPU的类型比较多。
缺点:数据传输的速度比较慢,如使用git clone下载模型文件的时候速度相对较慢(40个G用了将近两个小时),另外就是资源是共享的,可能在你想用的时候被别人占用了。
测试微调后的模型
CUDA_VISIBLE_DEVICES=0 python src/train_bash.py \
--stage sft \
--model_name_or_path /data/sim_chatgpt/Baichuan-13B-Chat \
--do_eval \
--template baichuan \
--dataset alpaca_gpt4_zh \
--finetuning_type lora \
--checkpoint_dir baichuan_lora_checkpoint \
--output_dir baichuan_lora_eval_result \
--per_device_eval_batch_size 1 \
--max_samples 100 \
--predict_with_generate \
--padding_side right
各个参数说明如下:
- CUDA_VISIBLE_DEVICES=0: 单卡运行。
- do_eval: 是否执行测试。
- model_name_or_path: 预训练模型路径。
- checkpoint_dir: 微调模型路径。
- dataset_dir: 测试数据存储目录。
- dataset: 测试数据集名称,可在 data/dataset_info.json 中增加自定义数据集。
- output_dir: 测试结果保存路径。
- per_device_eval_batch_size: 测试数据的批处理大小。可根据 GPU 显存大小,自行设置。
- predict_with_generate: 是否生成序列用于计算 ROUGE 或 BLEU 分数。
- padding_side: pad对齐方式,左对齐或者右对齐。
基于QLoRA 微调Baichuan-13B-Base过程(多轮)
下载Firefly项目仓库
git clone https://github.com/yangjianxin1/Firefly.git
cd Firefly
准备数据集
可使用项目中data下的dummy_data.jsonl数据进行代码调试,共33条数据。实际的训练数据使用MOSS提供的多轮对话数据:moss-003-sft-data。
数据一共有67.1万条
数据下载地址:https://huggingface.co/datasets/YeungNLP/moss-003-sft-data
下载方法:git clone https://huggingface.co/datasets/YeungNLP/moss-003-sft-data
数据集说明:每一行为一个多轮对话,其中conversation字段是必需的,可以根据实际需求添加或删除其他字段。
数据示例如下所示:
{
"conversation_id":44,
"category":"Brainstorming",
"conversation":[
{
"human":"怎么能够有效地提升个人能力?",
"assistant":"提升个人能力可以通过以下几个方面实现:\n\n1. 学习新知识和技能:阅读相关书籍、参加课程和工作坊、观看教育视频等学习方式,可以帮助你掌握新的知识和技能,从而提升个人能力。\n\n2. 持续练习和实践:不断地练习和实践所学的知识和技能,可以帮助你更好地掌握和应用这些技能,提高你的表现和效率。\n\n3. 寻求反馈和改进:寻求他人的反馈和建议可以帮助你发现自己的不足之处,进一步完善和改进自己的能力。\n\n4. 建立良好的工作和生活习惯:建立良好的工作和生活习惯,如合理安排时间、注意健康、保持积极态度等,可以提高你的工作效率和生活品质,从而提升个人能力。\n\n5. 社交和交流:与他人交流和合作,可以帮助你更好地了解他人的观点和经验,从而提升自己的能力和见识。"
},
{
"human":"对于初学者来说,如何快速掌握编程技能?",
"assistant":"以下是几个建议,可以帮助初学者快速掌握编程技能:\n\n1. 学习基础知识:建议先学习编程语言的基础知识和语法,例如变量、数据类型、控制结构、函数等。可以通过在线课程、编程书籍、视频教程等方式学习。\n\n2. 实践编程:进行实际的编程练习是非常重要的,可以通过参加编程挑战、编写小项目等方式来进行实践。\n\n3. 寻求反馈:可以寻求他人的反馈和建议,例如在线编程社区、编程导师等,他们可以帮助你发现问题并及时纠正。\n\n4. 阅读优秀代码:阅读和分析优秀的代码可以帮助你学习其他程序员的编程思路和技巧,从而提高自己的编程能力。\n\n5. 不断学习和更新:编程技术和工具在不断更新和发展,因此需要不断学习新的知识和技能,例如学习新的编程语言、框架、工具等,以跟上技术的发展和变化。\n\n总之,学习编程需要耐心和坚持,并且需要不断地实践和学习。通过以上建议,可以帮助初学者快速掌握编程技能。"
},
{
"human":"除了参加编程挑战和阅读代码,还有哪些方式可以提升自己的编程能力呢?",
"assistant":"除了参加编程挑战和阅读代码,还有以下几种方式可以提升自己的编程能力:\n\n1. 参与开源项目:加入一个开源项目,可以让你了解到实际的软件开发流程和团队合作方式,并且可以与其他开发人员合作,学习和分享编程技巧和经验。\n\n2. 进行代码重构:对已经编写的代码进行重构,可以帮助你了解更好的编程实践和设计模式,从而提高代码的可读性和可维护性。\n\n3. 练习算法和数据结构:算法和数据结构是编程中的重要基础,练习算法和数据结构可以帮助你了解不同的数据结构和算法,从而更好地解决实际问题。\n\n4. 学习软件工程和架构:学习软件工程和架构的知识,可以帮助你了解如何设计和构建可靠、可扩展和可维护的软件系统。\n\n5. 参加编程社区和论坛:参加编程社区和论坛可以让你与其他开发人员分享和讨论编程经验和技巧,了解最新的技术趋势和解决方案。\n\n总之,提升编程能力需要不断地学习和实践,并与其他开发人员和编程专家进行交流和合作,以获取更多的经验和知识。"
},
{
"human":"你有没有推荐的编程挑战网站?",
"assistant":"当然,以下是一些值得推荐的编程挑战网站:\n\n1. HackerRank:HackerRank 是一个全球领先的技术招聘平台,提供数百种编程挑战和比赛,包括算法、数据结构、数学、SQL、AI 等多个技术领域。\n\n2. LeetCode:LeetCode 是一个在线编程学习和实践平台,提供数千道编程题目,主要涵盖算法和数据结构。\n\n3. Codeforces:Codeforces 是一个全球知名的编程竞赛网站,提供数百个比赛和练习题目,主要涵盖算法和数据结构。\n\n4. Codewars:Codewars 是一个在线编程学习和实践平台,提供数千道编程题目,主要涵盖算法、数据结构、面向对象编程等多个技术领域。\n\n5. Project Euler:Project Euler 是一个非营利性的在线编程挑战平台,提供一系列数学和计算机科学问题,需要用编程语言进行解答。\n\n以上这些编程挑战网站可以帮助你提高编程能力,并且可以与其他编程爱好者进行交流和竞争。"
},
{
"human":"在学习编程的过程中,如何避免陷入困境和放弃呢?",
"assistant":"学习编程是一个需要长期坚持和不断学习的过程,以下是一些避免陷入困境和放弃的方法:\n\n1. 制定合理的学习计划:制定合理的学习计划,包括学习时间、学习内容、目标等,可以帮助你更好地管理时间和精力,避免学习过程中的松懈和分心。\n\n2. 寻找合适的学习资源:选择适合自己的学习资源,例如在线课程、编程书籍、视频教程等,可以让你更好地了解和掌握编程知识和技能。\n\n3. 寻求帮助和支持:在学习过程中,遇到问题和困难是很正常的,可以寻求他人的帮助和支持,例如参加编程社区、找到编程导师等。\n\n4. 进行实践和项目:实践和项目是学习编程的重要组成部分,可以帮助你更好地了解和掌握编程技能,同时也可以提高学习的兴趣和动力。\n\n5. 坚持并保持兴趣:坚持学习和保持兴趣是学习编程的关键。可以通过参加编程社区、参加编程竞赛、与其他编程爱好者交流等方式来保持兴趣和动力。\n\n总之,学习编程需要耐心和坚持,并需要不断学习和实践。通过以上方法可以帮助你避免陷入困境和放弃。"
}
],
}
配置训练参数
所有训练参数配置,均存储在train_args目录下,方便统一管理。以微调Baichuan-13B为例,其训练参数配置文件为train_args/qlora/baichuan-13b-sft-qlora.json,大家可根据情况对文件中的训练参数进行修改。
训练参数说明如下:
- output_dir:训练输出目录,存储checkpoint、tokenizer、tensorboard等
- model_name_or_path:预训练模型的本地目录,或者在huggingface上的模型名称。
- train_file:训练数据集路径。可以使用data/dummy_data.jsonl进行debug,或者指定为本地的训练文件。
- num_train_epochs:训练的轮次。如果数据量足够大,一般建议只训一个epoch。
- per_device_train_batch_size:每张显卡的batch size。
- gradient_accumulation_steps:梯度累计步数。global batch=num_gpus * per_device_train_batch_size * gradient_accumulation_steps。
- gradient_checkpointing:如果显存捉襟见肘,可以开启。以时间换空间,模型不缓存激活状态,会进行两次forward计算,以节省显存,我们默认开启。
- learning_rate:学习率。全量参数微调的时候,建议小一些,1e-5或5e-6。qlora训练时,根据模型大小的不同,建议设置为2e-4或1e-4。
- max_seq_length:训练时的最大长度。按照自己的设备进行设置,越长需要占用越多显存。
- logging_steps:每隔多少步打印一次train loss,结果会打印到日志中,也会保存在tensorboard中。
- save_steps:每隔多少步保存一次模型。
- save_total_limit:output_dir目录中最多保存多少个checkpoint,超出则会将最旧的删除。
- lr_scheduler_type:学习率变化策略。
- warmup_steps:warm up步数。学习率经过多少步,增长到指定的数值。
- optim:优化器。如果是全量参数微调,建议使用adamw_hf。如果是qlora微调,建议使用paged_adamw_32bit。
- seed:随机种子,用于复现实验结果。
- fp16:使用使用fp16混合精度。V100建议开启。
- bf16:使用使用fp16混合精度。A100建议开启。
- lora_rank:qlora矩阵的秩。一般设置为8、16、32、64等,在qlora论文中作者设为64。越大则参与训练的参数量越大,一般来说效果会更好,但需要更多显存,。
- lora_alpha: qlora中的缩放参数。一般设为16、32即可。
- lora_dropout: lora权重的dropout rate。
参数设置如下:
{
"output_dir": "output/baichuan-13b",
"model_name_or_path": "/data/sim_chatgpt/Baichuan-13B-Base",
"train_file": "./data/moss-003-sft-data.jsonl",
"num_train_epochs": 1,
"per_device_train_batch_size": 1,
"gradient_accumulation_steps": 2,
"learning_rate": 1e-4,
"max_seq_length": 900,
"logging_steps": 300,
"save_steps": 500,
"save_total_limit": 1,
"lr_scheduler_type": "constant_with_warmup",
"warmup_steps": 3000,
"lora_rank": 16,
"lora_alpha": 16,
"lora_dropout": 0.05,
"gradient_checkpointing": true,
"disable_tqdm": false,
"optim": "paged_adamw_32bit",
"seed": 42,
"fp16": true,
"report_to": "tensorboard",
"dataloader_num_workers": 5,
"save_strategy": "steps",
"weight_decay": 0,
"max_grad_norm": 0.3,
"remove_unused_columns": false
}
微调过程
执行如下脚本,即可启动训练,由于是单卡,命令如下:
python train_qlora.py --train_args_file train_args/qlora/baichuan-13b-sft-qlora.json
如果是多卡:
torchrun --nproc_per_node={num_gpus} train_qlora.py --train_args_file train_args/qlora/baichuan-13b-sft-qlora.json
显存16G单卡运行,out of memory,尝试调小lora_rank为16,可以运行,但需要3700多个小时(数据量太大了),所以就没有继续进行微调,大家有资源的可以尝试,或者使用小点儿的数据集。
微调完成后,adapter的权重会保存到output_dir设置的目录。
合并权重
微调过程中,为了提高训练效率,会只保存adapter的权重(不保存合并后的模型权重),因此,在微调结束后,需要手动将adapter与base model进行权重合并,执行的代码文件为scripts目录下的merge_lora.py,运行完成后就会得到合并后的模型权重。
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
"""
使用该脚本,将lora的权重合并到base model中
"""
def merge_lora_to_base_model():
model_name_or_path = '/data/sim_chatgt/baichuan-13B-Base'
adapter_name_or_path = 'output/baichuan-13b/checkpoint-20000'
save_path = 'checkpoint/baichuan-13b'
tokenizer = AutoTokenizer.from_pretrained(
model_name_or_path,
trust_remote_code=True
)
model = AutoModelForCausalLM.from_pretrained(
model_name_or_path,
trust_remote_code=True,
low_cpu_mem_usage=True,
torch_dtype=torch.float16,
device_map='auto'
)
model = PeftModel.from_pretrained(model, adapter_name_or_path)
model = model.merge_and_unload()
tokenizer.save_pretrained(save_path)
model.save_pretrained(save_path)
if __name__ == '__main__':
merge_lora_to_base_model()
模型推理
权重合并之后,我们就可以使用该模型进行推理了。项目提供了单轮对话和多轮对话的脚本,详见script/chat目录。
参考:https://zhuanlan.zhihu.com/p/643950663
https://github.com/yangjianxin1/Firefly
Baichuan-13B LoRA 微调快速上手