自然语言处理: 第十九章LoRAQLoRA微调技巧

论文地址:使用低秩自适应 (LoRA) 进行参数高效LLM微调 - Lightning AI — Parameter-Efficient LLM Finetuning With Low-Rank Adaptation (LoRA) - Lightning AI



本篇文章是由位来自威斯康星大学麦迪逊分校的统计学助理教授Sebastian Raschka,也是人工智能平台Lightning AI的LLM研究员,进行了成百上千次关于LoRA的实验。他的实验日记为我们提供了宝贵的见解,包括如何节省内存、选择最佳配置等问题。他的研究回答了一些关键问题,例如是否应该用SGD取代AdamW,使用调度器的潜在价值,以及如何调整LoRA的超参数。


实验内容

由于之前的文章已经着重的分别介绍了LoRA 和 QLoRA ,这里就不在赘述原理了,主要解释一下LoRA的几个超参数:

  • r: rank也就是LoRA的低秩的秩的大小),较小的 r 导致更简单的低秩矩阵,从而导致在适应过程中学习的参数更少。这可以加快训练速度,并可能降低计算需求。但是,随着 r 的越小,低秩矩阵捕获特定于任务的信息的能力就会降低。这可能会导致适应质量降低,并且与较高的 r 相比,模型在新任务上的表现可能不如新任务。总之,在 LoRA 中选择较小的 r 需要在模型复杂性、适应能力以及欠拟合或过拟合的风险之间进行权衡。因此,重要的是要尝试不同的 r 值,以找到合适的平衡点,以在新任务上实现所需的性能。

  • alpha:alpha 是一个比例因子,这个系数用于在前向传播过程中将 LoRA 权重应用于预训练之中,用于调整组合结果的大小(原始模型输出加上低秩适应)。这平衡了预训练模型的知识和新的特定于任务的适应(默认情况下, alpha 通常设置为 1)。正如下图中的公式所示,LoRA 权重的值越大,影响就越大

    scaling = alpha / r
    weight += (lora_B @ lora_A) * scaling
    
  • dropout: 随机丢失

  • q & k & v: 是否对是否对自注意力的q & k & v 进行训练

  • projection: 是否对投影层进行训练

  • mlp: 是否线性层进行训练

  • head: 是否输出头进行训练

在这里插入图片描述

微调数据集


作者使用Alpaca 数据集进行监督指令微调。当然,还有许多其他数据集可用于指令微调,包括 LIMA、Dolly、LongForm、FLAN 等。然而,探索多个数据集和数据集混合的训练将是未来研究的一个有趣的主题。
Alpaca 数据集由大约 50k 个用于训练的指令-响应对组成,输入大小的中位长度为 110 个标记(使用 Llama 2 SentencePiece标记器),如下面的直方图所示

在这里插入图片描述


模型选择

作者在phi-1.5 1.3B, Mistral 7B, Llama 2 7B, Llama 2 13B, and Falcon 40B 五个模型种分别进行了性能评估,最终选择了Llama2 7B作为本次实验的对照组。

在这里插入图片描述


性能评估

作者对于模型评估,我从 Eleuther AI 的评估工具中选择了一小部分任务,包括TruthfulQA、BLiMP Causative、 MMLU Global Facts以及具有两位数(算术 2ds)和四位数字(算术 4ds)的简单算术任务。在每个基准测试中,模型性能分数在 0 到 1 之间标准化,其中 1 是满分。(主要是评估算数和QA的性能)


代码框架

作者使用的自定义 LLM 微调代码基于开源Lit-GPT 存储库。这部分我看了下还比较简单,大家如果想要复现作者的结果的话,可以参考作者原文以及Lit-GPT库。



实验结果

首先,我使用以下默认设置评估了 LoRA 微调(这些设置可以在微调/lora.py 脚本中更改):

LoRA & QLoRA的影响

# Hyperparameters
learning_rate = 3e-4
batch_size = 128
micro_batch_size = 1
max_iters = 50000  # train dataset size
weight_decay = 0.01
lora_r = 8
lora_alpha = 16
lora_dropout = 0.05
lora_query = True
lora_key = False
lora_value = True
lora_projection = False
lora_mlp = False
lora_head = False
warmup_steps = 100

