大语言模型微调方法详解【全量微调、PEFT、LoRA、Adapter】

NLP-大语言模型学习系列目录

一、注意力机制基础——RNN,Seq2Seq等基础知识
二、注意力机制【Self-Attention,自注意力模型】
三、Transformer图文详解【Attention is all you need】
四、大语言模型的Scaling Law【Power Low】
五、大语言模型微调

文章目录

  • NLP-大语言模型学习系列目录
  • 一、为什么需要微调
  • 二、微调简介
  • 三、全参数微调
  • 四、PEFT
    • 1 Intuition behind PEFT
    • 2 Prefix Tuning
    • 3 Prompt Tuning
    • 4 Adapter Tuning
    • 5 LoRA
      • (1)核心思想
      • (2)图解
    • 6 BitFit
    • 7 多种不同的高效微调方法对比
    • 8 关于PEFT的库
  • 参考资料


一、为什么需要微调

回顾GPT1,GPT2,GPT3,我们知道GPT3发现了Few-shot 的涌现能力,也就是说预训练好的模型,不用微调更新参数,仅仅通过Prompt 加入Few-shot,GPT3便可以在多个下游任务取得很好的效果。 如下图所示,GPT3在SuperGLUE测试集上,不用经过微调,仅通过Few-shot就能达到和微调后的BERT-Large一样的效果。

image.png

并且思维链(CoT)的发现,让我知道通过CoT的方式,LLM的效果还能提升。如下表所示,在需要推理的数学任务上,加入CoT效果可以得到极大的提升。

截屏2024-10-24 10.18.19

虽然Prompt Engineering很有效,但是也有一些缺陷:

  1. 可以放入上下文中的信息是有限的
  2. 复杂任务可能还是需要梯度更新步骤
  3. 没有通过指令微调的大模型,指令跟随效果不好(后训练的必要性)

如下图所示,仅通过预训练的语言模型并不一定能理解人类的意图并帮助我们(指令跟随效果不好)

image-20241023170058198

微调可以提升语言模型的指令跟随能力(指令微调),如下图所示,微调后的语言模型能正确回答提出的问题。

image-20241023170035362

所以当前大模型的训练范式主流仍然是预训练+后训练(微调),下面本文详细的介绍两种微调方式,特别是各种参数高效微调的算法。

二、微调简介

微调主要包含两类:

  1. 全参数微调,一般称作Full Fine-Tuning
  2. 参数高效微调,Parameter-Efficient Fine-Tuning

全参数微调空间、时间代价高,参数高效微调是指微调少量或额外的模型参数,固定大部分预训练模型(LLM)参数,从而大大降低了计算和存储成本,同时,也能实现与全量参数微调相当的性能。参数高效微调方法甚至在某些情况下比全量微调效果更好,可以更好地泛化到域外场景。

PEFT全参数微调
目标提高预训练模型在特定任务上的性能,使用有限的数据和计算资源提高预训练模型在特定任务上的性能,使用有限的数据和充足的计算资源
训练时间较快较长
计算资源较少较多
模型参数仅修改非常少量的参数修改所有参数
过拟合由于仅训练少量参数,较不容易过拟合由于修改所有参数,更容易过拟合
性能性能不如微调,但仍然足够好性能更好

三、全参数微调

全参数微调(Full Fine-tuning)就是继续训练一个预训练语言模型,但这个方法可能需要大量的内存(取决于不同优化器、优化方法).下面以一个具有65B(650亿)参数的模型为例,展示使用16位混合精度(16-bit mixed precision)进行微调训练时的内存消耗情况。

Model

  • 每个参数用16位,也就是2Byte,所以模型参数需要130GB内存
  • 每个参数要存梯度,130GB

