变体方法 #

变体概览 #

text
┌─────────────────────────────────────────────────────────────┐
│                    LoRA 变体家族                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  量化变体:                                                  │
│  ├── QLoRA: 4-bit 量化 + LoRA                               │
│  └── LoftQ: 量化感知 LoRA                                   │
│                                                             │
│  自适应变体:                                                │
│  ├── AdaLoRA: 自适应秩调整                                  │
│  └── SoRA: 稀疏 LoRA                                        │
│                                                             │
│  优化变体:                                                  │
│  ├── LoRA+: 非对称学习率                                    │
│  ├── DoRA: 权重分解                                         │
│  └── rsLoRA: 稳定秩缩放                                     │
│                                                             │
│  结构变体:                                                  │
│  ├── LoRA-FA: 冻结 A 矩阵                                   │
│  ├── VeRA: 向量随机化                                       │
│  └── Delta-LoRA: 增量更新                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

QLoRA #

简介 #

QLoRA(Quantized Low-Rank Adaptation)结合了量化和 LoRA,在保持效果的同时大幅降低显存需求。

text
┌─────────────────────────────────────────────────────────────┐
│                    QLoRA 核心技术                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 4-bit NormalFloat (NF4) 量化                            │
│     ├── 针对正态分布权重优化                                 │
│     └── 比标准 4-bit 更精确                                 │
│                                                             │
│  2. 双重量化 (Double Quantization)                          │
│     ├── 量化量化常数                                        │
│     └── 进一步节省显存                                      │
│                                                             │
│  3. 分页优化器 (Paged Optimizers)                           │
│     ├── GPU 显存不足时使用 CPU 内存                          │
│     └── 避免显存溢出                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

QLoRA 实现 #

python
import torch
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training

model_name = "meta-llama/Llama-2-7b-hf"

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.float16,
    bnb_4bit_use_double_quant=True,
)

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    quantization_config=bnb_config,
    device_map="auto",
)

model = prepare_model_for_kbit_training(model)

