Fine-tuning:个性化AI的妙术

在本篇文章中,我们将深入探讨Fine-tuning的概念、原理以及如何在实际项目中运用它,以此为初学者提供一份入门级的指南。

一、什么是大模型

ChatGPT大模型今年可谓是大火,在正式介绍大模型微调技术之前,为了方便大家理解,我们先对大模型做一个直观的抽象。

本质上,现在的大模型要解决的问题,就是一个序列数据转换的问题:

输入序列 X = [x1, x2, ..., xm], 输出序列Y = [y1, y2, …, yn],X和Y之间的关系是:Y = WX。

我们所说的“大模型”这个词:“大”是指用于训练模型的参数非常多,多达千亿、万亿;而“模型”指的就是上述公式中的矩阵W。

在这里,矩阵W就是通过机器学习,得出的用来将X序列,转换成Y序列的权重参数组成的矩阵。

需要特别说明:这里为了方便理解,做了大量的简化。在实际的模型中,会有多个用于不同目的的权重参数矩阵,也还有一些其它参数。

二、大模型Fine-tuning的概念

Fine-tuning源于对已经训练好的模型进行微调的概念。传统的机器学习模型需要通过大量数据进行训练,而Fine-tuning则利用了在庞大数据集上训练好的大型深度学习模型。这些预训练模型,如ChatGPT大模型,已经通过数以亿计的文本数据学到了庞大的知识库。

在预训练模型的基础上进行额外训练,使其适应特定任务或领域。这一过程包括选择预训练模型,准备目标任务的数据,调整模型结构,进行微调训练,以及评估和部署。

微调的优点在于节省时间和资源,提高性能,但也存在过拟合风险和模型选择与调整的复杂性。总体而言,它是一种强大的技术,特别适用于数据受限或计算资源有限的情况。

三、大模型微调的方式

在 OpenAI 发布的 ChatGPT应用中,就主要应用了大模型微调技术,从而获得了惊艳全世界的效果。

而随着ChatGPT的火热,parameter-efficient fine-tuning和prompt-tuning技术似乎也有替代传统fine-tuning的趋势,本篇论文将简单描述预训练模型领域这三种微调技术及其差别。

3.1 full fine-tuning全量微调

大模型全量微调通过在预训练的大型模型基础上调整所有层和参数,使其适应特定任务。这一过程使用较小的学习率和特定任务的数据进行,可以充分利用预训练模型的通用特征,但可能需要更多的计算资源。

3.2 参数高效微调

PEFT技术旨在通过最小化微调参数的数量和计算复杂度,来提高预训练模型在新任务上的性能,从而缓解大型预训练模型的训练成本。

Prompt Tuning

Prompt Tuning的出发点,是基座模型(Foundation Model)的参数不变,为每个特定任务,训练一个少量参数的小模型,在具体执行特定任务的时候按需调用。

Prompt Tuning的基本原理是在输入序列X之前,增加一些特定长度的特殊Token,以增大生成期望序列的概率。

具体来说,就是将X = [x1, x2, ..., xm]变成,X` = [x`1, x`2, ..., x`k; x1, x2, ..., xm], Y = WX`。

如果将大模型比做一个函数:Y=f(X),那么Prompt Tuning就是在保证函数本身不变的前提下,在X前面加上了一些特定的内容,而这些内容可以影响X生成期望中Y的概率。

Prefix Tuning

Prefix Tuning的灵感来源是,基于Prompt Engineering的实践表明,在不改变大模型的前提下,在Prompt上下文中添加适当的条件,可以引导大模型有更加出色的表现。

Prefix Tuning的出发点,跟Prompt Tuning的是类似的,只不过它们的具体实现上有一些差异。

而Prefix Tuning是在Transformer的Encoder和Decoder的网络中都加了一些特定的前缀。

具体来说,就是将Y=WX中的W,变成W` = [Wp; W],Y=W`X。

Prefix Tuning也保证了基座模型本身是没有变的,只是在推理的过程中,按需要在W前面拼接一些参数。

LoRA

LoRA是跟Prompt Tuning和Prefix Tuning完全不相同的另一条技术路线。

LoRA背后有一个假设:我们现在看到的这些大语言模型,它们都是被过度参数化的。而过度参数化的大模型背后,都有一个低维的本质模型。

通俗讲人话:大模型参数很多,但并不是所有的参数都是发挥同样作用的;大模型中有其中一部分参数,是非常重要的,是影响大模型生成结果的关键参数,这部分关键参数就是上面提到的低维的本质模型。

LoRA的基本思路,包括以下几步:

首先, 要适配特定的下游任务,要训练一个特定的模型,将Y=WX变成Y=(W+∆W)X,这里面∆W主是我们要微调得到的结果;

其次,将∆W进行低维分解∆W=AB (∆W为m * n维,A为m * r维,B为r * n维,r就是上述假设中的低维);

接下来,用特定的训练数据,训练出A和B即可得到∆W,在推理的过程中直接将∆W加到W上去,再没有额外的成本。

另外,如果要用LoRA适配不同的场景,切换也非常方便,做简单的矩阵加法即可:(W + ∆W) - ∆W + ∆W`。