Optimizer

  • 这里提到的 optimizer 存储 parameters 是因为在某些情况下,混合精度训练需要为模型参数同时保留两个版本,模型参数在更新的时候,要用高精度,所以要存一个副本,260GB:
    • 低精度参数(16-bit):在实际的前向和后向传播过程中,模型的参数是以16位精度(16-bit)进行计算和存储的。这种精度可以减少内存占用,并加速计算过程。
    • 高精度副本(32-bit):为了避免数值精度的损失,在混合精度训练中,优化器需要维护一个模型参数的高精度副本(通常是32-bit)。这个副本并不用于前向或后向传播的计算,而是用于在每次参数更新时执行更精确的累加操作,以确保最终更新的准确性和模型的稳定性。因此,虽然参数以16位精度参与计算,但优化器还需要保留一个高精度(32位)的版本来进行更新操作。因此,图中的“65B parameters * 4b = 260GB” 指的是这一部分的存储需求,它是优化器需要维护的模型参数的高精度副本。
  • Adam的参数260GB+260GB

Activations

  • 前向传播和后向传播的一些中间计算量

截屏2024-10-23 17.23.15

所以我们可以看到全参数微调对内存的需求很大,即使是65B的中等模型,需要很多张显卡才行(每张显卡80GB内存)。

四、PEFT

PEFT主要有如下几类1

  • 增加额外参数,如:Prefix Tuning、Prompt Tuning、Adapter Tuning及其变体。
  • 引入重参数化,如:LoRA、AdaLoRA、QLoRA。
  • 选取一部分参数更新,如:BitFit。
  • 混合高效微调,如:MAM Adapter、UniPELT。

截屏2024-07-23 13.02.46

1 Intuition behind PEFT

模型微调的背后直觉:

  • 微调具有低内在维度,意思是:为了达到令人满意的性能,模型实际需要调整的参数数量并不多。这表明,在一个庞大的模型中,并不需要修改所有的参数,只要修改其中一部分关键的参数就可以让模型获得不错的性能。这一发现是PEFT的核心思想。
  • 我们可以用低维的代理参数来重新参数化模型中的一部分原始参数。这意味着在进行模型微调时,我们可以不必对模型的所有参数进行优化,只需找到一些“代理参数”(low-dimensional proxy parameters),这些代理参数是低维的,且能很好地代表原始模型的一部分,从而简化优化的过程。

2 Prefix Tuning

如下图所示,Prefix Tuning在每一个Transformer层都加上一些可训练的virtual token作为前缀,以适应不同的任务。

截屏2024-10-23 17.41.51

具体怎么做呢,下图是没有Prefix的注意力计算。

截屏2024-10-23 17.43.16

下图是加入Prefix的注意力计算,我们可以看到:

  • 前缀不影响原始输入数据本身,在 Prefix Tuning 中 , 前缀 向量不会在模型输入之前直接添加,不会像 Prompt Tuning 会在输入前添加一个额外的提示词那样。相反,前缀向量是添加在模型的隐藏层(尤其是自注意力机制)中的,影响模型对输入数据的处理,但不改变输入数据本身。
  • 比如,假设你有一个输入句子 “Starbucks serves coffee”,这个句子作为输入传入模型,Prefix Tuning 的前缀不会直接拼接在这个句子前,加入到每层自注意力机制的 Key 和 Value 中,从而影响模型的内部计算

截屏2024-10-23 17.43.39

在微调时,我们只会更新Prefix这些参数,所以前缀向量的作用是增强自注意力机制中的上下文信息:

  • 在 Transformer 模型中,注意力机制的核心在于通过每个 token 之间的关联性来构建上下文。Prefix Tuning 通过给每层 Transformer 添加一组可训练的前缀向量,这些向量与输入的 token 一起作为注意力机制的输入,但它们不对应输入的具体 token,而是额外的信息源。
  • 具体来说,在计算注意力分数时,前缀向量作为额外的注意力查询键(key)和值(value)参与自注意力的计算。这意味着,输入的 token 不仅会彼此之间产生注意力分数,还会与这些前缀向量产生注意力,从而增强模型对任务相关上下文的理解。

