0 LORA

一、为什么需要Lora训练?

在自然语言处理领域,预训练大模型(如LLaMAGPT等)往往包含数十亿甚至千亿级参数。传统全参数微调方法需要更新整个模型的权重,这不仅需要巨大的计算资源,还会导致极高的存储成本。例如,微调一个100亿参数的模型需要约40GB*4的显存,这对普通开发者来说是难以承受的。

在预训练⼤规模模型时,微调整个模型的参数可能会带来较⼤的计算和存储开销。

Lora(Low-Rank Adaptation)提出了一种巧妙的解决方案:冻结原始预训练模型的参数,仅通过低秩分解矩阵来模拟参数更新。这种方式将训练参数量减少到原模型的0.1%以下,同时保持模型性能几乎无损。

LoRA 通过引⼊ 低秩矩阵分解 ,在微调时不再调整原始模型的所有权重,⽽是通过将权重矩阵分解成两 个较⼩的低秩矩阵来表⽰权重的变化。尽管预训练模型拥有⼤量的参数, 但许多参数在特定任务的微 调过程中实际上是不活跃的 。LoRA通过低秩分解的⽅式,只更新那些对特定任务最重要的参数,这样 做可以在保持模型性能的同时,显著减少微调所需的计算资源和时间。
LoRA 的核⼼思想是将权重的变化通过两个⼩型矩阵的乘积进⾏表⽰, 利⽤低秩矩阵分解的⽅式
有效降低参数量 。这样只需要训练低秩矩阵的参数,⽽不是完整的权重矩阵。

二、Lora原理详解

1. 低秩分解的数学基础

假设预训练模型的某个权重矩阵为W \varepsilon R^{^{d*k}}。在微调时,传统方法直接更新W为W′=W+ΔW,而Lora则对增量矩阵ΔW进行低秩分解:

其中,r是远小于d和k的秩(通常为4~64)。这种分解将参数数量从d×k(原始梯度更新) 减少到r×(d+k)。例如当d=1024,k=1024,r=8时,参数量从1M减少到16K(仅为1.6%)。

2. 前向传播过程

修改后的前向计算为:

h=Wx+BAx

其中,B和A是可训练的矩阵,而W被冻结。在训练过程中,只有B和A的梯度被计算和更新

3. 为何低秩有效?

预训练模型通常位于一个低维任务空间中。Lora假设参数更新也具有低秩性质,因此低秩分解能够有效捕捉核心特征。这与奇异值分解(SVD)中主成分的概念相似。

从Figure2也可以看出,LoRA训练的模型与全参微调的结果相差不大,甚至更优。这种既省显存,又不失性能的方法妥妥的真香。

4 参数初始化

在 LoRA 的实现中,矩阵B初始化为零矩阵,矩阵A使⽤随机⾼斯分布初始化,这样做的主要⽬的是 在微调开始时确保权重调整 \Delta W是零矩阵,从⽽稳定训练过程并保持模型在初始阶段的表现与预 训练模型⼀致。下⾯详细解释这种初始化⽅式的原因和优点:
LoRA 的⽬标是在不改变预训练模型原始权重 W的情况下,通过微调来对模型进⾏轻量级的适配。如 果在微调⼀开始,矩阵 A和B的初始值导致较⼤的权重变化(即\Delta W\neq 0),模型的表现可能会 发⽣突变,偏离原本的预训练模型表现,从⽽导致不稳定的训练过程。
通过将 B 初始化为零矩阵, Δ W = A × B ⼀开始为零矩阵,这样确保了在微调开始时:
Wnew = W + Δ W = W + 0 = W
        即,初始时微调模型的权重与预训练模型的权重保持⼀致。 这确保了模型不会⼀开始就因为过⼤的权重变化⽽导致性能波动。
        尽管B初始化为零,但 A使⽤随机⾼斯分布进⾏初始化。这是为了确保在训练过程中,当B不再 为零矩阵时, 能够提供多样的参数更新⽅向 。具体原因包括:
  • 增加表⽰能⼒ :随机初始化A可以确保它具有丰富的表⽰能⼒,使得低秩矩阵A × B够探索⼴泛的权重调整空间。随机初始化提供了不同的起始点,从⽽能够在训练过程中捕捉更多的特征。
  • 避免对称性问题 :如果A初始为零或相同的值,可能会限制模型在调整过程中学习到多样化的特征。随机初始化打破了这种对称性,使得矩阵 能够在训练过程中学到更复杂的特征组合。
  • 提供有效的梯度信息 :随机初始化 可以防⽌梯度更新过程中出现梯度消失的问题。初始化时提供的⾮零梯度信息可以加速收敛,帮助模型更快地找到适应任务的最优参数。

