从零学习大模型(六)-----LoRA(上)

ops/2024/10/25 15:56:15/

LoRA简介

LoRA(Low-Rank Adaptation)是一种参数高效的微调技术,旨在降低微调大规模预训练模型的存储和计算成本。**其核心思想是通过对模型的特定参数进行低秩分解,仅对少量附加参数进行训练,从而完成任务适应,而无需更新整个模型的权重。**这种方法通过引入额外的低秩矩阵来适应新的任务,保持了预训练模型的核心知识,使其更具灵活性和高效性。

在大规模语言模型的实际应用中,微调需要耗费巨大的计算资源和内存,因为要微调整个模型的参数(通常有数十亿甚至数千亿个参数)。LoRA通过只训练新增的低秩矩阵,使得训练过程变得更加轻量,同时减少了存储需求。这在许多硬件资源受限的场景中尤为有用。

大模型的微调挑战

对于大规模预训练模型(如GPT-3或BERT),传统的全参数微调面临着显著的挑战:

  • 高计算成本:在大规模模型中,对整个模型进行微调需要大量计算资源,训练时间非常长。
  • 存储限制:全参数微调意味着需要存储多个不同任务的完整模型副本,这对于资源受限的场景(如移动设备)来说非常不现实。
  • 共享问题:如果多个任务都需要对模型进行微调,必须为每个任务保存一个独立的微调版本,这导致模型的存储和部署变得复杂。

为了应对这些挑战,LoRA 提出了一种新的微调方法:

  • 参数冻结与低秩适配:LoRA的关键在于将预训练模型的原始权重冻结,仅对新增的适配矩阵(即低秩矩阵)进行训练,从而在不改变模型整体架构的情况下适应不同任务。
  • 适应性与灵活性:LoRA不仅减少了所需的训练资源,还增强了任务间的共享能力。多个任务可以共享同一个预训练模型,只需增加少量的适配参数即可适应不同的任务场景。

通过引入低秩适配,LoRA 在不影响模型整体表现的情况下,通过训练额外的低秩矩阵来完成任务特化,这显著减少了计算和存储的压力。这使得 LoRA 特别适合用于大规模预训练模型的参数高效微调,尤其是在硬件资源受限或希望共享模型的情况下。例如,在边缘设备、移动设备和小型服务器环境中,LoRA 可以帮助开发者将大规模模型应用到多种任务中,而无需反复地全量微调整个模型。

矩阵基础知识

通俗来说低秩矩阵理解为一个行列元素之间相关性较高的矩阵。换句话说,如果一个矩阵是低秩的,那么它的行向量或者列向量之间存在较强的线性依赖关系。也就是说,通过少量的线性组合,就可以用部分行或列表示出整个矩阵。例如,在一个低秩矩阵中,很多行或者列其实只是其他行或列的缩放或简单组合,因此矩阵的秩(也就是线性独立的行或列的个数)比较小。这种高相关性使得低秩矩阵可以通过更少的独立变量进行描述,从而在计算和存储方面更加高效。

低秩分解

是指将一个高维矩阵分解为多个低秩矩阵的乘积,以减少矩阵的表示维度和复杂度。具体来说,假设有一个原始矩阵 W ∈ R m × n W \in \mathbb{R}^{m \times n} WRm×n,我们可以将其近似为两个低秩矩阵的乘积 W ≈ A × B W \approx A \times B WA×B,其中 A ∈ R m × r A \in \mathbb{R}^{m \times r} ARm×r B ∈ R r × n B \in \mathbb{R}^{r \times n} BRr×n,并且 r ≪ min ⁡ ( m , n ) r \ll \min(m, n) rmin(m,n)。这样,原始矩阵的表示被低维化,大大减少了存储和计算的复杂度。 低秩分解的核心在于通过对矩阵的秩进行近似,保留原始矩阵的主要信息,同时丢弃冗余的信息,从而简化计算。这种方法在机器学习中非常有用,尤其是在需要对大规模矩阵进行高效处理时,例如在 LoRA 技术中,它被用来减少大模型微调时需要调整的参数数量。 常见的低秩分解方法包括奇异值分解(SVD,Singular Value Decomposition),其中一个矩阵被分解为三个子矩阵的乘积,以捕捉其主成分信息。低秩分解的目标是通过找到一个较小的秩来表示原始矩阵,以减少计算负担并加速模型的训练过程。 在 LoRA 中,低秩分解被用来对大模型中的线性层进行参数化,将一个大的权重矩阵分解为两个低秩矩阵,从而仅对这两个低秩矩阵进行微调,而保持原始权重冻结。这使得在不同任务中适应大模型变得更加轻量和高效。

