大模型微调技术LoRA与QLoRA

这篇具有很好参考价值的文章主要介绍了大模型微调技术LoRA与QLoRA。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

LoRA: Low-Rank Adaptation of Large Language Models

动机

大模型的参数量都在100B级别,由于算力的吃紧,在这个基础上进行所有参数的微调变得不可能。LoRA正是在这个背景下提出的解决方案。

原理

虽然模型的参数众多,但其实模型主要依赖低秩维度的内容(low intrinsic dimension),由此引出低秩自适应方法lora,通过低秩分解来模拟参数的改变量,从而以极小的参数量来实现大模型的间接训练。

大模型微调技术LoRA与QLoRA

LoRA的思想也很简单,在原始PLM旁边增加一个旁路,做一个降维再升维的操作,来模拟所谓的 intrinsic rank 。

训练的时候固定PLM的参数,只训练降维矩阵A与升维矩阵B。而模型的输入输出维度不变,输出时将BA与PLM的参数叠加。

用随机高斯分布初始化A,用0矩阵初始化B,保证训练的开始此旁路矩阵依然是0矩阵。

大模型微调技术LoRA与QLoRA

这种思想有点类似于残差连接,同时使用这个旁路的更新来模拟full finetuning的过程。并且,full finetuning可以被看做是LoRA的特例(当r等于k时)

 LoRA详细过程

  • 在原模型旁边增加一个旁路,通过低秩分解(先降维再升维)来模拟参数的更新量;
  • 训练时,原模型固定,只训练降维矩阵A和升维矩阵B;
  • 推理时,可将BA加到原参数上,不引入额外的推理延迟;
  • 初始化,A采用高斯分布初始化,B初始化为全0,保证训练开始时旁路为0矩阵;
  • 可插拔式的切换任务,当前任务W0+B1A1,将lora部分减掉,换成B2A2,即可实现任务切换;
  • 秩的选取:对于一般的任务,rank=1,2,4,8足矣,而对于一些领域差距比较大的任务可能需要更大的rank。

总的来说,lora就是冻结预先训练的模型权重,并将可训练的秩分解矩阵注入Transformer架构的每一层。

目前对于大多数实验只在 Wq 和 Wv使用LoRA,可训练参数的数量由秩r和原始权值的形状决定。

大模型微调技术LoRA与QLoRA

 代码

源码:https://github.com/microsoft/LoRA

LoRALayer层

class LoRALayer():
    def __init__(
        self, 
        r: int, 
        lora_alpha: int, 
        lora_dropout: float,
        merge_weights: bool,
    ):
        self.r = r
        self.lora_alpha = lora_alpha
        # Optional dropout
        if lora_dropout > 0.:
            self.lora_dropout = nn.Dropout(p=lora_dropout)
        else:
            self.lora_dropout = lambda x: x
        # Mark the weight as unmerged
        self.merged = False
        self.merge_weights = merge_weights

Linear层

class Linear(nn.Linear, LoRALayer):
    # LoRA implemented in a dense layer
    def __init__(
        self, 
        in_features: int, 
        out_features: int, 
        r: int = 0, 
        lora_alpha: int = 1, 
        lora_dropout: float = 0.,
        fan_in_fan_out: bool = False, # Set this to True if the layer to replace stores weight like (fan_in, fan_out)
        merge_weights: bool = True,
        **kwargs
    ):
        nn.Linear.__init__(self, in_features, out_features, **kwargs)
        LoRALayer.__init__(self, r=r, lora_alpha=lora_alpha, lora_dropout=lora_dropout,
                           merge_weights=merge_weights)

        self.fan_in_fan_out = fan_in_fan_out
        # Actual trainable parameters
        if r > 0:
            self.lora_A = nn.Parameter(self.weight.new_zeros((r, in_features)))
            self.lora_B = nn.Parameter(self.weight.new_zeros((out_features, r)))
            self.scaling = self.lora_alpha / self.r
            # Freezing the pre-trained weight matrix
            self.weight.requires_grad = False
        self.reset_parameters()
        if fan_in_fan_out:
            self.weight.data = self.weight.data.transpose(0, 1)

    def reset_parameters(self):
        nn.Linear.reset_parameters(self)
        if hasattr(self, 'lora_A'):
            # initialize A the same way as the default for nn.Linear and B to zero
            nn.init.kaiming_uniform_(self.lora_A, a=math.sqrt(5))
            nn.init.zeros_(self.lora_B)

    def train(self, mode: bool = True):
        def T(w):
            return w.transpose(0, 1) if self.fan_in_fan_out else w
        nn.Linear.train(self, mode)
        if mode:
            if self.merge_weights and self.merged:
                # Make sure that the weights are not merged
                if self.r > 0:
                    self.weight.data -= T(self.lora_B @ self.lora_A) * self.scaling
                self.merged = False
        else:
            if self.merge_weights and not self.merged:
                # Merge the weights and mark it
                if self.r > 0:
                    self.weight.data += T(self.lora_B @ self.lora_A) * self.scaling
                self.merged = True       

    def forward(self, x: torch.Tensor):
        def T(w):
            return w.transpose(0, 1) if self.fan_in_fan_out else w
        if self.r > 0 and not self.merged:
            result = F.linear(x, T(self.weight), bias=self.bias)
            if self.r > 0:
                result += (self.lora_dropout(x) @ self.lora_A.transpose(0, 1) @ self.lora_B.transpose(0, 1)) * self.scaling
            return result
        else:
            return F.linear(x, T(self.weight), bias=self.bias)

