当前位置:   article > 正文

大语言模型ChatGLM + P-Tuning微调实践_chatglm大语言模型微调

chatglm大语言模型微调

大语言模型ChatGLM + P-Tuning微调实践

LLM微调基础

LLM微调可以对原有预模型进行专业领域知识的训练,相关领域知识需要进行预处理整理成语料,语料越充分相对来说微调后的模型预测越准,还要结合调参,反复地训练,才有可能达到预期的效果。

微调模型有多种,包括P-Tuning、LoRA等。本次实践采用P-Tuning。

  • P-Tuning有两个版本:
    1.论文GPT Understands, Too中的Prompt tuning,在本文行文过程中称为P-tuning v1,对应GitHub 代码:https://github.com/THUDM/P-tuningP-Tuning
    2.在论文《P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks》中提出,GitHub代码:https://github.com/THUDM/P-tuning-v2

本次实践环境说明

序号资源明细
1aliyun PAI-DSW,32G内存,16G显卡(NVidia Tesla V100),Ubuntu20.04。
2镜像环境:pytorch=2.1.2、cuda=12.1、python=3.10、Tensorflow=2.14.0
3镜像环境:ChatGLM2-6B、P-Tuning V2
4数据集:采用公开数据集AdvertiseGen

ChatGLM部署以及激活conda环境

在实践前,自行部署好ChatGLM、P-Tuning等,不在此篇赘述。
检查是否在自己安装好的conda chatgml环境中,或者直接激活conda环境。

conda info --envs
conda activate chatglm
  • 1
  • 2

重启终端。

安装依赖

安装transformers、jieba、datasets等

# 本次实践进行微调需要 4.27.1 版本的 transformers
install transformers==4.27.1
pip install rouge_chinese nltk jieba datasets
  • 1
  • 2
  • 3

jieba 等库必须安装,否则执行bash train.sh时会报错。

禁用 W&B

# 禁用 W&B
export WANDB_DISABLED=true
  • 1
  • 2

训练数据集、测试数据集准备

公开数据集,在镜像中直接下载语料库,语料库正常下载下来名为AdvertiseGen.tar.gz。在ubuntu中使用wget:

wget https://cloud.tsinghua.edu.cn/f/b3f119a008264b1cabd1/?dl=1
  • 1

或者

wget --no-check-certificate --no-cookies --header “Cookie: oraclelicense=accept-securebackup-cookie” https://cloud.tsinghua.edu.cn/f/b3f119a008264b1cabd1/?dl=1
  • 1

两种方式下载后结果一样,下载到本地的文件都被命名为:index.html?dl=1。这个问题可能是特例。

以为下载错误,但是观察容量大小,16M左右,正好是AdvertiseGen.tar.gz的大小。人工把“.html?dl=1”改成“.tar.gz”后缀,然后用命令解压:

tar -zxvf traindatabase.tar.gz
  • 1

解压后获得dev.json和train.json,正确,这就是需要的训练数据集和测试数据集。
把两个json文件复制/ChatGLM2-6B/ptuning/AdvertiseGen下,其中AdvertiseGen是人工新建。看其他教程,这个新建的目录可以叫任意名字,但是需要修改sh文件里的默认路径名,这个主要看个人喜好。

微调参数调整(train.sh\evaluate.sh)

1、train_file、validation_file和test_file修改成自己的 JSON 格式数据集路径

本人路径与文件默认路径一致,不需要修改。

2、将 prompt_column 和 response_column 改为 JSON 文件中输入文本和输出文本对应的 KEY

这个KEY指的是json中的key:value,本人下载的与文件默认参数一致,不需要修改。

3、可能还需要增大 max_source_length 和 max_target_length 来匹配你自己的数据集中的最大输入输出长度。

保持默认参数,没有修改。

4、并将模型路径 THUDM/chatglm2-6b 改为你本地的模型路径。

修改为:–model_name_or_path /mnt/workspace/ChatGLM2-6B/THUDM/chatglm2-6b \

说明:
在 P-tuning v2 训练时模型只保存 PrefixEncoder 部分的参数,所以在推理时需要同时加载原 ChatGLM-6B 模型以及 PrefixEncoder 的权重,因此需要指定 evaluate.sh 中的参数:

#仅作为说明使用,具体设置以上述内容为准
--model_name_or_path THUDM/chatglm-6b
--ptuning_checkpoint $CHECKPOINT_PATH
  • 1
  • 2
  • 3

参数说明备查