四、Fine-tuning的步骤和流程
  1. 选择预训练模型: Fine-tuning的第一步是选择一个合适的预训练模型。这通常取决于任务的性质和需求。

备注:预训练模型是指在庞大的数据集上进行训练得到的模型。这些数据集通常是通过无监督学习或其他任务进行训练的。简单来说就是“模型的母体”。

  1. 准备微调数据集: Fine-tuning的成功与否密不可分于数据的质量。确保你的数据与模型预期的输入格式一致,进行必要的清理和标记。

备注:微调数据集是指在模型微调过程中所使用的数据集,比如原有大模型是识别动物类的大模型,现在我们准备了全部是猫狗的图片数据集,迁移模型的识别到识别猫狗上。

  1. 调整模型数据集输入: 根据具体任务,调整模型的输入以适应任务的特性。比如,文本分类任务可能需要在模型输入中包含任务相关的信息。

备注:本质上,就是调节模型识别的标签,比如原来识别的猫,现在让识别成狗,就是调整模型的标签输入

  1. 定义损失函数: 根据任务类型,定义适当的损失函数。这是模型优化的目标,对于分类任务,通常使用交叉熵损失。

备注:损失函数就好比你在玩打靶游戏,目标是尽量靠近靶心。当你射击命中靶心时,你会得到一个很小的损失分数,代表你的射击非常准确;而当你偏离靶心时,损失分数会相应增加,代表你离目标更远了。

在机器学习中,损失函数类似于靶心,我们的模型的预测结果就类比为射击的结果。损失函数衡量了模型预测值与真实值之间的差距,我们的目标是尽量减小这种差距,即尽量减小损失函数的值。

  1. 冻结部分模型: Fine-tuning中你可以选择冻结模型的一部分,特别是底层。这有助于保留预训练模型学到的通用特征。

备注:冻结部分模型可以用一个简单的例子来解释。假设你正在准备一道复杂的菜肴,这个菜需要煎牛排、炒蔬菜和做汁料。你已经有了一个非常熟练的牛排煎得恰到好处的步骤,这是你多年的经验总结出来的。但是你对于炒蔬菜和做汁料的处理方法还不是很熟悉。

那么在这个情况下,你可以决定冻结(保持不变)你熟练的牛排煎的步骤,因为你已经能够很好地完成它。你只需要专注于学习和改进炒蔬菜和做汁料的步骤,以充分利用你的努力。

  1. 选择优化器和学习率: 选择一个适当的优化器(如Adam)和学习率。预训练模型的学习率通常较小,因为它已经包含了大量的知识。

备注:优化器和学习率是机器学习中调整模型参数的重要工具。

我们可以将机器学习模型的参数调整过程类比为学生学习的过程。学习过程中,学生需要根据老师的指导不断调整学习策略,使得自己的学习效果越来越好。

优化器就像是学生的学习策略,它决定了如何根据反馈信息来更新模型的参数。不同的优化器有不同的策略,比如一些优化器会根据参数的梯度(导数)大小来调整参数的更新步长,而另一些优化器则会考虑参数的历史更新情况来调整步长。这些策略旨在使模型更好地逼近最优解,就像学生通过不断调整学习策略来提高学习效果一样。

学习率则类似于学生的学习步长,它决定了每次参数更新的幅度。如果学习率很小,那么参数更新的幅度会很小,学习过程会比较稳定但可能会收敛得比较慢;如果学习率很大,那么参数更新的幅度会很大,学习过程可能会比较震荡但可能会收敛得较快。选择合适的学习率可以帮助模型更快地找到最优解,就像选择合适的学习步长可以帮助学生更快地掌握知识一样。

  1. 进行微调训练: 利用准备好的数据和定义好的设置,开始模型的训练。迭代多个周期,直到在验证集上表现良好。
  1. 评估模型性能: 使用测试集来评估fine-tuned模型的性能。查看模型在任务上的表现,并根据需要进行调整。

备注:评估模型性能就好比是给学生考试一样,我们想知道学生掌握知识的程度。在考试中,我们通过评估学生的答题情况来得出一个分数,这个分数反映了学生在掌握知识方面的能力。

五、大模型微调开源项目

作者后来将各种大模型的高效微调,统一到了一个项目里:https://github.com/hiyouga/LLaMA-Factory(opens new window)

截止2023年10月29日,已经支持微调的模型型号有:

