🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏 - 机器学习【ML】 自然语言处理【NLP】 深度学习【DL】
🖍foreword
✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。
如果你对这个系列感兴趣的话,可以关注订阅哟👋
文章目录
什么是LoRA?
超参数
Rank:8
Alpha: 16
目标模块:所有密集层
Base learning rate:1e-4
模型质量结果
非结构化文本的功能表示 (ViGGO)
小学数学 (GSM8k)
SQL
LoRA 与全参数微调:需要考虑的事项
任务类型很重要
LoRA 对学习率的敏感度
提示的作用
LoRA 与嵌入层中特殊令牌的相互作用
LoRA 的训练速度优势
LoRA 的内存使用优势
检查点大小和 LoRA 的服务优势
结论
在本文中,我将全参数微调与 LoRA 进行比较,并回答有关这两种技术的优缺点的问题。使用 LoRA 涉及服务效率和模型质量之间的权衡,这根据手头的具体任务而变化。此外,我还提供有关如何通过智能提示技术稳定 LoRA 训练的见解。进一步表明,采用较低的学习率可以提高所得模型检查点的可靠性。
近几个月来,开源LLM与 OpenAI 的专有模型展开了一场竞赛。提高开源 LLM 性能的一种流行策略是全参数微调。在该方法中,所有模型的参数都被优化。
全参数微调是资源密集型的,需要大量的计算能力来管理优化器状态和检查点。提供一些背景信息:优化器状态和梯度通常会导致内存占用大约比模型本身大 12 倍。这使得即使是最小的 Llama-2(拥有 70 亿个参数)的微调也成为一项艰巨的计算任务。因此,该领域出现了所谓的“参数高效微调”(又名 peft)方法。这些策略,例如 LoRA(大型语言模型的低秩适应),旨在细化相对较小的参数子集,从而最大限度地减少资源利用率并加快训练周期。
在本文中,我们比较了全参数和 LoRA 微调,并重点介绍了两者的优缺点。介绍了三个数据集的基准,我们对这些数据集的基准和通过全参数微调获得的改进有了很好的理解。由于 LoRA 仍然是一项相当新的技术,我们还更详细地讨论了我们使用 LoRA 进行训练的经验,提供提示和技巧,以便您可以简化您的 LoRA 训练体验。
当应用于 Llama-2 LLM 时,基于 LoRA 的微调提供的性能几乎与全参数微调相当。因此,它在生成 SQL 查询或基于文本的函数表示等专门任务中可以胜过 GPT-4,尽管它在数学推理任务中表现不佳。在附图中,紫色条表示 GPT-4 的性能;深色条代表基线聊天调整模型;中阴影条显示 LoRA 微调的增益;最亮的条显示全参数微调的结果。
什么是LoRA?
LoRA 代表大型语言模型的低秩适应,其运作基于一个重要的见解:专门任务的微调权重与初始预训练权重之间的差异通常表现出“低内在等级”——这意味着它可以通过低秩矩阵很好地近似。矩阵的低阶意味着什么?低秩矩阵具有很少的线性独立列,这意味着,简单来说,该矩阵不太“复杂”。低秩矩阵的一个很酷的特性是它们可以表示为两个较小矩阵的乘积。这种认识导致了这样的假设:微调权重和初始预训练权重之间的增量可以表示为两个小得多的矩阵的矩阵乘积。
实际上,原始权重矩阵在微调过程中保持冻结状态。相反,两个额外的矩阵 A 和 B 被微调。这些矩阵充当微调权重矩阵的分解。请考虑 LoRA 原始论文中的以下插图:
该图取自原始论文,可视化模型中一个矩阵的张量运算。A和B是前面提到的小矩阵。输入向量 d 通过原始预训练权重和 LoRA 的微调低秩分解矩阵并行处理。
值得注意的是,通过在训练过程中冻结原始“预训练权重”并选择 r << d,与全参数微调相比,优化器的内存占用和检查点的大小都可以显着减少。该方法可以应用于模型架构中的任何密集层。自最初的 LoRA 论文发布以来,已经引入了许多基于 LoRA 的技术,尽管它们超出了本讨论的范围。
LoRA 等参数高效方法的主要优点在于更高效的模型部署,特别是在管理多个专用模型时。随着开发一系列针对各种任务量身定制的专业法学硕士的趋势,这一点变得越来越重要。
超参数
在深入研究我们的实验结果之前,我们先简要介绍一下我们在本文中用作 LoRA 配置基线的超参数。
每个选择背后的基本原理仍然是大型语言模型 (LLM) 社区中活跃争论的主题,我们对以下决定进行了一些阐述:
Rank:8
为我们的分解矩阵选择更高的等级会抵消 LoRA 的效率增益。我们的初步测试表明,当将等级增加到例如 16 时,性能提升幅度很小。因此,我们决定将等级设置为 8,以保持较小的检查点大小并避免人为地夸大我们的检查点文件。
Alpha: 16
Alpha 缩放学习到的权重。现有文献,包括最初的LoRA 论文,通常建议固定 Alpha(通常为 16),而不是将其视为可调节的超参数。
目标模块:所有密集层
最初的 LoRA 论文专注于仅微调“Q”和“V”注意力矩阵,取得了证明该技术有效性的可靠结果。然而,后续工作表明,针对其他层,甚至所有层,可以提高性能。我们假设将 LoRA 应用到更多层数可以让我们更接近实现全参数微调的能力。因此,我们选择在所有层实施 LoRA。
Base learning rate:1e-4
1e-4 的学习率已成为使用 LoRA 微调 LLM 时的标准。尽管我们偶尔会遇到训练损失不稳定的情况,但事实证明,将学习率降低到较低的值(例如 3e-5)可以有效稳定过程 - 接下来将对此进行更多介绍。
模型质量结果
针对 GSM8k、ViGGO 和 SQL 数据集微调小模型的有效性。在这里,我们使用那里获得的结果作为评估 LoRA 的基线。这里我们将重点关注全参数微调和 LoRA 微调的结果比较。
非结构化文本的功能表示 (ViGGO)
我们训练模型的第一个数据集是 ViGGO。任务是从句子中提取功能表示。以下是失败预测的一个数据点:
上面的数据点表明,这项任务不需要更高水平的逻辑或推理。该任务本质上只需要模型从一种表示映射到另一种表示。这是一个带有全参数微调的小模型可以很好地学习的任务;现在的问题是 LoRA 是否也能学习它。
ViGGO 数据集上模型大小和微调方法的预测精度。绘图显示,我们的 LoRA 微调模型仅比全参数微调模型稍差,在 ViGGO 测试集上实现了几乎 100% 的准确度。
从这些结果中我们可以了解到,尽管已经进行了一定程度的超参数优化,但我们必须为 LoRA 实验牺牲一些准确性。作为一个具体示例,我们在 13B 模型上权衡了 2% 的准确率(95% 与 97%)。在大多数现实世界的用例中,我们部署经过微调的 LLM 来使其发挥作用,LoRA 将是首选技术,因为它可以更有效地提供服务,并且 2% 的准确性损失可能不会太大交易。
小学数学 (GSM8k)
该学术数据集测试了模型对数学问题的逻辑推理能力。问题和答案的结构类似于以下:
请注意,有很多方法可以得出正确答案,这与我们测试的其他数据集形成鲜明对比。考虑到这一点,在评估我们的模型时,我们只考虑四个主题标签前面的最终答案。那么,LoRA 的表现如何呢?下面显示了我们针对 GSM8k 训练的模型的准确性:
GSM8k 数据集上模型大小和微调方法的预测精度。与全参数微调模型相比,这两个 LoRA 微调模型的表现较差。70B 模型显然不是这样,LoRA 达到了与全参数微调几乎相同的精度。话虽如此,70B 型号相对于基准的改进相对较小。
通过这两种微调技术,基础模型的能力在模型的逻辑/数学推理能力中发挥着重要作用。尽管如此,LoRA 的性能始终明显低于全参数微调。这可以追溯到 LoRA 是一种低阶近似的事实,它可能无法最好地概括数学技能。请注意,与其他任务相比,即使是全参数微调也不是特别好。学习数学并不是一项微不足道的任务——一个人不能仅仅通过几千个例子来“微调”自己的方式来培养强大的数学推理能力。
SQL
我们评估的最终数据集是与现实世界用例相关的数据集。此 SQL 数据集将自然语言查询映射到函数式 SQL 查询。更具体地说,任何数据点都包含三个字段:
从与 ViGGO 任务的相似性,我们可以看出为什么经过微调的 LLM 应该是解决这个问题的有希望的候选者。同样,模型需要学习一组形式原则来解决此任务,而不是应用高水平的逻辑或推理。
通过模型大小和 SQL 数据集上的微调方法来预测准确性。LoRA微调模型几乎与全参数微调模型相当。 请注意,LoRA 微调 13B 模型的表现略优于全参数微调 7B 模型。
LoRA 与全参数微调:需要考虑的事项
尽管 LoRA 被设计为全参数微调的替代方案,但在训练过程中需要记住一些具体的细微差别。
任务类型很重要
需要强调的是,LoRA 在微调时充当理想权重的低阶近似。这有效地限制了网络的“适应能力”。为了从数学角度构建这一点,请将大型语言模型 (LLM) 的原始权重视为矩阵“X”。对于任何给定的任务,经过优化微调的 LLM 的权重将由矩阵“Y”表示。微调的目标是发现一个 delta 矩阵“Z”,使得 X+Z=Y。然而,在 LoRA 的情况下,这个增量矩阵“Z”是通过低秩分解来近似的。因此,对于某些类型的任务来说,实现最佳解决方案可能具有挑战性。一些数据集可能更容易适应,而另一些数据集可能会带来困难。相比之下,全参数微调则没有这个约束;学习到的权重保留了原始模型的表达能力,可能简化了拟合不同数据的任务。这是一个经验问题,值得通过实践测试进行探索。
在我们的实验中,我们观察到 GSM8k 数学数据集上全参数和 LoRA 微调之间的最大性能差距。这项任务需要学习一项具有挑战性的新技能——低秩近似可能无法最好地捕捉到这一技能。然而,对于其他任务,这种差距要小得多。
LoRA 对学习率的敏感度
即使对于 LoRA 表现良好的任务,我们也需要调整学习率以实现稳定的训练。由于参数数量有限,LoRA 的优化环境比全参数调整更加棘手。请考虑 SQL 实验中的以下图表:
图表显示了学习率对训练稳定性和验证集困惑度的影响。对于这个特定任务,我们将学习率从 1e-4 降低到 3e-5 以稳定学习。
训练损失的这种差异会导致评估损失的巨大差异,从而导致 LoRA 微调模型的表现严重不佳,这是可以理解的。虽然存在稳定性问题,但当选择正确的学习率时,在针对全参数微调进行测量时,收敛性可以接近最佳。
让我们从生产微调的角度来考虑这一点。下图显示了使用 LoRA 的 70B 模型的微调,并且除学习率之外的所有超参数均保持不变。
图表显示两次训练达到了大致相同的困惑度。对于较低的学习率,困惑度达到最低,而训练损失稳定下降。对于高学习率,训练损失会爆炸,使我们对检查点的最优性信心不足。
两种模型在 GSM8k 数据集上的成功率均为 61%。虽然较低的学习率会产生“教科书”学习曲线,但较高的学习率却显得不稳定。因此,尽管坚持 1e-4 的学习率可以节省培训成本,但认识到潜在的不稳定因素仍然至关重要。解决这个问题对于确保生产微调中的成本效益和性能可靠性至关重要。
提示的作用
您可能会想,“我真的需要进行超参数调整吗?” LoRA 的主要优势之一是其内存和服务效率。但如果这意味着必须启动多个作业并进行网格搜索以找到最佳配置,那么它似乎就没那么有吸引力了。这就是提示可以真正缓解问题的地方。
在我们之前关注全参数微调的博客文章中,我们讨论了如何用输入和所需输出的简单串联(由特殊学习的标记分隔)来替换提示是有效的。然而,通过 LoRA,我们发现这种输入和输出的盲目合并(即使使用特殊令牌)可能不是最稳定的方法。这与我们之前的断言一致,即数据分布太远会导致 LoRA 陷入困境。
考虑 ViGGO 任务。在没有提示的设置中,数据可能显示如下:
正确提示的数据点将包括任务的描述,在某种程度上类似于没有少量示例的提示工程:
使用聊天格式作为适用于各种任务的通用框架。然而,关键的一点是,任务的描述将使答案中标记的出现更有可能以问题中存在的标记为条件,从而使优化问题变得更容易,微调也更有效。
该图显示了 ViGGO 任务微调期间任务描述提示对模型性能的影响。在其他超参数保持固定的情况下,学习稳定性随着提示而显着增加。
虽然任务描述可以提高微调效率,但它们可能会破坏微调的目标之一——缩短提示。当使用 LoRA 作为微调策略时,这种权衡变得更加突出。因此,您可能会发现自己处于尝试各种提示以优化微调模型的循环中。
LoRA 与嵌入层中特殊令牌的相互作用
正如我们在之前的博客文章中强调的那样,我们集成了额外的特殊标记来更好地构建我们的数据。在我们正在使用的 Llama 2 模型中,这些标记将词汇量从 32,000 增加到 32,004。当然,这提出了一个问题:我们应该训练这些额外的代币吗?如果是这样,我们应该将 LoRA 应用于整个层还是使额外的嵌入可训练?
对于我们的微调目标,简单地随机初始化它们,然后将 LoRA 应用于整个嵌入层似乎就足够了。然而,重要的是要记住将这些随机初始化的新词汇嵌入包含在模型的检查点中,以便稍后进行准确的推理。
嵌入层 LoRA 检查点结构的可视化。这里显示的是 LoRA 等级为 8 的示例。除了 LoRA 特定的矩阵 A 和 B 之外,保存在词汇扩展期间创建的附加嵌入也很重要,这些嵌入是随机初始化的。
LoRA 的训练速度优势
LoRA 为模型引入了新的参数和操作,使得前向传播稍微慢一些。另一方面,由于 GPU 之间所需的梯度通信较少,可训练参数越少,后向传递速度就越快。
我们发现,如果不利用减少的内存占用(通过增加批量大小),LoRA 不会比全参数微调提供显着的速度优势。也就是说,如果您的工作负载不受计算限制,那么增加批量大小确实可以提高您的训练吞吐量。
例如,在 p4de.24xlarge 节点上微调 Llama-7B 模型时,全参数方法需要批量大小为 8,才能充分利用可用的 GRAM 内存。另一方面,使用 LoRA,您可以将批量大小提高到 64,并且仍然保持在内存限制范围内,从而优化训练速度。
p4de.24xlarge 节点上上下文长度为 512 的 7B 模型的训练吞吐量(每秒令牌数)的比较。LoRA 内存占用较低,可实现更大的批量大小,从而使吞吐量提高约 30%。
这里还有另一个需要考虑的方面:虽然您确实见证了 LoRA 带来的吞吐量增加,但这并不一定意味着与全参数微调相比您会更快地达到收敛。LoRA 虽然对内存有效,但可能会影响模型收敛的速度。为了说明这一点,让我们看一下之前实验中的训练损失曲线:
LoRA 和全参数训练损失的并排比较,显示了实时测量时相似的收敛率。
我们的测试表明,经过 20 分钟的训练后,这两种方法都会产生类似的困惑度。因此,就达到相似质量检查点的成本效益而言,LoRA 和全参数微调基本不相上下。也就是说,如果您正在运行多个模型,LoRA 更高效的资源部署可能会真正改变游戏规则。
LoRA 的内存使用优势
LoRA 在训练过程中的最大优势是减少了内存使用。这开启了诸如对更便宜的低内存实例进行微调的能力或诸如对更大的上下文长度进行微调的其他功能。为了说明这一点,我们尝试训练所有模型大小(7B、13B 和 70B)。下面是应用全参数微调与 LoRA 时的一个时期的内存消耗对比:
训练期间 GPU 内存(顶部)和 CPU 内存(底部)的集群总利用率。左边的运行表示全参数微调的一个时期。正确的运行标志着 LoRA 微调的一个纪元。顶部图表中的每种颜色代表一个 GPU 的内存利用率。
从这两张图中我们可以看到,内存消耗在一个纪元结束时(检查点期间)达到峰值。我们可以测量检查点期间 GPU 内存和 CPU 内存的消耗,以估计所需的最大内存。下图进一步说明了微调技术之间的差异:
说明在单个 p4de.24xlarge 节点上微调 Llama 2 模型系列(上下文长度为 512 个标记且批量大小为 8)时所需内存总量的差异。对于 7B 和 13B 型号,LoRA 消耗的内存要少得多,因此可以在更少或更便宜的实例上运行。全参数微调的“缺失”图表强调了内存需求超出了 p4de.24xlarge 实例的规格这一事实。
对于 70B 模型,由于内存占用较小,我们能够在单个 p4de.24xlarge 节点上使用 LoRA 运行微调作业。这凸显了 LoRA 的另一个优势:显着降低的内存要求使我们能够利用更少的资源。
检查点大小和 LoRA 的服务优势
下表描述了全参数微调和两种不同 LoRA 配置之间检查点大小的差异。后一种 LoRA 配置将 LoRA 应用到所有层,使我们能够实现本文前面详细介绍的有希望的精度。
该数据强调了 LoRA 在同时服务多个微调模型方面的实际优势。就上下文而言:存储 20 个完全微调的 7B 模型将需要大约 280GB 的空间。相比之下,根据我们选择的 LoRA 参数,相同的存储空间可以容纳大约 700 个经过 LoRA 微调的 70B 模型(包括基本模型)。
在服务方面,LoRA 较小的检查点可以实现各种模型的高效存储和快速加载。当您需要为每个服务请求使用唯一的模型时,这尤其有利。此外,在同一批次中跨请求重用基本模型的能力使我们能够采用更大的批次大小,从而通过增加吞吐量、减少延迟和降低成本来提高服务效率。
结论
通过我们对硬件要求和预测精度的比较,我们希望使读者相信以下内容:
LoRA 的主要权衡很简单:您可能会放弃一些模型质量,但您可以获得更有效地服务许多模型的能力。
虽然 LoRA 在专业应用中表现出色,但它可能会在需要逻辑推理技能等更广泛的任务中遇到困难。
通过输入到输出的盲目串联,我们应该调整学习率以获得可靠的训练检查点。
不要低估数据提示的作用。它可以提高训练的稳定性,使我们能够选择更高的学习率,而不会造成训练的不稳定。
无法保护 A100?借助 LoRA,您仍然可以在较小的 GPU 上微调模型。
与常规检查点相比,LoRA 检查点明显更小,有助于实现更具可扩展性的服务,特别是在管理多个微调模型时。
翻译自:Fine-Tuning LLMs: LoRA or Full-Parameter? An in-depth Analysis with Llama 2