3 Prompt Tuning

该方法可以看着是Prefix Tuning的简化版本,针对不同的任务,仅在输入层引入virtual token形式的软提示(soft prompt),如下图所示:

image-20241023174821321

特点:

  • 相对于Prefix Tuning,参与训练的参数量和改变的参数量更小,更节省显存。
  • 对一些简单的NLU 任务还不错,但对硬序列标记任务(即序列标注)表现欠佳。

4 Adapter Tuning

该方法设计了Adapter结构,并将其嵌入Transformer的结构里面,针对每一个Transformer层,增加了两个Adapter结构,在训练时,固定住原来预训练模型的参数不变,只对新增的Adapter结构和Layer Norm 层进行微调。 Adapter结构如下图右边所示:

image-20241023194344400

如下图所示,Adapter可以加在每个Transformer Layer.

image-20241024092450260

Adapter的缺点:

  • 添加新层会导致推理速度变慢。
  • 这也会使模型变大(可能更难适应现有的GPU资源)。
  • 适配器层在推理时需要顺序处理,这可能会破坏模型的并行性。

5 LoRA

LoRA的主要特点为:

  • LoRA通过冻结预训练模型的权重,并在Transformer架构的每一层中注入可训练的低秩分解矩阵来解决上述问题。
  • 这种方法显著减少了下游任务的可训练参数数量。例如,与GPT-3 175B的全参数微调相比,LoRA将可训练参数数量减少了10,000倍,GPU内存需求减少了3倍。

(1)核心思想

在Transformer中有很多全连接层,这些全连接层涉及到矩阵相乘的运算。论文的一个核心假设是针对于特定的任务,这些全连接层的权重矩阵在低秩的情况下,模型的效果也很好。

所以作者提出在微调时,可以学习模型中全连接矩阵增量的一个低秩表示,同时这里还用到了类似“残差”的思想,不重新学习整个 W W W,而是学习一个增量 Δ W = A ⋅ B \Delta W=A\cdot B ΔW=AB,最终的参数为:
W T = W + Δ W W_T=W+\Delta W WT=W+ΔW
其中 W W W是预训练模型的原始参数。同时,原论文只关注注意力层的权重矩阵,如下图所示:

截屏2024-07-23 14.02.43

上图右边部分更加具体的结构如下图所示:

截屏2024-07-23 14.11.44

这里 r r r远小于 d d d,假设 d = 1000 d=1000 d=1000 W W W矩阵参数量为 1000 × 1000 1000\times1000 1000×1000,若采用低秩分解,设 r = 2 r=2 r=2,则 A 、 B A、B AB矩阵参数量为 1000 × 2 × 2 = 4000 1000\times2\times 2=4000 1000×2×2=4000远小于 W W W训练的参数量大大减小!

(2)图解

原论文是对Attention的权重矩阵做Lora分解,实际应用也可以对Feed-forward层做,如下图所示。

image-20241024093014034

全连接层一般有两个矩阵,一个上投影矩阵 H × 4 H H\times 4H H×4H,一个下投影矩阵 4 H × H 4H\times H 4H×H,可以对每个矩阵做Lora,如下图所示:

image-20241024093204659

同理,Lora也可以在每个Transformer层加,如下图所示:

image-20241024093359981

6 BitFit

BitFit( Bias-terms Fine-tuning),顾名思义,仅更新Bias项的微调技术。

image-20241024103336892

如下图所示,仅更新Bias项,所需要的内存大大减少。

image-20241024103354266

7 多种不同的高效微调方法对比

如下图所示,PEFT需要更新的参数比例非常小!

image-20241024103614433

多种PEFT方法和全参数微调效果对比2

image-20241024103821376

总的来说,全参数微调效果最好,如果资源足够首选全参数微调。像LoRA、P-Tuning v2等都是综合评估很不错的高效微调技术。如果显存资源有限可以考虑QLoRA;如果只是解决一些简单任务场景,可以考虑P-Tuning、Prompt Tuning也行。

