首页 > 其他分享 >LoRA: Low-Rank Adaptation of Large Language Models 笔记

LoRA: Low-Rank Adaptation of Large Language Models 笔记

时间:2024-09-25 13:34:55浏览次数:11  
标签:初始化 训练 Language Models 模型 矩阵 Rank 参数 LoRA

问题背景

  • ⼤模型通常包含数亿甚⾄数百亿个参数,对其进⾏微调需要⼤量的计算资源和存储空间。
  • 在微调过程中,直接修改预训练模型的所有参数可能会破坏模型的原始性能。
  • 存储和部署微调后的⼤模型需要⼤量存储空间,尤其是当需要在多个应⽤场景中部署不同微调版本时。
  • 许多微调⽅法会增加推理阶段的计算延迟,影响模型的实时性应⽤。

LoRA

LoRA(Low-Rank Adaptation) 通过引⼊低秩矩阵分解,在减少计算资源和存储需求的同时,保持了预训练模型的初 始性能,稳定了微调过程,并降低了存储和部署成本。它特别适⽤于⼤规模模型的微调,在资源有限的环境中具有显 著的优势。

  • 存储与计算效率:通过低秩适应(LoRA),可以显著减少所需存储的参数数量,并减少计算需求。
  • 适应性与灵活性:LoRA⽅法允许模型通过只替换少量特定的矩阵A和B来快速适应新任务,显著提⾼任务切换的 效率。
  • 训练与部署效率:LoRA的简单线性设计允许在不引⼊推理延迟的情况下,与冻结的权重结合使⽤,从⽽提⾼部署 时的操作效率。

在推理时,对于使用LoRA的模型来说,可直接将原预训练模型权重与训练好的LoRA权重合并,因此在推理时不存在额外开销。

原理

作用:这种初始化方法使得在训练初期,新增的部分△W=BA对原始权重Wpretrained的影响为零,从而不会破坏预训练模型的初始性能。

参数量计算

秩r << d,只有d×r + r×d参数需要训练,减少了计算梯度所需的内存和浮点运算量(FLOPS)。

假设我们有一个预训练的大模型,其中某个权重矩阵W的维度为d×d。

假设d=4096,即这个权重矩阵的尺寸为4096 x 4096。
原始权重矩阵W的参数数量为:d×d=4096×4096=16,777,216

使⽤ LoRA ⽅法

选择一个较小的秩r,例如r=16。在LoRA中,我们将权重矩阵分解为两个低秩矩阵A和B。

使用LoRA方法后,需要训练的参数数量为:
d×r + r×d=4096×16 + 16×4096

​ =131,072+131,072

​ =262,144

与原始模型相比,使用LoRA后的参数数量显著减少。
只需要训练原始参数数量的约1.56%。

应用于自注意力层

Q、K、V和O矩阵在信息传播和特征表示中起着关键作⽤:

  • 查询与键的交互: Q和 K的交互决定了注意⼒分布,影响模型对输⼊序列的不同部分的关注度。

  • 数值的加权求和: V矩阵通过加权求和操作,将注意⼒分布转化为具体的输出。

  • 多头输出的整合: O矩阵整合多头注意⼒的输出,提供最终的特征表示。

LoRA通过将权重矩阵分解为两个低秩矩阵(例如W≈BA),减少了参数数量,降低了计算和存储成本,同时保持模型性能:

  • 参数压缩:Q、K、V和O矩阵通常包含大量参数,LoRA的低秩分解显著减少了需要优化的参数数量。
  • 性能保持:低秩矩阵能够捕捉到原始矩阵的主要信息,确保模型性能不受显著影响。

实现

变量:

import numpy as np

# 初始化矩阵 W, 预训练的模型参数
W = np.array([[4, 3, 2, 1],
              [2, 2, 2, 2],
              [1, 3, 4, 2],
              [0, 1, 2, 3]])
