在不断发展的人工智能和自然语言处理领域,大型语言模型和生成式人工智能已成为各种应用的强大工具。实现这些模型的期望结果涉及到不同的方法,可以广泛地分为三类:提示工程、微调和创建新模型。随着我们从一个级别向另一个级别进展,资源和成本方面的要求显著增加。
在本博客文章中,我们将探讨这些方法,并重点介绍一种名为参数高效微调(PEFT)的高效技术,它允许我们通过最少的基础设施进行模型微调,同时保持高性能。
使用现有模型进行提示工程
在基本级别上,从大型语言模型中获得预期结果涉及到谨慎的提示工程。这个过程涉及到 crafting 合适的提示和输入,以调动模型产生预期的回复。提示工程是各种用例中的一种重要技术,特别是当通用回复足够时。
创建新模型
在最高级别上,创建新模型涉及到从头开始训练一个专门针对特定任务或领域的模型。这种方法提供了最高级别的定制化,但它需要大量的计算能力、广泛的数据和时间。
微调现有模型
在处理需要模型调整的特定领域用例时,微调变得至关重要。微调允许我们利用现有的预训练基础模型,并对其进行适应特定任务或领域。通过在特定领域的数据上训练模型,我们可以将其定制为在目标任务上表现良好。
然而,这个过程可能需要大量的资源和成本,因为我们将对所有数百万个参数进行修改作为训练的一部分。微调模型需要大量的训练数据、庞大的基础设施和努力。
在完全微调 LLMs 的过程中,存在着遗忘之灾的风险,即来自预训练的先前获得的知识会丧失。
将完全微调应用于单个模型以执行不同的领域特定任务通常会产生针对特定任务的大型模型,缺乏模块化。我们需要的是一种模块化的方法,既避免改变所有参数,同时又要求更少的基础设施资源和更少的数据。
有各种技术,如参数高效微调(PEFT),提供了一种以最优资源和成本进行模块化微调的方式。
参数高效微调(PEFT)
PEFT 是一种设计用于在最小化资源需求和成本的情况下微调模型的技术。PEFT 在处理需要模型调整的特定领域任务时是一个很好的选择。通过使用 PEFT,我们可以在保留预训练模型中有价值的知识的同时,通过减少参数数量来有效适应目标任务。有各种实现参数高效微调的方法,其中低秩参数(LoRA)和 QLoRA 是最广泛使用且最有效的。
低秩参数
这是最常用的方法之一,其中一组参数以较低维空间的模块方式添加到网络中。不是修改整个网络,只有这些低秩网络被修改以达到结果。
让我们深入研究其中最受欢迎的技术之一,称为 LoRA 和 QLoRA
低秩适应(LoRA)
低秩适应提供了在特定领域任务上微调模型的模块化方法,并提供了迁移学习的能力。LoRA 技术可以使用较少的资源,并且具有内存效率。
在下面的图片中,您可以看到降低内存占用的维度/秩分解。
我们将通过增加一个 LoRA 适配器来应用这种方法到现有的前馈网络中。我们将冻结原始的前馈网络,并将 LoRA 网络用于训练。请参考下面的图片获取更多细节。
- LoRA 可以作为适配器实现,用于增强和扩展现有的神经网络层。它引入了一组可训练参数(权重),同时保持原始参数处于冻结状态。这些可训练参数具有显著降低的秩(维度),与原始网络的维度相比。这是 LoRA 简化和加快将原始模型适应于特定领域任务的过程的机制。现在,让我们更仔细地观察 LoRA 适配器网络内部的组件。
- 原始模型的预训练参数(
W
)被冻结。在训练过程中,这些权重不会被修改。 - 一组新的参数同时被添加到网络
WA
和WB
中。这些网络利用低秩权重向量,其中这些向量的维度表示为dxr
和rxd
。这里,’d’ 表示原始冻结网络参数向量的维度,’r’ 表示所选择的低秩或较低的维度。’r’ 的值始终较小,选取更小的’r’ 可以让模型训练过程更加快速和简化。确定 ‘r’ 的合适值是 LoRA 中的关键决策。选择较低的值会导致更快、更节省成本的模型训练,但可能无法产生最佳结果。相反,选择较高的 ‘r’ 值会延长训练时间和成本,但增强了模型处理更复杂任务的能力。 - 原始网络和低秩网络的结果通过点积计算得到一个 n 维的权重矩阵,用于生成结果。
- 然后将该结果与预期结果(在训练过程中)进行比较,计算损失函数,并根据损失函数调整 WA 和 WB 权重,作为标准神经网络的反向传播的一部分。
让我们探讨这种方法如何减少内存占用并最小化基础设施需求。假设我们在前馈网络中有一个512×512的参数矩阵,总共有262,144个需要进行训练的参数。如果我们选择在训练过程中冻结这些参数,并引入一个rank为2的LoRA适配器,结果如下:WA将有512*2个参数,WB也将有512*2个参数,总共为2,048个参数。这些是接受域特定数据进行训练的具体参数。这在计算效率方面表示了显著的提升,大大减少了反向传播过程中所需的计算次数。这个机制对于实现加速训练至关重要。
这种方法最有优势的一点是训练过的LoRA适配器可以独立保留并用作独立模块。通过以这种方式构建领域特定模块,我们有效地实现了高度的模块化。此外,通过不改变原始权重,我们成功地避免了灾难性遗忘的问题。
现在,让我们深入研究可以在LoRA之上实施的进一步增强,特别是通过使用QLoRA来提升优化至下一个水平。
量化低秩适应(QLoRA)
QLoRA通过将原始网络的权重值从高分辨率数据类型(如Float32)量化为较低分辨率数据类型(例如int4),扩展了LoRA以提高效率。这导致了降低的内存需求和更快的计算速度。
QLoRA在LoRA基础上带来了三个关键优化,使其成为最佳的PEFT方法之一。
4位NF4量化
4位NormalFloat4是一种优化的数据类型,可用于存储权重,可以显著降低内存占用。4位NormalFloat4量化是一个三步过程。
- 标准化和量化:作为标准化和量化步骤的一部分,权重被调整为零均值和恒定单位方差。4位数据类型只能存储16个数字。作为标准化的一部分,权重被映射到这些16个数字中,以零中心分布,并且存储最接近的位置而不是权重。以下是一个示例:
假设我们有一个值为0.2121的FP32权重。在-1到1之间进行4位划分的数字位置如下:
0.2121最接近于0.1997,这是第10个位置。我们存储的是10,而不是0.2121的FP32权重。
典型的公式:
int4Tensor = roundedValue(totalNumberOfPositions/absmax(inputXTensor)) * FP32WeightsTensor在上述示例中totalNumberOfPositions = 16
值totalNumberOfPositions/absmax(inputXTensor)
被称为量化常数
显然,从高分辨率数据类型FP32到低分辨率数据类型时,即使我们标准化和量化,也会有数据损失。只要输入张量中没有异常值影响absmax()并最终破坏分布,损失就不会太大。为了避免这个问题,通常我们会通过较小的块独立地量化权重,以标准化异常值。
- 反量化:为了反量化值,我们做完全相反的操作。
dequantizedTensor = int4Tensor/roundedValue(totalNumberOfPositions/absmax(inputXTensor))在上述示例中totalNumberOfPositions = 16
4位NormalFloat量化应用于原始模型的权重;LoRA适配器的权重将是FP32的,因为所有的训练都会在这些权重上进行。一旦所有的训练完成,原始权重将被反量化。
双重量化
双重量化通过量化量化常数进一步降低内存占用。在前面的4位FP4量化步骤中,我们计算了量化常数。甚至该常数也可以进行量化以提高效率,这就是我们在双重量化中所做的。
由于量化是以块为单位进行的,为了避免异常值,通常每个块有64个权重,我们将拥有一个量化常量。这些量化常量可以进一步进行量化,以减少内存占用。
假设我们每个块将64个参数/权重分组,并且每个量化常量占用32位,因为它是FP32。平均每个参数增加0.5位,这意味着对于一个典型的100万参数模型,至少需要500,000位。
通过双量化,我们对这些量化常量进行量化,进一步优化内存使用。我们可以取256个量化值并进行8位量化。我们可以达到每个参数约0.127位,将该值降至125,000位,适用于100万参数模型。
以下是计算过程:我们有256个块中的64个权重,为32位,即32/(64*256),即0.001953125。
我们有64个权重的8位,即8/64=0.125。
如果我们将它们相加,0.125+0.001953125,约等于0.127。
统一内存分页
结合上述技术,QLoRA还利用了nVidia的统一内存特性,当GPU内存不足时,可以实现GPU到CPU的无缝页面转移,从而管理GPU中的突发内存占用,并有助于解决内存溢出/溢出问题。
LoRA和QLoRA是最新兴和广泛使用的参数高效微调技术之一。
在下一部分,我们将实现QLoRA;在那之前,尽情享受LLMs。
希望这对您有用;请留下您的评论和反馈…
暂时就这些了…