此配置在总共 6,738,415,616 个可训练参数中训练了 4,194,304 个 LoRA 参数,使用单个 A100 在我的机器上花费了大约 1.8 小时。最大内存使用量为 21.33 GB。为了衡量方差,我重复了三次实验,以观察运行之间的性能波动,结果如下。可以发现几点:

  1. 运行之间的性能非常一致和稳定
  2. LoRA 默认模型在算术方面变得非常糟糕,但这可能是意料之中的,因为据我所知,Alpaca 不包含 (m)任何算术任务。(所以微调的数据集任务一定要由一定的倾向性,或者泛化性去对齐下游任务的性能)

在这里插入图片描述

除此之外,作者还同时做了QLoRA(4-bit下)的对比:可以发QLoRA能够明显的降低显存占用,但是也极大的提高了训练时间(我们可以看到 QLoRA 将内存需求降低了近 6 GB。然而,代价是训练时间减慢 30%,这是由于额外的量化和解定步骤而可以预料的)。但是在性能上QLoRA对模型性能的影响确实很小。该模型在算术基准上有所改进,但在MMLU Global Facts基准上有所下降。所以作者本着节省内存的目的,后续都利用QLoRA来作为对照组。

默认 LoRA(使用 bfloat-16):

  • Training time: 6685.75s 训练时间:6685.75s
  • Memory used: 21.33 GB 使用的内存:21.33 GB

QLoRA 通过 –-量化 “bnb.nf4”:

  • Training time: 10059.53s 训练时间:10059.53s
  • Memory used: 14.18 GB 使用的内存:14.18 GB

QLoRA 通过 –quantize “bnb.fp4”:

  • Training time: 9334.45s 训练时间:9334.45秒
  • Memory used: 14.19 GB 使用的内存:14.19 GB

在这里插入图片描述



Optimizer的影响