Peft实现

from peft import LoraConfig, get_peft_model, prepare_model_for_int8_training, TaskType

# Define LoRA Config
lora_config = LoraConfig(
 r=16,
 lora_alpha=32,
 target_modules=["q", "v"],
 lora_dropout=0.05,
 bias="none",
 task_type=TaskType.SEQ_2_SEQ_LM
)
# prepare int-8 model for training
model = prepare_model_for_int8_training(model)

# add LoRA adaptor
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

# trainable params: 18874368 || all params: 11154206720 || trainable%: 0.16921300163961817

 参考链接:

https://zhuanlan.zhihu.com/p/631077870

https://zhuanlan.zhihu.com/p/636759194

https://zhuanlan.zhihu.com/p/514033873

QLoRA:Efficient Finetuning of Quantized LLMs

动机

微调非常大的模型的成本过高;对650亿参数的LLaMA模型进行进行16位微调需要超过780GB的GPU内存,QLORA使用一种新的高精度技术将预训练模型量化为int4,然后添加一小组可学习的低秩适配器权重。它是通过量化权重反向传播梯度来调整的。QLORA将65B参数模型进行微调的平均内存需求从 >780GB 的 GPU 内存减少到 <48GB,而不会降低运行时间或预测性能。这标志着LLM微调可访问性的显著转变:现在最大的公开可用的模型,迄今为止在单个GPU上进行微调。

创新

首先分析下LoRA微调中的痛点

  1. 参数空间小:LoRA中参与训练的参数量较少,解空间较小,效果相比全量微调有一定的差距。

  2. 微调大模型成本高:对于上百亿参数量的模型,LoRA微调的成本还是很高。

  3. 精度损失:针对第二点,可以采用int8或int4量化,进一步对模型基座的参数进行压缩。但是又会引发精度损失的问题,降低模型性能。

今天的主角QLoRA优点

  1. 4-bit NormalFloat:提出一种理论最优的4-bit的量化数据类型,优于当前普遍使用的FP4与Int4。对于正态分布权重而言,一种信息理论上最优的新数据类型,该数据类型对正态分布数据产生比 4 bit整数和 4bit 浮点数更好的实证结果。QLORA包含一种低精度存储数据类型(通常为4-bit)和一种计算数据类型(通常为BFloat16)。在实践中,QLORA权重张量使用时,需要将将张量去量化为BFloat16,然后在16位计算精度下进行矩阵乘法运算。模型本身用4bit加载,训练时把数值反量化到bf16后进行训练。

  2. Double Quantization:对第一次量化后的那些常量再进行一次量化,减少存储空间。相比于当前的模型量化方法,更加节省显存空间。每个参数平均节省0.37bit,对于65B的LLaMA模型,大约能节省3GB显存空间。

  3. Paged Optimizers:使用NVIDIA统一内存特性,该特性可以在在GPU偶尔OOM的情况下,进行CPU和GPU之间自动分页到分页的传输,以实现无错误的 GPU 处理。该功能的工作方式类似于 CPU 内存和磁盘之间的常规内存分页。使用此功能为优化器状态(Optimizer)分配分页内存,然后在 GPU 内存不足时将其自动卸载到 CPU 内存,并在优化器更新步骤需要时将其加载回 GPU 内存。

  4. 增加Adapter:4-bit的NormalFloat与Double Quantization,节省了很多空间,但带来了性能损失,作者通过插入更多adapter来弥补这种性能损失。在LoRA中,一般会选择在query和value的全连接层处插入adapter。而QLoRA则在所有全连接层处都插入了adapter,增加了训练参数,弥补精度带来的性能损失。

大模型微调技术LoRA与QLoRA

 文章来源地址https://www.toymoban.com/news/detail-501022.html

参考:

https://zhuanlan.zhihu.com/p/632164305

https://zhuanlan.zhihu.com/p/636215898

https://zhuanlan.zhihu.com/p/634256206

https://zhuanlan.zhihu.com/p/632229856

https://blog.csdn.net/qq_39970492/article/details/131048994