# 矩阵维度
d = W.shape[0] # 4
# 秩
r = 2
# 随机初始化 A 和 B
np.random.seed(666)
# A 和 B 的元素服从标准正态分布
A = np.random.randn(d, r)
B = np.zeros((r, d))

# 定义超参数
lr = 0.01 # 学习率,用于控制梯度下降的步长。
epochs = 1000 # 迭代次数,进行多少次梯度下降更新。

函数:

# 定义损失函数
def loss_function(W, A, B):
    '''
    W:目标矩阵
    A:矩阵分解中的一个矩阵,通常是随机初始化的。
    B:矩阵分解中的另一个矩阵,通常是零矩阵初始化的。
    '''
    # 矩阵相乘,@是Python中的矩阵乘法运算符,相当于np.matmul(A, B)。
    W_approx = A @ B
    # 损失函数越小,表示 A 和 B 的乘积 W_approx越接近于目标矩阵 W
    return np.linalg.norm(W - W_approx, "fro")**2
  
 # 定义梯度下降更新
def descent(W, A, B, lr, epochs):
    '''梯度下降法'''
    # 用于记录损失值
    loss_history = []
    for i in range(epochs):
        # 计算梯度
        W_approx = A @ B
        # 计算损失函数关于矩阵A的梯度
        gd_A = -2 * (W - W_approx) @ B.T
        # 计算损失函数关于矩阵B的梯度
        gd_B = -2 * A.T @ ( W - W_approx)
        # 使用梯度下降更新矩阵A和B
        A -= lr * gd_A
        B -= lr * gd_B
        # 计算当前损失
        loss = loss_function(W, A, B)
        loss_history.append(loss)
        # 每100个epoch打印一次
        if i % 100 == 0:
            print(f"Epoch: {i} , 损失: {loss:.4f}")
    # 返回优化后的矩阵
    return A, B, loss_history

运行

# 进行梯度下降优化
A, B, loss_history = descent(W, A, B, lr, epochs)

# 最终的近似矩阵
W_approx = A @ B
print(W_approx)
# 原始的矩阵 W
print(W)

QA

为什么需要低秩分解?

  • 现代预训练模型虽然是过参数化的,但在微调时参数更新主要集中在⼀个低维⼦空间中。

  • 参数更新 可以在低维度中进⾏优化,⾼维参数空间中的⼤部分参数在微调前后⼏乎没有变化。

  • 低秩分解使参数优化更⾼效,但如果参数更新实际上在⾼维⼦空间中发⽣,可能会导致重要信息遗漏和LoRA⽅法 失效。

为什么初始化参数使⽤正态分布?

这样做的原因包括:

  • 确保初始梯度的有效传播:正态分布初始化有助于在训练初期确保梯度有效传播,避免梯度消失或爆炸的问题。
  • 提供⾜够的随机性:正态分布的随机初始化为模型提供了⾜够的随机性,从⽽能够探索更⼴泛的参数空间,增加了模型找到最优解的可能性。
  • 平衡训练初期的影响:正态分布初始化的值⼀般较⼩,结合 B 初始化为零矩阵,可以在训练初期确保新增的偏置矩阵对原始预训练权重的影响为零,从⽽避免破坏预训练模型的初始性能。

为什么 A初始化服从正态分布?⽽B初始化为零矩阵?

  • 如果B和A全部初始化为零矩阵,缺点是很容易导致梯度消失。
  • 如果B和A全部正态分布初始化,那么在模型训练开始时,就会容易得到一个过大的偏移值△W,从而引起太多噪声,导致难以收敛。

参考

原始论文: https://arxiv.org/abs/2106.09685

B站

博客园:大模型高效微调-LoRA原理详解和训练过程深入分析

标签:初始化,训练,Language,Models,模型,矩阵,Rank,参数,LoRA
From: https://www.cnblogs.com/ag-chen/p/18431163

