跳转至

PEFT 参数高效微调 — HuggingFace 官方出品的 LoRA/Adapter 工具库


一句话说明

PEFT(Parameter-Efficient Fine-Tuning,v0.14+)是 HuggingFace 出品的官方微调库,提供 LoRA、QLoRA、Adapter、Prompt Tuning、IA3 等多种参数高效方法,只需几行代码就能给任意 Transformer 模型加上微调能力。


安装与配置

# 安装 PEFT(通常随 transformers 一起用)
pip install peft                            # 安装最新版(v0.14+)
pip install peft transformers accelerate   # 推荐:同时安装常用依赖

# 可选:量化支持(QLoRA 需要)
pip install bitsandbytes                   # 4bit/8bit 量化库

# 验证安装
python -c "import peft; print(peft.__version__)"

核心用法

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, get_peft_model, TaskType  # PEFT 核心类

# 第一步:加载基座模型
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-3.2-8B",
    torch_dtype="auto",                    # 自动选择数据类型
    device_map="auto"                      # 自动分配到 GPU
)

# 第二步:定义 LoRA 配置
lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,          # 任务类型:因果语言模型(生成类任务)
    r=16,                                  # LoRA 秩(低秩矩阵的维度)
    lora_alpha=32,                         # 缩放系数(控制 LoRA 的影响强度)
    lora_dropout=0.1,                      # Dropout 比例
    target_modules=["q_proj", "v_proj"],   # 对哪些层加 LoRA(默认 q 和 v 注意力层)
    bias="none",                           # 是否训练 bias(none/all/lora_only)
)

# 第三步:把 LoRA 加到模型上
model = get_peft_model(model, lora_config)

# 查看可训练参数比例(通常只有 0.1%-1%)
model.print_trainable_parameters()
# 输出示例:trainable params: 4,194,304 || all params: 8,030,261,248 || trainable%: 0.0522

参数详解

from peft import LoraConfig, AdaLoraConfig, PromptTuningConfig

# 1. LoRA 完整参数
lora_config = LoraConfig(
    r=16,                                  # 秩,推荐范围:4-64
    lora_alpha=32,                         # 缩放系数,通常是 r 的 2 倍
    lora_dropout=0.05,                     # Dropout,防止过拟合
    target_modules=["q_proj", "k_proj",   # 目标模块列表(None=自动选)
                    "v_proj", "o_proj",
                    "gate_proj", "up_proj", "down_proj"],
    bias="none",                           # bias 处理方式
    use_rslora=True,                       # 使用 RS-LoRA(更稳定的 rank-stabilized 版本)
    modules_to_save=["lm_head"],          # 这些层保存全量权重(不用 LoRA)
)

# 2. QLoRA(4bit 量化 + LoRA)
from transformers import BitsAndBytesConfig
import torch

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,                     # 用 4bit 加载基座模型
    bnb_4bit_quant_type="nf4",            # 量化类型(nf4 效果最好)
    bnb_4bit_compute_dtype=torch.bfloat16, # 计算时用 bf16(内存少但速度快)
    bnb_4bit_use_double_quant=True,        # 二次量化(进一步省内存)
)
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-3.2-8B",
    quantization_config=bnb_config,
    device_map="auto"
)
# 然后再用 get_peft_model() 加 LoRA

# 3. AdaLoRA(自适应 LoRA,自动分配秩给重要层)
adalora_config = AdaLoraConfig(
    init_r=12,                             # 初始秩
    target_r=8,                            # 最终目标秩
    tinit=200,                             # 开始调整前的预热步数
    tfinal=1000,                           # 调整结束步数
    deltaT=10,                             # 调整间隔步数
    lora_alpha=32,
)

实战案例

# 完整 QLoRA 微调流程

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

model_name = "meta-llama/Llama-3.2-8B-Instruct"

# 4bit 量化配置
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
)

# 加载量化模型
model = AutoModelForCausalLM.from_pretrained(
    model_name, quantization_config=bnb_config, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token   # Llama 没有 pad token,用 eos 代替

# 准备模型进行量化训练(必须调用这个函数!)
model = prepare_model_for_kbit_training(model)

# 加 LoRA
lora_config = LoraConfig(r=8, lora_alpha=16, target_modules="all-linear")
model = get_peft_model(model, lora_config)

# 保存和加载 LoRA 权重
model.save_pretrained("./my_lora_model")          # 只保存 LoRA 权重(几十 MB)

# 加载 LoRA 并推理
from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto")
model = PeftModel.from_pretrained(base_model, "./my_lora_model")
model = model.merge_and_unload()                  # 合并 LoRA 到基座模型

常见报错与解决

报错信息原因解决方法
Expected all tensors to be on same device模型分布在不同设备设置 device_map="auto"
bitsandbytes not found未安装量化库pip install bitsandbytes
target_modules not found模块名写错model.named_modules() 查看层名
prepare_model_for_kbit_training 报错旧版 PEFT升级 pip install --upgrade peft
LoRA 权重文件很大意外保存了全量模型确认用 get_peft_model() 包装后再保存

速查表

功能代码
基础 LoRALoraConfig(r=16, lora_alpha=32)
自适应 LoRAAdaLoraConfig(init_r=12, target_r=8)
QLoRA 量化BitsAndBytesConfig(load_in_4bit=True)
查看可训练参数model.print_trainable_parameters()
保存 LoRAmodel.save_pretrained("path")
加载 LoRAPeftModel.from_pretrained(base, "path")
合并权重model.merge_and_unload()
官方文档https://huggingface.co/docs/peft