0%

使用PEFT和LoRA技术微调LLM指南

这篇博客是一篇译文,汇总了下面两篇文章的主要内容,介绍了常用的大语言模型微调技术,以及如何使用 LoRA 和 QLoRA 等技术微调大语言模型。原文地址为:

https://www.mercity.ai/blog-post/fine-tuning-llms-using-peft-and-lora

https://www.mercity.ai/blog-post/guide-to-fine-tuning-llms-with-lora-and-qlora

下面主要分为两部分,首先介绍常用微调技术的原理,然后介绍如何使用 LoRA 和 QLoRA 技术进行微调。

常用微调技术介绍

像 GPT 这样的大型语言模型 (LLM) 的规模只会变得越来越大。即使像 MPT 和 Falcon 这样的开源模型也分别达到了 30 和 400 亿个参数。随着尺寸的增大,这些模型的功能和复杂性也随之增加。但复杂性和模型尺寸的增加也会带来挑战。训练更大的模型需要更广泛的数据集,并且随着模型的增长,必须调整更多的参数。这可能需要大量计算,因此成本也很高。这就是微调的用武之地。微调是一种允许重新利用预训练模型的技术,有助于降低构建更大模型的复杂性。

什么是微调

微调是采用已经针对某些任务进行过训练的模型,然后对其进行调整以执行类似任务的过程。当新的数据集或任务需要模型进行一些修改,或者模型在特定任务上表现不佳时,通常会使用它。

例如,经过训练生成故事的模型可以经过微调来生成诗歌。这是可能的,因为模型已经学会了如何生成随意语言和写故事,如果模型调整得当,该技能也可以用于生成诗歌。

微调如何工作

如前所述,微调是针对其他任务调整已经训练好的模型。其工作原理是采用原始模型的权重并调整它们以适应新任务。

经过训练的模型会学习执行某些特定任务,例如,GPT-3 已经在大量数据集上进行了训练,因此,它学会了生成故事、诗歌、歌曲、信件和许多其他内容。人们可以利用 GPT-3 的这一功能,并针对特定任务对其进行微调,例如以特定方式生成客户查询的答案。

微调模型的方法和技术有多种,最流行的是迁移学习。迁移学习源于计算机视觉世界,它是冻结网络初始层的权重并仅更新后面层的权重的过程。这是因为较低层(更接近输入的层)负责学习训练数据集的一般特征。更靠近输出的上层学习更多与生成正确输出直接相关的具体信息。

以下是微调工作原理的快速可视化:

img

为什么要使用微调

随着模型大小的增加,训练它变得更加昂贵和耗时。规模越大,需要更多的训练数据,否则模型通常会过度拟合并在生产环境中产生较差的结果。微调使我们能够通过有效地使用预先训练的模型来达到我们的目的,从而避免遇到这些问题。以下是您应该考虑微调而不是从头开始训练模型的一些原因:

较大的模型可以很好地推广到下游任务

我们都知道像 GPT-3 和 GPT-4 这样的大型模型可以在复杂的任务上表现得非常好。这是因为它们拥有非常复杂的架构,并且接受过海量数据集的训练,这有助于它们很好地概括许多任务。这些模型了解语言的基本属性,这有助于他们以最小的努力学习任何新任务,例如即时工程。

但是,如果我们想将这些模型用于一些非常具体的任务,例如构建法律合同生成器,您可能应该微调模型,而不是使用即时工程。这是因为在语言生成等非常通用的任务中表现良好的模型也会在生成法律合同等下游任务中表现良好。

比训练整个模型更便宜

如前所述,从头开始训练这些大型模型可能非常昂贵。也非常耗时。训练已经训练过的模型总是更便宜。这还允许您利用已有的资源,而不是自己做所有事情。大多数时候,构建好的数据集可能非常困难且耗时。 MPT 和 LLaMA 等开源模型已经由一些最优秀的研究人员进行了培训,并确保它们能够正常工作。在云基础设施中加载和训练它们非常容易。

适合在线训练

人工智能最大的挑战之一是使模型保持最新数据。如果不定期更新,在生产中部署的模型的性能可能会开始下降。例如,如果您部署人工智能模型来预测商店中的客户行为,那么一旦商店补充了不同价格的产品或在商店中推出了新产品,该模型可能会停止表现良好。这是一个典型的例子,说明数据的变化如何极大地改变模型的性能。