低秩矩阵

是指一个矩阵的秩(rank)较低,或者说其非零特征值的数量较少。矩阵的秩是线性代数中的一个概念,它表示矩阵的列向量或行向量的线性无关数量。如果一个矩阵的秩远小于其行数或列数,那么它就是一个低秩矩阵。

例如,对于一个矩阵 A A A,如果它的秩为 r r r,且 r ≪ min ⁡ ( m , n ) r \ll \min(m, n) rmin(m,n)(其中 m m m n n n 分别是矩阵的行数和列数),那么这个矩阵被称为低秩矩阵。低秩矩阵具有较少的线性独立的行或列,这意味着它可以用更少的参数来近似描述其内容。

低秩矩阵的好处在于它能够以较少的数据表示矩阵,从而在数据压缩、计算复杂度降低等方面有显著的优势。例如,在大规模机器学习中,低秩矩阵通常被用来通过矩阵分解来减少计算负担,从而提高训练速度和资源利用效率。

低秩分解(例如 SVD)常用于将一个高维矩阵近似为多个低秩矩阵的乘积,以便通过低秩矩阵来表示原始矩阵,从而降低其计算和存储复杂度。

奇异向量

你可以把奇异向量理解为描述矩阵数据中最重要方向的工具。我们以图像为例,假设你有一张二维图像,其中包含许多点。奇异值分解就是找出描述这些点分布的主要方向次要方向,而这些方向就是由奇异向量定义的。

奇异值分解(SVD)会把原始矩阵拆分为三个部分,其中左奇异向量和右奇异向量就类似于描述这个数据在不同维度上的“基准轴”。它们告诉我们数据在哪些方向上最有特征,这些方向就是数据中最“重要”的部分,可以帮助我们用更简洁的方式描述数据。

简单来说,奇异向量是矩阵中描述数据“主要趋势”的方向,它们帮助我们理解数据的本质特征,比如数据在哪些方向上有变化,在哪些方向上是重复的或不重要的。通过奇异值分解,我们能够将一个复杂的数据集分解为更简单的部分,从而更有效地进行数据压缩或降维。

奇异值

奇异值是奇异值分解(SVD)中的核心部分,用来衡量矩阵在某些特定方向上的重要性。简单来说,奇异值告诉我们矩阵在某些方向上有多“强”或者说这些方向有多重要。

具体来说,当我们对一个矩阵进行奇异值分解时,会得到一个对角矩阵 Σ,其中对角线上的元素就是奇异值。这些奇异值通常按降序排列,代表了矩阵的不同方向上的特征大小。

你可以把奇异值理解为衡量数据在某些方向上的“强度”或“权重”。如果某个奇异值很大,那么它对应的方向对矩阵的特征描述非常重要;如果某个奇异值接近零,那么这个方向对描述矩阵的信息几乎没什么帮助。

奇异值分解可以用来压缩数据或降维,因为我们可以只保留那些较大的奇异值及其对应的方向,而忽略那些很小的奇异值,这样既可以保留数据的大部分特征,又能够减少计算量和存储需求。这种方法广泛应用于图像压缩、特征提取和数据降噪等任务中。

LoRA的工作原理

LoRA(Low-Rank Adaptation)是一种通过增加低秩矩阵来微调大型预训练模型的方法,旨在降低微调过程的存储和计算需求,同时保持微调后的模型在特定任务上的高效性。其工作原理主要包括以下几个关键步骤:

