ChatGLM2-6B微调
微调工具
本次我们使用ChatGLM-Efficient-Tuning,基于 🤗PEFT 的高效 🤖ChatGLM-6B 微调工具
目前实现了针对以下高效微调方法的支持:
- LoRA
- 仅微调低秩适应器。
- P-Tuning V2
- 仅微调前缀编码器。
- Freeze Tuning
- 仅微调后几层的全连接层。
- 全量微调
- 微调模型所有参数。
本次我们使用LoRA微调方法。
微调步骤
下载代码
git clone https://github.com/hiyouga/ChatGLM-Efficient-Tuning.git
安装依赖
cd ChatGLM-Efficient-Tuning
# 创建conda环境
conda create -n chatglm2 python=3.9
conda activate chatglm2
# 安装pytorch,如果已安装可以忽略
conda install pytorch==2.0.0 torchvision==0.15.0 torchaudio==2.0.0 pytorch-cuda=11.7 -c pytorch -c nvidia
# 安装项目依赖
pip install -r requirements.txt
下载模型
下载地址: huggingface.co/THUDM/chatg…
注意必须要将整个项目git clone下来
这里建议已经下载过模型的重新将项目中的几个py文件重新下载一次,不然会报错
git lfs install
git clone https://huggingface.co/THUDM/chatglm2-6b
编辑数据集
数据集按照如下格式即可
[
{
"question": "人们为何常常感到委屈", //输入
"instruction": "问答", //指令 如 翻译/问答
"output": "人常会不自觉地记下对自己有利的部分,这是形成委屈的重要原因。" //输出
}
]
在src/data/data_info.json
中新增数据集并编辑字段映射
"zhangyiming": {
"file_name": "https://b2.7b2.com/gemini/data-1/zhangyiming.json",
"columns": { //对应数据集的字段名
"prompt": "instruction",
"query": "input",
"response": "output"
}
}
运行微调命令
这里是单机单cpu,所以只需要用device0就行
CUDA_VISIBLE_DEVICES=0 python src/train_sft.py --model_name_or_path /gemini/code/model --use_v2 --plot_loss --do_train --dataset zhangyiming --finetuning_type lora --output_dir /gemini/code/output --per_device_train_batch_size 4 --gradient_accumulation_steps 4 --lr_scheduler_type cosine --logging_steps 10 --save_steps 1000 --learning_rate 5e-5 --num_train_epochs 100 --fp16
部分参数解释:
名称 | 说明 |
---|---|
use_v2 | 是否微调的是ChatGLM2 |
model_name_or_path | 模型路径 |
finetuning_type | 微调类型: lora p-tuning freeze |
dataset | 数据集名称 |
output_dir | 输出微调模型的路径 |
num_train_epochs | 训练轮次 |
其他参数见项目wiki
其中各微调类型介绍:
- Freeze: 即参数冻结,对原始模型部分参数进行冻结操作,仅训练部分参数,以达到在单卡或不进行TP或PP操作,就可以对大模型进行训练。
- P-Tuning: 在输入的embedding层前,将prompt转换为可学习的额外一层embedding层.(这里我也没有太懂=)
- LoRA: 在大型语言模型上对指定参数(权重矩阵)并行增加额外的低秩矩阵,并在模型训练过程中,仅训练额外增加的并行低秩矩阵的参数,冻结其他参数。 当“秩值”远小于原始参数维度时,新增的低秩矩阵参数量也就很小。在下游任务tuning时,仅须训练很小的参数,但能获取较好的表现结果。
目前我在24G显存(用的趋动云,不知道具体的GPU型号)情况下,LoRA微调100个epoch大概7分钟就跑完了,微调结果会保存到配置的output目录.我准备了58条训练数据,大概在500个epoch左右loss开始不再下降。
其中,adapter_config.json
和adapter_model.bin
就是微调后的模型
测试
Cli测试
CUDA_VISIBLE_DEVICES=0 python src/cli_demo.py
--checkpoint_dir /gemini/code/output --model_name_or_path /gemini/code/model --use_v2
代码测试
from transformers import AutoModel, AutoTokenizer
from peft import PeftModel
model_path = '/gemini/code/model/'
peft_model_path = '/gemini/code/output/'
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModel.from_pretrained(model_path, trust_remote_code=True).half().cuda()
model = PeftModel.from_pretrained(model, peft_model_path, is_trainable=True)
input_text = '人们为何常常感到委屈?'
response, history = model.chat(tokenizer=tokenizer, query=input_text)
print(response)