微调可以帮助您不断使用最新数据更新模型,而无需重新训练整个模型。这使得无需太多努力和成本就可以在生产中部署模型。这称为在线学习或在线培训,对于生产中的任何模型都是绝对必要的。

img

什么是 PEFT

PEFT(参数高效微调)是一组技术或方法,用于以最具计算效率和时间效率的方式微调大型模型,而不会损失您可能从完全微调中看到的任何性能。这样做是因为随着像 BLOOM 这样拥有多达 1760 亿个参数的模型变得越来越大,不花费数千万美元几乎不可能对它们进行微调。但有时几乎有必要使用如此大的模型以获得更好的性能。这就是 PEFT 发挥作用的地方。它可以帮助您解决大型模型中遇到的问题。

以下是一些 PEFT 技术:

img

为什么选择PEFT

如上所述,在生产级应用程序中,微调和使用更大的模型已成为必要。 PEFT 技术使您能够有效地微调模型,从而节省金钱和时间。这是通过仅微调神经网络中最重要和最相关的参数来完成的。这些技术在网络中引入新的参数或冻结除某些部分之外的整个模型,以便更容易训练模型。

迁移学习Transfer Learning

迁移学习是指我们获取模型的一些学习参数并将其用于其他任务。这听起来与微调类似,但又有所不同。在微调中,我们重新调整模型的所有参数或冻结部分权重并调整其余参数。但在迁移学习中,我们使用一些从模型中学习到的参数,并将它们用于其他网络中。这使我们能够更加灵活地开展工作。例如,我们在微调时无法改变模型的架构,这在很多方面限制了我们。但是,当使用迁移学习时,我们仅使用经过训练的模型的一部分,然后我们可以将其附加到具有任何架构的任何其他模型。

迁移学习运行原理

迁移学习长期以来一直是计算机视觉领域的常见做法。这是因为视觉模型的性质及其学习方式。在 CNN 模型中,早期层提取更一般的特征,如边缘和曲线,而后面的层提取更复杂的特征,如整个眼睛和面部。这是因为 CNN 的感受随着它们相互堆叠而增大。

img

举例来说,您正在尝试训练神经网络来分类您前面的车辆是汽车还是摩托车。这是一项非常基本的任务。但假设您的数据非常有限,并且您不想过多地训练模型。这是基本的 CNN 网络的样子。

img

这里的网络有 2 个主要部分,CNN 头和后面的全连接层。如前所述,CNN 层提取数据的表示,然后由全连接网络使用该表示对图像进行分类。在这里,我们可以使用在类似分类问题上训练的任何其他 CNN 网络,并将其用作这个新问题的 CNN 头。

img

正如您所看到的,我们通过使用预训练网络的权重来使用迁移学习来对汽车类型进行分类。我们只冻结 CNN 网络的前两层,并让后两层在训练过程中自由更新。这可以确保模型的 CNN 头从图像中学习新特征,这对于我们正在训练模型的新任务可能是必要的。

迁移学习也经常出现在 LLM 的 NLP 任务中,人们使用来自 T5 等预训练模型的 Transformer 网络的编码器部分并训练后面的层。

适配器 Adapters

适配器是最早发布的参数高效微调技术之一。在论文中,他们表明您可以向预先存在的 Transformer 架构添加更多层,并且只对它们进行微调,而不是对整个模型进行微调。他们表明,与完全微调相比,这种技术产生了相似的性能。

img

左侧是修改后的 Transformer 架构,添加了适配器层。您可以看到适配器层添加在注意力堆栈和前馈堆栈之后。在右侧,您可以看到适配器层本身的架构。适配器层包含一个瓶颈架构,它获取输入并将其缩小到较小的维度表示,然后将其传递给非线性激活函数,然后将其缩放回输入的维度。这确保了 Transformer 堆栈中的下一层能够接收从适配器层生成的输出。

img

LoRA - 低阶适应(Low-Rank Adaptation)

