Doramagic 项目包 · 项目说明书
peft 项目
生成时间:2026-05-16 06:44:08 UTC
PEFT概述与快速入门
PEFT(Parameter-Efficient Fine-Tuning,参数高效微调)是一个用于将大型预训练模型高效适配到各种下游应用的Python库。该库由Hugging Face团队维护,通过仅微调少量(额外)模型参数而非全部模型参数,显著降低计算和存储成本。资料来源:[README.md:1-10]()
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
什么是PEFT
PEFT(Parameter-Efficient Fine-Tuning,参数高效微调)是一个用于将大型预训练模型高效适配到各种下游应用的Python库。该库由Hugging Face团队维护,通过仅微调少量(额外)模型参数而非全部模型参数,显著降低计算和存储成本。资料来源:README.md:1-10
PEFT的核心设计目标是:
| 目标 | 说明 |
|---|---|
| 参数效率 | 只需训练少量参数即可实现与全量微调相当的性能 |
| 计算效率 | 大幅降低GPU显存占用和训练时间 |
| 模块化设计 | 支持多种PEFT方法,便于扩展 |
| 框架集成 | 无缝对接Transformers、Diffusers和Accelerate |
PEFT架构概览
PEFT采用模块化架构,主要包含以下几个核心组件:
graph TD
A[PeftModel 基类] --> B[任务特定模型]
A --> C[Tuner层]
A --> D[配置管理]
B --> B1[PeftModelForCausalLM]
B --> B2[PeftModelForSeq2SeqLM]
B --> B3[PeftModelForSequenceClassification]
B --> B4[PeftModelForTokenClassification]
B --> B5[PeftModelForQuestionAnswering]
B --> B6[PeftModelForFeatureExtraction]
C --> C1[LoraModel]
C --> C2[ShiraModel]
C --> C3[GraloraModel]
C --> C4[XloraModel]
C --> C5[MissModel]
C --> C6[OFTModel]
D --> D1[PeftConfig]
D --> D2[get_peft_config]
D --> D3[from_pretrained]资料来源:src/peft/peft_model.py:1-50
支持的PEFT方法
PEFT库支持多种参数高效微调方法,每种方法适用于不同的场景和模型架构。
| 方法 | 简称 | 描述 | 适用场景 |
|---|---|---|---|
| LoRA | Low-Rank Adaptation | 通过低秩矩阵分解近似权重更新 | 通用场景,支持大多数模型 |
| QLoRA | Quantized LoRA | 结合量化技术的LoRA变体 | 大模型int4/int8量化训练 |
| Prefix Tuning | 前缀微调 | 在输入前添加可学习前缀 | 生成任务 |
| Prompt Tuning | 提示微调 | 仅学习软提示向量 | 极端参数高效场景 |
| P-Tuning | P-tuning | 使用LSTM/MLP编码提示 | NLU任务 |
| IA³ | Infused Adapter by Inhibiting Amplify | 注入式适配器 | 任务迁移 |
| AdaLoRA | Adaptive LoRA | 自适应秩分配 | 资源受限场景 |
| LoHa | LoRA with Hadamard Product | 使用Hadamard积 | 低参数场景 |
| LoKR | LoRA with Kronecker Product | 使用Kronecker积 | 高效参数利用 |
| OFT | Orthogonal Finetuning | 正交微调 | 扩散模型 |
| SHiRA | 层级正则化适配器 | 分层正则化策略 | 多任务场景 |
| GraLoRA | Gradient-aware LoRA | 梯度感知LoRA | 复杂任务 |
| xLoRA | 专家混合LoRA | 多专家LoRA组合 | 大模型高效适配 |
| MiSS | 模型分片共享 | 分片权重共享结构 | 资源受限训练 |
资料来源:src/peft/tuners/lora/model.py:1-30、src/peft/tuners/shira/model.py:1-20、src/peft/tuners/gralora/model.py:1-20
安装指南
基础安装
pip install peft
完整安装(包含所有依赖)
pip install peft[dev,models,diffusers,qualcomm]
从源码安装
git clone https://github.com/huggingface/peft.git
cd peft
pip install -e .
GPU特定版本
对于需要GPU支持的环境:
pip install peft --extra-index-url https://download.pytorch.org/whl/cu118
快速入门
基本使用流程
使用PEFT进行模型微调的标准流程如下:
graph LR
A[加载基础模型] --> B[创建PeftConfig]
B --> C[初始化PeftModel]
C --> D[训练PeftModel]
D --> E[保存Adapter]
E --> F[加载Inference]LoRA快速示例
以下示例展示如何使用LoRA方法对因果语言模型进行微调:
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, get_peft_model, TaskType
# 1. 加载基础模型
base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
# 2. 配置LoRA参数
lora_config = LoraConfig(
task_type=TaskType.CAUSAL_LM, # 任务类型
r=16, # LoRA秩
lora_alpha=32, # LoRA alpha参数
lora_dropout=0.05, # Dropout率
target_modules=["q_proj", "v_proj"], # 目标模块
bias="none",
)
# 3. 创建PeftModel
peft_model = get_peft_model(base_model, lora_config)
# 4. 查看可训练参数
peft_model.print_trainable_parameters()
# 输出: trainable params: 8388608 || all params: 125018880 || trainable%: 6.710
# 5. 训练模型
# ... 训练代码 ...
# 6. 保存Adapter
peft_model.save_pretrained("lora_adapter")
# 7. 推理时加载
from peft import PeftModel
model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
peft_model = PeftModel.from_pretrained(model, "lora_adapter")
不同任务的模型适配
PEFT为不同任务类型提供了专门的模型类:
| 任务类型 | 模型类 | 典型应用 |
|---|---|---|
| 因果语言模型 | PeftModelForCausalLM | 文本生成 |
| Seq2Seq | PeftModelForSeq2SeqLM | 翻译、摘要 |
| 序列分类 | PeftModelForSequenceClassification | 情感分析、文本分类 |
| Token分类 | PeftModelForTokenClassification | NER、词性标注 |
| 问答 | PeftModelForQuestionAnswering | 问答系统 |
| 特征提取 | PeftModelForFeatureExtraction | 嵌入向量生成 |
资料来源:src/peft/peft_model.py:50-150
PeftModel.from_pretrained方法
从预训练加载PEFT模型的核心参数:
PeftModel.from_pretrained(
model, # 基础模型 (torch.nn.Module)
model_id, # 模型ID或本地路径 (str)
adapter_name="default", # Adapter名称 (str)
is_trainable=False, # 是否可训练 (bool)
config=None, # 配置对象 (PeftConfig, optional)
autocast_adapter_dtype=True # 是否自动转换dtype (bool)
)
资料来源:src/peft/peft_model.py:150-200
QLoRA配置示例
对于大模型,推荐使用QLoRA进行高效训练:
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
from peft import prepare_model_for_kbit_training, LoraConfig, get_peft_model
# 量化配置
quantization_config = BitsAndBytesConfig(
load_in_8bit=True,
llm_int8_threshold=6.0,
llm_int8_has_fp16_weight=False
)
# 加载量化模型
model = AutoModelForCausalLM.from_pretrained(
"mistralai/Mistral-7B-Instruct-v0.1",
quantization_config=quantization_config,
device_map="auto"
)
# 准备kbit训练
model = prepare_model_for_kbit_training(model)
# 配置LoRA
lora_config = LoraConfig(
r=64,
lora_alpha=16,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type=TaskType.CAUSAL_LM
)
# 创建PeftModel
peft_model = get_peft_model(model, lora_config)
配置详解
LoraConfig主要参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
r | int | 8 | LoRA秩,决定低秩矩阵的维度 |
lora_alpha | int | 16 | 缩放因子,通常设为2倍r |
lora_dropout | float | 0.0 | LoRA层的Dropout率 |
target_modules | List[str] | None | 要应用LoRA的模块名 |
bias | str | "none" | 偏置更新策略: none/all/lora_only |
fan_in_fan_out | bool | False | 是否转置权重矩阵 |
modules_to_save | List[str] | None | 需要保存的额外模块 |
init_lora_weights | bool | True | 是否初始化LoRA权重 |
资料来源:src/peft/tuners/lora/model.py:30-80
任务类型枚举
class TaskType:
CAUSAL_LM = "CAUSAL_LM" # 因果语言模型
SEQ_CLS = "SEQ_CLS" # 序列分类
TOKEN_CLS = "TOKEN_CLS" # Token分类
QUESTION_ANS = "QUESTION_ANS" # 问答
FEATURE_EXTRACTION = "FEATURE_EXTRACTION" # 特征提取
SEQ_2_SEQ_LM = "SEQ_2_SEQ_LM" # 序列到序列
高级功能
模型合并与卸载
PEFT支持将adapter与基础模型合并,或完全卸载adapter:
# 合并并卸载(生成独立模型)
merged_model = peft_model.merge_and_unload()
# 仅卸载adapter(返回原始基础模型)
base_model = peft_model.unload()
资料来源:src/peft/tuners/tuners_utils.py:50-80
Adapter热切换
使用hotswap功能在不重新加载模型的情况下切换adapter:
from peft import hotswap_adapter
# 热切换adapter
hotswap_adapter(model, "path-to-new-adapter", adapter_name="default")
多Adapter管理
PEFT支持同时加载和使用多个adapter:
# 加载多个adapter
model.add_adapter("adapter_1", config_1)
model.add_adapter("adapter_2", config_2)
# 设置活动adapter
model.set_adapter("adapter_1")
# 使用特定adapter推理
model.eval()
辅助函数
PEFT提供了多个辅助函数用于签名更新和模型检查:
from peft.helpers import update_signature, check_if_peft_model
# 更新forward/generate签名
update_signature(peft_model, method="forward")
update_signature(peft_model, method="generate")
update_signature(peft_model, method="all")
# 检查是否为PEFT模型
is_peft = check_if_peft_model("path-to-model")
资料来源:src/peft/helpers.py:1-100
模型适配器注入机制
PEFT通过inject_adapter方法将adapter注入到基础模型:
def inject_adapter(
model, # 目标模型
adapter_name, # Adapter名称
autocast_adapter_dtype=True, # 自动转换dtype
low_cpu_mem_usage=False, # 低内存使用
state_dict=None # 可选的状态字典
)
该过程会遍历模型模块,将目标层替换为对应的tuner层:
graph TD
A[inject_adapter调用] --> B[遍历模型模块]
B --> C{检查模块类型}
C -->|Linear层| D[创建TunerLayer]
C -->|其他层| E[跳过]
D --> F[替换原模块]
F --> G[注册adapter]资料来源:src/peft/tuners/tuners_utils.py:80-120
与主流框架的集成
Transformers集成
PEFT与Hugging Face Transformers库深度集成,支持直接使用AutoModel系列加载预训练模型并应用PEFT:
from transformers import AutoModelForCausalLM
from peft import get_peft_model, LoraConfig
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b")
peft_model = get_peft_model(model, lora_config)
Diffusers集成
对于扩散模型,PEFT提供了专门的适配器:
from diffusers import StableDiffusionPipeline
from peft import OFTModel, OFTConfig
config = OFTConfig(
r=8,
target_modules=["k_proj", "q_proj", "v_proj"]
)
model.unet = OFTModel(model.unet, config, "default")
资料来源:src/peft/tuners/miss/model.py:1-30、src/peft/tuners/oft/model.py:1-30
Accelerate集成
对于分布式训练和超大规模模型,PEFT支持与Accelerate配合使用:
from accelerate import Accelerator
from peft import get_peft_model
accelerator = Accelerator()
model = get_peft_model(model, config)
model = accelerator.prepare_model(model)
性能基准
PEFT方法在保持参数效率的同时,能够达到与全量微调相当甚至更好的性能:
| 方法 | 可训练参数量 | 性能对比 |
|---|---|---|
| 全量微调 | 100% | 基准 |
| LoRA (r=8) | ~0.1-1% | 相当 |
| QLoRA | ~0.1-1% | 略低于全量 |
| Prefix Tuning | ~0.1% | 因任务而异 |
| Prompt Tuning | ~0.01% | 需更多数据 |
下一步
- 深入阅读PEFT支持的PEFT方法文档
- 查看示例代码库
- 了解自定义Tuner开发指南
- 尝试使用多模态模型微调
资料来源:[src/peft/peft_model.py:1-50]()
核心模块与架构
PEFT(Parameter-Efficient Fine-Tuning)库的核心架构围绕适配器模式设计,通过在不修改原始预训练模型参数的情况下添加少量可训练参数来实现高效的模型微调。该架构采用模块化设计,核心组件包括PeftModel基类、各类任务专用模型类、通用适配器注入机制以及丰富的工具函数。资料来源:[src/peft/peftmodel.py:1-200]()
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
PEFT(Parameter-Efficient Fine-Tuning)库的核心架构围绕适配器模式设计,通过在不修改原始预训练模型参数的情况下添加少量可训练参数来实现高效的模型微调。该架构采用模块化设计,核心组件包括PeftModel基类、各类任务专用模型类、通用适配器注入机制以及丰富的工具函数。资料来源:src/peft/peft_model.py:1-200
核心模块架构图
graph TD
A[PeftModel 基类] --> B[PeftModelForSequenceClassification]
A --> C[PeftModelForQuestionAnswering]
A --> D[PeftModelForTokenClassification]
A --> E[PeftModelForSeq2SeqLM]
A --> F[PeftModelForFeatureExtraction]
G[BaseTuner] --> A
H[TunersUtils] --> G
I[各Tuner模型类] --> H
J[ShiraModel] --> I
K[GraloraModel] --> I
L[XloraModel] --> I
M[MissModel] --> I
N[OFTModel] --> I
O[AdamssModel] --> IPeftModel 基类
类职责与定位
PeftModel是整个库的核心基类,负责管理适配器的加载、切换、合并与卸载。它封装了底层的基础模型,并提供了统一的接口供各任务类型模型继承使用。资料来源:src/peft/peft_model.py:100-150
主要方法
| 方法名 | 功能描述 | 返回类型 |
|---|---|---|
from_pretrained() | 从预训练路径加载PEFT模型和适配器 | PeftModel |
merge_and_unload() | 合并适配器权重到基础模型并卸载适配器 | torch.nn.Module |
unload() | 返回基础模型,移除所有PEFT模块 | torch.nn.Module |
inject_adapter() | 注入适配器层并替换目标模块 | None |
from_pretrained 方法参数
@classmethod
def from_pretrained(
cls,
model: torch.nn.Module,
model_id: str or os.PathLike,
adapter_name: str = "default",
is_trainable: bool = False,
config: PeftConfig = None,
autocast_adapter_dtype: bool = True,
**kwargs
) -> PeftModel
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
model | torch.nn.Module | 必需 | 被适配的基础模型 |
model_id | str 或 os.PathLike | 必需 | PEFT配置的模型ID或本地路径 |
adapter_name | str | "default" | 适配器名称,支持加载多个适配器 |
is_trainable | bool | False | 是否训练模式,False时适配器被冻结 |
config | PeftConfig | None | 预定义的配置对象,与model_id互斥 |
autocast_adapter_dtype | bool | True | 是否自动转换适配器数据类型 |
资料来源:src/peft/peft_model.py:150-200
任务专用模型类
PEFT针对不同任务类型提供了专用的模型封装类,每个类针对特定任务进行了输入输出接口的适配。
模型类列表与继承关系
graph LR
A[PeftModel] --> B[PeftModelForSequenceClassification]
A --> C[PeftModelForQuestionAnswering]
A --> D[PeftModelForTokenClassification]
A --> E[PeftModelForSeq2SeqLM]
A --> F[PeftModelForFeatureExtraction]PeftModelForSequenceClassification
用于序列分类任务(如情感分析),自动配置分类层。构造函数中定义了默认的分类器模块名称列表:
classifier_module_names = ["classifier", "score"]
资料来源:src/peft/peft_model.py:50-80
PeftModelForQuestionAnswering
用于问答任务,配置问答输出层名称:
qa_module_names = ["qa_outputs"]
资料来源:src/peft/peft_model.py:30-50
PeftModelForTokenClassification
用于令牌级分类任务(如命名实体识别),使用与序列分类相同的分类器模块名称:
classifier_module_names = ["classifier", "score"]
资料来源:src/peft/peft_model.py:180-210
PeftModelForSeq2SeqLM
用于序列到序列生成任务(如翻译、摘要),继承基类并额外保存生成相关方法引用:
self.base_model_prepare_inputs_for_generation = self.base_model.prepare_inputs_for_generation
self.base_model_prepare_encoder_decoder_kwargs_for_generation = (
self.base_model._prepare_encoder_decoder_kwargs_for_generation
)
资料来源:src/peft/peft_model.py:230-260
PeftModelForFeatureExtraction
用于特征提取任务,支持标准forward接口并提供灵活的输入处理能力。
资料来源:src/peft/peft_model.py:80-110
BaseTuner 与适配器注入机制
inject_adapter 方法
inject_adapter 是将适配器层注入到目标模型的核心方法,负责创建适配器层并替换原模型中的目标模块。
def inject_adapter(
self,
model: nn.Module,
adapter_name: str,
autocast_adapter_dtype: bool = True,
low_cpu_mem_usage: bool = False,
state_dict: Optional[dict[str, torch.Tensor]] = None,
) -> None:
| 参数名 | 类型 | 说明 |
|---|---|---|
model | nn.Module | 需要注入适配器的模型 |
adapter_name | str | 适配器名称 |
autocast_adapter_dtype | bool | 是否自动转换适配器数据类型 |
low_cpu_mem_usage | bool | 是否在元设备上创建空适配器权重以加速加载 |
state_dict | Optional[dict] | 可选的预定义状态字典 |
资料来源:src/peft/tuners/tuners_utils.py:100-150
_check_target_module_compatibility 方法
该方法防止将LoRA等适配器应用于不兼容的模块(如Mamba架构):
def _check_target_module_compatiblity(
self, peft_config: PeftConfig, model: nn.Module, target_name: str
):
_check_lora_target_modules_mamba(peft_config, model, target_name)
资料来源:src/peft/tuners/tuners_utils.py:90-95
各类型Tuner模型
Tuner模型通用架构
每种Tuner模型(如SHiRA、GrALoRA、xLoRA、MiSS、OFT、Adamss)都遵循统一的架构模式:
graph TD
A[BaseTuner] --> B[各TunerModel类]
B --> C{_create_and_replace}
C -->|Linear层| D[update_layer]
C -->|非Linear层| E[_create_new_module]
D --> F[替换原模块]
E --> FSHiRA 模型
SHiRA(Structured HieraRchy Adapter)模型具有以下特征:
| 属性 | 值 |
|---|---|
prefix | "shira_" |
tuner_layer_cls | ShiraLayer |
mask_type | 支持 "random" 类型 |
创建新模块时,支持通过 random_seed 参数控制随机性:
kwargs["random_seed"] = shira_config.random_seed
资料来源:src/peft/tuners/shira/model.py:30-80
Gralora 模型
GradoRA模型专注于梯度相关的高效微调:
| 属性 | 值 |
|---|---|
prefix | "gralora_" |
tuner_layer_cls | GraloraLayer |
对于Linear层,直接调用 update_layer 方法进行参数更新:
if isinstance(target, Linear):
target.update_layer(
adapter_name,
current_key,
r=r,
config=gralora_config,
)
资料来源:src/peft/tuners/gralora/model.py:40-70
xLoRA 模型
xLoRA是一种支持混合适配器配置的模型类型:
def __init__(
self,
model: nn.Module,
config: Union[dict[str, XLoraConfig], XLoraConfig],
adapter_name: str,
torch_device: Optional[str] = None,
ephemeral_gpu_offload: bool = False,
autocast_adapter_dtype: bool = True,
**kwargs,
) -> None:
| 参数名 | 类型 | 说明 |
|---|---|---|
config | XLoraConfig 或 dict | 支持单个或多个适配器配置 |
torch_device | str | 加载适配器的目标设备 |
ephemeral_gpu_offload | bool | 是否启用临时GPU卸载 |
资料来源:src/peft/tuners/xlora/model.py:40-80
MiSS 模型
MiSS(Multi-Adapter Integration for Stable Diffusion)专为扩散模型设计:
| 属性 | 值 |
|---|---|
prefix | "miss_" |
tuner_layer_cls | MissLayer |
target_module_mapping | TRANSFORMERS_MODELS_TO_MISS_TARGET_MODULES_MAPPING |
创建新模块时的处理逻辑区分普通层和MissLayer:
if not isinstance(target, MissLayer):
new_module = self._create_new_module(miss_config, adapter_name, target, **kwargs)
# 新适配器默认不训练
new_module.requires_grad_(False)
self._replace_module(parent, target_name, new_module, target)
else:
target.update_layer(adapter_name, config=miss_config, **kwargs)
资料来源:src/peft/tuners/miss/model.py:40-90
OFT 模型
OFT(Orthogonal Fine-Tuning)模型保持参数的正交性约束:
| 属性 | 值 |
|---|---|
prefix | "oft_" |
tuner_layer_cls | OFTLayer |
loaded_in_8bit | 支持8位量化加载 |
kwargs = {
"r": oft_config.r,
"fan_in_fan_out": oft_config.fan_in_fan_out,
"loaded_in_8bit": getattr(self.model, "is_loaded_in_8bit", False)
}
资料来源:src/peft/tuners/oft/model.py:40-80
Adamss 模型
Adamss模型采用多子空间注意力机制:
| 属性 | 值 |
|---|---|
prefix | "adamss_" |
tuner_layer_cls | (AdamssLayer,) |
_asa_total_subspaces | ASA子空间跟踪字典 |
初始化时在BaseTuner注入适配器之前创建ASA跟踪属性:
def __init__(
self, model, config, adapter_name, low_cpu_mem_usage: bool = False, state_dict: Optional[dict] = None
) -> None:
self._asa_total_subspaces = {}
super().__init__(model, config, adapter_name, low_cpu_mem_usage, state_dict)
资料来源:src/peft/tuners/adamss/model.py:50-70
工具函数模块
helpers.py 核心功能
#### check_if_peft_model
检测指定路径的模型是否为PEFT模型:
def check_if_peft_model(model_name_or_path: str) -> bool:
is_peft_model = True
try:
PeftConfig.from_pretrained(model_name_or_path)
except Exception:
is_peft_model = False
return is_peft_model
资料来源:src/peft/helpers.py:40-60
#### update_signature
更新PeftModel的接口签名以包含父类方法的参数:
def update_signature(model: PeftModel, method: str = "all") -> None:
if method == "forward":
update_forward_signature(model)
elif method == "generate":
update_generate_signature(model)
elif method == "all":
update_forward_signature(model)
update_generate_signature(model)
| method参数值 | 效果 |
|---|---|
"forward" | 仅更新forward方法签名 |
"generate" | 仅更新generate方法签名 |
"all" | 同时更新两者 |
#### rescale_adapter_scale
上下文管理器,用于临时调整适配器缩放因子:
@contextmanager
def rescale_adapter_scale(model, multiplier):
# 临时修改缩放值
yield
# 恢复原始值
资料来源:src/peft/helpers.py:60-90
#### update_forward_signature
当forward签名仅包含 *args 和 **kwargs 时,用基类的完整签名替换:
current_signature = inspect.signature(model.forward)
if (
len(current_signature.parameters) == 2
and "args" in current_signature.parameters
and "kwargs" in current_signature.parameters
):
forward = deepcopy(model.forward.__func__)
update_wrapper(forward, type(model.get_base_model()).forward, ...)
资料来源:src/peft/helpers.py:90-130
#### update_generate_signature
类似地更新generate方法签名,支持处理单参数(仅kwargs)情况:
if (
len(current_signature.parameters) == 2
and "args" in current_signature.parameters
and "kwargs" in current_signature.parameters
) or (len(current_signature.parameters) == 1 and "kwargs" in current_signature.parameters):
generate = deepcopy(model.generate.__func__)
update_wrapper(generate, type(model.get_base_model()).generate, ...)
资料来源:src/peft/helpers.py:130-170
MixedModel 混合适配器模型
MixedModel支持同时使用多个不同类型的PEFT适配器。其 from_pretrained 方法架构如下:
graph LR
A[from_pretrained] --> B[load config]
B --> C[PEFT_TYPE_TO_MIXED_MODEL_MAPPING]
C --> D[创建MixedModel实例]@classmethod
def from_pretrained(
cls,
model: nn.Module,
model_id: str or os.PathLike,
adapter_name: str = "default",
is_trainable: bool = False,
config: PeftConfig = None,
low_cpu_mem_usage: bool = False,
**kwargs,
) -> PeftModel:
资料来源:src/peft/mixed_model.py:100-150
适配器生命周期管理
graph TD
A[from_pretrained] --> B[inject_adapter]
B --> C[创建新模块或更新现有层]
C --> D[active_adapters管理]
D --> E{merge_and_unload?}
E -->|是| F[合并权重并卸载]
E -->|否| G[继续训练/推理]
F --> H[返回基础模型]
G --> I[unload: 返回纯基础模型]merge_and_unload 与 unload 区别
| 方法 | 合并权重 | 卸载适配器 | 返回内容 |
|---|---|---|---|
merge_and_unload() | ✅ | ✅ | 合并后的模型 |
unload() | ❌ | ✅ | 原始基础模型 |
def merge_and_unload(self, progressbar: bool = False, safe_merge: bool = False, adapter_names: List = None):
return self._unload_and_optionally_merge(
progressbar=progressbar, safe_merge=safe_merge, adapter_names=adapter_names
)
def unload(self) -> torch.nn.Module:
return self._unload_and_optionally_merge(merge=False)
资料来源:src/peft/tuners/tuners_utils.py:60-90
总结
PEFT库的核心架构采用分层设计模式:
- PeftModel基类 提供统一的适配器管理接口
- 任务专用模型类 针对不同NLP任务进行接口适配
- BaseTuner与TunersUtils 实现适配器注入的核心逻辑
- 各类TunerModel 实现不同的高效微调算法(LoRA、SHiRA、GrALoRA、xLoRA、MiSS、OFT、Adamss等)
- helpers工具模块 提供运行时签名更新、模型检测等辅助功能
这种架构设计使得PEFT能够以统一的方式支持多种参数高效微调算法,同时保持良好的可扩展性以接入新的微调方法。
资料来源:[src/peft/peft_model.py:150-200]()
配置系统
PEFT(Parameter-Efficient Fine-Tuning)库的配置系统是整个框架的核心基础设施,负责定义、管理和序列化各种参数高效微调方法的配置参数。该系统通过统一的配置类层次结构,为不同的微调技术(如 LoRA、Prefix Tuning、AdaLoRA 等)提供了一致的配置接口,同时保持了各方法特有的参数定制能力。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
系统架构概述
PEFT 配置系统采用分层设计模式,核心层定义了所有配置类的基类和枚举类型,方法层则实现了各种特定微调技术的配置类。这种设计确保了配置的通用性与扩展性的平衡。
graph TB
subgraph 核心层
PeftConfig[PeftConfig 基类]
PeftType[PeftType 枚举]
TaskType[TaskType 枚举]
end
subgraph 配置映射层
PEFT_TYPE_TO_CONFIG_MAPPING[PEFT_TYPE_TO_CONFIG_MAPPING]
PEFT_TYPE_TO_MIXED_MODEL_MAPPING[PEFT_TYPE_TO_MIXED_MODEL_MAPPING]
end
subgraph 方法层
LoraConfig[LoRA 配置]
PrefixTuningConfig[Prefix Tuning 配置]
PromptTuningConfig[Prompt Tuning 配置]
AdaLoraConfig[AdaLoRA 配置]
IA3Config[IA³ 配置]
LoHaConfig[LoHa 配置]
LokrConfig[LoKr 配置]
VeraConfig[VeRA 配置]
HieraConfig[HiRA 配置]
end
subgraph 应用层
PeftModel[PeftModel]
MixedModel[MixedModel]
end
PeftConfig --> PEFT_TYPE_TO_CONFIG_MAPPING
PeftConfig --> 配置映射层
配置映射层 --> 方法层
方法层 --> 应用层核心配置类
PeftConfig 基类
PeftConfig 是所有 PEFT 配置类的基类,封装了微调配置的基本属性和序列化逻辑。该类继承自 transformers.PretrainedConfig,因此具备标准的模型配置保存和加载功能。
#### 核心属性
| 属性名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
peft_type | PeftType | PEFT 方法类型 | 必需 |
task_type | TaskType | 任务类型 | 可选 |
inference_mode | bool | 是否为推理模式 | False |
r | int | 秩(用于 LoRA 等方法) | 8 |
target_modules | Optional[Union[List[str], str]] | 目标模块名称 | None |
modules_to_save | Optional[List[str]] | 需保存参数的额外模块 | None |
fan_in_fan_out | bool | 是否转置权重 | False |
资料来源:src/peft/config.py
#### 关键方法
PeftConfig 提供了以下核心方法用于配置管理:
save_pretrained(save_directory)- 将配置保存到指定目录from_pretrained(pretrained_model_name_or_path, **kwargs)- 从预训练路径加载配置to_dict()- 将配置转换为字典格式
PeftType 枚举
PeftType 枚举定义了 PEFT 库支持的所有微调方法类型:
| 枚举值 | 说明 | 对应配置类 |
|---|---|---|
LORA | Low-Rank Adaptation | LoraConfig |
PREFIX_TUNING | Prefix Tuning | PrefixTuningConfig |
PROMPT_TUNING | Prompt Tuning | PromptTuningConfig |
ADALORA | Adaptive LoRA | AdaLoraConfig |
ADAPTION_PROMPT | Adaption Prompt | AdaptionPromptConfig |
IA3 | (IA)³ | IA3Config |
LOHA | LoHA | LoHaConfig |
LOKR | LoKr | LokrConfig |
VERA | VeRA | VeraConfig |
HIRA | HiRA | HiraConfig |
OFT | OFT | OftConfig |
POLY | Poly | PolyConfig |
LINEAR | Linear | LinearConfig |
MANUAL | Manual | ManualConfig |
资料来源:src/peft/utils/peft_types.py
TaskType 枚举
TaskType 枚举定义了支持的模型任务类型,用于配置与具体任务的适配:
| 枚举值 | 说明 | 适用模型类 |
|---|---|---|
SEQ_CLS | 序列分类 | PeftModelForSequenceClassification |
SEQ_2_SEQ_LM | 序列到序列语言模型 | PeftModelForSeq2SeqLM |
CAUSAL_LM | 因果语言模型 | PeftModelForCausalLM |
TOKEN_CLS | Token 分类 | PeftModelForTokenClassification |
QUESTION_ANS | 问答任务 | PeftModelForQuestionAnswering |
FEATURE_EXTRACTION | 特征提取 | PeftModelForFeatureExtraction |
配置映射机制
PEFT 使用两个关键的映射字典来管理配置类型与实际配置类之间的对应关系。
PEFT_TYPE_TO_CONFIG_MAPPING
此映射字典建立了 PeftType 枚举值与具体配置类之间的关联:
PEFT_TYPE_TO_CONFIG_MAPPING: dict[PeftType, type[PeftConfig]] = {
PeftType.LORA: LoraConfig,
PeftType.PROMPT_TUNING: PromptTuningConfig,
PeftType.PREFIX_TUNING: PrefixTuningConfig,
# ... 其他映射
}
PEFT_TYPE_TO_MIXED_MODEL_MAPPING
此映射用于混合模型场景,关联 PeftType 与混合模型类:
PEFT_TYPE_TO_MIXED_MODEL_MAPPING: dict[PeftType, type[PeftMixedModel]] = {
PeftType.LORA: PeftMixedModel,
# ... 其他映射
}
配置加载流程
配置加载遵循统一的流程,支持从 Hugging Face Hub 或本地目录加载配置。
sequenceDiagram
participant 用户
participant PeftConfig
participant HF Hub
participant 本地文件系统
用户->>PeftConfig: from_pretrained(model_id)
PeftConfig->>PeftConfig: 确定配置类型
alt 模型在 Hub 上
PeftConfig->>HF Hub: 下载配置文件
HF Hub-->>PeftConfig: 返回配置数据
else 本地模型
PeftConfig->>本地文件系统: 读取配置文件
本地文件系统-->>PeftConfig: 返回配置数据
end
PeftConfig->>PeftConfig: 解析并实例化配置对象
PeftConfig-->>用户: 返回 PeftConfig 实例加载参数说明
| 参数名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
pretrained_model_name_or_path | str | 模型标识或路径 | 必需 |
subfolder | str | 子文件夹路径 | "" |
revision | str | Git 修订版本 | "main" |
cache_dir | Optional[str] | 缓存目录 | None |
force_download | bool | 强制重新下载 | False |
resume_download | bool | 恢复下载 | False |
proxies | Optional[dict] | 代理设置 | None |
token | Optional[Union[str, bool]] | HuggingFace Hub Token | None |
方法特定配置
LoRA 配置
LoraConfig 是最常用的配置类,继承自 PeftConfig 并添加了 LoRA 方法特有的参数:
class LoraConfig(PeftConfig):
def __init__(
self,
r: int = 8,
lora_alpha: int = 8,
lora_dropout: float = 0.0,
target_modules: Optional[Union[List[str], str]] = None,
bias: str = "none",
inference_mode: bool = False,
# ... 其他参数
):
| 参数名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
r | int | LoRA 秩(低秩矩阵维度) | 8 |
lora_alpha | int | LoRA 缩放因子 | 8 |
lora_dropout | float | LoRA 层 Dropout 率 | 0.0 |
bias | str | 偏置训练策略 | "none" |
task_type | TaskType | 任务类型 | 可选 |
modules_to_save | Optional[List[str]] | 需训练的其他模块 | None |
Prefix Tuning 配置
PrefixTuningConfig 用于 Prefix Tuning 方法:
class PrefixTuningConfig(PeftConfig):
def __init__(
self,
num_virtual_tokens: int = 20,
token_dim: int = None,
num_transformer_submodules: int = 1,
num_attention_heads: int = 1,
num_layers: int = 1,
prefix_projection: bool = False,
# ... 其他参数
):
| 参数名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
num_virtual_tokens | int | 虚拟 token 数量 | 20 |
token_dim | int | token 维度 | 自动 |
num_transformer_submodules | int | Transformer 子模块数 | 1 |
num_attention_heads | int | 注意力头数 | 自动 |
prefix_projection | bool | 是否投影前缀 | False |
配置验证机制
目标模块兼容性检查
tuners_utils.py 中的 _check_target_module_compatiblity 方法负责验证目标模块的兼容性:
def _check_target_module_compatiblity(self, peft_config: PeftConfig, model: nn.Module, target_name: str):
"""
Prevent applying LoRA to incompatible modules in specific architectures (e.g., Mamba).
"""
_check_lora_target_modules_mamba(peft_config, model, target_name)
该方法防止在特定架构(如 Mamba)上应用不兼容的 LoRA 配置。
资料来源:src/peft/tuners/tuners_utils.py
模块名称验证
配置系统对以下模块名称进行特殊处理:
- 分类任务:
"classifier","score" - 问答任务:
"qa_outputs" - Token 分类:
"classifier","score"
配置的动态更新
PEFT 支持在运行时动态更新配置参数,通过 inject_adapter 方法实现:
def inject_adapter(
self,
model: nn.Module,
adapter_name: str,
autocast_adapter_dtype: bool = True,
low_cpu_mem_usage: bool = False,
state_dict: Optional[dict[str, torch.Tensor]] = None,
) -> None:
此方法创建适配器层并替换目标模块,允许在不重新初始化模型的情况下添加新的适配器配置。
热插拔配置
hotswap.py 模块支持配置的动态热切换:
def hotswap_adapter(
model: "PeftModel",
model_name_or_path: str,
adapter_name: str = "default",
torch_device: Optional[str] = None,
**kwargs,
) -> None:
该功能允许在推理过程中替换适配器配置,无需重新加载整个模型。
资料来源:src/peft/utils/hotswap.py
配置序列化
配置系统支持将配置保存为标准格式,便于分享和复用:
保存流程
- 调用
save_pretrained(save_directory)方法 - 创建目标目录(如不存在)
- 将配置转换为 JSON 格式
- 保存为
config.json文件 - 返回保存的文件路径
加载流程
- 调用
from_pretrained(pretrained_model_name_or_path) - 自动检测 PEFT 配置类型
- 实例化对应的配置类
- 返回配置对象
目标模块映射
每种微调方法都定义了默认的目标模块映射,确保在未知模型架构时也能正常工作:
| 方法 | 映射变量 | 典型目标模块 |
|---|---|---|
| LoRA | TRANSFORMERS_MODELS_TO_LORA_TARGET_MODULES_MAPPING | q_proj, v_proj, k_proj, o_proj |
| IA³ | TRANSFORMERS_MODELS_TO_IA3_TARGET_MODULES_MAPPING | 针对特定层的向量 |
| Prefix Tuning | TRANSFORMERS_MODELS_TO_PREFIX_TUNING_TARGET_MODULES_MAPPING | 全模型层级 |
适配器管理
配置系统与适配器管理系统紧密集成,支持多适配器配置:
适配器注册
class PeftModel:
def __init__(self, model, peft_config, adapter_name: str = "default", **kwargs):
# 默认适配器名为 "default"
适配器切换
通过 active_peft_config 属性访问当前激活的适配器配置:
peft_config = self.active_peft_config
if not peft_config.is_prompt_learning:
if peft_config.peft_type == PeftType.LORA:
# LoRA 特定处理
总结
PEFT 配置系统通过以下设计原则实现了灵活且可扩展的配置管理:
- 分层架构:基类提供通用接口,派生类实现特定方法配置
- 类型安全:通过枚举类型确保配置值的有效性
- 映射驱动:使用字典映射实现配置类型与实现类的解耦
- 序列化支持:与 Hugging Face 生态系统无缝集成
- 运行时动态性:支持适配器的热插拔和动态更新
这套配置系统使得用户能够以统一的方式使用不同的参数高效微调方法,同时为高级用户提供了充分的定制能力。
资料来源:[src/peft/config.py](https://github.com/huggingface/peft/blob/main/src/peft/config.py)
LoRA及其变体实现
LoRA(Low-Rank Adaptation)是一种高效的参数微调技术,通过在预训练模型的权重矩阵旁边添加低秩分解矩阵来实现参数高效微调。PEFT库实现了LoRA及其多种变体,包括DoRA、AdaLoRA和VeRA,每种变体在参数效率和适应性方面有不同的优化策略。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
LoRA(Low-Rank Adaptation)是一种高效的参数微调技术,通过在预训练模型的权重矩阵旁边添加低秩分解矩阵来实现参数高效微调。PEFT库实现了LoRA及其多种变体,包括DoRA、AdaLoRA和VeRA,每种变体在参数效率和适应性方面有不同的优化策略。
LoRA核心架构
核心技术原理
LoRA的核心思想是将预训练权重矩阵 $W_0 \in \mathbb{R}^{d \times k}$ 的更新表示为低秩分解形式:
$$W' = W_0 + \Delta W = W_0 + BA$$
其中 $B \in \mathbb{R}^{d \times r}$,$A \in \mathbb{R}^{r \times k}$,$r \ll \min(d, k)$。
模块结构
graph TD
A[预训练模型 Linear层] --> B[LoRA包装]
B --> C[LoraLayer]
C --> D[Lora_A: 降维矩阵]
C --> E[Lora_B: 升维矩阵]
C --> F[scaling缩放因子]
D --> G[前向传播: Wx + BAx]
LoraConfig配置详解
LoraConfig是LoRA微调的核心配置类,主要参数如下:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| r | int | 8 | 低秩矩阵的秩 |
| lora_alpha | int | 16 | 缩放因子,通常设为r的两倍 |
| lora_dropout | float | 0.0 | LoRA层的dropout率 |
| target_modules | Optional[List[str]] | None | 需要应用LoRA的模块名称 |
| bias | str | "none" | bias处理方式: none/lora_only/all |
| fan_in_fan_out | bool | False | 是否转置权重 |
| init_weights | bool | True | 是否初始化LoRA权重 |
LoraLayer实现
LoraLayer是LoRA的核心计算层,主要包含以下组件:
# 资料来源:src/peft/tuners/lora/layer.py
class LoraLayer:
prefix: str = "lora_"
# 核心低秩矩阵
lora_A: nn.Parameter # 降维矩阵
lora_B: nn.Parameter # 升维矩阵
scaling: float # 缩放因子
前向传播逻辑
graph LR
A[输入x] --> B[原始输出: Wx]
A --> C[LoRA输出: BAx * scaling]
B --> D[合并输出: Wx + BAx * scaling]
LoRAModel类结构
LoRAModel继承自PeftModel,负责将LoRA适配器应用到基础模型:
# 资料来源:src/peft/tuners/lora/model.py
class LoRAModel(PeftModel):
prefix: str = "lora_"
tuner_layer_cls = LoraLayer
target_module_mapping = TRANSFORMERS_MODELS_TO_LORA_TARGET_MODULES_MAPPING
_create_and_replace方法
该方法负责在基础模型中创建或替换LoRA层:
# 资料来源:src/peft/tuners/lora/model.py:77-95
def _create_and_replace(
self,
lora_config,
adapter_name,
target,
target_name,
parent,
current_key,
*,
parameter_name: Optional[str] = None,
) -> None:
if current_key is None:
raise ValueError("Current Key shouldn't be `None`")
DoRA实现
DoRA(Weight-Decomposed LoRA)将LoRA的更新分解为幅度和方向两个分量:
$$W' = m \cdot \frac{W_0 + \Delta W}{\|W_0 + \Delta W\|} = m \cdot \hat{W}$$
其中 $m$ 是可学习的幅度向量,$\hat{W}$ 是归一化的权重矩阵。
DoRA层结构
graph TD
A[原始权重 W₀] --> B[LoRA更新 ΔW]
B --> C[权重合并 W₀ + ΔW]
C --> D[幅度向量 m]
C --> E[方向归一化]
D --> F[乘积: m × direction]
E --> F
AdaLoRA实现
AdaLoRA(Adaptive LoRA)是一种自适应的LoRA变体,根据参数重要性动态分配秩:
核心特性
| 特性 | 描述 |
|---|---|
| 重要性评估 | 基于奇异值分解评估参数重要性 |
| 动态秩分配 | 重要参数获得更高秩 |
| 渐进式调整 | 训练过程中逐步调整秩分配 |
VeRA实现
VeRA(Vector-based Random Matrix LoRA)使用随机投影向量替代可训练矩阵以减少参数量:
参数效率对比
| 方法 | 可训练参数 | 存储需求 |
|---|---|---|
| LoRA | 2 × d × r | O(dr + kr) |
| VeRA | d + k + 2r | O(d + k + r) |
使用示例
标准LoRA配置
# 资料来源:src/peft/tuners/lora/model.py
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
config = LoraConfig(
r=8,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.1,
bias="none",
task_type="CAUSAL_LM"
)
model = AutoModelForCausalLM.from_pretrained("base-model")
peft_model = get_peft_model(model, config)
peft_model.print_trainable_parameters()
DoRA配置
from peft import DoRAConfig, get_peft_model
config = DoRAConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "v_proj"],
dora_dropout=0.1
)
目标模块映射
TRANSFORMERS_MODELS_TO_LORA_TARGET_MODULES_MAPPING定义了不同模型架构的默认目标模块:
# 常见目标模块映射
{
"bert": ["query", "value"],
"gpt2": ["c_attn", "c_proj"],
"llama": ["q_proj", "v_proj"],
"t5": ["q", "v"]
}
多适配器支持
PEFT支持同时加载多个LoRA适配器:
# 加载多个适配器
model.load_adapter("path/to/adapter_1", "adapter_1")
model.load_adapter("path/to/adapter_2", "adapter_2")
# 激活特定适配器
model.set_adapter("adapter_1")
# 合并所有适配器到基础模型
model.merge_and_unload()
状态切换与合并
graph TD
A[基础模型] --> B[添加LoRA层]
B --> C{是否合并?}
C -->|是| D[merge_and_unload]
C -->|否| E[保持LoRA权重独立]
D --> F[融合后模型]
E --> G[可切换适配器]
导出与部署
LoRA权重可以导出为独立文件:
# 保存LoRA权重
model.save_pretrained("output_path")
# 加载已保存的LoRA模型
from peft import PeftModel
peft_model = PeftModel.from_pretrained(base_model, "output_path")
与其他技术的兼容性
BitsAndBytes量化支持
# 资料来源:src/peft/tuners/lora/model.py
from peft import get_peft_model, prepare_model_for_kbit_training
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(
"model_name",
quantization_config=quantization_config
)
model = prepare_model_for_kbit_training(model)
peft_model = get_peft_model(model, lora_config)
梯度检查点
LoRA层支持与梯度检查点技术结合使用,适用于超大模型的微调场景。
总结
PEFT库中的LoRA及其变体实现提供了灵活的参数高效微调方案。标准LoRA通过低秩分解减少可训练参数,DoRA通过分解幅度和方向提升表达能力,AdaLoRA通过自适应秩分配优化参数效率,VeRA通过随机投影进一步降低存储开销。
来源:https://github.com/huggingface/peft / 项目说明书
其他PEFT方法
PEFT(Parameter-Efficient Fine-Tuning)库不仅支持主流的 LoRA 方法,还实现了多种参数高效微调技术。本页面详细介绍 IA³、OFT、Prompt Tuning、Prefix Tuning、P-Tuning 和 Multitask Prompt Tuning 等方法的设计原理、配置参数和使用方式。
继续阅读本节完整说明和来源证据。
其他PEFT方法
PEFT(Parameter-Efficient Fine-Tuning)库不仅支持主流的 LoRA 方法,还实现了多种参数高效微调技术。本页面详细介绍 IA³、OFT、Prompt Tuning、Prefix Tuning、P-Tuning 和 Multitask Prompt Tuning 等方法的设计原理、配置参数和使用方式。
来源:https://github.com/huggingface/peft / 项目说明书
高级调谐器与实验性方法
PEFT(Parameter-Efficient Fine-Tuning)库提供了多种高级调谐器(Advanced Tuners)和实验性方法,这些方法超越了传统的 LoRA 线性低秩分解范式,引入频域变换、Hadamard 积、Kronecker 积等更复杂的参数化策略。这些高级调谐器在保持参数效率的同时,提供了更丰富的表达能力,适用于对模型性能有更高要求的复杂微调任务。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
PEFT(Parameter-Efficient Fine-Tuning)库提供了多种高级调谐器(Advanced Tuners)和实验性方法,这些方法超越了传统的 LoRA 线性低秩分解范式,引入频域变换、Hadamard 积、Kronecker 积等更复杂的参数化策略。这些高级调谐器在保持参数效率的同时,提供了更丰富的表达能力,适用于对模型性能有更高要求的复杂微调任务。
高级调谐器的核心设计目标包括:
- 提高表达能力:通过非线性结构或频域表示增强适配器的建模能力
- 保持参数效率:仍通过冻结原模型参数,仅训练少量附加参数来实现
- 支持多样化架构:覆盖卷积层、自注意力层、全连接层等多种网络结构
高级调谐器架构总览
graph TD
A[PEFT 高级调谐器] --> B[频域变换类]
A --> C[低秩分解类]
A --> D[结构化参数类]
B --> B1[BOFT]
B --> B2[FourierFT]
B --> B3[WaveFT]
C --> C1[LoHA]
C --> C2[LoKR]
D --> D1[HRA]
D --> D2[Poly]
style A fill:#e1f5fe
style B fill:#fff3e0
style C fill:#e8f5e9
style D fill:#f3e5f5频域变换类调谐器
频域变换类调谐器通过将参数矩阵变换到频域进行操作,利用频域中的特殊性质(如正交性、稀疏性)来实现高效且富有表达力的参数适配。
BOFT(Block-wise Orthogonal Fourier Transform)
BOFT 是一种基于块状正交傅里叶变换的高级调谐器,它在频域中使用块状正交矩阵来实现参数适配。
#### 核心原理
BOFT 的核心思想是将权重更新表示为块状正交矩阵的线性组合:
ΔW = Σᵢ αᵢ · Bᵢ · F
其中 Bᵢ 表示块状正交矩阵,F 表示傅里叶变换矩阵,αᵢ 是可训练的标量系数。
#### 关键特性
| 特性 | 描述 |
|---|---|
| 正交约束 | 块状正交矩阵确保更新方向的稳定性 |
| 频域稀疏性 | 仅需少量频域分量即可达到良好效果 |
| 计算效率 | 通过 FFT 实现快速矩阵运算 |
| 表达能力 | 相比纯低秩方法具有更强表达能力 |
资料来源:src/peft/tuners/boft/__init__.py:1-50
FourierFT(傅里叶变换调谐器)
FourierFT 是直接在傅里叶域进行参数化的调谐器,利用傅里叶变换的正交基函数来表示权重变化。
#### 架构设计
graph LR
A[原始权重 W] --> B[傅里叶变换]
B --> C[频域系数 C]
C --> D[可训练缩放]
D --> E[逆傅里叶变换]
E --> F[更新权重 W']
style D fill:#ffcdd2#### 适用场景
- 需要捕获周期性模式的NLP任务
- 图像处理中的频域特征学习
- 需要处理具有固有周期性的序列数据
资料来源:src/peft/tuners/fourierft/__init__.py:1-50
WaveFT(小波变换调谐器)
WaveFT 利用小波变换的多尺度特性,在不同分辨率下进行参数适配,特别适合处理具有层次结构的数据。
#### 多尺度分解
| 尺度 | 特性 | 应用 |
|---|---|---|
| 低频分量 | 全局趋势 | 基础语义理解 |
| 中频分量 | 局部特征 | 语法结构学习 |
| 高频分量 | 细节变化 | 细粒度任务适配 |
资料来源:src/peft/tuners/waveft/__init__.py:1-50
低秩分解类调谐器
低秩分解类调谐器在传统 LoRA 的基础上引入更复杂的矩阵分解结构,以在保持参数效率的同时增强表达能力。
LoHA(Low-Rank Hadamard Product)
LoHA 使用 Hadamard 积(元素级乘法)结合低秩分解来构建适配器,这种结构能够更有效地捕获参数间的非线性交互。
#### 数学形式
给定原始权重矩阵 W ∈ ℝᵈˣᵏ,LoHA 的更新形式为:
ΔW = (A ⊙ B) · H
其中:
- A ∈ ℝᵈˣʳ, B ∈ ℝᵈˣʳ 为低秩矩阵
- H ∈ ℝʳˣᵏ 为 Hadamard 基础矩阵
- ⊙ 表示 Hadamard 积(元素级乘法)
#### 优势
| 维度 | LoRA | LoHA |
|---|---|---|
| 参数数量 | 2dr | 2dr + rk |
| 表达能力 | 线性组合 | 元素级交互 |
| 计算复杂度 | O(dr + kr) | O(dr + kr) |
| 适用场景 | 基础任务 | 复杂交互任务 |
资料来源:src/peft/tuners/loha/__init__.py:1-50
LoKR(Low-Rank Kronecker Product)
LoKR 利用 Kronecker 积的结构化低秩分解,在保持参数效率的同时提供更强的表达能力。
#### 数学形式
LoKR 将权重更新表示为 Kronecker 积的形式:
ΔW = Σᵢ αᵢ · (Aᵢ ⊗ Bᵢ)
其中 ⊗ 表示 Kronecker 积,Aᵢ 和 Bᵢ 分别为低秩矩阵。
#### 参数效率分析
| 分解方式 | 原始参数 | 分解后参数 | 压缩比 |
|---|---|---|---|
| 标准低秩 | d × k | r(d + k) | r(d+k)/dk |
| Kronecker | d × k | r(d₁+k₁) | r(d₁+k₁)/dk |
当 d = d₁d₂, k = k₁k₂ 时,Kronecker 分解可实现显著参数压缩。
资料来源:src/peft/tuners/lokr/__init__.py:1-50
结构化参数类调谐器
HRA(High-Rank Adaptation)
HRA 是一种高秩适配方法,设计用于在保持参数效率的同时允许更高秩的参数更新。
#### 设计理念
传统 LoRA 等方法强制使用低秩更新,这在某些复杂任务中可能限制表达能力。HRA 通过结构化的高秩分解来突破这一限制:
graph TD
A[高秩目标] --> B{分解策略选择}
B --> C[块对角结构]
B --> D[带状结构]
B --> E[分层结构]
C --> F[块内高秩<br/>块间独立]
D --> G[带内交互<br/>带间解耦]
E --> H[层级递进<br/>渐进表达]
style A fill:#ffcdd2#### 与其他方法的对比
| 方法 | 秩约束 | 参数效率 | 表达能力 |
|---|---|---|---|
| LoRA | 固定低秩 | 极高 | 中等 |
| DoRA | 固定低秩 | 极高 | 较高 |
| HRA | 可调结构化 | 高 | 高 |
| Full FT | 无约束 | 低 | 最高 |
资料来源:src/peft/tuners/hra/__init__.py:1-50
Poly(多项式调谐器)
Poly 使用多项式参数化来实现权重更新,通过多项式基函数的线性组合来捕获更复杂的变换模式。
#### 多项式基
对于 d 阶多项式,权重更新可表示为:
ΔW = Σₚ cₚ · Pₚ(W)
其中 Pₚ 是多项式基函数,cₚ 是可训练系数。
#### 特性
- 非线性建模:通过多项式基引入非线性表达能力
- 可调复杂度:通过多项式阶数控制表达能力
- 梯度平滑:相比 ReLU 等激活函数具有更平滑的梯度流
资料来源:src/peft/tuners/poly/__init__.py:1-50
统一配置接口
配置参数对照表
| 参数名 | 类型 | 说明 | 适用调谐器 |
|---|---|---|---|
r | int | 低秩维度 | LoHA, LoKR, HRA |
modules_to_save | List[str] | 额外训练的模块 | 全部 |
fan_in_fan_out | bool | 权重初始化方式 | LoHA, LoKR |
init_weights | bool | 是否初始化权重 | 全部 |
layers_to_transform | List[int] | 指定变换层 | 全部 |
使用示例
from peft import get_peft_model, LoraConfig
# LoHA 配置示例
loha_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# FourierFT 配置示例
fourier_config = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
task_type="CAUSAL_LM"
)
技术选型指南
graph TD
A[任务类型?] --> B{参数效率优先?}
B -->|是| C{交互复杂度?}
B -->|否| D[使用 HRA 或 Poly]
C -->|简单线性| E[使用 LoRA]
C -->|中等| F[使用 LoHA]
C -->|复杂| G[使用 LoKR]
A --> H{频域特征重要?}
H -->|是| I{多尺度需求?}
I -->|是| J[使用 WaveFT]
I -->|否| K[使用 FourierFT]
style E fill:#c8e6c9
style F fill:#fff9c4
style G fill:#ffccbc
style J fill:#bbdefb
style K fill:#e1bee7场景推荐
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 通用文本微调 | LoRA | 成熟稳定,资源消耗低 |
| 复杂语义任务 | LoHA | 元素级交互增强表达 |
| 大模型高效微调 | LoKR | Kronecker 结构节省参数 |
| 周期模式识别 | FourierFT | 频域表示天然捕获周期 |
| 多粒度任务 | WaveFT | 小波多尺度分析 |
| 高表达需求 | HRA | 结构化高秩保持效率 |
底层实现架构
调谐器类层次结构
classDiagram
class BaseTuner {
<<abstract>>
+merge_weights()
+unmerge_weights()
+set_adapter()
}
class BaseLayer {
+forward()
+extra_capabilities()
}
class BOFT {
+_create_boft_modules()
+forward()
}
class FourierFT {
+_create_fourier_modules()
+forward()
}
class WaveFT {
+_create_wavelet_modules()
+forward()
}
class LoHA {
+_create_hadamard_modules()
+forward()
}
class LoKR {
+_create_kronecker_modules()
+forward()
}
class HRA {
+_create_hra_modules()
+forward()
}
class Poly {
+_create_poly_modules()
+forward()
}
BaseTuner <|-- BOFT
BaseTuner <|-- FourierFT
BaseTuner <|-- WaveFT
BaseTuner <|-- LoHA
BaseTuner <|-- LoKR
BaseTuner <|-- HRA
BaseTuner <|-- Poly
BaseLayer <|-- BOFT
BaseLayer <|-- FourierFT
BaseLayer <|-- WaveFT
BaseLayer <|-- LoHA
BaseLayer <|-- LoKR
BaseLayer <|-- HRA
BaseLayer <|-- Poly性能与效率对比
参数量对比(以 d=1024, k=1024, r=16 为例)
| 方法 | 可训练参数量 | 理论压缩比 |
|---|---|---|
| Full Fine-tune | 2,097,152 | 1× |
| LoRA | 65,536 | 32× |
| LoHA | 65,536 + α | ~32× |
| LoKR | ~32,768 | ~64× |
| BOFT | ~65,536 | ~32× |
| FourierFT | ~32,768 | ~64× |
计算开销
| 方法 | 前向计算开销 | 反向梯度开销 |
|---|---|---|
| LoRA | O(dr + kr) | O(dr + kr) |
| LoHA | O(dr + kr) | O(dr + kr) |
| LoKR | O(d₁r + d₂r + k₁r + k₂r) | O(d₁r + d₂r + k₁r + k₂r) |
| FourierFT | O(dk log d) | O(dk log d) |
| WaveFT | O(dk log d) | O(dk log d) |
最佳实践
配置建议
- 秩的选择:从 r=8 或 r=16 开始,根据任务复杂度逐步增加
- 目标模块:优先选择注意力层的 q_proj 和 v_proj
- 学习率:高级调谐器通常需要比 LoRA 稍低的学习率
- 初始化:建议使用 PEFT 默认初始化策略
常见问题排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 收敛慢 | 学习率过高 | 降低学习率 2-5 倍 |
| 性能下降 | 秩过低 | 适当增加 r 值 |
| 显存溢出 | batch size 过大 | 减小 batch size |
| 效果不稳定 | 初始化不当 | 使用预定义初始化 |
总结
PEFT 库的高级调谐器为参数高效微调提供了丰富的选择,涵盖了频域变换、低秩分解、结构化参数等多种技术路线。这些方法在保持参数效率的同时,通过各自独特的参数化策略增强了模型的表达能力。
开发者和研究人员可以根据具体任务需求、计算资源和性能要求,在这些高级调谐器中选择最合适的方案。随着研究的深入,这些实验性方法有望在未来得到进一步优化和广泛应用。
资料来源:[src/peft/tuners/boft/__init__.py:1-50]()
模型合并与融合工具
PEFT(Parameter-Efficient Fine-Tuning)库提供了强大的模型合并与融合工具,使用户能够将适配器(Adapter)的权重与基础模型合并,生成一个独立的、合并后的模型。这些工具的核心功能包括:
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
PEFT(Parameter-Efficient Fine-Tuning)库提供了强大的模型合并与融合工具,使用户能够将适配器(Adapter)的权重与基础模型合并,生成一个独立的、合并后的模型。这些工具的核心功能包括:
- 合并与卸载(Merge and Unload):将适配器权重合并回基础模型,生成标准Transformer模型
- 卸载(Unload):移除所有PEFT模块,恢复基础模型
- 混合适配器合并(Mixed Adapter Merging):支持在多适配器场景下选择性合并特定适配器
合并后的模型不再依赖PEFT框架,可以像标准模型一样加载和使用,同时保留了适配器训练带来的能力增强。
资料来源:src/peft/tuners/tuners_utils.py:1-100
核心架构
合并机制流程
graph TD
A[PEFT模型] --> B{合并方式选择}
B --> C[merge_and_unload<br/>合并并卸载适配器]
B --> D[unload<br/>仅卸载适配器]
C --> E[合并权重到基础层]
D --> F[移除PEFT模块]
E --> G[返回合并后的基础模型]
F --> G
G --> H[标准Transformer模型]多适配器合并架构
graph TD
A[基础模型] --> B[Adapter 1<br/>LoRA权重]
A --> C[Adapter 2<br/>LoRA权重]
A --> D[Adapter N<br/>LoRA权重]
B --> E{选择性合并}
C --> E
D --> E
E --> F[合并指定适配器]
E --> G[合并全部适配器]
F --> H[合并后的模型]
G --> H主要接口
PeftModel 基类方法
所有PEFT模型继承自 PeftModel 基类,提供以下合并相关方法:
| 方法名 | 参数 | 返回值 | 功能描述 |
|---|---|---|---|
merge_and_unload | progressbar, safe_merge, adapter_names | torch.nn.Module | 合并并卸载适配器,返回合并后的模型 |
unload | 无 | torch.nn.Module | 仅卸载适配器,返回基础模型 |
_unload_and_optionally_merge | merge, progressbar, safe_merge, adapter_names | torch.nn.Module | 内部实现,根据参数决定是否合并 |
资料来源:src/peft/tuners/tuners_utils.py:150-180
方法详细说明
#### merge_and_unload 方法
def merge_and_unload(
self,
progressbar: bool = False,
safe_merge: bool = False,
adapter_names: Optional[list[str]] = None,
) -> torch.nn.Module:
参数说明:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
progressbar | bool | False | 是否显示合并进度条 |
safe_merge | bool | False | 是否使用安全合并模式(避免数值溢出) |
adapter_names | Optional[list[str]] | None | 指定要合并的适配器名称列表,None表示全部 |
使用示例:
>>> from peft import PeftModel
>>> base_model = AutoModelForCausalLM.from_pretrained("base_model_path")
>>> peft_model = PeftModel.from_pretrained(base_model, "adapter_path")
>>> merged_model = peft_model.merge_and_unload()
资料来源:src/peft/tuners/tuners_utils.py:120-145
#### unload 方法
def unload(self) -> torch.nn.Module:
该方法将所有PEFT模块从模型中移除,返回原始的基础模型。
重要提示:必须将返回的模型赋值给一个变量并使用它,这不是原地操作。
资料来源:src/peft/tuners/tuners_utils.py:155-165
合并策略
基础模型合并
基础模型合并是最常见的场景,将单个适配器与基础模型合并:
graph LR
A[Base Model] -->|加载| B[PeftModel]
B -->|添加适配器| C[LoRA Layers]
C -->|merge_and_unload| D[合并后的模型]多适配器选择性合并
在多适配器场景下,可以选择性合并特定的适配器:
# 合并指定适配器
merged_model = peft_model.merge_and_unload(
adapter_names=["adapter_1", "adapter_2"]
)
# 安全合并避免数值问题
merged_model = peft_model.merge_and_unload(
safe_merge=True
)
合并过程中的兼容性检查
PEFT库实现了目标模块兼容性检查机制,防止在特定架构(如Mamba)上应用不兼容的LoRA模块:
def _check_target_module_compatiblity(
self,
peft_config: PeftConfig,
model: nn.Module,
target_name: str
):
"""防止在不兼容的模块上应用LoRA"""
_check_lora_target_modules_mamba(peft_config, model, target_name)
资料来源:src/peft/tuners/tuners_utils.py:170-175
适配器热切换
hotswap_adapter 功能
PEFT还提供了热切换适配器的功能,允许在不重新加载模型的情况下替换适配器:
from peft.utils.hotswap import hotswap_adapter
# 替换默认适配器
hotswap_adapter(
model,
"path-to-new-adapter",
adapter_name="default",
torch_device="cuda"
)
参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
model | PeftModel | 包含已加载适配器的PEFT模型 |
model_name_or_path | str | 新适配器的路径 |
adapter_name | str | 要替换的适配器名称 |
torch_device | str | 加载新适配器的设备 |
资料来源:src/peft/utils/hotswap.py:1-50
热切换工作流程
sequenceDiagram
participant U as 用户
participant M as PeftModel
participant A1 as 原适配器
participant A2 as 新适配器
U->>M: 调用hotswap_adapter
M->>M: 加载新适配器配置
M->>M: 验证适配器兼容性
M->>A1: 卸载原适配器权重
M->>A2: 加载新适配器权重
M->>U: 返回热切换后的模型Mixed PeftModel
对于需要同时使用多个适配器的场景,PEFT提供了 MixedPeftModel 类,支持更灵活的多适配器管理。
主要特性
| 特性 | 说明 |
|---|---|
| 多适配器加载 | 同时加载多个适配器 |
| 动态切换 | 在不同适配器间动态切换 |
| 选择性合并 | 合并指定的适配器组合 |
| 权重融合 | 支持不同合并策略的权重融合 |
资料来源:src/peft/mixed_model.py:1-100
保存与加载
模型保存
PEFT提供了 save_peft_model 函数用于保存PEFT模型:
>>> from peft import save_peft_model
>>> peft_model.save_peft_model(save_path)
模型加载
使用 from_pretrained 方法加载已保存的PEFT模型:
>>> from peft import PeftModel
>>> base_model = AutoModelForCausalLM.from_pretrained("base_model")
>>> peft_model = PeftModel.from_pretrained(base_model, "peft_model_path")
资料来源:src/peft/utils/save_and_load.py:1-100
使用场景
场景一:训练后合并
在完成适配器训练后,将适配器权重合并到基础模型:
from peft import PeftModel, AutoModelForCausalLM
# 1. 加载基础模型
base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b")
# 2. 加载训练好的PEFT适配器
peft_model = PeftModel.from_pretrained(base_model, "./lora_checkpoint")
# 3. 合并并卸载
merged_model = peft_model.merge_and_unload()
# 4. 保存合并后的模型
merged_model.save_pretrained("./merged_model")
场景二:多适配器选择性合并
在多适配器训练后,选择性地合并部分适配器:
# 假设有多个适配器
peft_model.add_adapter("adapter_style_a", config_a)
peft_model.add_adapter("adapter_style_b", config_b)
# 只合并特定适配器
merged_model = peft_model.merge_and_unload(
adapter_names=["adapter_style_a"]
)
场景三:推理时热切换
在推理过程中动态切换不同适配器:
from peft.utils.hotswap import hotswap_adapter
# 使用适配器A推理
output_a = model(inputs)
# 热切换到适配器B
hotswap_adapter(model, "path-to-adapter-b", adapter_name="default")
# 使用适配器B推理
output_b = model(inputs)
注意事项
内存需求
合并操作需要额外的内存来存储中间结果,合并过程中内存使用量可能达到原模型大小的2-3倍。
安全合并
启用 safe_merge=True 可以避免合并过程中的数值溢出问题:
merged_model = peft_model.merge_and_unload(safe_merge=True)
不兼容模块
某些特定架构(如Mamba)可能不支持标准的LoRA合并操作,系统会进行兼容性检查并抛出相应错误。
相关文件索引
| 文件路径 | 功能描述 |
|---|---|
src/peft/utils/merge_utils.py | 核心合并工具函数 |
src/peft/utils/save_and_load.py | 模型保存与加载工具 |
src/peft/mixed_model.py | 混合适配器模型实现 |
src/peft/tuners/tuners_utils.py | tuner基类,包含merge_and_unload实现 |
src/peft/peft_model.py | PEFT模型主类定义 |
src/peft/utils/hotswap.py | 适配器热切换工具 |
总结
PEFT库的模型合并与融合工具提供了完整的工作流程,从适配器训练后的模型合并、多适配器选择性合并,到推理过程中的适配器热切换。这些工具使得用户可以灵活地管理和部署高效的参数微调模型,同时保持部署模型的简洁性和兼容性。
资料来源:[src/peft/tuners/tuners_utils.py:1-100]()
量化支持与加速优化
PEFT 库提供了全面的量化支持与加速优化功能,旨在降低大语言模型的显存占用和计算成本,同时保持模型性能。通过集成多种业界领先的量化方法,PEFT 使用户能够在量化模型上无缝应用 LoRA 等参数高效微调技术。量化支持覆盖了从 4-bit 量化到极致压缩的多种方案,包括 BitsAndBytes (bnb)、GPTQ、AWQ、AQLM 和 HQQ 等主流量化框架。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
PEFT 库提供了全面的量化支持与加速优化功能,旨在降低大语言模型的显存占用和计算成本,同时保持模型性能。通过集成多种业界领先的量化方法,PEFT 使用户能够在量化模型上无缝应用 LoRA 等参数高效微调技术。量化支持覆盖了从 4-bit 量化到极致压缩的多种方案,包括 BitsAndBytes (bnb)、GPTQ、AWQ、AQLM 和 HQQ 等主流量化框架。
架构总览
PEFT 的量化系统采用模块化设计,每种量化方法都有独立的实现模块,与 LoRA 微调层深度集成。这种设计允许用户在量化模型上直接添加和训练适配器,而无需对原始量化架构进行大幅修改。
graph TD
A[用户配置] --> B[PEFT 量化模块]
B --> C[bnb.py<br/>BitsAndBytes 4-bit]
B --> D[gptq.py<br/>GPTQ 量化]
B --> E[awq.py<br/>AWQ 量化]
B --> F[aqlm.py<br/>AQLM 量化]
B --> G[hqq.py<br/>HQQ 量化]
C --> H[LoRA 适配器层]
D --> H
E --> H
F --> H
G --> H
H --> I[量化模型推理/训练]量化方法详解
BitsAndBytes 量化 (bnb)
BitsAndBytes 是由 Meta 开发的 4-bit 量化方案,采用 NormalFloat (NF4) 数据类型实现高效的权重量化。该方法在量化过程中使用双重量化技术,进一步减少显存占用。
#### 核心参数配置
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
load_in_4bit | bool | 启用 4-bit 量化加载 | False |
load_in_8bit | bool | 启用 8-bit 量化加载 | False |
bnb_4bit_quant_type | str | 量化类型,可选 nf4 或 fp4 | nf4 |
bnb_4bit_compute_dtype | dtype | 计算数据类型 | float16 |
bnb_4bit_use_double_quant | bool | 启用双重量化 | False |
#### 工作原理
BitsAndBytes 在模型加载时自动替换原有的 Linear 层为自定义的 BNB Linear 层。该实现支持在量化模型上直接添加 LoRA 适配器,适配器参数保持原始精度以确保训练稳定性。
资料来源:src/peft/tuners/lora/bnb.py:1-200
GPTQ 量化
GPTQ 是一种后训练量化 (PTQ) 方法,通过逐层优化实现 4-bit 权重量化。该方法在保持模型性能的同时实现显著的压缩率。
#### 关键特性
- 支持 4-bit 和 8-bit 量化精度
- 与现有 PEFT 方法完全兼容
- 支持量化感知训练
#### 量化配置
| 参数 | 说明 | 可选值 |
|---|---|---|
bits | 量化位数 | 2, 3, 4, 8 |
tokenizer | 分词器实例 | - |
dataset | 校准数据集 | 字符串或列表 |
samples | 校准样本数量 | 整数 |
资料来源:src/peft/tuners/lora/gptq.py:1-180
AWQ 量化
AWQ (Activation-Aware Weight Quantization) 是一种硬件感知的权重量化方法,通过分析激活值分布来优化量化策略。该方法特别适合在特定硬件平台上部署。
#### 核心优势
- 针对硬件优化的高效推理
- 保留重要权重为全精度
- 与多种部署框架兼容
资料来源:src/peft/tuners/lora/awq.py:1-150
AQLM 量化
AQLM (Additive Quantization Language Models) 是一种基于加数量化的高级压缩方法,通过将权重矩阵分解为多个码本的组合实现极致压缩。
#### 技术特点
- 支持多码本量化架构
- 高压缩率下的性能保持
- 适合大规模模型的极致优化
资料来源:src/peft/tuners/lora/aqlm.py:1-160
HQQ 量化
HQQ (Hessian Quantization) 是一种基于 Hessian 矩阵的量化方法,通过考虑参数重要性进行自适应量化。该方法在量化过程中利用二阶信息来保护关键权重。
#### 核心机制
- 基于 Hessian 的敏感性分析
- 自适应位宽分配
- 训练后量化支持
资料来源:src/peft/tuners/lora/hqq.py:1-170
优化器集成
PEFT 的优化器模块提供了与量化系统深度集成的优化算法,专门针对量化环境下的训练进行了优化。
graph LR
A[量化模型] --> B[优化器选择]
B --> C[标准优化器]
B --> D[PEFT 优化器]
C --> E[SGD/AdamW]
D --> F[8bit AdamW]
D --> G[32bit AdamW]
F --> H[梯度更新]
G --> H8-bit AdamW 优化器
针对量化环境优化的 8-bit AdamW 实现,通过分块量化技术保持训练稳定性。该优化器使用专利的分块方案处理梯度统计量,显著降低显存占用。
优化器配置
| 优化器类型 | 适用场景 | 显存节省 |
|---|---|---|
| 8-bit AdamW | 量化模型训练 | ~60% |
| 32-bit AdamW | 精度敏感场景 | ~40% |
| PyTorch SGD | 简单任务 | ~20% |
资料来源:src/peft/optimizers/__init__.py:1-100
量化与 LoRA 的结合
工作流程
graph TD
A[加载基础模型] --> B{选择量化方法}
B --> C[BitsAndBytes]
B --> D[GPTQ]
B --> E[AWQ]
B --> F[AQLM]
B --> G[HQQ]
C --> H[量化模型转换]
D --> H
E --> H
F --> H
G --> H
H --> I[注入 LoRA 适配器]
I --> J[PEFT 配置]
J --> K[训练/推理]兼容性矩阵
| 量化方法 | LoRA | AdaLoRA | QLoRA | Prefix Tuning |
|---|---|---|---|---|
| BitsAndBytes | ✓ | ✓ | ✓ | ✓ |
| GPTQ | ✓ | ✓ | ✓ | ✓ |
| AWQ | ✓ | ✓ | ✓ | ✓ |
| AQLM | ✓ | ✓ | ✓ | ✓ |
| HQQ | ✓ | ✓ | ✓ | ✓ |
使用示例
BitsAndBytes 量化配置
from peft import get_peft_model, LoraConfig, BitsAndBytesConfig
# 配置量化参数
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype="float16",
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4"
)
# 加载量化模型并应用 LoRA
model = AutoModelForCausalLM.from_pretrained(
"model_name",
quantization_config=bnb_config
)
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
QLoRA 训练流程
QLoRA 结合了量化与 LoRA 的优势,实现极低显存占用的高效训练。该方案在 4-bit 量化的模型上训练 LoRA 适配器,同时保持优化器状态为全精度。
性能与精度权衡
量化精度对比
| 量化方法 | 精度损失 | 压缩比 | 推理速度提升 |
|---|---|---|---|
| FP16 (基线) | 0% | 1x | 1x |
| INT8 | <1% | 2x | 1.3x |
| NF4 (bnb) | <2% | 4x | 2x |
| GPTQ-4bit | <3% | 4x | 2.5x |
| AQLM | <4% | 8x | 3x |
显存占用分析
模型规模: 7B 参数
FP16 完整微调: ~28GB 显存
QLoRA (4bit): ~6GB 显存
LoRA (FP16): ~14GB 显存
技术实现要点
量化感知训练
PEFT 支持在量化模型上进行量化感知训练 (QAT),通过以下机制实现:
- 直通的梯度流动:LoRA 适配器层保持原始精度计算
- 动态量化更新:权重更新采用舍入机制
- 兼容性检查:自动验证量化配置与 PEFT 配置的兼容性
混合精度策略
量化配置中可指定不同的计算精度层级:
compute_dtype = torch.float16 # 计算使用 FP16
quantization_config = {
"weight_bit_width": 4, # 权重 4-bit
"calib_bit_width": 8 # 校准使用 8-bit
}
最佳实践
量化方法选择指南
| 应用场景 | 推荐量化方法 | 理由 |
|---|---|---|
| 消费级 GPU 训练 | BitsAndBytes NF4 | 成熟稳定,生态完善 |
| 服务器端部署 | GPTQ-4bit | 推理效率高 |
| 移动端部署 | AWQ | 硬件适配性好 |
| 极致压缩 | AQLM | 最高压缩率 |
常见陷阱与规避
- 精度回退:确保优化器状态使用足够精度
- 校准数据质量:使用代表性数据避免分布偏移
- 目标模块选择:优先量化 attention 和 FFN 层
- 梯度检查:启用梯度监控以检测数值问题
总结
PEFT 的量化支持与加速优化模块为用户提供了完整的模型压缩解决方案。通过集成多种主流量化框架并保持与 LoRA 系列的深度兼容,PEFT 使得在资源受限环境下训练和部署大语言模型成为可能。开发者应根据具体应用场景、硬件条件和性能要求选择合适的量化策略,在模型效果和资源效率之间取得最佳平衡。
资料来源:[src/peft/tuners/lora/bnb.py:1-200](https://github.com/huggingface/peft/blob/main/src/peft/tuners/lora/bnb.py)
示例与用例概览
PEFT(Parameter-Efficient Fine-Tuning)库提供了丰富的示例和用例,涵盖了从语言建模到图像分类的多种任务类型。这些示例展示了如何使用不同的适配器方法(如 LoRA、IA³、Prefix Tuning、Prompt Tuning 等)来高效地微调预训练模型。示例代码位于 examples/ 目录下,涵盖了因果语言建模、条件生成、序列分类、图像分...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
PEFT(Parameter-Efficient Fine-Tuning)库提供了丰富的示例和用例,涵盖了从语言建模到图像分类的多种任务类型。这些示例展示了如何使用不同的适配器方法(如 LoRA、IA³、Prefix Tuning、Prompt Tuning 等)来高效地微调预训练模型。示例代码位于 examples/ 目录下,涵盖了因果语言建模、条件生成、序列分类、图像分类、监督微调(SFT)以及 INT8 训练等多种场景。
PEFT 的示例设计遵循统一的设计模式,通过 get_peft_model() 函数将 PEFT 配置应用到基础模型上,然后使用标准的 Transformers API 进行训练和推理。这种设计使得用户可以轻松地在不同的适配器方法之间切换,同时保持代码的一致性。
核心任务类型
PEFT 库针对不同的下游任务提供了专门的任务类型(Task Type),每种任务类型对应特定的模型类和应用场景。
任务类型与模型类映射
| 任务类型 | 枚举值 | 对应模型类 | 主要应用场景 |
|---|---|---|---|
| 因果语言建模 | CAUSAL_LM | PeftModelForCausalLM | GPT 系列模型的自回归生成 |
| 条件生成 | SEQ_2_SEQ_LM | PeftModelForSeq2SeqLM | T5、BART 等编码器-解码器模型 |
| 序列分类 | SEQ_CLS | PeftModelForSequenceClassification | 文本分类任务 |
| Token 分类 | TOKEN_CLS | PeftModelForTokenClassification | 命名实体识别、词性标注 |
| 问答任务 | QUESTION_ANS | PeftModelForQuestionAnswering | 阅读理解问答 |
| 特征提取 | FEATURE_EXTRACTION | PeftModelForFeatureExtraction | 嵌入向量提取 |
资料来源:src/peft/peft_model.py:1-100
因果语言建模(Causal Language Modeling)
因果语言建模是 GPT 系列模型的核心任务,模型需要根据前面的 token 预测下一个 token。PEFT 提供了 PeftModelForCausalLM 类来处理这类任务。
from transformers import AutoModelForCausalLM
from peft import get_peft_model, LoraConfig, TaskType
model = AutoModelForCausalLM.from_pretrained("gpt2")
peft_config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=16,
lora_alpha=32,
lora_dropout=0.05,
target_modules=["q_proj", "v_proj"]
)
peft_model = get_peft_model(model, peft_config)
peft_model.print_trainable_parameters()
在因果语言建模中,LoRA 适配器通常应用于注意力机制的查询(Query)和值(Value)投影层,以实现高效的参数更新。模型的 generate() 方法保持了与原始模型相同的签名,可以通过 update_generate_signature() 函数来更新以包含完整的参数说明。
资料来源:src/peft/tuners/lora/model.py:1-50 资料来源:src/peft/helpers.py:1-60
序列到序列生成(Sequence-to-Sequence Generation)
序列到序列任务适用于 T5、BART 等编码器-解码器架构的模型。PeftModelForSeq2SeqLM 类专门处理这类任务,支持条件生成、翻译、摘要等应用。
from transformers import AutoModelForSeq2SeqLM
from peft import PeftModelForSeq2SeqLM, get_peft_config
config = {
"peft_type": "LORA",
"task_type": "SEQ_2_SEQ_LM",
"inference_mode": False,
"r": 8,
"lora_alpha": 32,
"lora_dropout": 0.1,
"target_modules": ["q", "v"]
}
peft_config = get_peft_config(config)
model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
peft_model = PeftModelForSeq2SeqLM(model, peft_config)
PeftModelForSeq2SeqLM 初始化时会保存基础模型的 prepare_inputs_for_generation 和 _prepare_encoder_decoder_kwargs_for_generation 方法引用,以确保生成过程中的兼容性。
资料来源:src/peft/peft_model.py:100-150
序列分类(Sequence Classification)
序列分类任务将整个序列映射到单个标签,常用于情感分析、主题分类等场景。PeftModelForSequenceClassification 专门处理此类任务。
from transformers import AutoModelForSequenceClassification
from peft import PeftModelForSequenceClassification, get_peft_config
config = {
"peft_type": "PREFIX_TUNING",
"task_type": "SEQ_CLS",
"num_virtual_tokens": 20,
"token_dim": 768,
"num_transformer_submodules": 1,
"num_attention_heads": 12,
"num_layers": 12
}
peft_config = get_peft_config(config)
model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased")
peft_model = PeftModelForSequenceClassification(model, peft_config)
在序列分类中,PEFT 默认识别 classifier 和 score 作为分类层名称,可以通过配置中的 modules_to_save 参数指定其他需要训练的分类层。
资料来源:src/peft/peft_model.py:50-100
Token 分类(Token Classification)
Token 分类任务为输入序列中的每个 token 预测一个标签,适用于命名实体识别(NER)、词性标注等任务。
from transformers import AutoModelForTokenClassification
from peft import PeftModelForTokenClassification, get_peft_config
peft_config = get_peft_config({
"peft_type": "LORA",
"task_type": "TOKEN_CLS",
"r": 16,
"target_modules": ["query", "value"]
})
model = AutoModelForTokenClassification.from_pretrained("bert-base-cased")
peft_model = PeftModelForTokenClassification(model, peft_config)
与序列分类类似,Token 分类也使用 modules_to_save 参数来控制哪些层需要被训练和保存。
资料来源:src/peft/peft_model.py:100-150
问答任务(Question Answering)
问答任务要求模型根据给定的上下文回答问题。PeftModelForQuestionAnswering 类专门处理抽取式问答场景。
from transformers import AutoModelForQuestionAnswering
from peft import PeftModelForQuestionAnswering, get_peft_config
peft_config = get_peft_config({
"peft_type": "LORA",
"task_type": "QUESTION_ANS",
"r": 16,
"target_modules": ["query", "value"]
})
model = AutoModelForQuestionAnswering.from_pretrained("bert-base-cased")
peft_model = PeftModelForQuestionAnswering(model, peft_config)
默认情况下,问答任务的分类层名称为 qa_outputs,可以通过配置参数进行自定义。
资料来源:src/peft/peft_model.py:1-50
特征提取(Feature Extraction)
特征提取任务用于获取输入序列的嵌入表示,可用于下游任务的特征输入或相似度计算等场景。
from transformers import AutoModel
from peft import PeftModelForFeatureExtraction, get_peft_config
peft_config = get_peft_config({
"peft_type": "LORA",
"task_type": "FEATURE_EXTRACTION",
"r": 16
})
model = AutoModel.from_pretrained("bert-base-cased")
peft_model = PeftModelForFeatureExtraction(model, peft_config)
PeftModelForFeatureExtraction 的 forward() 方法支持丰富的参数,包括 input_ids、attention_mask、inputs_embeds、output_attentions、output_hidden_states 等,可根据具体需求灵活配置。
资料来源:src/peft/peft_model.py:50-100
适配器方法与配置
PEFT 支持多种参数高效微调方法,每种方法都有其独特的配置选项和应用场景。
LoRA(Low-Rank Adaptation)
LoRA 是最广泛使用的 PEFT 方法之一,通过在预训练权重旁边添加低秩分解矩阵来实现高效微调。
| 参数 | 类型 | 说明 |
|---|---|---|
r | int | LoRA 矩阵的秩,值越大表示表达能力越强,但参数量也越大 |
lora_alpha | int | LoRA 的缩放因子,通常设置为 r 的两倍 |
lora_dropout | float | LoRA 层的 Dropout 概率 |
target_modules | List[str] | 需要应用 LoRA 的模块名称,如 ["q_proj", "v_proj"] |
bias | str | bias 的训练策略,可选 "none"、"all"、"lora_only" |
fan_in_fan_out | bool | 是否将权重转置 |
资料来源:src/peft/tuners/lora/model.py:1-80
IA³(Adapters by Inhibiting and Amplifying Inner Activations)
IA³ 方法通过学习向量来缩放隐藏状态,实现对模型行为的精细调控。
from peft import IA3Config, IA3Model
config = IA3Config(
task_type=TaskType.SEQ_2_SEQ_LM,
target_modules=["q", "v", "k", "wo", "wi"],
feedforward_modules=["wi"]
)
model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
ia3_model = IA3Model(config, model)
IA³ 特别适合序列到序列任务,其 target_modules 和 feedforward_modules 参数用于指定缩放向量应用的位置。
资料来源:src/peft/tuners/ia3/model.py:1-60
Prefix Tuning(前缀微调)
Prefix Tuning 通过在注意力层之前添加可学习的前缀 token 来引导模型生成。
from peft import PrefixTuningConfig
config = PrefixTuningConfig(
task_type=TaskType.SEQ_CLS,
num_virtual_tokens=20,
token_dim=768,
num_transformer_submodules=1,
num_attention_heads=12,
num_layers=12,
prefix_projection=False
)
关键参数包括 num_virtual_tokens(虚拟 token 数量)、prefix_projection(是否使用两层 MLP 投影)以及 postprocess_past_key_value_function(用于自定义 KV 缓存后处理的函数)。
资料来源:src/peft/peft_model.py:50-100
Prompt Tuning
Prompt Tuning 是一种简洁的提示学习方法,仅通过学习嵌入层来实现任务适应。
from peft import PromptTuningConfig, PromptTuningInit
config = PromptTuningConfig(
task_type=TaskType.SEQ_2_SEQ_LM,
num_virtual_tokens=20,
prompt_tuning_init="TEXT",
prompt_tuning_init_text="Predict if sentiment of this review is positive, negative or neutral",
tokenizer_name_or_path="t5-base"
)
PromptTuningInit 支持多种初始化方式:RANDOM、TEXT、AVERAGE_EMBEDDINGS 和 SAMPLE_VOCAB。当使用 SAMPLE_VOCAB 时,嵌入会根据词汇表进行随机采样初始化。
资料来源:src/peft/tuners/prompt_tuning/model.py:1-80
X-LoRA
X-LoRA 是一种支持多适配器动态组合的方法,允许在推理时动态加载和组合多个 LoRA 适配器。
from peft import XLoraConfig, get_xlora_config
config = XLoraConfig(
base_model_config=None,
adapters={
"adapter_1": "./path/to/checkpoint1/",
"adapter_2": "./path/to/checkpoint2/"
}
)
xlora_model = get_peft_model(model, config)
X-LoRA 支持量化模型(INT8/INT4),可通过 BitsAndBytesConfig 配置,支持 flash_attention_2 加速推理。
资料来源:src/peft/tuners/xlora/model.py:1-100
工作流程与架构
典型 PEFT 工作流程
graph TD
A[加载预训练模型] --> B[创建 PEFT 配置]
B --> C[应用 PEFT 配置]
C --> D{适配器类型}
D -->|LoRA| E[替换目标层为 LoRA 层]
D -->|IA³| F[添加缩放向量]
D -->|Prefix| G[添加可学习前缀]
D -->|Prompt| H[替换嵌入层]
E --> I[训练 PEFT 模型]
F --> I
G --> I
H --> I
I --> J[保存适配器]
J --> K[加载并合并]适配器注入机制
PEFT 的核心机制是通过 inject_adapter() 方法将适配器层注入到基础模型中。这个过程涉及目标模块的识别、替换和配置。
def inject_adapter(
model: nn.Module,
adapter_name: str,
autocast_adapter_dtype: bool = True,
low_cpu_mem_usage: bool = False,
state_dict: Optional[dict[str, torch.Tensor]] = None,
) -> None:
注入过程会遍历模型的子模块,根据配置中的 target_modules 映射找到需要替换的目标层,然后创建对应的适配器层进行替换。系统会检查目标模块的兼容性,防止在不支持的架构(如 Mamba)上应用不兼容的适配器。
资料来源:src/peft/tuners/tuners_utils.py:1-50
模型合并与卸载
训练完成后,PEFT 支持将适配器权重合并回基础模型,或完全卸载适配器恢复原始模型。
# 合并并卸载
merged_model = peft_model.merge_and_unload()
# 仅卸载(恢复基础模型)
base_model = peft_model.unload()
merge_and_unload() 方法使用 safe_merge 参数控制在合并前是否进行数值稳定性检查。unload() 方法则完全移除所有 PEFT 层,返回原始的基础模型。
资料来源:src/peft/tuners/tuners_utils.py:1-50
高级功能
签名更新工具
PEFT 提供了 update_forward_signature() 和 update_generate_signature() 工具函数,用于更新封装后的模型方法签名,使 IDE 和帮助系统能够正确显示参数信息。
from peft import update_forward_signature, update_generate_signature
peft_model = get_peft_model(model, peft_config)
update_forward_signature(peft_model) # 更新 forward 方法签名
update_generate_signature(peft_model) # 更新 generate 方法签名
这些函数会检查当前签名的参数数量和名称,仅当签名只包含 *args 和 **kwargs 时才进行更新,确保不会意外覆盖有意义的方法签名。
资料来源:src/peft/helpers.py:1-100
适配器缩放上下文管理器
rescale_adapter_scale() 上下文管理器允许临时调整适配器的缩放因子,这在某些特殊的推理场景下非常有用。
from peft import rescale_adapter_scale
with rescale_adapter_scale(peft_model, multiplier=2.0):
outputs = peft_model(inputs)
该管理器会在进入上下文时修改缩放值,在退出时自动恢复原始值,确保不改变模型状态的持久性。
资料来源:src/peft/helpers.py:100-150
多适配器管理
PEFT 支持在同一模型上同时管理多个适配器,通过 add_adapter() 方法添加新适配器,通过 set_adapter() 方法切换当前活动的适配器。
# 添加新适配器
peft_model.add_adapter(new_adapter_name, new_peft_config)
# 切换适配器
peft_model.set_adapter(adapter_name)
添加适配器时,新层默认设置为 requires_grad_(False)(不可训练),需要显式调用才能激活训练。
资料来源:src/peft/tuners/tuners_utils.py:1-50
量化训练支持
PEFT 与 bitsandbytes 库深度集成,支持 INT8 和 INT4 量化训练。
import torch
import transformers
from peft import get_peft_model, LoraConfig, prepare_model_for_kbit_training
quantization_config = transformers.BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(
"mistralai/Mistral-7B-Instruct-v0.1",
quantization_config=quantization_config,
device_map="auto"
)
model = prepare_model_for_kbit_training(model)
peft_model = get_peft_model(model, peft_config)
prepare_model_for_kbit_training() 函数负责准备量化模型以进行梯度计算,包括正确配置嵌入层和 lm_head 层的梯度设置。
资料来源:src/peft/tuners/lora/model.py:1-50
配置参数速查表
LoRA 配置参数
| 参数名 | 必需 | 默认值 | 说明 |
|---|---|---|---|
r | 是 | - | LoRA 矩阵秩 |
lora_alpha | 否 | r | 缩放因子 |
lora_dropout | 否 | 0.0 | Dropout 概率 |
target_modules | 否 | None | 目标模块列表 |
bias | 否 | "none" | bias 训练策略 |
fan_in_fan_out | 否 | False | 权重转置 |
modules_to_save | 否 | None | 额外保存的模块 |
Prefix Tuning 配置参数
| 参数名 | 必需 | 默认值 | 说明 |
|---|---|---|---|
num_virtual_tokens | 是 | - | 虚拟 token 数量 |
token_dim | 是 | - | token 维度 |
num_transformer_submodules | 否 | 1 | transformer 子模块数 |
num_attention_heads | 是 | - | 注意力头数 |
num_layers | 是 | - | 层数 |
prefix_projection | 否 | False | 是否投影 |
Prompt Tuning 配置参数
| 参数名 | 必需 | 默认值 | 说明 |
|---|---|---|---|
num_virtual_tokens | 是 | - | 虚拟 token 数量 |
prompt_tuning_init | 否 | RANDOM | 初始化方式 |
prompt_tuning_init_text | 条件 | - | 文本初始化内容 |
tokenizer_name_or_path | 条件 | - | 分词器路径 |
最佳实践
目标模块选择建议
不同的模型架构适合不同的目标模块配置:
- Transformer 注意力层:优先选择
q_proj、v_proj,其次考虑k_proj、o_proj - Feed-Forward 层:对于 MoE 或大型 FFN 层,可考虑
gate_proj、up_proj、down_proj - 嵌入层:对于特定任务,可添加
embed_tokens或word_embeddings
秩(Rank)选择指南
| 任务复杂度 | 推荐秩值 | 参数量级 |
|---|---|---|
| 简单分类 | 4-8 | ~100K |
| 标准生成 | 8-16 | ~500K |
| 复杂推理 | 16-64 | ~2M |
| 大规模微调 | 64-128 | ~10M+ |
训练技巧
- 学习率调整:PEFT 模型通常需要比全量微调更高的学习率,建议 1e-3 到 5e-4
- Epoch 数量:由于参数较少,PEFT 通常需要更多 epoch 才能收敛
- 权重衰减:建议对 LoRA 层使用较小的权重衰减(0.01 或 0.0)
- Gradient Clipping:标准设置 max_norm=1.0 适用于大多数场景
相关资源
- 因果语言建模示例:
examples/causal_language_modeling - 条件生成示例:
examples/conditional_generation - 序列分类示例:
examples/sequence_classification - 图像分类示例:
examples/image_classification - SFT 微调示例:
examples/sft - INT8 训练示例:
examples/int8_training - LoRA Dreambooth 示例:
examples/lora_dreambooth
资料来源:[src/peft/peft_model.py:1-100]()
开发者指南与贡献
PEFT(Parameter-Efficient Fine-Tuning)是一个专注于参数高效微调方法的开源库,集成了 Transformers、Diffusers 和 Accelerate 等主流深度学习框架。该项目旨在帮助开发者以最小的计算和存储成本,将大规模预训练模型高效适配到各类下游应用场景。资料来源:README.md
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
PEFT(Parameter-Efficient Fine-Tuning)是一个专注于参数高效微调方法的开源库,集成了 Transformers、Diffusers 和 Accelerate 等主流深度学习框架。该项目旨在帮助开发者以最小的计算和存储成本,将大规模预训练模型高效适配到各类下游应用场景。资料来源:README.md
本页面面向希望深度参与 PEFT 项目开发的贡献者,涵盖自定义 Tuner 实现、模型集成、低级 API 使用、问题排查以及贡献流程等核心主题。
架构设计概览
PEFT 采用模块化的 Tuner 架构,每种微调方法(如 LoRA、IA³、OFT 等)都有独立的实现模块。资料来源:src/peft/tuners/tuners_utils.py:1-50
graph TD
A[PeftModel 基类] --> B[TunerMixin]
B --> C[各 Tuner 实现]
C --> D[LoRA]
C --> E[IA³]
C --> F[OFT]
C --> G[HRA]
C --> H[其他 Tuner]
I[BaseTunerLayer] --> J[各 Tuner Layer]
J --> K[LoRALayer]
J --> L[IA³Layer]
J --> M[OFTLayer]
N[PeftConfig] --> O[各配置类]
O --> P[LoraConfig]
O --> Q[IA³Config]
O --> R[OFTConfig]自定义 Tuner 开发
核心组件结构
每个 Tuner 实现需要包含以下核心组件:资料来源:src/peft/tuners/lora/model.py:1-60
| 组件 | 说明 | 必需性 |
|---|---|---|
| Config 类 | 存储 Tuner 特定配置参数 | 必须 |
| Layer 类 | 封装原始层并添加适配逻辑 | 必须 |
| Model 类 | 实现模块替换和适配器注入 | 必须 |
| target_module_mapping | 目标模块名称映射 | 推荐 |
Model 类实现规范
Tuner 的 Model 类必须继承自适当的基类,并实现以下关键方法:资料来源:src/peft/tuners/oft/model.py:1-80
class MyTunerModel(BaseTunerModel):
# 类级别属性
prefix: str = "my_tuner_"
tuner_layer_cls = MyTunerLayer
target_module_mapping = TRANSFORMERS_MODELS_TO_MY_TUNER_TARGET_MODULES_MAPPING
def _create_and_replace(
self,
my_tuner_config,
adapter_name,
target,
target_name,
parent,
current_key,
**optional_kwargs,
):
# 核心替换逻辑
if isinstance(target, Linear):
# 创建或更新适配层
Layer 类实现
Layer 类负责在基础层之上添加适配参数:资料来源:src/peft/tuners/ia3/model.py:1-100
| 方法 | 功能 |
|---|---|
__init__ | 初始化适配层参数 |
update_layer | 更新已存在适配层的配置 |
merge | 合并适配权重到基础层 |
unmerge | 从基础层分离适配权重 |
_create_and_replace 方法详解
此方法是 Tuner 替换逻辑的核心,负责将原始模块替换为适配层:资料来源:src/peft/tuners/hra/model.py:80-120
def _create_and_replace(
self,
hra_config,
adapter_name,
target,
target_name,
parent,
current_key,
**optional_kwargs,
):
if current_key is None:
raise ValueError("Current Key shouldn't be `None`")
# 如果不是 HRALayer,创建新模块;否则更新现有层
if not isinstance(target, HRALayer):
new_module = self._create_new_module(hra_config, adapter_name, target, r=hra_config.r)
if adapter_name not in self.active_adapters:
new_module.requires_grad_(False)
self._replace_module(parent, target_name, new_module, target)
else:
target.update_layer(
adapter_name,
r=hra_config.r,
config=hra_config,
)
低级 API 使用
inject_adapter 方法
inject_adapter 方法允许开发者手动将适配器注入到模型中,而不依赖 get_peft_model 封装:资料来源:src/peft/tuners/tuners_utils.py:1-50
| 参数 | 类型 | 说明 |
|---|---|---|
| model | nn.Module | 要注入适配器的模型 |
| adapter_name | str | 适配器名称,默认 "default" |
| autocast_adapter_dtype | bool | 是否自动转换适配器数据类型 |
| low_cpu_mem_usage | bool | 是否在 meta 设备上创建空权重以加速加载 |
| state_dict | dict | 可选的预加载权重字典 |
merge_and_unload 操作
合并操作将适配器权重与基础模型融合:资料来源:src/peft/tuners/tuners_utils.py:1-30
# 合并并卸载适配器
merged_model = peft_model.merge_and_unload(progressbar=True, safe_merge=False)
# 仅卸载而不合并
base_model = peft_model.unload()
Helper 函数
helpers.py 模块提供了多个实用函数用于签名更新和模型检查:资料来源:src/peft/helpers.py:1-100
| 函数 | 功能 |
|---|---|
update_forward_signature | 更新 PeftModel 的 forward 签名以包含父类参数 |
update_generate_signature | 更新 PeftModel 的 generate 签名 |
check_if_peft_model | 检查模型是否为 PEFT 模型 |
rescale_adapter_scale | 临时调整适配器缩放因子的上下文管理器 |
适配器生命周期管理
graph LR
A[加载基础模型] --> B[创建 PeftConfig]
B --> C[get_peft_model 或 inject_adapter]
C --> D[创建适配层]
D --> E[训练适配器]
E --> F[merge_and_unload 或保存]
F --> G[卸载适配器]贡献流程
提交 Pull Request 规范
- Fork 仓库并创建功能分支
- 确保代码通过所有现有测试
- 为新功能添加测试用例
- 更新相关文档
- 提交 PR 并描述变更内容
代码风格要求
- 遵循 PEP 8 代码规范
- 为公共 API 添加完整的类型注解
- 为复杂逻辑编写文档字符串
- 确保提交信息清晰描述变更内容
新 Tuner 贡献检查清单
添加新的 Tuner 实现时,需确保完成以下内容:资料来源:CONTRIBUTING.md
| 检查项 | 说明 |
|---|---|
| Config 类 | 实现完整的配置验证逻辑 |
| Layer 类 | 实现权重初始化、更新和合并方法 |
| Model 类 | 实现模块替换逻辑 |
| 测试用例 | 覆盖核心功能和边界情况 |
| 文档示例 | 提供完整的使用示例代码 |
| 目标模块映射 | 定义支持的模型架构和层名称 |
常见问题排查
模块兼容性检查
某些特定架构(如 Mamba)存在不兼容的模块,PEFT 提供了专门的检查机制:资料来源:src/peft/tuners/tuners_utils.py:1-50
def _check_target_module_compatiblity(self, peft_config, model, target_name):
"""防止将 LoRA 应用于不兼容的模块"""
_check_lora_target_modules_mamba(peft_config, model, target_name)
适配器状态管理
| 问题 | 解决方案 |
|---|---|
| 适配器未激活 | 使用 set_adapter 方法切换活动适配器 |
| 权重未更新 | 检查 active_peft_config 配置 |
| 合并失败 | 确认基础模型支持合并操作 |
内存优化建议
| 策略 | 适用场景 |
|---|---|
low_cpu_mem_usage=True | 大模型加载阶段 |
| 4-bit/8-bit 量化 | 显存受限环境 |
| 梯度检查点 | 长序列训练 |
集成最佳实践
与 Transformers 集成
PEFT 与 Transformers 库深度集成,支持直接使用 AutoModelForX 系列接口:资料来源:src/peft/peft_model.py:1-100
from transformers import AutoModelForSequenceClassification
from peft import PeftModelForSequenceClassification, get_peft_config
model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased")
peft_model = PeftModelForSequenceClassification(model, peft_config)
peft_model.print_trainable_parameters()
与 Diffusers 集成
对于 Stable Diffusion 等扩散模型,PEFT 提供专门的适配接口:资料来源:src/peft/tuners/oft/model.py:1-60
from diffusers import StableDiffusionPipeline
from peft import OFTModel
model = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
model.text_encoder = OFTModel(model.text_encoder, config_te, "default")
model.unet = OFTModel(model.unet, config_unet, "default")
扩展阅读
来源:https://github.com/huggingface/peft / 项目说明书
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
可能增加新用户试用和生产接入成本。
可能影响授权、密钥配置或安全边界。
可能增加新用户试用和生产接入成本。
可能影响升级、迁移或版本选择。
Pitfall Log / 踩坑日志
项目:huggingface/peft
摘要:发现 18 个潜在踩坑项,其中 2 个为 high/blocking;最高优先级:配置坑 - 来源证据:[BUG] peft 0.19 target_modules (str) use set。
1. 配置坑 · 来源证据:[BUG] peft 0.19 target_modules (str) use `set`
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:[BUG] peft 0.19 target_modules (str) use
set - 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_bd098228d56f4251949a351ac90335fc | https://github.com/huggingface/peft/issues/3229 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
2. 安全/权限坑 · 来源证据:Comparison of Different Fine-Tuning Techniques for Conversational AI
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Comparison of Different Fine-Tuning Techniques for Conversational AI
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_408252d26b4a4d87b9ca9362c3b4b37b | https://github.com/huggingface/peft/issues/2310 | 来源类型 github_issue 暴露的待验证使用条件。
3. 安装坑 · 来源证据:Feature Request: Improve offline support for custom architectures in get_peft_model_state_dict
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Feature Request: Improve offline support for custom architectures in get_peft_model_state_dict
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_32e0990aa35b430bac525df543e75cac | https://github.com/huggingface/peft/issues/3211 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
4. 配置坑 · 来源证据:0.17.0: SHiRA, MiSS, LoRA for MoE, and more
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:0.17.0: SHiRA, MiSS, LoRA for MoE, and more
- 对用户的影响:可能影响升级、迁移或版本选择。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_a7ec4779d09a4fcebe0901d73f869bf0 | https://github.com/huggingface/peft/releases/tag/v0.17.0 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
5. 配置坑 · 来源证据:Applying Dora to o_proj of Meta-Llama-3.1-8B results in NaN
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个配置相关的待验证问题:Applying Dora to o_proj of Meta-Llama-3.1-8B results in NaN
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_ce144c340d9f40929a6551e9dbca770d | https://github.com/huggingface/peft/issues/2049 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
6. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 建议检查:将假设转成下游验证清单。
- 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
- 证据:capability.assumptions | github_repo:570384908 | https://github.com/huggingface/peft | README/documentation is current enough for a first validation pass.
7. 运行坑 · 来源证据:0.17.1
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个运行相关的待验证问题:0.17.1
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_cd675dc497c44319af556a2e7059dd95 | https://github.com/huggingface/peft/releases/tag/v0.17.1 | 来源类型 github_release 暴露的待验证使用条件。
8. 运行坑 · 来源证据:v0.15.1
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个运行相关的待验证问题:v0.15.1
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_66bfe8be731a44de971b991569f61e57 | https://github.com/huggingface/peft/releases/tag/v0.15.1 | 来源类型 github_release 暴露的待验证使用条件。
9. 运行坑 · 来源证据:v0.15.2
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个运行相关的待验证问题:v0.15.2
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_3d5933ee300d4f68bfab2f0440fae679 | https://github.com/huggingface/peft/releases/tag/v0.15.2 | 来源类型 github_release 暴露的待验证使用条件。
10. 维护坑 · 来源证据:0.16.0: LoRA-FA, RandLoRA, C³A, and much more
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题:0.16.0: LoRA-FA, RandLoRA, C³A, and much more
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_5ef66863f7c64b3e9e3ba6a72eaab639 | https://github.com/huggingface/peft/releases/tag/v0.16.0 | 来源类型 github_release 暴露的待验证使用条件。
11. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
- 证据:evidence.maintainer_signals | github_repo:570384908 | https://github.com/huggingface/peft | last_activity_observed missing
12. 安全/权限坑 · 下游验证发现风险项
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:下游已经要求复核,不能在页面中弱化。
- 建议检查:进入安全/权限治理复核队列。
- 防护动作:下游风险存在时必须保持 review/recommendation 降级。
- 证据:downstream_validation.risk_items | github_repo:570384908 | https://github.com/huggingface/peft | no_demo; severity=medium
13. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 建议检查:把风险写入边界卡,并确认是否需要人工复核。
- 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
- 证据:risks.scoring_risks | github_repo:570384908 | https://github.com/huggingface/peft | no_demo; severity=medium
14. 安全/权限坑 · 来源证据:0.18.0: RoAd, ALoRA, Arrow, WaveFT, DeLoRA, OSF, and more
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:0.18.0: RoAd, ALoRA, Arrow, WaveFT, DeLoRA, OSF, and more
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_b28315fbb2d44b748ca46f87fafd3d33 | https://github.com/huggingface/peft/releases/tag/v0.18.0 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
15. 安全/权限坑 · 来源证据:v0.15.0
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:v0.15.0
- 对用户的影响:可能影响升级、迁移或版本选择。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_1a3ce413d14349658dc005c25754bb1f | https://github.com/huggingface/peft/releases/tag/v0.15.0 | 来源类型 github_release 暴露的待验证使用条件。
16. 安全/权限坑 · 来源证据:v0.19.0
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:v0.19.0
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_abcf15a2812744f0a37ad5c5d75643cf | https://github.com/huggingface/peft/releases/tag/v0.19.0 | 来源类型 github_release 暴露的待验证使用条件。
17. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
- 防护动作:issue/PR 响应未知时,必须提示维护风险。
- 证据:evidence.maintainer_signals | github_repo:570384908 | https://github.com/huggingface/peft | issue_or_pr_quality=unknown
18. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
- 证据:evidence.maintainer_signals | github_repo:570384908 | https://github.com/huggingface/peft | release_recency=unknown
来源:Doramagic 发现、验证与编译记录