大模型
参数量的增加使得突然出现(涌现)了原来不具有的能力。
Pre-train + fine-tuning
微调
但随着模型增大,full fine-tuning变得不可行。
因此,只微调一小部分或额外加入参数(LoRA)。
更多微调相关可参考这篇:
大模型训练——PEFT与LORA介绍_常鸿宇的博客-CSDN博客
LoRA
LoRA(low-Rank Adaptation):
https://arxiv.org/pdf/2106.09685.pdf
冻结全部原模型参数,加入新的层,进行低秩近似(因此模型量大大减少)。
P-tuning v2:
https://arxiv.org/pdf/2103.10385.pdf
P-tuning v2首先确定模型在处理特定任务时需要的新的参数(这些参数通常是模型的某些特性或功能),然后在模型中添加这些新的参数,以提高模型在特定任务上的表现。
P-tuning v2 官方介绍:【官方教程】ChatGLM-6B 微调:P-Tuning,LoRA,Full parameter_哔哩哔哩_bilibili
把各种任务都形式化成语言模型任务:
对于各种下游任务,只需要对应去构造特定的指令与输入即可。例如,在本次任务中,我们需要让大模型实现文本分类任务,那我们构造的指令、输入与输出应该为:
-
instruction:指令,Please judge whether it is a medical field paper according to the given paper title and abstract, output 1 or 0, the following is the paper title and abstract -->
-
"-->":加上一个箭头就是让大模型明白,下次再遇到这种问题,就是我们想让大模型进行二分类任务。
-
input:prompt。对于这个任务来说那就是 title+abstract+author 拼接成的字符串了。
-
output:response,即大模型的回答,0 or 1。
实践
clone微调脚本:git clone
https://github.com/KMnO4-zx/xfg-paper.git
下载chatglm2-6b模型:git clone
https://huggingface.co/THUDM/chatglm2-6b
安装依赖:cd ./
xfg-paper
;pip install -r requirements.txt
训练权重:(将其中model_name_or_path改为chatglm2-6b路径)
sh xfg_train.sh
导入数据:
# 导入 pandas 库,用于数据处理和分析
import pandas as pd
# 读取训练集和测试集
train_df = pd.read_csv('./csv_data/train.csv')
testB_df = pd.read_csv('./csv_data/testB.csv')
制作数据集:
# 创建一个空列表来存储数据样本
res = []
# 遍历训练数据的每一行
for i in range(len(train_df)):
# 获取当前行的数据
paper_item = train_df.loc[i]
# 创建一个字典,包含指令、输入和输出信息
tmp = {
"instruction": "Please judge whether it is a medical field paper according to the given paper title and abstract, output 1 or 0, the following is the paper title and abstract -->",
"input": f"title:{paper_item[1]},abstract:{paper_item[3]}",
"output": str(paper_item[5])
}
# 将字典添加到结果列表中
res.append(tmp)
# 导入json包,用于保存数据集
import json
# 将制作好的数据集保存到data目录下
with open('./data/paper_label.json', mode='w', encoding='utf-8') as f:
json.dump(res, f, ensure_ascii=False, indent=4)
修改data目录下data_info文件:
{ "paper_label": { "file_name": "paper_label.json" } }
加载训练好的LoRA权重:
Parameter-Efficient Fine-Tuning (PEFT)https://github.com/huggingface/peft
用来实现LoRA。
# 导入所需的库和模块
from peft import PeftModel
from transformers import AutoTokenizer, AutoModel, GenerationConfig, AutoModelForCausalLM
# 定义预训练模型的路径
model_path = "../chatglm2-6b"
model = AutoModel.from_pretrained(model_path, trust_remote_code=True).half().cuda()
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
# 加载 label lora权重
model = PeftModel.from_pretrained(model, './output/label_xfg').half()
model = model.eval()
# 使用加载的模型和分词器进行聊天,生成回复
response, history = model.chat(tokenizer, "你好", history=[])
response
# 预测函数
def predict(text):
# 使用加载的模型和分词器进行聊天,生成回复
response, history = model.chat(tokenizer, f"Please judge whether it is a medical field paper according to the given paper title and abstract, output 1 or 0, the following is the paper title and abstract -->{text}", history=[],
temperature=0.01)
return response
制作submit:
# 预测测试集
# 导入tqdm包,在预测过程中有个进度条
from tqdm import tqdm
# 建立一个label列表,用于存储预测结果
label = []
# 遍历测试集中的每一条样本
for i in tqdm(range(len(testB_df))):
# 测试集中的每一条样本
test_item = testB_df.loc[i]
# 构建预测函数的输入:prompt
test_input = f"title:{test_item[1]},author:{test_item[2]},abstract:{test_item[3]}"
# 将预测结果存入lable列表
label.append(int(predict(test_input)))
# 把label列表赋予testB_df
testB_df['label'] = label
# task1虽然只需要label,但需要有一个keywords列,用个随意的字符串代替
testB_df['Keywords'] = ['tmp' for _ in range(2000)]
# 制作submit,提交submit
submit = testB_df[['uuid', 'Keywords', 'label']]
submit.to_csv('submit.csv', index=False)