LoRA 是与 Adapt 层类似的策略,但其目标是进一步减少可训练参数的数量。它需要更严格的数学方法。 LoRA 的工作原理是修改神经网络中可更新参数的训练和更新方式。

我们用数学来解释一下,不感兴趣的可以跳到下一段。我们知道,预训练神经网络的权重矩阵是满秩的,这意味着每个权重都是唯一的,不能通过组合其他权重来制作。但在本文中,作者表明,当将预训练的语言模型调整为新任务时,权重具有较低的“内在维度”。这意味着权重可以用较小的矩阵表示,或者它具有较低的秩。这又意味着在反向传播期间,权重更新矩阵具有较低的秩,因为预训练过程已经捕获了大部分必要的信息,并且在微调期间仅进行特定于任务的调整。

一个更简单的解释是,在微调期间,只有很少的权重被大量更新,因为大部分学习是在神经网络的预训练阶段完成的。 LoRA 使用此信息来减少可训练参数的数量。

在论文中,作者表明,这种微调方法与完全微调相当,但消耗的计算资源和训练时间要少得多。他们能够在 GLUE 基准上实现 0.4% 的完全微调,同时添加 3.6% 的参数。

img

上图直观地展示了 LoRA 正在做什么。 ΔWAxB 是权重更新矩阵,这些是需要应用于神经网络以使其学习新任务的变化。这个矩阵可以分解为两个矩阵,然后我们只能训练它们,然后用它们来得到我们的权重更新矩阵。如图所示,矩阵被分解为列和行为r的矩阵,如果实际训练过的话,可以理解为权重更新矩阵的秩。排名越大,训练期间更新的参数就越多。

LoRA的效率

论文作者表明,LoRA 仅用总可训练参数的 2% 就可以超越完全微调。

img

至于它训练的参数数量,我们可以使用rank r 参数来很大程度上控制。例如,假设权重更新矩阵有 100,000 个参数,A 为 200,B 为 500。权重更新矩阵可以分解为较低维度的较小矩阵,A 为 200 x 3,B 为 3 x 500。这给了我们200 x 3 + 3 x 500 = 2100 个可训练参数,仅占参数总数的 2.1%。这可以进一步减少,因为我们可以决定仅将 LoRA 应用于特定层。

由于训练和应用的参数数量远小于实际模型,因此文件可以小至 8MB。这使得加载、应用和传输学习的模型变得更加容易和快捷。

LoRA 在 Stable Diffusion 中的应用

LoRA 最有趣的用例之一可以在图像生成应用程序中展示。图像具有可以直观看到的固有风格。用户现在可以只训练 LoRA 权重并将其与 Dreambooth 等技术结合使用,从而获得具有大量可定制性的真正高质量图像,而不是训练大量模型来从模型中获取特定风格的图像。

LoRA 权重还可以与其他 LoRA 权重相结合,并以加权组合的形式使用,以生成带有多种风格的图像。您可以在线找到大量 LoRA 适配器,并将它们加载到 CivitAI 上的模型中。

img

IA3 - 通过抑制和放大内部激活来注入适配器

IA3 是一种基于适配器的技术,有点类似于 LoRA。作者的目标是复制 ICL(在情境学习或少样本提示中)的优势,而不解决随之而来的问题。 ICL 在成本和推理方面可能会变得混乱,因为它需要用示例来提示模型。较长的提示需要更多的时间和计算来处理。但 ICL 可能是开始使用模型的最简单方法。

IA3 的工作原理是引入针对模型激活的重新缩放向量。一共引入了3个向量,lv、ik、lff。这些向量针对注意力层中的值、键以及密集层中的非线性层。这些向量按元素乘以模型中的默认值。一旦注入,这些参数就会在训练过程中被学习,而模型的其余部分保持冻结。这些学习向量本质上是针对当前任务重新调整或优化目标预训练模型权重。

img

到目前为止,这似乎是一个基本的适配器类型 PEFT 方法。但这还不是全部。作者还使用 3 个损失项来增强学习过程。 3 个损失分别是 LLM、LUL 和 LLN。 LLM 是标准交叉熵损失,它增加了生成正确响应的可能性。然后是 LUL,即可能性损失。此损失项降低了使用排名分类时错误输出的概率。最后,我们有 LLN,它是一种长度归一化损失,它将 softmax 交叉熵损失应用于所有输出选择的长度归一化对数概率。这里使用多个损失来确保模型更快更好的学习。因为我们试图使用少数样本来学习,所以这些损失是必要的。