通过将B初始化为零矩阵以及将A随机初始化,LoRA 保证了模型在微调开始时的稳定性,并能逐 渐引⼊权重更新。这种初始化⽅式确保了模型在训练初期不会出现性能波动,同时提供了⾜够的参数 ⾃由度来进⾏有效的任务适配,从⽽使 LoRA 在微调过程中能够实现⾼效且稳定的性能提升。

三、代码实现详解(基于PyTorch)

1. 定义Lora层

import torch
import torch.nn as nn

class LoraLayer(nn.Module):
    def __init__(self, original_layer, rank=8, alpha=16):
        super().__init__()
        self.original_layer = original_layer  # 原始预训练层(如nn.Linear)
        self.original_layer.requires_grad_(False)  # 冻结原参数
        
        d, k = original_layer.weight.shape
        self.lora_A = nn.Parameter(torch.randn(d, rank))  # 低秩矩阵A
        self.lora_B = nn.Parameter(torch.zeros(rank, k))  # 低秩矩阵B
        self.scaling = alpha / rank  # 缩放系数,用于稳定训练
        
    def forward(self, x):
        orig_output = self.original_layer(x)
        lora_output = x @ (self.lora_A @ self.lora_B).T * self.scaling
        return orig_output + lora_output

2. 替换模型中的线性层

假设我们选择对Transformer中的query和value层应用Lora:

def apply_lora(model, rank=8):
    for name, layer in model.named_modules():
        if 'query' in name or 'value' in name:  # 选择特定层
            if isinstance(layer, nn.Linear):
                # 用Lora层包装原始层
                new_layer = LoraLayer(layer, rank=rank)
                # 替换模块(需要处理层次结构)
                parent_name = '.'.join(name.split('.')[:-1])
                parent = model.get_submodule(parent_name)
                layer_name = name.split('.')[-1]
                setattr(parent, layer_name, new_layer)
    return model

3. 训练过程

model = AutoModelForCausalLM.from_pretrained('llama-7b')
 model = apply_lora(model, rank=8)  # 应用Lora

 optimizer = torch.optim.AdamW(
    params=[p for p in model.parameters() if p.requires_grad], 
    lr=1e-4
)

for batch in dataloader:
    outputs = model(**batch)
    loss = outputs.loss
    loss.backward()
    optimizer.step()
    optimizer.zero_grad()

4. 权重合并(部署时)

训练完成后,可将Lora权重合并到原模型中以便推理:

with torch.no_grad():
    for name, layer in model.named_modules():
        if isinstance(layer, LoraLayer):
            # 合并权重 ΔW = B*A
            delta_w = layer.lora_B @ layer.lora_A * layer.scaling
            layer.original_layer.weight += delta_w.T  # 更新原层参数

四、Lora的超参数

1、应用LoRA的权重

由Table5可知,在可训练的参数量一致的情况下,同时训练 和 的性价比最高。

2、超参数r的选择

由Table6可知,选择更大的r性能差别不大,因此选择更低的r性价比更高。

3、实践经验

  1.  秩(Rank r)。4~32 即可。
  2. 缩放因子(Alpha α)。典型设置:α = 2r。
  3. 目标模块(target_modules)。Transformer架构:优先选择queryvalue投影矩阵(实验显示调整这两个模块可获得95%的全量微调效果)
  4.  学习率(learning_rate)。LoRA微调:建议1e-4~5e-4
  5. 3~5轮。

五、参考文献

1、LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值