Loading...

文章背景图

PEFT:HuggingFace 参数高效微调库安装与使用指南

2026-10-26
0
- 字
- 分钟
|

PEFT:HuggingFace 参数高效微调库安装与使用指南

一、官方信息

项目名称PEFT (Parameter-Efficient Fine-Tuning)
仓库地址https://github.com/huggingface/peft
官方文档https://huggingface.co/docs/peft
最新更新持续高频迭代(2026-10-26)
Star 数15k+
项目定位HuggingFace 官方出品,统一 LoRA / QLoRA / Prefix Tuning / P-Tuning / Adapter / IA3 等所有参数高效微调方法,是 LLaMA-Factory、Unsloth、Axolotl 的底层依赖

二、项目背景

PEFT 是 HuggingFace 官方维护的参数高效微调库,2023 年初由 Benjamin Mallet 等人发起。它把学术界提出的 LoRA、QLoRA、Prefix Tuning、P-Tuning v2、Adapter Layers、IA3、AdaLoRA、LoHa、LoKr 等方法全部统一成一套简洁 API,与 Transformers、Accelerate、TRL 深度集成。

PEFT 本身不是训练框架,而是一个"插件":在任意 HuggingFace 模型上套一层 PEFT wrapper,即可冻结原模型权重、只训练少量可训练参数(通常 < 1%)。这使得单张消费级显卡也能微调 7B/13B 模型,成为大模型时代个人开发者和企业做领域适配的基础设施。LLaMA-Factory、Unsloth、Axolotl、LLM-Adapters 等上层框架底层都依赖 PEFT。

三、核心特性

  • 方法齐全:LoRA / QLoRA / Prefix / P-Tuning v2 / Adapter / IA3 / AdaLoRA / BOFT / LNT 全收录。
  • HF 生态原生:与 Transformers、Datasets、Accelerate、TRL、Diffusers 无缝集成。
  • 超轻权重:7B 模型 LoRA 权重仅 ~50MB,易于分发和版本管理。
  • 多任务切换:同一基座模型可挂多个 LoRA,推理时动态切换。
  • 量化友好:配合 bitsandbytes 4/8bit 量化,QLoRA 48GB 显存可跑 65B。
  • 跨模态:不仅支持 LLM,还支持扩散模型(Stable Diffusion)PEFT。
  • 官方文档完善:大量 Notebook 示例,是学习 PEFT 的权威资料。

四、环境要求

  • Python:3.9 ~ 3.12
  • PyTorch:≥ 2.0
  • GPU(可选):NVIDIA 显卡 ≥ 8GB(QLoRA 7B)
  • 依赖:transformers ≥ 4.36、accelerate、bitsandbytes(量化用)

五、详细部署步骤

方式一:pip 安装(推荐)

conda create -n peft python=3.10 -y
conda activate peft

pip install peft
# 或指定版本
pip install peft==0.13.0

# 验证
python3 -c "import peft; print(peft.__version__)"

方式二:源码安装

git clone https://github.com/huggingface/peft.git
cd peft
pip install -e .

最小 LoRA 微调示例

# train_lora.py
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from peft import LoraConfig, get_peft_model
from trl import SFTTrainer
from datasets import load_dataset

# 1. 加载基座模型
model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen2.5-7B-Instruct",
    torch_dtype="auto",
    device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")

# 2. 配置 LoRA
lora_config = LoraConfig(
    r=8,
    lora_alpha=16,
    target_modules=["q_proj","v_proj"],   # 只挂 Q/V 投影
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

# 3. 包装模型(原权重自动冻结)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# 输出:trainable params: 2,097,152 || all params: 7,611,034,624 || trainable%: 0.0276%

# 4. 数据集
dataset = load_dataset("json", data_files="my_data.jsonl", split="train")

# 5. Trainer
trainer = SFTTrainer(
    model=model,
    tokenizer=tokenizer,
    train_dataset=dataset,
    args=TrainingArguments(
        output_dir="./lora-out",
        per_device_train_batch_size=4,
        gradient_accumulation_steps=4,
        num_train_epochs=3,
        learning_rate=2e-4,
        logging_steps=10,
        save_steps=100,
        fp16=True,
    ),
)
trainer.train()

# 6. 保存 LoRA 权重(仅几十 MB)
model.save_pretrained("./my-lora")
tokenizer.save_pretrained("./my-lora")

QLoRA 4bit 微调(8GB 显存跑 7B)

from transformers import BitsAndBytesConfig
import torch

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(
    "Qwen/Qwen2.5-7B-Instruct",
    quantization_config=bnb_config,
    device_map="auto",
)
# 后续与上面一样套 LoRA
model = get_peft_model(model, lora_config)

加载并使用已训练的 LoRA 权重

from peft import PeftModel, PeftConfig
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# 1. 加载基座
base = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen2.5-7B-Instruct",
    torch_dtype=torch.bfloat16,
    device_map="auto",
)

# 2. 挂上 LoRA
model = PeftModel.from_pretrained(base, "./my-lora")
model.eval()

# 3. 推理
tok = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
inputs = tok("你好,请介绍自己", return_tensors="pt").to("cuda")
out = model.generate(**inputs, max_new_tokens=200)
print(tok.decode(out[0], skip_special_tokens=True))

合并 LoRA 为完整模型

# 合并后推理无需再加载基座
model = model.merge_and_unload()
model.save_pretrained("./merged-model")
tok.save_pretrained("./merged-model")

# 之后可直接用 vLLM / TGI / Ollama 部署

其他方法速览

# Prefix Tuning
from peft import PrefixTuningConfig
config = PrefixTuningConfig(num_virtual_tokens=20, task_type="CAUSAL_LM")

# IA3
from peft import IA3Config
config = IA3Config(task_type="CAUSAL_LM")

# AdaLoRA(自适应分配秩)
from peft import AdaLoraConfig
config = AdaLoraConfig(init_r=12, target_r=4, task_type="CAUSAL_LM")

# 统一用 get_peft_model(model, config) 包装即可

六、常见问题(FAQ)

Q1:trainable% 是 0%?
A:target_modules 名字写错了。用 model.print_trainable_parameters() 检查,并打印 model 看真实层名(Qwen 是 q_proj/k_proj/v_proj/o_proj,Llama 也是同名)。

Q2:保存的 LoRA 只有几十 MB,正常吗?
A:完全正常。LoRA 只保存低秩矩阵,7B 模型 r=8 时约 20~50MB。

Q3:如何在推理时切换多个 LoRA?
A:model.load_adapter("path/to/adapter2", adapter_name="v2"),然后 model.set_adapter("v2") 切换。

Q4:bitsandbytes 在 Windows 报错?
A:Windows 上 bitsandbytes 支持不佳,建议 WSL2 或 Linux。新版已部分支持 Windows。

Q5:和 LLaMA-Factory 是什么关系?
A:LLaMA-Factory 是上层封装,底层微调逻辑就是调用 PEFT。你可以理解为 PEFT 是"引擎",LLaMA-Factory 是"整车"。

七、跳转链接

评论交流

文章目录