冻结预训练模型的核心权重:在使用 LoRA 进行微调时,首先将预训练模型的核心权重(主要是线性变换层的权重)冻结,不对这些权重进行更新。这意味着,微调过程并不会改变原始预训练模型的参数,从而减少了计算量和内存开销。

增加可训练的低秩适配矩阵:为了实现任务的特定适应,LoRA 在冻结的预训练模型中添加了额外的低秩矩阵,这些矩阵可以被训练以适应特定任务。这些新增的矩阵被称为适配矩阵(adapter matrices),其大小和秩都相对较小,因此训练这些矩阵的计算量也很小。

假设一个线性层的权重矩阵为 W ∈ R m × n W \in \mathbb{R}^{m \times n} WRm×n,LoRA 会将其表示为:
W ′ = W + A B W' = W + AB W=W+AB
W W W 是预训练权重,保持冻结。

A ∈ R m × r A \in \mathbb{R}^{m \times r} ARm×r B ∈ R r × n B \in \mathbb{R}^{r \times n} BRr×n 是新增的适配矩阵, r r r 是低秩的大小,通常远小于 m m m n n n

举例子说明低秩分解如何减少参数数量

假设我们有一个神经网络中的线性层,其权重矩阵 W W W 的大小为 1000 × 1000 1000 \times 1000 1000×1000。如果直接更新这个矩阵,需要存储和计算 1000 × 1000 = 1 , 000 , 000 1000 \times 1000 = 1,000,000 1000×1000=1,000,000 个参数,这对于大型模型来说可能会带来非常高的计算开销。 使用低秩分解的方法,我们可以将矩阵 W W W 分解为两个较小的矩阵 A A A B B B,其中 A ∈ R 1000 × r A \in \mathbb{R}^{1000 \times r} AR1000×r B ∈ R r × 1000 B \in \mathbb{R}^{r \times 1000} BRr×1000,并且 r ≪ 1000 r \ll 1000 r1000。假设 r = 50 r = 50 r=50,那么矩阵 A A A B B B 各自的参数数量为:
1000 × 50 + 50 × 1000 = 100 , 000 1000 \times 50 + 50 \times 1000 = 100,000 1000×50+50×1000=100,000
这比直接更新 W W W 1 , 000 , 000 1,000,000 1,000,000 个参数少了许多。在训练过程中,我们只需要更新矩阵 A A A B B B 的参数,而不需要更新原始的 W W W,这大大减少了计算和存储的开销。 通过这种低秩分解,我们利用两个较小的矩阵来近似表示一个大的权重矩阵,从而实现对大模型的高效微调,保留模型的主要特征,同时大幅减少参数数量和计算复杂度。

如何在预训练模型中添加适配矩阵?

在预训练模型中添加适配矩阵是 LoRA 的核心步骤,其目标是通过添加额外的低秩矩阵来实现高效的任务适应。以下是详细的过程:

**冻结预训练模型的权重:**首先,将原始预训练模型的所有权重冻结,不再更新它们。这意味着在训练过程中,原始模型的权重不会被调整,从而大大降低了计算复杂度和存储需求。

**添加适配矩阵:**对于每个需要微调的线性层(例如 Transformer 模型中的全连接层),我们会在原始权重矩阵 W ∈ R m × n W \in \mathbb{R}^{m \times n} WRm×n 上添加两个额外的低秩矩阵 A A A B B B。具体来说,假设:
A ∈ R m × r , B ∈ R r × n A \in \mathbb{R}^{m \times r}, \quad B \in \mathbb{R}^{r \times n} ARm×r,BRr×n
其中 r r r 是低秩的大小,通常比 m m m n n n 小得多。通过添加 A A A B B B,新权重矩阵的形式变为:
W ′ = W + A B W' = W + AB W=W+AB
在这个公式中:

W W W 是预训练模型的原始权重,保持冻结状态。

A A A B B B 是新增的低秩矩阵,经过训练来适应特定任务。

