游乐游手机版
首页/AI热点日报/热点详情

大模型高效微调DoRA:LoRA升级版技术

类型:热点整理2026-06-12
将预训练权重分解为幅度和方向两个独立部分,仅对方向施加低秩更新,幅度单独调整,从而实现更精细的模型微调。相比LoRA,DoRA在保持参数高效的同时,提升了学习能力与控制精度,在常识推理、视觉指令调整等任务中表现更优,且推理成本未增加。

在模型微调这件事上,学术界一直在试图找到一个平衡点——既要足够灵活,又要尽量节省参数。这也就解释了为什么像LoRA这类方法会受到如此多的关注。但即便LoRA已经足够优秀,它仍然存在一些结构性上的局限。而DoRA的出现,一定程度上补上了这个缺口。

模型训练

DoRA的全称是Weight-Decomposed Low-Rank Adaptation。它最大的突破点在于:把预训练权重拆成了“幅度”和“方向”两个独立的部分,然后只对方向部分施加LoRA更新,幅度则单独调整。这样一来,模型在微调时的学习过程就被拆解得更精细——就像调节音量(幅度)和调音色(方向)分成了两个旋钮,可以分别微调。

LoRA回顾

要理解DoRA,先得清楚LoRA到底做了什么。简单来说,LoRA就是用一个低秩分解来近似大矩阵的更新——把一个大权重矩阵拆成两个小矩阵的乘积。

看段代码会更直观:

import torch
import torch.nn as nn
import torch.nn.functional as F

class LoRALayer(nn.Module):
    def __init__(self, in_dim, out_dim, rank, alpha):
        super().__init__()
        std_dev = 1 / torch.sqrt(torch.tensor(rank).float())
        self.A = nn.Parameter(torch.randn(in_dim, rank) * std_dev)
        self.B = nn.Parameter(torch.zeros(rank, out_dim))
        self.alpha = alpha

    def forward(self, x):
        x = self.alpha * torch.matmul(torch.matmul(x, self.A), self.B)
        return x

class LinearWithLoRAMerged(nn.Module):
    def __init__(self, linear, rank, alpha):
        super().__init__()
        self.linear = linear
        self.lora = LoRALayer(linear.in_features, linear.out_features, rank, alpha)

    def forward(self, x):
        lora = torch.matmul(self.lora.A, self.lora.B)
        combined_weight = self.linear.weight + self.lora.alpha * lora.T
        return F.linear(x, combined_weight, self.linear.bias)

看上去很简洁对吧?但就是这种“拆小再合”的思路,大幅降低了全量微调的计算成本。

DoRA

DoRA的核心组成可以拆成以下几个层次:

  • 权重分解:将每个预训练权重矩阵先分解成幅度向量(magnitude)和方向矩阵(direction)。这里的关键在于,分解后的两个组件在微调时可以各司其职。

  • 幅度和方向分别调整:幅度决定权重整体的大小,方向决定权重的走向。DoRA对这两部分独立调整,互不干扰。

  • 方向更新用LoRA:在更新方向部分时,DoRA沿用了LoRA的低秩适配手段,只更新方向相关的参数。

  • 混合权重构建:最终的权重由调整后的幅度m和经过LoRA更新的方向V组合而成:W' = m * (V + ∆V) / ||V + ∆V||c

  • 模块选择策略:在微调过程中,DoRA并不是对所有模块都一视同仁。比如对QKV模块,它同时调整幅度和方向;而对MLP等线性层,则只微调幅度。这种粒度控制,既提升了性能,又减少了参与训练的参数数量。

综合来看,DoRA通过权重分解和定向低秩适配,在保持全量微调学习能力的同时,还做到了参数效率的优化。从NLP到跨模态任务,它的表现普遍优于传统LoRA。

具体实现上,代码也不复杂:

import torch
import torch.nn as nn
import torch.nn.functional as F

torch.manual_seed(0)

class DoRALayer(nn.Module):
    def __init__(self, d_in, d_out, rank=4, weight=None, bias=None):
        super().__init__()
        if weight is not None:
            self.weight = nn.Parameter(weight, requires_grad=False)
        else:
            self.weight = nn.Parameter(torch.Tensor(d_out, d_in), requires_grad=False)
        if bias is not None:
            self.bias = nn.Parameter(bias, requires_grad=False)
        else:
            self.bias = nn.Parameter(torch.Tensor(d_out), requires_grad=False)

        self.m = nn.Parameter(self.weight.norm(p=2, dim=0, keepdim=True))
        std_dev = 1 / torch.sqrt(torch.tensor(rank).float())
        self.lora_A = nn.Parameter(torch.randn(d_out, rank) * std_dev)
        self.lora_B = nn.Parameter(torch.zeros(rank, d_in))

    def forward(self, x):
        lora = torch.matmul(self.lora_A, self.lora_B)
        adapted = self.weight + lora
        column_norm = adapted.norm(p=2, dim=0, keepdim=True)
        norm_adapted = adapted / column_norm
        calc_weights = self.m * norm_adapted
        return F.linear(x, calc_weights, self.bias)

DoRA相比LoRA的优势

聊完原理,我们来看看DoRA在实际表现中到底比LoRA好在哪里。根据已有的实验数据,在常识推理、视觉指令调整、图像/视频文本理解等下游任务中,微调LLaMA、LLaVA、VL-BART等模型时,DoRA几乎全面优于LoRA。

具体优势可以归纳为四点:

  • 更精准的控制:把权重拆成幅度和方向后,模型可以针对任务需求做更细颗粒度的适配。

  • 学习能力更强:这种分解策略放大了模型在微调阶段的可塑性,无论是小模型还是大模型,DoRA的表现都更接近全参数微调。

  • 维持高效性:虽然策略上做了创新,但并没有带来额外的推理成本——本质还是低秩更新的路子。

  • 训练更稳定:通过将权重分解并单独对方向做低秩适应,DoRA有效抑制了过拟合和训练过程的不稳定因素。

说到底,DoRA并不是碘伏性的方法论创新,而是在LoRA这条被验证过的路径上做了一个非常巧妙的结构优化。正是这种“再精细一点”的思维,让它在兼顾效率的同时,把性能又往前推了一步。

来源:https://www.53ai.com/news/qianyanjishu/1003.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。