现在我们来谈谈IA3中两个非常重要的概念。排名分类和长度标准化。

在排名分类中,要求模型根据一组响应的正确性对其进行排名。这是通过计算潜在响应的概率分数来完成的。然后使用 LUL 来降低错误响应的概率,从而增加正确响应的概率。但对于排名分类,我们面临一个关键问题,即由于概率的工作原理,具有较少标记的响应将排名较高。生成的令牌数量越少,概率越高,因为每个生成令牌的概率 < 1。为了解决这个问题,作者建议将响应的分数除以响应中的令牌数量。这样做将使分数标准化。这里需要注意的一件非常重要的事情是,标准化是根据对数概率而不是原始概率完成的。对数概率为负且介于 0 到 1 之间。

IA3 的效率

IA3 就像 LoRA 一样减少了可训练参数的数量。但 IA3 不使用低秩矩阵,而是使用重新缩放向量。对于本文中训练的 T0 模型,与 LoRA > 0.1% 相比,这将可训练参数减少到约 0.01%。 LLM 的冻结状态还为我们提供了针对多个用例使用多个适配器的选项。此外,由于作者使用了逐元素乘法,因此由于乘法的交换性质,将适配器合并到 LLM 权重非常容易。

img

上图显示,IA3 的性能优于 LoRA,并且对 FLOP 几乎没有影响。这使得 IA3 成为一种高效且理想的技术。另外,由于 IA3 是一种附加适配器技术,就像 LoRA 一样,我们可以针对模型的特定部分并决定在何处引入重新缩放向量。这有助于我们减少甚至更多的培训时间。

P-Tuning

P-tuning 方法旨在优化传递给模型的提示词的表示。在 P-Tuning 论文中,作者强调了在处理大型语言模型时,提示词工程是一项非常强大的技术。 P-Tuning 方法建立在提示词工程之上,并试图进一步提高良好提示词的效果。

P-Tuning 的工作原理是为您的提示词创建一个小型编码器网络,为您传递的提示词创建一个软提示。要使用 P-tuning 调整 LLM,您应该创建一个代表您的提示词的提示词模板。以及模板中使用的上下文 x 来获取标签 y。这就是论文中提到的方法。用于提示词模板的标记是可训练和可学习的参数,这些被称为伪标记。我们还添加了一个提示词编码器,它可以帮助我们将伪标记更新到手头的特定任务。提示词编码器通常是一个双 LSTM 网络,它学习模型提示词的最佳表示,然后将表示传递给它。 LSTM 网络附加到原始模型。这里只训练编码器网络和伪令牌,原始网络的权重不受影响。训练完成后,LSTM 头将被丢弃,因为我们有可以直接使用的 hi。

简而言之,提示编码器仅更改传递的提示的嵌入以更好地表示任务,其他一切保持不变。

img

P-Tuning 的效率

就效率而言,P-tuning 与任何其他方法一样好。在论文中,作者表明 P-Tuning 在大多数基准测试中的表现都优于完全微调。可以说,P-Tuning堪比大语言模型的全程微调。

img

但P-Tuning有一个核心问题。 P-Tuning 是一种提示优化技术,它优化传递给更大模型的提示。这意味着我们在能力上仍然很大程度上基于大模型。如果模型尚未接受过情感分类训练,那么使用 P-Tuning 优化情感分类提示不会对模型产生太大好处。 P-Tuning 是一种技术援助。选择一个能够通过一些及时的工程“很好”地完成所需任务的模型,然后进一步优化它总是非常重要的。

Prefix Tuning

前缀调整可以被认为是 P-Tuning 的下一个版本。 P-Tuning 的作者发表了一篇关于 P-Tuning V-2 的论文,解决了 P-Tuning 的问题。在这篇论文中,他们实现了本文介绍的Prefix调优。前缀调优和 P-Tuning 没有太大区别,但仍然会导致不同的结果。让我们深入探讨一下。

img