Model

Model size

Default module

Template

href="https://github.com/facebookresearch/llama" LLaMA

7B/13B/33B/65B

q_proj,v_proj

-

href="https://huggingface.co/meta-llama" LLaMA-2

7B/13B/70B

q_proj,v_proj

llama2

href="https://huggingface.co/bigscience/bloom" BLOOM

560M/1.1B/1.7B/3B/7.1B/176B

query_key_value

-

href="https://huggingface.co/bigscience/bloomz" BLOOMZ

560M/1.1B/1.7B/3B/7.1B/176B

query_key_value

-

href="https://huggingface.co/tiiuae/falcon-7b" Falcon

7B/40B

query_key_value

-

href="https://github.com/baichuan-inc/Baichuan-13B" Baichuan

7B/13B

W_pack

baichuan

href="https://github.com/baichuan-inc/Baichuan2" Baichuan2

7B/13B

W_pack

baichuan2

href="https://github.com/InternLM/InternLM" InternLM

7B/20B

q_proj,v_proj

intern

href="https://github.com/QwenLM/Qwen-7B" Qwen

7B/14B

c_attn

chatml

href="https://github.com/THUDM/ChatGLM3" ChatGLM3

6B

query_key_value

chatglm3

href="https://huggingface.co/microsoft/phi-1_5" Phi-1.5

1.3B

Wqkv

-

5.1 ChatGLM大模型微调
  1. Full Tuning(全参数微调):就像你重新学习一门课程一样,这种微调方式会重新调整模型中所有参数,让模型在新的任务上学习适应最佳的参数配置。这样可以让模型更好地适应新的数据和任务,但可能需要花费更多的时间和计算资源。
  2. LoRA(Layer-wise Relevance Adaption,逐层相关性适应):这种微调方式是针对特定层次的调整,就好比给身体的不同部位做不同的锻炼一样。通过逐层调整,模型可以更灵活地适应新的任务,而不是一刀切地调整所有参数。
  3. P-Tuning V2:这是谷歌提出的一种参数微调方法,它使用了预训练的大型语言模型来进行微调,以适应特定的应用场景。这种方式类似于在预训练的基础上进行精细化调整,以获得更好的性能。
  4. Freeze(冻结):就像冻结时间一样,这种微调方式会保持模型的某些部分不变。在微调时,你可以冻结一些不需要调整的模型参数,集中精力在需要调整的部分上,以节省时间和计算资源,同时保留已有的良好性能。

总的来说,这些微调方式都是为了让模型更好地适应新的任务或数据,但它们的策略和重点略有不同。选择合适的微调方式可以帮助我们更快地实现模型性能的提升,就好比选择合适的训练方式可以让我们更好地提高学习效果一样。

5.2 LLaMA大模型微调

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/324917.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++系统笔记教程----vscode远程连接ssh

C系统笔记教程 文章目录 C系统笔记教程前言开发环境配置总结 前言 开发环境配置 Ubuntu20.24VScode 如果没有linux系统,但是想用其编译,可以使用ssh远程连接。 首先进入vscode,打开远程连接窗口(蓝色的小箭头这) 选择连接到主机…

Redis主从架构、哨兵集群原理实战

1.主从架构简介 背景 单机部署简单,但是可靠性低,且不能很好利用CPU多核处理能力生产环境必须要保证高可用,一般不可能单机部署读写分离是可用性要求不高、性能要求较高、数据规模小的情况 目标 读写分离,扩展主节点的读能力&…

案例:应用内字体大小调节

文章目录 介绍相关概念完整实例 代码结构解读保存默认大小获取字体大小修改字体大小 介绍 本篇Codelab将介绍如何使用基础组件Slider,通过拖动滑块调节应用内字体大小。要求完成以下功能: 实现两个页面的UX:主页面和字体大小调节页面。拖动…

【电子通识】开漏输出和推挽输出有什么差别?

在看一些MCU芯片手册的时候,能发现GPIO的功能有开漏输出和推挽式输出。那么这两种输出到底有什么差别? 如下是STM32F10xxx参考手册中对于GPIO的功能描述: 如下为GPIO内部框图: 在一些其他的芯片规格书中也同样看到不同的GPIO工作…

java基于Spring Boot的灾害应急救援评估调度平台

灾害应急救援平台的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品,体验高科技时代带给人们的方便,同时也能让用户体会到与以往常规产品不同的体验风格。(1)鉴于该系统是一款面向…

详细讲解Python连接Mysql的基本操作

目录 前言1. mysql.connector2. pymysql 前言 连接Mysql一般有几种方法,主要讲解mysql.connector以及pymysql的连接 后续如果用到其他库还会持续总结! 对于数据库中的表格,本人设计如下:(为了配合下面的操作) 1. mysql.connector mysql.connector 是一…