训练适配矩阵:在微调过程中,仅对新增的适配矩阵 A A A B B B 进行训练,而不更新原始的 W W W。这种方式使得模型的微调变得更加轻量,训练过程只需要优化 A A A B B B 中的参数,而原始模型的权重保持不变。这减少了对硬件的内存和计算资源的需求,同时也使得模型能够适应多个任务。

**应用于模型前向传播:**在进行模型的前向传播时,权重矩阵 W ′ W' W 被用于进行线性变换。具体来说,对于输入向量 x x x,计算公式为:
y = W ′ x = ( W + A B ) x y = W' x = (W + AB) x y=Wx=(W+AB)x
在这个过程中, W W W 是固定的,而 A A A B B B 提供了对特定任务的灵活适应能力。

**多任务适应与共享:**由于 LoRA 中的 A A A B B B 矩阵是小规模的,并且是任务特定的,这意味着我们可以在同一个预训练模型上添加多个任务的适配矩阵来实现多任务微调。这种方法使得我们可以在保持相同预训练模型核心参数不变的情况下,高效地适应不同的下游任务。


http://www.ppmy.cn/ops/128377.html

相关文章

证明在由特定矩阵生成的幺半子群中,存在收敛序列的子序列,其元素也能分别构成收敛序列

设 H H H是 G L 4 ( R ) GL_4(\mathbb{R}) GL4​(R)的由矩阵 ( 1 a 0 0 0 1 0 0 0 0 1 0 0 0 0 1 ) , ( 1 0 0 0 0 1 b 0 0 0 1 0 0 0 0 1 ) , ( 1 0 0 0 0 1 0 0 0 0 1 c 0 0 0 1 ) \begin{pmatrix}1&a&0&0\\ 0&1&0&0\\ 0&0&1&0\\ 0&…

Linux内核常见的网络丢包场景分析,零基础入门到精通,收藏这一篇就够了

摘要 一个数据包在网络中传输的过程中,是没法保证一定能被目的机接收到的。其中有各种各样的丢包原因,今天来学习一下数据包经过 linux 内核时常见的丢包场景。 1 收发包处理流程 有必要再回顾下 linux 内核的收发包处理流程,才能更好的认清…

pytorch nn.NLLLoss和nn.CrossEntropyLoss函数区别

nn.CrossEntropyLoss(交叉熵损失函数) 和nn.NLLLoss (负对数似然损失函数)的区别 输入格式: nn.CrossEntropyLoss:直接接受未归一化的 logits 作为输入,并在内部自动应用 log_softmax 来计算对数概率。nn.NLLLoss:接受对数概率&a…

【分布式微服务云原生】《Redis 分布式锁的挑战与解决方案及 RedLock 的强大魅力》

《Redis 分布式锁的挑战与解决方案及 RedLock 的强大魅力》 摘要: 本文深入探讨了使用 Redis 做分布式锁时可能遇到的各种问题,并详细阐述了相应的解决方案。同时,深入剖析了 RedLock 作为分布式锁的原因及原理,包括其多节点部署…

孤岛架构在异构性方面优势

1. 技术多样性 支持多种技术栈:孤岛架构允许每个孤岛使用最适合其业务需求的技术栈。这意味着可以根据不同的业务功能或数据处理需求选择不同的编程语言、数据库、框架和工具。 2. 独立性 独立开发和部署:每个孤岛可以独立开发和部署,这使…

docker 资源限制+调优详解

容器资源限制介绍 下面我将详细讲解 Docker 的各种资源限制及其在生产环境中的实际应用案例。我们将逐一探讨 CPU、内存、磁盘 I/O 和网络带宽的限制,并提供具体的配置示例和解释。 1. CPU 限制 1.1 设置 CPU 份额 --cpu-shares:设置容器的 CPU 优先…

重修设计模式-行为型-迭代器模式

重修设计模式-行为型-迭代器模式 提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。 迭代器模式(Iterator Pattern)将容器的遍历操作从容器类中拆分出来,放到迭代器类中,让两者的职责更加单一。…

在Nodejs中使用MySQL数据库

简介 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS(Relational Database Management System&#xff0…