总结

 QLORA 可以使用 4 位基础模型和低秩适配器 (LoRA) 复制 16 位完全微调性能。QLORA将微调65B参数模型的平均内存需求从>780GB的GPU内存降低到<48GB,与完全微调的16位基准相比,既不降低运行时间也不降低预测性能,这意味着可以在单个GPU上微调迄今为止最大的公开可用模型。

 

到了这里,关于大模型微调技术LoRA与QLoRA的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • LLM:LoRA: Low-Rank Adaptation of Large Language Models

    随着模型规模的不断扩大,微调模型的所有参数(所谓full fine-tuning)的可行性变得越来越低。以GPT-3的175B参数为例,每增加一个新领域就需要完整微调一个新模型,代价和成本很高。 为解决微调大规模语言模型到不同领域和任务的挑战,已有多种方案,比如部分微调、使用

    2024年02月07日
    浏览(44)
  • 【论文精读】LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS

    当下大模型时代最火的低资源微调大模型方法之一,方法简单易懂,道理清晰明了,对未来的工作有很强的启发性。如果想要深入了解LoRA的底层原理,建议仔细看一看这篇文章,如果只是应用,那么简单了解就好了~ 大模型预训练后的全量微调往往由于算力缺口而不可行,因

    2024年02月10日
    浏览(133)
  • LORA: LOW-RANK ADAPTATION OF LARGE LAN-GUAGE MODELS

    Paper name LORA: LOW-RANK ADAPTATION OF LARGE LAN-GUAGE MODELS Paper Reading Note Paper URL: https://arxiv.org/pdf/2106.09685.pdf Code URL: huggingface 集成: https://github.com/huggingface/peft 官方代码: https://github.com/microsoft/LoRA 本文提出了低秩自适应 (Low-Rank Adaptation, LoRA),它冻结了预训练的模型权重,并将可训练

    2023年04月21日
    浏览(68)
  • [论文阅读笔记77]LoRA:Low-Rank Adaptation of Large Language Models

    题目 论文作者与单位 来源 年份 LoRA: Low-Rank Adaptation of Large Language Models microsoft International Conference on Learning Representations 2021 524 Citations 论文链接:https://arxiv.org/pdf/2106.09685.pdf 论文代码:https://github.com/microsoft/LoRA 研究主题 问题背景 核心方法流程 亮点 数据集 结论 论文类型 关

    2024年02月06日
    浏览(55)
  • 2021-arxiv-LoRA Low-Rank Adaptation of Large Language Models

    Paper: https://arxiv.org/abs/2106.09685 Code: https://github.com/microsoft/LoRA 自然语言处理的一个重要范式包括对通用领域数据的大规模预训练和对特定任务或领域的适应。当预训练更大的模型时,完全微调(重新训练所有模型参数)变得不那么可行。以 GPT-3 175B 为例,部署微调模型的独立

    2024年02月07日
    浏览(66)
  • 【DL】《LoRA: Low-Rank Adaptation of Large Language Models》译读笔记

    《Low-rank Adaption of Large Language Models: Explaining the Key Concepts Behind LoRA》 LoRA的秩分解矩阵是随机初始化的,然后通过梯度下降法进行训练。文章中提到,这种初始化方法可以保证LoRA的矩阵与预训练模型的权重相互正交,从而避免了对预训练模型的干扰。文章还比较了其他几种初

    2024年02月08日
    浏览(50)
  • 【论文&代码阅读】LORA: LOW-RANK ADAPTATION OF LARGE LAN- GUAGE MODELS

    最近很多工作好像都绕不开lora,无论是sd还是llm.... 问题:大模型重新训练所有模型参数的完全微调变得不太可行。 lora在做什么 我们提出了低秩自适应,即LoRA,它冻结预先训练的模型权重,并将可训练的秩分解矩阵注入Transformer架构的每一层 为什么work? 学习过的参数化模

    2024年02月10日
    浏览(44)
  • Raki的读paper小记:LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS

    研究任务 对大模型进行部分微调 已有方法和相关工作 现有技术通常通过扩展模型深度引入推理延迟(Houlsby 等人,2019;Rebuffi 等人,2017),或通过减少模型可用序列长度(Li 和 Liang,2021;Lester 等人,2021;Ham-bardzumyan 等人,2020;Liu 等人,2021) 面临挑战 这些方法通常无法

    2024年02月15日
    浏览(48)
  • Lora升级!ReLoRa!最新论文 High-Rank Training Through Low-Rank Updates

    关注公众号TechLead,分享AI与云服务技术的全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。 尽管通过扩展导致具有数千亿参

    2024年02月10日
    浏览(42)
  • 大模型微调技术LoRA与QLoRA

    大模型的参数量都在100B级别,由于算力的吃紧,在这个基础上进行所有参数的微调变得不可能。LoRA正是在这个背景下提出的解决方案。 虽然模型的参数众多,但其实模型主要依赖低秩维度的内容( low intrinsic dimension ),由此引出低秩自适应方法lora,通过低秩分解来模拟参数的

    2024年02月11日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包