高通平台开发系列讲解(PCIE篇)MHI (Modem Host Interface)驱动详解

文章目录 一、MHI驱动代码二、MHI读数据流程三、MHI写数据流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢MHI (Modem Host Interface)我们通过名字顾名思义知道,它是Modem与Host的桥梁。 MHI 可以很容易地适应任何外围总线,但它主要用于基于 PCIe 的设备。 MHI(…

MathType中文网站2024最新版本下载及嵌入word教程

MathType是一款专业的数学公式编辑器,兼容Office word,excel等700多种程序,用于编辑数学试卷、书籍、报刊、论文、幻灯演示等文档轻松输入各种复杂的数学公式和符号。 MathType是一款功能强大的数学公式编辑器,广泛用于编写和编辑数学公式。Word是微软公司推出的文…

力扣精选算法100题——水果成篮(滑动窗口专题)

本题链接👉水果成篮 第一步:了解题意 我就按照实例1来进行对这题的理解。 1代表种类类型,这个数组里面有2个种类类型 ps:种类1和种类2 ,只不过种类1是有2个水果,种类2有一个水果,共计3个水果。 本题需要解…

【K8s学习】

k8s的简单执行流程: Kubernetes Master(API Server、Scheduler等组件)负责调度Pod到合适的Node上。 当Pod被调度到某个Node时,该Node上的kubelet代理会收到指令并开始执行Pod的生命周期管理任务,包括创建、监控和终止P…

Java代码审计FastJson反序列化利用链跟踪动态调试autoType绕过

目录 0x00 前言 0x01 基础参考 JNDI注入实例 使用type加入User类解析 FastJson历史漏洞简介 0x02 FastJson 1.2.24 利用链分析 调试过程 构造Poc思路 CC链关键流程 0x03 FastJson 1.2.25-1.2.47 利用链分析 1、开启autoTypeSupport:1.2.25-1.2.41 调试过…

centos7 arm服务器编译安装python 3.8

前言 CentOS (Community Enterprise Operating System) 是一种基于 Red Hat Enterprise Linux (RHEL) 进行源代码再编译并免费提供给用户的 Linux 操作系统。 CentOS 7 采用了最新的技术和软件包,并提供了强大的功能和稳定性。它适用于各种服务器和工作站应用场景&a…

【数据库原理】(27)数据库恢复

在数据库系统中,恢复是指在发生某种故障导致数据库数据不再正确时,将数据库恢复到已知正确的某一状态的过程。数据库故障可能由多种原因引起,包括硬件故障、软件错误、操作员失误以及恶意破坏。为了确保数据库的安全性和完整性,数…

SpringMVC SpringMVC 的入门

2.1.环境搭建 2.1.1.创建工程 2.1.2.添加web支持 右键项目选择Add framework support... 如果没有,可以参考idea2023版如何新建web项目 2.添加web支持 ​ 3.效果 ​ 注意: 不要先添加打包方式将web目录要拖拽到main目录下,并改名为…

MySQL多表关联查询练习题

一、创建表的素材 1.创建student和score表 CREATE TABLE student ( id INT(10) NOT NULL UNIQUE PRIMARY KEY , name VARCHAR(20) NOT NULL , sex VARCHAR(4) , birth YEAR, department VARCHAR(20) , address VARCHAR(50) ); 创建score表。SQL代码如下: …

QTabelView使用代理自定义,第一列为QLabel第二列为下拉框

预览界面 代理源文件 CustomParamViewDelegate.cpp #include "CustomParamViewDelegate.h"CustomParamViewDelegate::CustomParamViewDelegate(QObject *parent): QStyledItemDelegate(parent) {}CustomParamViewDelegate::~CustomParamViewDelegate() {}QWidget* …

C#MQTT编程06--MQTT服务器和客户端(winform版)

1、前言 介绍完基础理论部分,下面在Windows平台上搭建一个简单的MQTT应用,进行简单的应用,整体架构如下图所示; 消息模型: 运用MQTT协议,设备可以很方便地连接到物联网云服务,管理设备并处理数…

基于SSM的网上招聘系统的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

云服务器CVM_云主机_云计算服务器_弹性云服务器-腾讯云

腾讯云服务器CVM提供安全可靠的弹性计算服务,腾讯云明星级云服务器,弹性计算实时扩展或缩减计算资源,支持包年包月、按量计费和竞价实例计费模式,CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格,提供9个9的数…

【QML COOK】- 009-组件(Components)

组件对于QML来说就如同C的类一样。可以用同一个组件创建多个对象。 组件有两种定义方式: 用独立的.qml文件定义组件在.qml文件中用Component对象定义组件 1. 创建项目,新建文件IndependentComponent.qml import QtQuickRectangle {id : rootText {id…