8 关于PEFT的库

  • OpenAI 微调 API

    • 可用的模型:gpt-3.5-turbo-0613,babbage-002 和 davinci-002.
  • HuggingFace PEFT 库

    • 实现了 LoRA,Prefix Tuning,Prompt Tuning等;
    • 有多种不同的模型可供适配.

参考资料


  1. Scaling Down to Scale Up: A Guide to Parameter-Efficient Fine-Tuning ↩︎

  2. Delta Tuning: A Comprehensive Study of Parameter Efficient Methods for Pre-trained Language Models.” Ding et al. 2023 ↩︎

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

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

相关文章

12个免费商用视频素材网站,助你打造高质量短视频!

我来啦,作为一个资深短视频运营! 在剪辑了1362条片子后,我总结出下面的这些素材网站~ 基本上都是剪辑中常用到的,下载的视频也是MP4格式,直接就可以用,还有图片、音效和Pr教程推荐,总有一款适…

使用Llama Index与Streamlit实现一个从文本中提取专业术语和定义网页小程序

Llama Index有许多用例(语义搜索、摘要等),并且都有很好的记录。然而,这并不意味着我们不能将Llama Index应用到非常具体的用例中! 在本教程中,我们将介绍使用Llama Index从文本中提取专业术语和定义的设计…

迭代器边遍历边删除存在的问题