相关文章

  • LLM大模型: Denoising Diffusion Probabilistic Models 原理解析与核心代码
      根据文本生成图片是AI的核心应用之一,2020年后主流的生成方式都是基于DenoisingDiffusionProbabilisticModels原理的,逐渐替代了之前使用GAN的方式生成图片!那么DDPM为啥能取代GAN了?其优势在哪?或者说GAN的劣势在哪?  1、CLIP模型都知道吧?text和image都通过各自的enco......
  • 大型语言模型(Large Language Models)的介绍
    背景大型语言模型(LargeLanguageModels,简称LLMs)是一类先进的人工智能模型,它们通过深度学习技术,特别是神经网络,来理解和生成自然语言。这些模型在自然语言处理(NLP)领域中扮演着越来越重要的角色。以下是大型语言模型的一些关键特点和应用:1.定义和工作原理定义:大型语言模型是基于大......
  • A Survey on Large Language Models with Multilingualism: Recent Advances and New
    本文是LLM系列文章,针对《ASurveyonLargeLanguageModelswithMultilingualism:RecentAdvancesandNewFrontiers》的翻译。多语言大型语言模型调查:最新进展和新前沿摘要1引言2前言3具有多语言功能的大型语言模型4多语言推理策略5多语言大型语言模型......
  • A SURVEY ON FAIRNESS OF LARGE LANGUAGE MODELS IN E-COMMERCE: PROGRESS, APPLICATI
    本文是LLM系列文章,针对《ASURVEYONFAIRNESSOFLARGELANGUAGEMODELSINE-COMMERCE:PROGRESS,APPLICATION,ANDCHALLENGE》的翻译。电子商务中大型语言模型公平性的调查:进展、应用与挑战摘要1引言2电子商务LLM的原则3偏差挑战4电子商务应用5未来方......
  • Phi-2: The surprising power of small language models
    Phi-2:Thesurprisingpowerofsmalllanguagemodelshttps://www.microsoft.com/en-us/research/blog/phi-2-the-surprising-power-of-small-language-models/ Phi-2EvaluationBelow,wesummarizePhi-2performanceonacademicbenchmarkscomparedtopopularla......
  • 论文阅读笔记:Sapiens: Foundation for Human Vision Models
    Sapiens:FoundationforHumanVisionModels1背景1.1问题1.2目标2方法3创新点4模块4.1Humans-300M数据集4.2预训练4.32D位姿估计4.4身体部位分割4.5深度估计4.6表面法线估计5实验5.1实现细节5.22D位姿估计5.3身体部位分割5.4深度估计5.5表面法线估......
  • modelscope 命令行工具下载模型
    默认下载路径Windows系统在Windows系统上,默认的缓存目录通常是:自定义下载路径如果你想指定下载路径,可以使用 --local-dir 选项。例如:这样,模型文件将会下载到 E:\tmp\model_file 目录中。 参考文档: 模型的下载·文档中心(modelscope.cn)......
  • Why Is Prompt Tuning for Vision-Language Models Robust to Noisy Labels?
    文章汇总本文的作者针对了提示学习的结构设计进行了分析,发现了一些规律:1)固定的类名令牌为模型的优化提供了强正则化,减少了由噪声样本引起的梯度。2)从多样化和通用的web数据中学习到的强大的预训练图像文本嵌入为图像分类提供了强大的先验知识。3)CLIP的噪声零样本预测......
  • Analysis of Code and Test-Code generated by Large Language Models
    本文是LLM系列文章,针对《AnalysisofCodeandTest-CodegeneratedbyLargeLanguageModels》的翻译。大型语言模型生成的代码和测试代码的分析摘要1引言2方法3进行实验4测试结果的评估5讨论6相关工作7结论和未来工作摘要ChatGPT和Copilot等......
  • Imitating Language via Scalable Inverse Reinforcement Learning
    本文是LLM系列文章,针对《ImitatingLanguageviaScalableInverseReinforcementLearning》的翻译。通过可扩展的逆向强化学习模仿语言摘要1引言2方法3实验4相关工作5讨论6结论摘要大多数语言模型训练都建立在模仿学习的基础上。它涵盖了预训练、监......