目标:低成本微调大模型,拥有属于自己的AI助手。
一切的一切,都得益于LoRA、QLoRA微调方法,没有A100一样可以微调大模型(用3090 24G显存微调70亿参数的baichuan绰绰有余,甚至参数量小一点的模型3060也能跑)。具体原理可以看论文,或者去看知乎上的总结,这里只谈怎么用。
这里,有一个极其方便的大模型项目推荐:Github传送地址,打开即用,然后我在这个基础上做一些小小小改动。
下面介绍一下微调的步骤:
实验在Linux上进行,先用conda创建一个虚拟环境:baichuan,要求python版本3.8,pytorch版本1.13.0,CUDA Toolkit11.7,装完长这样:
pytorch仍然推荐用whl安装,不知道怎么装可以看看我这篇博客关于pytorch安装的部分,传送地址
Step1: 运行conda activate baichuan进入环境
conda activate baichuan
Step2: 克隆Firefly仓库并进入项目文件夹中,安装项目必要依赖
git clone https://github.com/noob-dqt/QLoRA_baichuan.git
cd QLoRA_baichuan
pip install -r requirements.txt
Step3: 可以前往huggingface下载baichuan-7B模型,下载后模型文件位于baichuan-inc/baichuan-7B中,其中包含预训练模型,模型配置参数,特定的分词器等文件,项目文件夹里有baichuan-inc/baichuan-7B这个目录,不过里面的模型文件被我删除了,下载直接覆盖这个文件夹就行,或者单独把下载后的模型文件复制到baichuan-inc/baichuan-7B/下也可以。没用魔法的话官网很慢,这里提供一种比较快的方法,运行:
pip install modelscope
python
from modelscope.hub.snapshot_download import snapshot_download
snapshot_download('../baichuan-inc/baichuan-7B', cache_dir='../baichuan-inc')
Step4: 准备训练数据集,在这里选用了Firefly提供的数据集moss-003-sft-data(下载地址),其来源于复旦大学MOSS项目,包含大量中文训练对话,考虑训练设备、时长限制,可以从数据集中采样部分对话作为训练集,其中,训练数据文件为jsonl,以如下形式组织:
{
"conversation_id":44,
"category":"Brainstorming",
"conversation":[
{
"human":"怎么高效学习英语?",
"assistant":"想要高效学习英语可以通过以下几个…"},
{
"human":"对于初学者来说,如何快速掌握英语?",
"assistant":"以下是几个建议,可以帮助初学者快速掌…"}
],
}
PS:选用任何想用的数据集,不过格式都必须和上面一样,后缀是jsonl,Firefly里本身也有一个简单的小数据集(几条对话)供测试。
Step5: 编辑配置训练参数,主要是修改配置文件baichuan-qlora.json,位于文件夹finetune中(你不用其他模型可以不改)。
Step6: 编写文件训练入口文件train_qlora.py,不用修改
Step7: 开始训练,若使用3090设备进行训练,使用下面命令设置两个环境变量,否则会报错
export NCCL_P2P_DISABLE="1"
export NCCL_IB_DISABLE="1"
训练,启动!
torchrun --nproc_per_node=2 train_qlora.py --train_args_file finetune/baichuan-qlora.json
在这里使用了两张显卡进行训练,根据卡的数量修nproc_per_node。
Step7: 训练结束后,需要将Adapter与基座模型进行权重合并。Adapter的权重保存到了output_dir设置的目录这里是output/baichuan-7b/中,使用merge.py脚本获得合并后的模型权重,合并后模型文件位于checkpoint文件夹下。
Step8: 编写测试脚本。模型可支持多轮对话,主要原理即通过在限制上下文长度的范围内,将历史对话保存,并在新提问产生时进行拼接,使用拼接后的问题作为模型输入进行推理,从而达到对话的记忆功能,回答更加个性化。加载合并后模型文件,使用轻量库tkinter编写一个简洁的对话界面方便使用,脚本名为ChatMulti.py,对提问进行推理并将结果返回到界面。
这里面基本上不需要做改动,影响训练的是配置文件baichuan-qlora.json,这里也基本没改,用的就是Firefly中的参数。
{
"output_dir": "./output/baichuan-7b",
"model_name_or_path": "baichuan-inc/baichuan-7B",
"train_file": "./data/moss.jsonl", # 改成自己训练数据文件路径
"num_train_epochs": 1,
"per_device_train_batch_size": 6,
"gradient_accumulation_steps": 2,
"learning_rate": 2e-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": 64,
"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": 0,
"save_strategy": "steps",
"weight_decay": 0,
"max_grad_norm": 0.3,
"remove_unused_columns": false
}
目录结构长这样子:
本文整理了包括知乎、CSDN在内的很多网络资源,在此鸣谢各位博主,如果有侵权的地方可以联系删除