先说一下ChatGPT的训练过程:
1.先在大规模的语料数据上进行自监督训练得到预训练模型,什么是自监督?就是把一句话后面的内容遮住,然后让模型预测,Bert则是把中间某些词遮住。
2.此时的预训练模型已经具备通用知识,也可以用于某个具体领域,但为了更好地适用于Chat模式,在预训练模型基础上,使用监督数据进行指令微调。
监督数据的格式是将问题和答案用特殊分隔符拼接在一起,训练过程中输入what is AI?,模型会基于此进行续写,通过训练过程中的损失函数和优化器的作用下调整参数,使模型的输出尽量与答案一致。
<start>what is AI?<sep>AI is .....<eos>
3.光会聊天还不行,还要尽量和人类在一个频道上,为了进一步与人类对齐,ChatGPT会使用Reinforcement learning through human feedback(RLHF)方式,也就是通过人类反馈结果进一步微调。
这样就得到了一个会聊天的ChatGPT。
上面的第2,3步还是挺麻烦的,但如果你直接将预训练模型应用于某个垂直领域,例如,金融,农业,医疗。或者是公司内部产品,效果不会很好,因为它的训练数据中不包括你公司的内部资料。
所以,要想取得好的结果,一般都需要对预训练模型进行微调。
微调可以从模型和Prompt两方面下手。
从模型入手,当然是要更新模型的参数。
但有多少参数参与更新也有说法。
Full fine-tuning,模型全部参数都会参与更新,例如,使用医疗数据在预训练模型上继续训练,让它更加熟悉医疗知识。这个其实就是迁移学习。在图像领域,先在ImageNet上预训练,学习图像基本特征表示,然后使用医疗数据微调,微调过程中,全部参数都会更新。对于微调所需要的数据量,与预训练数据越相似,需要的微调数据就越少。
Parameter-efficient fine-tuning,只更新部分参数,其它参数冻结,或者增加一个Adaptor,预训练模型参数不变,只更新Adaptor参数,典型的例子是LORA。这种方式只需要一份预训练模型,针对不同任务训练不同的Adaptor即可,所以这样方式效率很高。
如上图所示,预训练模型参数矩阵W要比A和B大的多,Lora训练过程只需要更新A和B,A和B的可视为W的低秩分解,。
Instruction-tuning,这个就是刚才在ChatGPT中说的,预训练完成后,用有监督的方式继续训练。
从Prompt下手,不改模型参数。
prompt engineering,不用改任何参数,也不增加任何adaptor,完全依靠人的能力把Prompt写好就行了。
Prefix tuning(前缀调整),这种方法的核心思想是在模型的输入前添加一个连续的、任务特定的向量序列,这个序列被称为Virtual Token,是可学习的。通过优化这个Virtual Token,而不是修改预训练语言模型的参数,Prefix Tuning 能够适应新任务,从而提高模型在特定任务上的性能。
P-Tuning,与Prefix tuning类似,只不过Virtual Tokens是通过一个额外的Prompt Encoder生成,例如,LSTM。
今天介绍一个NLP以及大模型领域非常知名的包:HuggingFace的Transformer。并基于此使用Lora方法对预训练模型进行微调。
安装必要的库:确保你已经安装了 Transformers 库和 PEFT 库。如果没有,可以通过以下命令安装:
pip install transformers peft
选择预训练模型:选择一个预训练模型,例如 T5、BERT 或 GPT-2。你可以通过 Hugging Face 的模型库找到合适的模型。
准备数据集:准备你的数据集,这通常包括训练集和测试集。你需要使用相应的 Tokenizer 对数据进行分词处理。
定义 LoRA 配置:创建一个 LoRA 配置对象,指定需要适配的参数和训练设置。例如:
from peft import LoraConfig
lora_config = LoraConfig(
r=16, # 秩的大小
lora_alpha=32, # 每个自注意力头的参数数量
target_modules=["q", "v"], # 需要适配的模块
lora_dropout=0.05, # dropout 率
bias="none", # 是否包含偏置项
task_type=TaskType.SEQ_2_SEQ_LM # 任务类型
)
加载模型和 Tokenizer:使用 Transformers 库加载预训练模型和对应的 Tokenizer。
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
model_name ="google/flan-t5-xxl"# 例如使用 Flan-T5 XXL 模型
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
准备模型进行 LoRA 训练:使用 PEFT 库准备模型以进行 LoRA 训练。
from peft import get_peft_model, prepare_model_for_int8_training
model = prepare_model_for_int8_training(model) # 准备模型进行 int-8 训练
model = get_peft_model(model, lora_config) # 添加 LoRA 适配器
定义训练参数和数据收集器:设置训练参数,并定义如何收集数据以进行训练。
from transformers import Seq2SeqTrainingArguments, DataCollatorForSeq2Seq
training_args = Seq2SeqTrainingArguments(
output_dir="lora-flan-t5-xxl",
learning_rate=1e-3,
num_train_epochs=5,
# 其他训练参数...
)
data_collator = DataCollatorForSeq2Seq(
tokenizer=tokenizer,
model=model,
# 其他数据收集参数...
)
创建 Trainer 并开始训练:使用 Trainer 类开始训练过程。
from transformers import Seq2SeqTrainer
trainer = Seq2SeqTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=your_train_dataset, # 你的训练数据集
eval_dataset=your_eval_dataset, # 你的评估数据集
training_args=training_args,
data_collator=data_collator,
)
trainer.train()
评估和推理:训练完成后,你可以使用训练好的模型进行评估和推理。
今天介绍了除RAG外让大模型更专业的另一种方法:微调,并且介绍分别基于模型和提示词的微调方法,并基于HuggingFace的Transformer实现了LORA微调。
人工智能大讲堂 2024-03-26