前置知识: 大语言模型

微调与LoRA

00:00
4 min Advanced

理解 LoRA 和 QLoRA 微调技术,用极少参数高效适配 LLM

微调与LoRA

参数微调 70B 模型需要 280GB GPU 内存。LoRA 只训练 0.1% 的参数——不到 1GB——就能达到 95% 以上的全参数微调效果。这就是参数高效微调(PEFT)的力量。

类型 构建 语言 Python 前置条件 Phase 10 Lesson 06(指令微调 SFT) 预计时间 ~60 分钟

学习目标

  • 理解 LoRA 的数学原理:低秩分解
  • 掌握 LoRA 的关键超参数:rank、alpha、目标
  • 理解 QLoRA 和 NF4 量化
  • 实现完整的 LoRA 微调流程

LoRA 原理

LoRA(Low-Rank Adaptation)将权重更新分解为低秩矩阵:

其中

原始权重 冻结不更新,只训练

import torch
import torch.nn as nn


class LoRALayer(nn.Module):
    """LoRA 适配层"""

    def __init__(self, original_layer, rank=8, alpha=16):
        super().__init__()
        self.original_layer = original_layer
        self.rank = rank
        self.alpha = alpha
        self.scaling = alpha / rank

        # 获取原始层的维度
        if isinstance(original_layer, nn.Linear):
            d_out, d_in = original_layer.weight.shape
        else:
            raise ValueError("LoRA only supports Linear layers")

        # 低秩矩阵
        self.lora_A = nn.Parameter(torch.randn(d_in, rank) * 0.01)
        self.lora_B = nn.Parameter(torch.zeros(rank, d_out))

        # 冻结原始权重
        original_layer.weight.requires_grad = False
        if original_layer.bias is not None:
            original_layer.bias.requires_grad = False

    def forward(self, x):
        # 原始变换
        original_output = self.original_layer(x)

        # LoRA 增量
        lora_output = (x @ self.lora_A @ self.lora_B) * self.scaling

        return original_output + lora_output

参数量对比

模型参数LoRA (r=8)LoRA (r=16)比例
LLaMA-7B6.7B4.2M8.4M0.06%
LLaMA-13B13B6.6M13.1M0.05%
LLaMA-70B70B20.2M40.3M0.03%

使用 PEFT 库

from peft import LoraConfig, get_peft_model, TaskType
from transformers import AutoModelForCausalLM


def setup_lora(model_name="meta-llama/Llama-2-7b-hf", rank=8, alpha=16):
    """配置 LoRA 微调"""
    # 加载基座模型
    model = AutoModelForCausalLM.from_pretrained(
        model_name,
        torch_dtype=torch.bfloat16,
        device_map="auto",
    )

    # LoRA 配置
    lora_config = LoraConfig(
        task_type=TaskType.CAUSAL_LM,
        r=rank,
        lora_alpha=alpha,
        lora_dropout=0.05,
        target_modules=["q_proj", "v_proj", "k_proj", "o_proj",
                        "gate_proj", "up_proj", "down_proj"],
        bias="none",
    )

    # 应用 LoRA
    model = get_peft_model(model, lora_config)
    model.print_trainable_parameters()
    # 输出: trainable params: 13,107,200 || all params: 6,738,415,616 || trainable%: 0.1945

    return model

QLoRA

QLoRA 在 LoRA 基础上加入 4-bit 量化,进一步降低内存:

from transformers import BitsAndBytesConfig


def setup_qlora(model_name="meta-llama/Llama-2-7b-hf", rank=64, alpha=16):
    """配置 QLoRA 微调"""
    # 4-bit 量化配置
    bnb_config = BitsAndBytesConfig(
        load_in_4bit=True,
        bnb_4bit_quant_type="nf4",
        bnb_4bit_compute_dtype=torch.bfloat16,
        bnb_4bit_use_double_quant=True,
    )

    # 加载量化模型
    model = AutoModelForCausalLM.from_pretrained(
        model_name,
        quantization_config=bnb_config,
        device_map="auto",
    )

    # LoRA 配置(QLoRA 通常用更高的 rank)
    lora_config = LoraConfig(
        task_type=TaskType.CAUSAL_LM,
        r=rank,
        lora_alpha=alpha,
        target_modules=["q_proj", "v_proj", "k_proj", "o_proj",
                        "gate_proj", "up_proj", "down_proj"],
    )

    model = get_peft_model(model, lora_config)
    return model

Rank 选择指南

任务复杂推荐 Rank推荐 Alpha说明
简单(风调整)4-88-16低秩足够捕获变化
中等(领域适配)16-3232-64需要更容量学习领域知识
复杂(新任务64-128128-256提供表达能力

合并 LoRA 适配器

def merge_lora(model):
    """将 LoRA 权重合并到基座模型"""
    model = model.merge_and_unload()
    return model

# 保存合并后的模型
model = merge_lora(model)
model.save_pretrained("merged_model")

关键术语

术语通俗说法实际含义
LoRA”低秩适配”Low-Rank Adaptation,通过低秩矩阵分解实现参数微调
QLoRA”量化 LoRA”在 LoRA 基础上使用 4-bit 量化进一步降低内存
Rank”秩”LoRA 低秩矩阵的维度控制训练数量
Alpha”缩放因子LoRA 增量的缩放系数,alpha/rank 决定实际缩放比
NF4”4-bit 正态浮NormalFloat4,QLoRA 使用的 4-bit 量化

延伸阅读

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式