我在之前的所有实验中都使用了 AdamW 优化器,因为它是训练的LLM常见选择。但是,众所周知,Adam 优化器可能非常占用内存。这是因为它为每个模型参数引入并跟踪两个附加参数( m 和 v)。本节探讨是否值得将 AdamW 换成 SGD 优化器。但是,对于 SGD 优化器,引入学习速率调度器尤为重要。我选择了余弦退火scheduler,在每次批量更新后降低学习率。作者发现:

  1. 将 AdamW 与 SGD 交换只能节省少量内存,从14.18GB -》 14.15GB
  2. SGD 优化器的性能似乎与 AdamW 相当。有趣的是,当将调度程序添加到 AdamW 时,TruthfulQA MC2 和 MMLU Global Facts 性能有所提高,但算术性能有所下降。(注意:TruthfulQA MC2 是其他公共排行榜中广为人知的基准测试。目前,我们不会过分强调算术性能,而是使用带有调度器的 AdamW 继续进行本文中的其余实验。(意思就是很玄学, 所以没太大差异)

在这里插入图片描述



数据集的影响

到目前为止,我已经用 50k 次迭代训练了所有模型——Alpaca 数据集有 50k 次训练示例。显而易见的问题是,我们是否可以通过多次迭代训练集来提高模型性能,因此我运行了之前的 100k 迭代实验,增加了 2 倍:整体结果如下:

  1. 增加的迭代会导致整体性能更差。对于算术基准来说,下降幅度最大。我的假设是,Alpaca 数据集不包含任何相关的算术任务,并且当模型更多地关注其他任务时,它会主动取消学习基本算术。(相当于过拟合微调的数据集了)

在这里插入图片描述


LoRA本身超参数的影响

LoRA 超参数调优第 1 部分:适用于所有层的 LoRA

现在我们已经探索了围绕 LoRA 微调脚本的基本设置,让我们将注意力转向 LoRA 超参数本身。默认情况下,LoRA 仅对多头自注意力块中的 Key 和 Query 矩阵启用。现在,我们还为值矩阵、投影层和线性层启用了它:

在这里插入图片描述


LoRA 超参数调优第 2 部分:提高 R

最重要的 LoRA 参数之一是“r”,它决定了 LoRA 矩阵的秩或维度,直接影响模型的复杂性和容量。较高的“r”表示较强的表现力,但可能导致过度拟合,而较低的“r”可以减少过度拟合,但会牺牲表现力。让所有层都启用 LoRA,让我们将 r 从 8 增加到 16,看看这对性能有什么影响:

  1. **作者这里暗示了参数r和alpha需要二者结合进行调参,最佳设置是alpha = 2 * r **

在这里插入图片描述



LoRA 超参数调优第 3 部分:更改 Alpha

在上一节中,我们增加了矩阵秩 r,同时保持 LoRA 的 alpha 参数不变。较高的“alpha”将更强调低秩结构或正则化,而较低的“alpha”将降低其影响,使模型更多地依赖原始参数。调整“alpha”有助于在拟合数据和通过正则化模型来防止过度拟合之间取得平衡。根据经验,在微LLMs调时,通常选择比秩大两倍的 alpha(请注意,在使用扩散模型时,这是不同的)。让我们试试这个,看看当我们将 alpha 增加两倍时会发生什么:

  1. r 和 alpha的增加不会明显影响峰值内存要求
  2. r 和 alpha 需要共同调整,一般alpha为r的两倍最佳。 然后r的大小一般根据任务集的难度来定(这个需要自己评估,越大适合难度越大的任务,越小适合简单任务)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传





结论

本文探讨了使用 LoRA 训练自定义LLMs时可以调整的各种旋钮。

  • 我们发现 QLoRA 是一个很好的内存节省器,尽管它增加了运行时成本。
  • 虽然学习速率调度器可能是有益的,但在 AdamW 和 SGD 优化器之间进行选择几乎没有区别。
  • 多次迭代数据集会使结果变得更糟。(过拟合微调数据集)
  • 通过优化 LoRA 设置(包括排名)可以实现最佳收益。增加排名将导致更多可训练的参数,这可能会导致更高程度的过拟合和运行时成本。但是,在提高排名时,选择适当的 alpha 值很重要,一般为2倍的r

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++除了Qt还有什么GUI库?

C除了Qt还有什么GUI库? 先,不要折腾,不要想着用 C 来做 App 类的 GUI 开发。 所以你问用 c gui 库,本来确实有很多,但是经过几十年的沉淀,最后只留下一个 qt quick 和其他特殊需求的库(包括 qt…

西圣、漫步者、万魔开放式耳机如何?甄选机型实测对比测评

无论是通勤、工作还是休闲时光,耳机总能为我们带来沉浸式的音乐体验。近年来,开放式耳机以其独特的优势逐渐受到市场的青睐,其中西圣、漫步者、万魔等品牌在市场上相当火热,那这三款开放式耳机的实际到底如何,还是有许…

nodeJs中实现连表查询

nodeJs中实现连表查询 router.post(/getOrder, async function(req, res, next) {let userId req.body.phone;let sql select * from orders where userId?;let orders await new Promise((resolve, reject) > {connection.query(sql, [userId], function(error, resul…

Python灰帽子网络安全实践

教程介绍 旨在降低网络防范黑客的入门门槛,适合所有中小企业和传统企业。罗列常见的攻击手段和防范方法,让网站管理人员都具备基本的保护能力。Python 编程的简单实现,让网络运维变得更简单。各种黑客工具的理论和原理解剖,让人知…

详解“外卡收单”系统(1)

近年来,随着跨境贸易和服务的不断发展,外卡收单行业展现出新的发展态势。随着越来越多外国人在中国消费,中国商家为满足海外消费者需求开始接受国际信用卡支付。根据官方数据显示,截至2023年11月,上海的外卡POS机已超过…

【C++】vector容器初步模拟

送给大家一句话: 努力一点,漂亮—点,阳光一点。早晚有一天,你会惊艳了时光,既无人能替,又光芒万丈。 vector容器初步模拟 1 认识vector开始了解底层实现 2 开始实现成员变量构造函数 析构函数尾插迭代器插入…

集成学习 | 集成学习思想:Boosting思想 | XGBoost算法、LightGBM算法

目录 一. XGBoost 算法1. XGBoost 算法流程2. XGBoost 算法评价 二. LightGBM 算法2. LightGBM 算法优势 上一篇文章中,我们了解了Boosting思想的两种算法:Adboost和GBDT;其中对于GBDT算法,存在两种改进,即&#xff1a…

外包干了20天,技术退步明显.......

先说一下自己的情况,大专生,21年通过校招进入杭州某软件公司,干了接近2年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了2年的功能测试…

1分钟带你学会使用Python操作 xlsx 文件绘制面积图

​我们工作中经常要处理海量的数据,如果没有一个直观的可视化工具,怎么可能一眼就看出数据背后的故事呢?数据可视化显得越来越重要,数据分析已经成了现代人必备的技能。 今天来和大家分享一个超有趣的数据可视化方法——绘制面积…

Redis中文乱码问题

最近排查问题,发现之前的开发将日志写在redis缓存中(不建议这样做),我在查看日志的时候发现没办法阅读,详细是这样的: 查阅资料后发现是进制问题,解决方法是启动客户端的时候将redis-cli改为red…

流畅的 Python 第二版(GPT 重译)(四)

第二部分:函数作为对象 第七章:函数作为一等对象 我从未认为 Python 受到函数式语言的重大影响,无论人们说什么或想什么。我更熟悉命令式语言,如 C 和 Algol 68,尽管我将函数作为一等对象,但我并不认为 Py…

【机器学习】机器学习是什么?

文章目录 前言 机器学习 序列学习和对抗学习有什么不同 总结 前言 在当今快速发展的科技时代,人工智能已经成为推动社会进步的重要力量。机器学习,作为人工智能领域的一个重要分支,它的核心能力在于使计算机系统能够从数据中学习规律&…

Python RPA简单开发实践(selenium登陆浏览器自动输入密码登陆)

打开csdn博客,简单版 class BS:def __init__(self, url):self.url url# self.password password# self.username usernamedef login_url(self):from selenium import webdriver# 不自动关闭浏览器option webdriver.ChromeOptions()option.add_experimental_opt…

Vue 若依框架 form-generator添加表格组件和动态表单组件

效果图: 在若依框架自带的流程表单配置基础上添加这两个组件 config.js // 表单属性【右面板】 export const formConf {formRef: elForm,formModel: formData,other: other,size: medium,labelPosition: right,labelWidth: 100,formRules: rules,gutter: 15,dis…

LeetCode每日一题[c++]-322.零钱兑换

题目描述 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无…

游戏提示steam_api64.dll丢失怎样修复?教你5种快速修复的方法

在计算机系统中,如果未能成功找到或加载steam_api64.dll文件,可能会引发一系列的问题和故障现象。这个特定的DLL文件是Steam平台的核心组件之一,对于运行基于Steam平台的游戏或应用至关重要。当系统提示“找不到steam_api64.dll”时&#xff…

抖音视频关键词爬虫批量采集软件|视频提取下载工具

视频关键词批量采集软件 — 助力您快速获取所需视频 主要功能: 关键词批量提取视频和单独视频提取,提取后下载功能。 功能解析: 1. 关键词批量提取视频的解析 通过输入关键词进行视频搜索和提取。例如,输入“汽车配件”&#x…

N9010B EXA 信号分析仪 10 Hz 至 44 GHz

N9010B EXA 信号分析仪 10 Hz 至 44 GHz 产品综述 <<<<频率范围&#xff1a;10 Hz 至 44 GHz>>> keysight N9010B EXA 信号分析仪&#xff0c;10 Hz 至 44 GHz无论是增强产品性能还是提高测试吞吐量&#xff0c;您的通用型信号分析仪都要有能力满足各…

为什么电商系统一定要跟企业ERP做数据对接?

一篇文章告诉你&#xff0c;为什么电商系统一定要跟企业ERP做数据对接&#xff1f; 在电商日益发展的情况下&#xff0c;每个电商企业的单量越来越大。但是电商系统对于财务来说并不友好&#xff0c;所以企业会另外上一套财务系统方便财务做账和企业内部管理。那如果还是按照之…

后端常问面经之操作系统

请简要描述线程与进程的关系,区别及优缺点&#xff1f; 本质区别&#xff1a;进程是操作系统资源分配的基本单位&#xff0c;而线程是任务调度和执行的基本单位 在开销方面&#xff1a;每个进程都有独立的代码和数据空间&#xff08;程序上下文&#xff09;&#xff0c;程序之…