你知道什么是微调吗?大模型为什么要微调?以及大模型微调的原理是什么? 原创
“ 预训练(pre+train)+微调(fine+tuning),是目前主流的范式”
在学习大模型的过程中,怎么设计神经网络和怎么训练模型是一个重要又基础的操作。
但与之对应的微调也是一个非常重要的手段,这里就着重讲一下为什么要微调,其优点是什么以及微调的本质。
01、什么是微调?
学习一门技术不但要知其然,也要知其所以然。
想了解为什么要微调,首先要知道什么是微调?
我们常说的大模型,指的是具有大量参数的神经网络模型,具体的可以看之前的文章大模型的参数是什么。然后经过大量的训练数据训练出来的模型叫做大模型,也叫做预训练模型。
微调指的是微调大模型,是在预训练模型(已经训练好的大模型)基础之上,使用少量数据对大模型的全部或部分参数进行调整,以达到在某个领域更好的效果。
举例来说,刚设计好的一个神经网络,就类似于一个从来没上过学的学生,他什么玩意都不懂,只会根据自己的本能去处理问题;
而训练大模型就相当于让这个学生完成了九年制义务教育或者上了大学,也就是说它接受过系统的教育,天文地理,物理化学等等均有涉猎,这样的模型就叫做预训练模型。
而微调就是在这个基础上完成某个方向的强化,比如想让这个学生去参加奥数比赛,就要让他对数学进行强化学习。
这个就是微调。
微调来源于迁移学习,所谓的迁移学习就是在已经训练好的模型基础上进行适当的优化或者说强化,这样可以更加合理的利用各种资源。
02、为什么要微调?
前面说了什么是微调,这里讲一下为什么要微调?
之所以需要进行微调,主要有以下两方面原因:
- 训练成本问题
- 训练数据问题
之所以要进行微调,其实最主要的原因就是成本问题。openAI公司训练GPT模型,一次的成本大概在几百万到上千万美元;换算成人民币就是上千万到上亿的成本。
虽然很多公司使用的大模型不需要有GPT模型那么强大,也不需要上亿的训练成本,但从零开始训练一个大模型,少说也要几百万人民币,这对个人和绝大部分公司来说都是不可接受的。
还一个原因就是,训练数据的收集同样需要巨大的成本,而抛开成本来说,很多公司根本无法收集到足够的训练数据,而没有足够的训练数据,那么就很难训练出一个很好的模型。
这时,微调的作用就体现出来了。微调只需要在别人已经训练好的模型之上,使用少量的数据对模型部分或全部参数进行调整即可。
之所以说对预训练模型的全部或部分参数进行调整是因为,微调分为全量(参数)微调(Full Fine Tuning)和部分(参数)微调——高效微调PEFT(Parameter-Efficient Fine Tuning),只不过很少有人会进行全量微调。
全量微调就相当于,你本来只是在一个普通的本科院校学习;然后突然有一天有个机会让你到一所985/211的学校去学习,学习的内容还是一样,不过人家教的会更好。
部分参数微调就是相当于,你进了你们学校的实验班或突击班,去强化学习部分课程。
所以什么情况下适合微调?
- 无法接受训练的成本问题
- 训练数据不足
- 想使用别人已经训练好的开源模型(huggingface上有大量开源模型)
- 数据安全问题,不能接受把数据上传到第三方大模型公司
这几种情况比较适合微调,如果不缺钱,又不缺数据,技术又过关;那么自己设计模型,自己训练是最好的方式。
当然,微调也不是万能的,只有在相似的条件下才可以进行微调;比如,一个识别猫狗的预训练模型,你要用人脸数据进行人脸识别微调,这就行不通了。毕竟,猫狗的数据特征和人脸还是有很大差别的。
02、怎么微调,微调的具体步骤?
前面说了,微调的目的是调整模型的参数,所以本质上和步骤上微调和训练没太大区别,都需要经过数据收集处理,数据加载,正向传播,反向传播优化的过程,然后给模型参数找到一个最优解。
只不过微调大部分情况下都是调整部分参数,而这种微调方式叫做——高效微调。也就是说用少量的数据,优化部分参数,以达到更好的效果。
既然是对模型参数的调整,那么具体是怎么操作的呢?
在神经网络的训练过程中,有数据处理,正向传播,反向传播和优化器,如果不了解神经网络训练过程的可以看神经网络的通用训练流程。
而微调就发生在优化器上,训练的过程是优化器根据损失差通过反向传播的方式调整参数;而微调也是通过优化器去调整模型的参数。
基于pytorch框架的神经网络,其微调部分参数的原理就是通过冻结参数,把不需要调整的参数冻结,这样大模型在微调的过程中就只会优化可以被调整的参数。
而全量微调就是不冻结参数,所有参数都会被调整。
代码如下所示:
"""
基于pytorch框架的神经网络
"""
# 加载模型
model = AutoModelForCausalLM.from_pretrained(
model_id, torch_dtype="auto", device_map="auto"
)
# 获取模型参数
for name, param in model.parameters():
# 判断哪些参数需要冻结 参数名中包含bias的参数被冻结 不会被修改
if "bias" not in name:
param.requires_grad = False
# 优化器
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
这样,通过微调模型,就可以让预训练模型达到自己想要的效果。
本文转载自公众号AI探索时代 作者:DFires
原文链接:https://mp.weixin.qq.com/s/LLZKnJGDB-2iJU2Q1AiuUA