PRE_SEQ_LEN=128: 定义了一个名为PRE_SEQ_LEN的变量,并将其设置为128。这个变量的作用在后续的代码中会用到。
LR=2e-2: 定义了一个名为LR的变量,并将其设置为2e-2,即0.02。这个变量表示学习率,在后续的代码中会用到。
–train_file /root/train.json : 指定训练数据文件的路径和文件名为"/root/train.json"。
–validation_file /root/verify.json : 指定验证数据文件的路径和文件名为"/root/verify.json"。
–prompt_column content : 指定输入数据中作为提示的列名为"content"。
–response_column summary : 指定输入数据中作为响应的列名为"summary"。
–overwrite_cache : 一个命令行参数,指示在缓存存在的情况下覆盖缓存。
–model_name_or_path THUDM/chatglm-6b : 指定使用的模型的名称或路径为"THUDM/chatglm-6b"。
–output_dir output/adgen-chatglm-6b-pt-PRESEQLEN−PRE_SEQ_LEN-PRE 
SEQLEN−LR : 指定输出目录的路径和名称为"output/adgen-chatglm-6b-pt-P R E SEQLEN − PRE_SEQ_LEN-PRESEQLEN−LR"。这是训练结果和日志的保存位置。
–overwrite_output_dir : 一个命令行参数,指示在输出目录存在的情况下覆盖输出目录。
–max_source_length 512 : 指定输入序列的最大长度为512。
–max_target_length 512 : 指定输出序列的最大长度为512。
–per_device_train_batch_size 1 : 指定每个训练设备的训练批次大小为1。
–per_device_eval_batch_size 1 : 指定每个评估设备的评估批次大小为1。
–gradient_accumulation_steps 16 : 指定梯度累积的步数为16。在每个更新步骤之前,将计算并累积一定数量的梯度。
–predict_with_generate : 一个命令行参数,指示在生成模型的预测时使用生成模式。
–max_steps 3000 : 指定训练的最大步数为3000。
–logging_steps 10 : 指定每隔10个步骤记录一次日志。
–save_steps 1000 : 指定每隔1000个步骤保存一次模型。
–learning_rate $LR : 指定学习率为之前定义的LR变量的值。
–pre_seq_len $PRE_SEQ_LEN : 指定预设序列长度为之前定义的PRE_SEQ_LEN变量的值。
–quantization_bit 4 : 指定量化位数为4。这个参数可能是与模型相关的特定设置。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

训练

  • 进入ptuning目录
cd ptuning
  • 1
  • 执行训练
bash train.sh
  • 1

训练总耗时:5小时

训练耗时请大家自行判断:
网上有教程对AdvertiseGen数据集进行微调,总耗时11个小时。
网上有教程对只有5条Pompt的数据集进行微调训练,总耗时50分钟。

推理

bash evaluate.sh
  • 1

耗时:58分钟

验证

先加入原始模型

import torch
import os
from transformers import AutoConfig, AutoModel, AutoTokenizer

# 载入Tokenizer
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True)

config = AutoConfig.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True, pre_seq_len=128)
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", config=config, trust_remote_code=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在此步骤后继可以有两种后继处理,一种是加入微调后的模型;一种是直接使用原始LLM预训练模型进行对话。
本实践继续加载微调模型:

#如果要调用微调后的
#checkpoint-3000情况下,模型完全忘记了原始模型,不管问什么回答全是微调内容

prefix_state_dict = torch.load(os.path.join("ptuning/output/adgen-chatglm2-6b-pt-128-2e-2/checkpoint-3000", "pytorch_model.bin"))
new_prefix_state_dict = {}
for k, v in prefix_state_dict.items():
    if k.startswith("transformer.prefix_encoder."):
        new_prefix_state_dict[k[len("transformer.prefix_encoder."):]] = v
model.transformer.prefix_encoder.load_state_dict(new_prefix_state_dict)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

模型继续处理

# Comment out the following line if you don't use quantization
model = model.quantize(4)
model = model.cuda()
model = model.eval()
  • 1
  • 2
  • 3
  • 4

使用微调后的新模型开始对话

response, history = model.chat(tokenizer, "你好", history=[])
print(response)
  • 1
  • 2

对于"<|user|>你好"的<|assistant|>回答,很奇葩。卖个关子,不截图出来了。大家自行体验。

随着对P-Tuning理解加深,微调后的新模型改变了认知,似乎都忘记了,回答变得很奇怪了。

B站上有个官方视频,里面提到了一句关于此种现象的解决办法,大意是:在使用AdvertiseGen数据集时,加入通用数据集一起微调。

可能会遇到的问题及解决

一个很意外的错误:在train.sh\evaluate.sh连个文件中–nproc-per-node中划线不对,应该改成下划线,如下:

#--nproc-per-node写的不对
torchrun --standalone --nnodes=1 --nproc-per-node=$NUM_GPUS main.py 
  • 1
  • 2

改成

torchrun --standalone --nnodes=1 --nproc_per_node=$NUM_GPUS main.py 
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/356650
推荐阅读
相关标签
  

闽ICP备14008679号