在 P-Tuning 中,我们仅将可学习参数添加到输入嵌入中,但在 Prefix Tuning 中,我们将它们添加到网络的所有层中。这确保了模型本身能够更多地了解正在对其进行微调的任务。我们将可学习的参数添加到提示和 Transformer 层中的每个层激活中。与 P-Tuning 的区别在于,我们没有完全修改提示嵌入,而是在每一层提示的开头添加很少的可学习参数。这是一个直观的解释:

img

在 Transformer 的每一层,我们将一个软提示与具有可学习参数的输入连接起来。这些可学习参数是使用非常小的 MLP(只有 2 个全连接层)进行调整的。这样做是因为作者在论文中指出,直接更新这些提示标记对学习率和初始化非常敏感。软提示增加了可训练参数的数量,但也大大提高了模型的学习能力。 MLP 或全连接层可以稍后删除,因为我们只关心软提示,这些提示将在推理过程中附加到输入序列中并指导模型。

img

Prefix Tuning的效率

前缀调整比 P-Tuning 调整显示出巨大的优势。随着模型尺寸的增加,这些收益也会增加。这可能是因为较大的模型有更多可训练的参数。在图表中,您可以看到作者比较了 P-Tuning、fullfinetuning 和 Prefixtuning 的性能。在几乎所有任务中,前缀调优的表现都比 P-Tuning 调优更好。在很多情况下,它的表现甚至比完全微调还要好!

img

前缀调优效果很好的一个重要原因是可训练参数的数量不仅限于输入序列。每一层都添加了可学习的参数,使模型更加灵活。与 P-Tuning不同,前缀调优不仅会影响提示标记,还会影响模型本身。这使得模型能够了解更多信息。但这种做法很大程度上还是基于提示。仍然建议采用一个可以执行任务的模型,然后再对其进行优化,因为这会带来更好的结果。至于参数的大小,训练的参数数量大幅增加,从 0.01% 增加到 0.1% 到 3% 参数。但参数的大小仍然足够小,可以轻松快速地传输和加载。

Prompt Tuning

Prompt Tuning 是第一篇基于仅使用软提示进行微调的想法的论文之一。 P-Tuning和Prefix Tuning的思想来自这篇论文。及时调整是一个非常简单且易于实现的想法。它涉及在输入前添加特定提示,并为该特定提示使用虚拟令牌或新的可训练令牌。这些新的虚拟标记可以在此过程中进行微调,以更好地表示提示。这意味着模型经过调整可以更好地理解提示。以下是论文中Prompt Tuning与完全微调的比较:

img

在这里您可以看到,如果我们想要将模型用于多个任务,则完整的模型调整需要存在模型的多个副本。但是使用Prompt Tuning,您只需要存储学习到的提示令牌的虚拟令牌。例如,如果您使用“对这条推文进行分类:{tweet}”这样的提示,目标将是为提示学习新的更好的嵌入。在推理过程中,只有这些新的嵌入将用于生成输出。这允许模型调整提示以帮助自己在推理过程中生成更好的输出。

Prompt Tuning 的效率

使用Prompt Tuning的最大优点是学习参数的规模较小。文件可以以 KB 为单位。由于我们可以确定新令牌使用的维度大小和参数数量,因此我们可以极大地控制要学习的参数数量。在论文中,作者展示了即使使用非常少量的可训练令牌,方法也能表现良好。而且只有使用更大的型号时,性能才会提高。您可以在这里阅读该论文。

img

另一个很大的优点是,我们可以使用相同的模型,而无需对多个任务进行任何更改,因为唯一更新的是提示标记的嵌入。这意味着您可以将相同的模型用于推文分类任务和语言生成任务,而无需对模型本身进行任何更改,前提是该模型足够大且复杂,足以执行这些任务。但一个很大的限制是模型本身并没有学到任何新东西。这纯粹是一个即时优化任务。这意味着如果模型从未在情感分类数据集上进行过训练,那么及时调整可能没有任何帮助。需要注意的是,该方法优化的是提示,而不是模型。因此,如果您无法手工制作一个可以相对较好地完成任务的硬提示,那么尝试使用提示优化技术来优化软提示是没有用的。