迭代器边遍历边删除存在的问题以及原理 01-问题 ​ 我们先来看看如下代码 public static void main(String[] args) {List<Integer> list new ArrayList<>();list.add(5);list.add(4);list.add(3);list.add(2);list.add(7);list.add(0);Iterator<Integer>…

CSP-J代码解析!最新2024CSP-J题解及参考代码

经过整理&#xff0c;老师已经整理了今年CSP-J复赛的题目和代码解析&#xff01; T4题目名称有误&#xff0c;更正&#xff1a;接龙&#xff01; 需要PDF版本的→malaoshi606 T1 扑克牌 poker 算法&#xff1a;模拟&#xff0c;桶数组思路&#xff1a;创建一个标记数组vis&…

贪心算法记录 - 下

135. 分发糖果 困难 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&#xff0c…

OpenCV中的图像通道合并

在计算机视觉和图像处理领域&#xff0c;OpenCV是一个强大的工具库&#xff0c;它提供了从基本操作到复杂算法的广泛功能。今天&#xff0c;我们将通过一个简单的示例来探索OpenCV中的图像通道处理&#xff0c;特别是如何操作和理解BGR与RGB颜色空间的差异。 Lena图像&#xf…

LinkedList和链表(下)

1. 什么是LinkedList 在练习了单链表的自我实现和单链表的一些习题之后,我们正式来认识一下java提供的LinkedList,这是一种双向链表结构,在增删元素的时候效率比较高,不需要像ArrayList一样搬运元素.但是在查找方面效率比较低(需要遍历链表),ArrayList效率就比较高(直接由数组下…

JS+Springboot做一个交互Demo

背景&#xff1a;老大做了一个 SDK&#xff0c;包含字符加解密、文件加解密&#xff0c;要求能从前端访问&#xff0c;并且能演示的 Demo。 思路&#xff1a;html 写页面&#xff0c;js 发送请求&#xff0c;freemarker 做简单的参数交互&#xff0c;JAVA 后端处理。 一、项目依…

CSS 样式 box-sizing: border-box; 用于控制元素的盒模型如何计算宽度和高度

文章目录 box-sizing: border-box; 的含义默认盒模型 (content-box)border-box 盒模型 在微信小程序中的应用示例 在微信小程序中&#xff0c;CSS 样式 box-sizing: border-box; 用于控制元素的盒模型如何计算宽度和高度。具体来说&#xff0c; box-sizing: border-box; 会改…

【已解决】C# NPOI如何在Excel文本中增加下拉框

前言 上图&#xff01; 解决方法 直接上代码&#xff01;&#xff01;&#xff01;&#xff01;综合了各个大佬的自己修改了一下&#xff01;可以直接规定在任意单元格进行设置。 核心代码方法块 #region Excel增加下拉框/// <summary>/// 增加下拉框选项/// </s…

Python游戏开发超详细(基础理论知识篇)

一、引导&#xff1a; Python游戏开发是一个非常有趣且富有挑战性的领域。通过Python&#xff0c;你可以利用其强大的库和框架来创建各种类型的游戏&#xff0c;从简单的2D游戏到复杂的3D游戏。以下是第一课的基础理论知识&#xff0c;帮助你入门Python游戏开发。 二、理论知识…

中小企业设备资源优化:Spring Boot系统实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

部署seatunnel2.3.8

部署seatunnel web参考&#xff1a;SeaTunnel Web1.0.0安装_plugindiscoveryutil.getallconnectors-CSDN博客 配置&#xff1a;两台centos服务器&#xff0c;2master2worker 一、下载包 v2.3.8[bin] apache-seatunnel-2.3.8-bin.tar.gz 将包上传到master节点和worker节点所…

Python开发日记 -- 实现bin文件的签名

目录 1.数据的不同表现形式签名值不一样&#xff1f; 2.Binascii模块简介 3.问题定位 4.问题总结 1.数据的不同表现形式签名值不一样&#xff1f; Happy Muscle试运行了一段时间&#xff0c;组内同事再一次提出了新的需求&#xff1a;需要对bin文件签名。 PS&#xff1a;服…

使用代码编辑组件的npm包

使用代码编辑组件的npm包 文章说明核心代码运行截图源码下载 文章说明 我将书写的代码编辑组件打包为npm包&#xff0c;下载即可使用&#xff0c;目前是1.0.4版本&#xff0c;虽然功能还有一些bug&#xff0c;但是可以较为简单的使用 npm地址 核心代码 安装依赖 npm i bingbing…

H7-TOOL的LUA小程序教程第16期:脉冲测量,4路PWM,多路GPIO和波形打印(2024-10-25, 更新完毕)

LUA脚本的好处是用户可以根据自己注册的一批API&#xff08;当前TOOL已经提供了几百个函数供大家使用&#xff09;&#xff0c;实现各种小程序&#xff0c;不再限制Flash里面已经下载的程序&#xff0c;就跟手机安装APP差不多&#xff0c;所以在H7-TOOL里面被广泛使用&#xff…

OpenCV-物体跟踪

文章目录 一、物体跟踪的定义二、OpenCV中的物体跟踪算法三、OpenCV物体跟踪的实现步骤四、代码实现五、注意事项 OpenCV是一个开源的计算机视觉和机器学习软件库&#xff0c;它提供了丰富的功能来实现物体跟踪。以下是对OpenCV中物体跟踪的详细解释&#xff1a; 一、物体跟踪的…

清华大学《2022年+2021年822自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《清华大学822自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2022年真题 2021年真题 Part1&#xff1a;2022年2021年完整版真题 2022年真题 2021年真题…

论文笔记:通用世界模型WorldDreamer

整理了WorldDreamer: Towards General World Models for Video Generation via Predicting Masked Tokens 论文的阅读笔记 背景模型实验 背景 现有的世界模型仅限于游戏或驾驶等特定场景&#xff0c;限制了它们捕捉一般世界动态环境复杂性的能力。针对这一挑战&#xff0c;本文…

【若依笔记】-- 精简若依项目只保留系统管理

环境&#xff1a;最近项目需要计划使用若依来开发软件&#xff0c;使用若依有一个问题&#xff0c;若依代码框架还是比较冗余&#xff0c;不够精简&#xff0c;还有一点是若依Security权限校验&#xff0c;对于实现一对多的前台&#xff0c;比较麻烦&#xff0c;我这边的业务是…