lora_config = LoraConfig(
    r=64,
    lora_alpha=16,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
                    "gate_proj", "up_proj", "down_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

QLoRA vs LoRA #

特性 LoRA QLoRA
显存需求 ~15GB (7B) ~6GB (7B)
模型精度 FP16/BF16 4-bit NF4
训练速度 稍慢
效果 基准 接近基准
适用场景 显存充足 显存受限

AdaLoRA #

简介 #

AdaLoRA(Adaptive Budget Allocation for Low-Rank Adaptation)根据重要性动态调整每个层的秩。

text
┌─────────────────────────────────────────────────────────────┐
│                    AdaLoRA 核心思想                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  动态秩调整:                                                │
│  ├── 重要层:分配更高秩                                     │
│  ├── 次要层:分配较低秩                                     │
│  └── 自动学习最优分配                                       │
│                                                             │
│  奇异值分解:                                                │
│  ├── ΔW = PΛQ                                               │
│  ├── Λ: 可学习的奇异值                                      │
│  └── 根据奇异值重要性剪枝                                   │
│                                                             │
│  优势:                                                     │
│  ├── 自动优化参数分配                                       │
│  ├── 更高效的参数利用                                       │
│  └── 适应不同任务需求                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

AdaLoRA 实现 #

python
from peft import AdaLoraConfig, get_peft_model

adalora_config = AdaLoraConfig(
    init_r=12,
    target_r=8,
    beta1=0.85,
    beta2=0.85,
    tinit=200,
    tfinal=1000,
    deltaT=10,
    lora_alpha=16,
    target_modules=["q_proj", "v_proj"],
    lora_dropout=0.05,
    task_type="CAUSAL_LM",
)

model = get_peft_model(model, adalora_config)
model.print_trainable_parameters()

AdaLoRA 参数说明 #

python
adalora_params = {
    "init_r": "初始秩",
    "target_r": "目标秩",
    "beta1": "奇异值更新系数",
    "beta2": "奇异值更新系数",
    "tinit": "开始调整的步数",
    "tfinal": "结束调整的步数",
    "deltaT": "调整间隔",
}

LoRA+ #

简介 #

LoRA+ 通过为 A 和 B 矩阵设置不同的学习率来优化训练。

text
┌─────────────────────────────────────────────────────────────┐
│                    LoRA+ 核心改进                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  非对称学习率:                                              │
│  ├── η_A = η / √r                                          │
│  ├── η_B = η × √r                                          │
│  └── η_B / η_A = r                                         │
│                                                             │
│  理论依据:                                                  │
│  ├── A 和 B 的梯度尺度不同                                  │
│  ├── 非对称学习率平衡更新                                   │
│  └── 加速收敛                                               │
│                                                             │
│  效果:                                                     │
│  ├── 训练速度提升 2x                                        │
│  ├── 最终效果更好                                           │
│  └── 无额外计算开销                                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

LoRA+ 实现 #

python
import torch
from torch.optim import AdamW

def create_lora_plus_optimizer(model, base_lr=2e-4, r=8):
    lora_a_params = []
    lora_b_params = []
    other_params = []
    
    for name, param in model.named_parameters():
        if not param.requires_grad:
            continue
        
        if "lora_A" in name:
            lora_a_params.append(param)
        elif "lora_B" in name:
            lora_b_params.append(param)
        else:
            other_params.append(param)
    
    import math
    lr_a = base_lr / math.sqrt(r)
    lr_b = base_lr * math.sqrt(r)
    
    optimizer = AdamW([
        {"params": lora_a_params, "lr": lr_a},
        {"params": lora_b_params, "lr": lr_b},
        {"params": other_params, "lr": base_lr},
    ])
    
    return optimizer

DoRA #

简介 #

DoRA(Weight-Decomposed Low-Rank Adaptation)将权重分解为幅度和方向两部分。

text
┌─────────────────────────────────────────────────────────────┐
│                    DoRA 核心思想                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  权重分解:                                                  │
│  W = m × V                                                  │
│                                                             │
│  其中:                                                     │
│  ├── m: 幅度向量 (magnitude)                               │
│  ├── V: 方向矩阵 (direction)                               │
│  └── ||V||_col = 1 (列归一化)                              │
│                                                             │
│  LoRA 更新:                                                 │
│  V' = V₀ + ΔV = V₀ + BA                                    │
│  m' = m₀ + Δm                                              │
│                                                             │
│  优势:                                                     │
│  ├── 分别优化幅度和方向                                     │
│  ├── 更稳定的学习过程                                       │
│  └── 更好的效果                                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

DoRA 实现 #

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

class DoRALinear(nn.Module):
    def __init__(self, in_features, out_features, r=8, alpha=16):
        super().__init__()
        self.in_features = in_features
        self.out_features = out_features
        self.r = r
        self.alpha = alpha
        self.scaling = alpha / r
        
        self.weight = nn.Parameter(torch.empty(out_features, in_features))
        self.weight.requires_grad = False
        
        self.lora_A = nn.Parameter(torch.empty(r, in_features))
        self.lora_B = nn.Parameter(torch.empty(out_features, r))
        
        self.magnitude = nn.Parameter(torch.ones(out_features))
        
        nn.init.kaiming_uniform_(self.lora_A, a=5**0.5)
        nn.init.zeros_(self.lora_B)
    
    def forward(self, x):
        result = F.linear(x, self.weight)
        
        lora_out = x @ self.lora_A.T @ self.lora_B.T
        
        V = self.weight + lora_out * self.scaling
        V_norm = F.normalize(V, p=2, dim=1)
        
        W_dora = self.magnitude.unsqueeze(1) * V_norm
        
        return F.linear(x, W_dora)

其他变体 #

LoRA-FA #

python
class LoRAFA(nn.Module):
    def __init__(self, in_features, out_features, r=8, alpha=16):
        super().__init__()
        self.r = r
        self.alpha = alpha
        self.scaling = alpha / r
        
        self.weight = nn.Parameter(torch.empty(out_features, in_features))
        self.weight.requires_grad = False
        
        self.lora_A = nn.Parameter(torch.empty(r, in_features))
        self.lora_B = nn.Parameter(torch.empty(out_features, r))
        
        nn.init.kaiming_uniform_(self.lora_A, a=5**0.5)
        self.lora_A.requires_grad = False
        
        nn.init.zeros_(self.lora_B)
    
    def forward(self, x):
        result = F.linear(x, self.weight)
        lora_out = x @ self.lora_A.T @ self.lora_B.T
        return result + lora_out * self.scaling

VeRA #

python
class VeRALinear(nn.Module):
    def __init__(self, in_features, out_features, r=8, alpha=16):
        super().__init__()
        self.r = r
        self.alpha = alpha
        self.scaling = alpha / r
        
        self.weight = nn.Parameter(torch.empty(out_features, in_features))
        self.weight.requires_grad = False
        
        self.shared_A = nn.Parameter(torch.empty(r, in_features))
        self.shared_B = nn.Parameter(torch.empty(out_features, r))
        
        self.vector_a = nn.Parameter(torch.ones(r))
        self.vector_b = nn.Parameter(torch.ones(r))
        
        nn.init.normal_(self.shared_A, std=0.1)
        nn.init.normal_(self.shared_B, std=0.1)
    
    def forward(self, x):
        result = F.linear(x, self.weight)
        
        A = self.shared_A * self.vector_a.unsqueeze(1)
        B = self.shared_B * self.vector_b.unsqueeze(0)
        
        lora_out = x @ A.T @ B.T
        return result + lora_out * self.scaling

变体对比 #

变体 核心改进 显存 效果 适用场景
LoRA 基准 基准 通用
QLoRA 量化 接近 显存受限
AdaLoRA 自适应秩 更好 复杂任务
LoRA+ 非对称学习率 更好 加速训练
DoRA 权重分解 更好 高质量需求
LoRA-FA 冻结 A 相当 参数更少
VeRA 共享权重 最低 相当 多任务

选择指南 #

text
┌─────────────────────────────────────────────────────────────┐
│                    变体选择指南                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  显存受限 (< 16GB):                                         │
│  └── 推荐: QLoRA                                            │
│                                                             │
│  追求最佳效果:                                               │
│  └── 推荐: DoRA 或 AdaLoRA                                  │
│                                                             │
│  加速训练:                                                   │
│  └── 推荐: LoRA+                                            │
│                                                             │
│  多任务场景:                                                 │
│  └── 推荐: VeRA                                             │
│                                                             │
│  通用场景:                                                   │
│  └── 推荐: 标准 LoRA                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

下一步 #

现在你已经了解了 LoRA 的各种变体方法,接下来学习 生态工具,掌握完整的 LoRA 工具链!

最后更新:2026-04-05