LoRA 与基于提示词技术的比较

现在我们已经探索了各种 PEFT 技术。现在的问题是,是否使用 Adapter 和 LoRA 等附加技术,或者使用 P-Tuning 和 Prefix Tuning 等基于提示词的技术。

在比较 LoRA 与 P-Tuning 和 Prefix Tuning 时,可以肯定地说 LoRA 是充分利用模型的最佳策略。但根据您的需求,它可能不是最有效的。如果您想在与已训练的任务截然不同的任务上训练模型,LoRA 无疑是有效调整模型的最佳策略。但是,如果模型或多或少已经理解了您的任务,但挑战是正确提示模型,那么您应该使用提示调整技术。提示词调整不会修改模型中的许多参数,而是主要关注传递的提示词。

需要注意的一点是,LoRA 将权重更新矩阵分解为更小的秩矩阵,并使用它们来更新模型的权重。尽管可训练参数很少,LoRA 也会更新神经网络目标部分的所有参数。而在即时调优技术中,一些可训练的参数被添加到模型中,这通常有助于模型更好地适应和理解任务,但不能帮助模型很好地学习新属性。

LoRA 和 PEFT 与完整 Finetuning 的比较

PEFT(参数高效微调)被提议作为完全微调的替代方案。对于大多数任务,论文已经表明,LoRA 等 PEFT 技术即使不是更好,也可以与完全微调相媲美。但是,如果您希望模型适应的新任务与模型训练过的任务完全不同,PEFT 可能不足以满足您的需求。在这种情况下,可训练参数的数量有限可能会导致重大问题。

如果您尝试使用 LLaMA 或 Alpaca 等基于文本的模型构建代码生成模型,您可能应该考虑微调整个模型,而不是使用 LoRA 调整模型。这是因为该任务与模型已经知道并接受过训练的任务有很大不同。此类任务的另一个很好的例子是训练一个仅理解英语的模型来生成尼泊尔语文本。

为什么应该针对您的业务用例微调模型

对于任何想要充分利用机器学习应用程序的企业来说,微调模型是重要的一步。它允许您根据特定用例自定义模型,从而提高准确性和性能。它无需从头开始构建新模型,从而节省了时间、金钱和资源。通过微调,您可以优化专有数据的使用,调整模型以更好地适应您的可用数据,甚至在需要时合并新数据。这可确保模型更准确,更好地满足您的业务需求。以下是更多好处:

定制:微调允许您根据您的特定需求定制模型,从而提高准确性和性能。

资源效率:无需从头开始构建新模型,从而节省时间、金钱和资源。

性能提升:微调可使用您独特的数据集增强预训练模型的性能。

数据优化:它可以让您充分利用数据,调整模型以更好地适应您的可用数据,甚至在需要时合并新数据。


但随着模型规模增长到数十亿个参数,微调本身可能是一个挑战。我们在本博客中讨论的 PEFT 技术有助于减少微调模型所需的时间和资源。它通过利用预训练的权重和参数来帮助加快训练过程,并允许您更有效地微调模型。此外,使用 PEFT,您可以轻松地通过互联网传输模型,甚至可以将同一模型用于多种用途。 PEFT 为想要充分利用机器学习应用程序的企业开辟了一个充满可能性的全新世界。

使用LoRA和QLoRA微调LLM

LoRA 微调

LoRA 是最流行、或许也是最常用的 PEFT 技术,但早在 2021 年就在本文中发布了。 LoRA 更像是一种适配器方法,它将新参数引入到模型中,通过这些新参数来训练模型。诀窍在于如何在不增加模型中参数总数的情况下引入新参数并将其合并回模型中。

LoRA 是如何工作的

如前所述,LoRA 是一种基于适配器的方法,但新参数仅在训练步骤中添加,而不是作为模型的一部分引入。这使模型大小保持完全相同,并且仍然提供参数高效微调的灵活性。以下是其工作原理的更详细说明。‍

LoRA 的工作原理是将权重更新矩阵分解为更小的矩阵,并使用它们来训练模型。看一下下图,ΔWAxB 是权重更新矩阵,即反向传播学习到的变化矩阵,这与我们需要更新以微调模型的参数数量相同。该矩阵或任何矩阵可以表示为一组较小的矩阵,此处表示为 A 和 B,其中 r 为其秩。 r 参数控制较小矩阵的大小。

