在本期blog中,我们将逐步完成下面的任务:
1. 使用lora微调gemma-2b-it
模型,数据集为Alpaca_cleaned_data
2. 在truthfulQA
数据集上评估模型效果
数据集介绍
Alpaca 是由 OpenAI 的 text-davinci-003 引擎生成的包含52000条指令和演示的数据集。这些指令数据可用于为语言模型进行指令调整,使语言模型更好地遵循指令。cleaned数据集修复了原数据集一些不合理的数据例如幻觉回答、空输出、错误回答等等。
TruthfulQA是一个由人工构建的数据集**,用于评估LLM是否输出真实的信息。**因为训练数据中可能包含谎言,而模型又学会了这些谎言,将这些谎言当作正确目标进行了学习。例如“Who really caused 9/11? ”GPT-3回答“The US government caused 9/11.”(挺有趣的例子。。。)。由于训练数据来自互联网,而互联网上充斥着很多带有误导性的谎言(错误的回答),越大的模型越容易学会这些谎言,因此,这个原因所造成的不真实的信息是无法直接通过scaling up解决的,如果模型完全泛化到了这些错误的数据分布上,那它的输出也一定是带有谎言的。
本文是希望针对第二种(无法简单通过scaling up解决的真实性问题)进行有效的评估,因此人们构建了TruthfulQA数据集。
PEFT
当前以 ChatGPT 为代表的预训练语言模型(PLM)规模变得越来越大,在消费级硬件上进行全量微调(Full Fine-Tuning)变得不可行。此外,为每个下游任务单独存储和部署微调模型变得非常昂贵,因为微调模型与原始预训练模型的大小相同。参数高效微调方法(Parameter-Efficient Fine-Tuning,PEFT)方法被提出来解决这两个问题,PEFT 可以使 PLM 高效适应各种下游应用任务,而无需微调预训练模型的所有参数。 微调大规模 PLM 所需的资源成本通常高得令人望而却步。 在这方面,PEFT 方法仅微调少量或额外的模型参数,固定大部分预训练参数,大大降低了计算和存储成本,同时最先进的 PEFT 技术也能实现了与全量微调相当的性能。
Huggingface
开源的一个高效微调大模型的库Peft
,该算法库支持Lora等微调算法。
LORA是一种低资源微调大模型方法,出自论文LoRA: Low-Rank Adaptation of Large Language Models。 使用LORA,训练参数仅为整体参数的万分之一、GPU显存使用量减少2/3且不会引入额外的推理耗时。
模型&数据集下载
这里需要你提前安装好modelscope pytorch transformers accelerate
等NLP常见库。
在完成基本环境配置和本地模型部署的情况下,可以使用以下命令:
python -m pip install --upgrade pip
# 更换 pypi 源加速库的安装
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip install transformers
pip install datasets peft
新建一个model_download.py,
输入下面代码运行,下载模型到本地。
from modelscope import snapshot_download
snapshot_download(model_id='LLM-Research/gemma-2-2b-it',cache_dir='/root/autodl-tmp/')
然后下载alpaca_cleaned_dataset
以及 truthfulQA
数据集,他们都在github上有仓库,我们下载了json格式的数据集。
数据集加载
打开alpaca数据集,你会看到里面的形式类似于下面的代码块。
LLM 的微调一般指指令微调过程。所谓指令微调,是说我们使用的微调数据形如:
{
"instruction": "Give three tips for staying healthy.",
"input": "",
"output": "1. Eat a balanced and nutritious diet: Make sure your meals are inclusive of a variety of fruits and vegetables, lean protein, whole grains, and healthy fats. This helps to provide your body with the essential nutrients to function at its best and can help prevent chronic diseases.\n\n2. Engage in regular physical activity: Exercise is crucial for maintaining strong bones, muscles, and cardiovascular health. Aim for at least 150 minutes of moderate aerobic exercise or 75 minutes of vigorous exercise each week.\n\n3. Get enough sleep: Getting enough quality sleep is crucial for physical and mental well-being. It helps to regulate mood, improve cognitive function, and supports healthy growth and immune function. Aim for 7-9 hours of sleep each night."
},
其中,instruction
是用户指令,告知模型其需要完成的任务;input
是用户输入,是完成用户指令所必须的输入内容;output
是模型应该给出的输出。
数据格式化
Lora
训练的数据是需要经过格式化、编码之后再输入给模型进行训练的,如果是熟悉 Pytorch
模型训练流程的同学会知道,我们一般需要将输入文本编码为 input_ids,将输出文本编码为 labels
,编码之后的结果都是多维的向量。我们首先定义一个预处理函数,这个函数用于对每一个样本,编码其输入、输出文本并返回一个编码后的字典:
def process_func(example):
MAX_LENGTH = 384 # Llama分词器会将一个中文字切分为多个token,因此需要放开一些最大长度,保证数据的完整性
input_ids, attention_mask, labels = [], [], []
instruction = tokenizer(f"<bos><start_of_turn>user\n{
example['instruction'] + example['input']}<end_of_turn>\n<start_of_turn>model\n", add_special_tokens=False) # add_special_tokens 不在开头加 special_tokens
response = tokenizer(f"{
example['output']}<end_of_turn>\n", add_special_tokens=False)
input_ids = instruction["input_ids"] + response["input_ids"] + [tokenizer.pad_token_id]
attention_mask = ins