
从零实现大模型-GPT2任务微调 原创
我们在BERT微调那篇文章中提到,许多NLP任务(如情感分析和问答)都依赖于上下文理解能力。而像BERT这种双向模型具有较强的上下文理解能力,因此非常适合用于任务微调,即针对某个具体任务进行微调。
而像GPT这种自回归模型,在预训练完成后会进行一个指令微调过程,用于跟随人类指令,然后通过指令去完成不同的任务(翻译,总结)。
那GPT能否像BERT那样,直接微调用于完成某个具体任务呢?虽然BERT更适合,但GPT确实也可以。
今天我们就基于之前的GPT2预训练模型,使用一个垃圾邮件数据集,来微调一个邮件分类模型。
1.垃圾邮件识别
传统ML方法
当然,也可以通过传统的机器学习方法实现垃圾邮件分类,例如,贝叶斯分类,或者基于统计学,事先设定一些敏感词汇,如果邮件中出现了这些敏感词汇,就认为是垃圾邮件。
Embedding
但传统机器学习方法依赖人类经验,既然我们正在写大模型的文章,就得入乡随俗。
我们通过Embedding实现文本分类,具体来说就是计算邮件内容的Embedding,然后计算“spam”和“none spam”的Embedding,最后通过计算余弦相似度来判断邮件类型。
指令微调模型
其实,还有比计算Embedding更简单的方法,如果大模型已经经过预训练、指令微调以及RLHF过程,那么就可以直接利用这种指令跟随能力来实现垃圾邮件分类。
例如,我们构造下面的prompt输入给chatGPT。
以下是GPT4-o给出的答案,不仅准确识别出了垃圾邮件,还遵循了人类指令输出了“yes”。
如果只使用预训练模型,没有经过指令微调,前面我们也测试过,模型虽然有输出,但输出只是简单的拷贝输入。
2.任务微调
本文完整代码如下,建议结合代码阅读文本。
在通过Embedding实现文本分类时,Embedding是通过调用openAI的API得到的,其实,这个Embedding也可以看作是GPT模型输出隐状态的一部分。
除了用Embedding计算余弦相似度来实现文分类外,还可以基于隐状态实现一个分类模型,也就是在模型的输出端加一个分类头。
准备数据
训练数据来自公开的垃圾邮件数据集,包括文本和标签两列,标签列中spam代表是垃圾邮件。
因为数据集中垃圾邮件数量少于正常邮件,所以要平衡正负样本数量。
接下来划分训练集,验证机和测试集。
接下来是tokenization,padding或者截断到最大长度。
最后构造Dataloader。
加载预训练模型
加载gpt2预训练模型。
再微调过程中,可以冻结大部分预训练模型参数。
添加分类头
在预训练模型的输出端加一个二分类分类头。
构造损失函数
因为是二分类,所以构造一个交叉熵损失函数。
然后开始训练,训练过程与指令微调过程基本一致。
本文转载自公众号人工智能大讲堂
原文链接:https://mp.weixin.qq.com/s/n1h9JeCxV3Kq_yj0-_RS5A