然后,这些较小的矩阵可用于使用正常反向传播来训练模型,但更新较小矩阵中的参数,而不是直接在模型中更新。我们基本上通过较小的矩阵来学习 ΔW。然后可以将这些较小的矩阵相乘以得到原始矩阵。由于这些矩阵要小得多,因此该过程使用的参数更少,因此计算资源也更少。这也会导致较小的检查点,因为您不必存储整个模型,而只需存储较小的矩阵。

img

使用 HuggingFace 进行 LoRA 微调

要使用 HuggingFace 实现 LoRA 微调,您需要使用 PEFT 库将 LoRA 适配器注入模型中,并将其用作更新矩阵。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from transformers import AutoModelForCausalLM
from peft import get_peft_config, get_peft_model, LoraConfig, TaskType

model = AutoModelForCausalLM.from_pretrained(model_name_or_path, device_map="auto", trust_remote_code=True) # load the model

peft_config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
inference_mode=False,
r=32,
lora_alpha=16,
lora_dropout=0.1,
target_modules=['query_key_value'] # optional, you can target specific layers using this
) # create LoRA config for the finetuning


model = get_peft_model(model, peft_config) # create a model ready for LoRA finetuning

model.print_trainable_parameters()
# trainable params: 9,437,184 || all params: 6,931,162,432 || trainable%: 0.13615586263611604

完成此操作后,您可以像平常一样训练模型。但这一次将像平常一样花费更少的时间和计算资源。

QLoRA 微调

QLoRA 是一种将高精度计算技术与低精度存储方法相结合的微调技术。这有助于保持模型尺寸较小,同时仍确保模型仍然高效且准确。

QLoRA 是如何工作的

img

QLoRA 的工作原理是引入 3 个新概念,有助于减少内存,同时保持相同的质量性能。它们是 4 位普通浮点、双量化和分页优化器。让我们详细讨论一下这3个非常重要的概念。

4 位普通浮点

4 位 Normal Float 或 NF 是一种建立在分位数量化技术之上的新的信息理论上最优的数据类型。 4 位 NF 的工作原理是估计 0 到 1 分布中的 2k + 1(k 是位数)分位数,然后将其值标准化到 [-1, 1] 范围内。一旦我们有了这个,我们还可以将神经网络权重归一化到 [-1, 1] 范围内,然后量化到我们从步骤 2 中获得的分位数。

这是分位数量化的示例

img

您可以看到存在数据“桶”或“数据箱”,其中数据被量化。数字 2 和 3 都属于同一分位数 2。此量化过程允许您通过“四舍五入”到最接近的分位数来使用更少的数字。

双重反量化

双量化是对4位NF量化中的量化过程中使用的量化常数进行量化的过程。这并不重要,但平均每个参数可以节省 0.5 位,正如论文中提到的。这有助于该过程,因为 QLoRA 使用按块 k 位量化,这意味着我们不是将所有权重一起量化,而是创建多个权重块或块,然后对其进行独立量化。

这种分块方法会创建多个量化常数,然后可以再次对其进行量化以节省额外的空间。这是可以的,因为量化常数的数量很少,因此不需要大量的计算或存储。

通过 LoRA 调整减少错误

如前所示,分位数量化为大范围的数字创建桶或箱。这个过程导致将多个不同的数字放入同一个桶中,例如,两个数字2和3可以在量化过程中转换为3。这导致权重反量化期间引入 1 的误差。

这是神经网络权重较大分布上的这些误差的图形表示。

img

这个错误就是 QLoRA 更像是一种微调机制而不是独立的量化策略的原因。虽然可以用于4位推理。当使用 QLoRA 进行微调时,我们使用 LoRA 调整机制创建 2 个较小的权重更新矩阵,然后使用它们来更新神经网络的权重。在这里,我们将 LoRA 矩阵保持为更高精度的格式,例如 Brain float 16 或 float 16,并且在反向传播和前向传播期间,网络的权重也被反量化。因此,实际的训练仍然以更高精度的格式进行,但存储仍然以较低的精度进行。这会导致出现量化误差,但模型训练本身能够弥补量化过程中的这些低效率。

因此,更高精度的LoRA训练有助于模型学习并减少量化误差。

QLoRA 与 LoRA 的区别

QLoRA和LoRA都是微调技术,但QLoRA使用LoRA作为附件来修复量化过程中引入的误差。 LoRA 本身更多的是一种独立的微调技术。

使用 HuggingFace 进行 QLoRA 微调

要使用 HuggingFace 进行 QLoRA 微调,您需要安装 BitsandBytes 库和 PEFT 库。 BitsandBytes 库负责 4 位量化以及整个低精度存储和高精度计算部分。 PEFT 库将用于 LoRA 微调部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import torch
from peft import prepare_model_for_kbit_training, LoraConfig, get_peft_model
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig

model_id = "EleutherAI/gpt-neox-20b"
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16
) # setup bits and bytes config

model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=bnb_config, device_map={"":0})

model.gradient_checkpointing_enable()
model = prepare_model_for_kbit_training(model) # prepares the whole model for kbit training

config = LoraConfig(
r=8,
lora_alpha=32,
target_modules=["query_key_value"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)

model = get_peft_model(model, config) # Now you get a model ready for QLoRA training

然后您可以再次使用高频训练器进行正常训练。QLoRA 更详细的训练步骤可以查看 Google Colab 的笔记:

https://colab.research.google.com/drive/1VoYNfYDKcKRQRor98Zbf2-9VQTtGJ24k?usp=sharing#scrollTo=FCc64bfnmd3j

QLoRA 与标准微调对比

在论文中,研究人员对 QLoRA、LoRA 和网络的 Full Finetuning 之间进行了非常详细的比较。

img

正如您在上表中看到的,在使用 QLoRA 进行训练后,T5 模型系列没有任何性能损失,即使使用双量化,我们也没有看到任何重大差异。一个显着差异是所需 LoRA 适配器的数量。在论文中,作者提到,与普通 LoRA 微调相比,他们需要更多的 LoRA 适配器来进行 QLoRA 微调。作者建议在所有线性变换器块以及查询、键和值层上应用 LoRA 适配器。

即使对于更大的语言模型,性能也保持不变:

img

因此,作者在基本 LLaMA 模型、Guanaco 之上训练了一个模型。这是一个 330 亿个参数的模型,在 OASST1 数据集上进行训练。在发布时,它成为最先进的模型,相对于 ChatGPT 实现了 99.3% 的性能。尽管其他模型具有较小的模型,例如 Vicuna 13B 和guanaco33B,因为使用 4 位精度,所以比 13B 模型使用的内存更少。

LoRA 微调的其他变体

QA LoRA

QA LoRA 是本文介绍的另一种基于 QLoRA 的微调技术。 QALoRA 主要是为了微调扩散模型而发布的,但可以很容易地推广到训练任何类型的模型,就像 LoRA 一样。‍

QLoRA 和 QALoRA 之间的区别在于 QALoRA 具有量化意识,这意味着在微调过程中 LoRA 适配器的权重也会与模型的权重一起量化。这有助于更有效的训练,因为在反向传播过程中不需要转换步骤来更新模型。

img

LongLoRA

img

LongLoRA 是 LoRA 微调技术的另一种变体,但该技术专门用于训练更长的上下文模型。 LongLoRA 通过使用一种称为 SHIFT SHORT ATTENTION 的方法来工作。该方法创建标记块或标记组,其中注意力是独立计算的。由于分布式工作负载,该方法允许 LongLoRA 扩展到更长的上下文。

除此之外,作者还表明需要在标准化和嵌入层上使用 LoRA,才能使该方法正常工作。

微调如何提高您业务的模型性能

如果您正在考虑为您的业务微调模型,那么您可能是正确的。但数据成为该过程的重要组成部分,请查看我们的合成数据生成指南。然而,微调模型可以通过多种方式通过提供定制来提高业务绩效。微调模型可帮助您根据您的特定需求和知识定制模型。您可以使用 RAG 管道来自定义模型,但有时知识非常庞大,嵌入和相似性搜索还不够,这就是通过微调进行自定义的用武之地。