PEFT documentation
AdaMSS
AdaMSS
AdaMSS(AdaMSS: Adaptive Multi-Subspace Approach for Parameter-Efficient Fine-Tuning)是一种参数高效微调方法,它利用 SVD 对权重矩阵进行分解,并将分解后的空间聚类为多个可训练子空间。每个子空间学习独立的低秩更新,同时原始权重保持冻结。AdaMSS 还支持自适应子空间分配(ASA),该方法基于梯度信息在训练过程中动态剪除重要性较低的子空间。
该论文的摘要如下:
我们提出了 AdaMSS,一种用于大模型参数高效微调的自适应多子空间方法。与传统在单个大型网络权重子空间内运行的参数高效微调方法不同,AdaMSS 利用子空间分割来获取多个较小的子空间,并在训练过程中自适应地减少可训练参数的数量,最终仅更新与目标下游任务最相关的一小部分子空间所关联的参数。通过使用最低秩表示,AdaMSS 实现了更紧凑的表达力和对模型参数更精细的调整。理论分析表明,与 LoRA、PiSSA 以及其他基于单子空间低秩的方法相比,AdaMSS 具有更好的泛化保证。在图像分类、自然语言理解和自然语言生成任务上的大量实验表明,AdaMSS 在大多数情况下达到了与全量微调相当的性能,并优于其他参数高效微调方法,同时所需的可训练参数更少。值得注意的是,在 ViT-Large 模型上,AdaMSS 在七个任务中的平均准确率比 LoRA 高出 4.7%,而使用的可训练参数仅为后者的 15.4%。在 RoBERTa-Large 上,AdaMSS 在六个任务中的平均准确率比 PiSSA 高出 7%,同时将可训练参数数量减少了约 94.4%。这些结果证明了 AdaMSS 在参数高效微调中的有效性。AdaMSS 的代码可在 https: //github.com/jzheng20/AdaMSS 获取。
AdaMSS 目前存在以下限制:
- 仅支持
nn.Linear层。 - KMeans 聚类步骤需要 scikit-learn。
如果这些约束条件不适用于您的使用场景,请考虑采用其他方法。
基准测试概览
API
AdamssConfig
类 peft.AdamssConfig
< source >( task_type: Optional[Union[str, TaskType]] = Nonepeft_type: Optional[Union[str, PeftType]] = Noneauto_mapping: Optional[dict] = Nonepeft_version: Optional[str] = Nonebase_model_name_or_path: Optional[str] = Nonerevision: Optional[str] = Noneinference_mode: bool = Falser: int = 100num_subspaces: int = 5subspace_rank: int = 1target_modules: Optional[Union[list[str], str]] = Noneinit_weights: Optional[Literal['orthogonal']] = 'orthogonal'modules_to_save: Optional[list[str]] = Nonelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = Noneuse_asa: bool = Falseasa_target_subspaces: int = 50init_warmup: int = 50final_warmup: int = 1000mask_interval: int = 100asa_importance_beta: float = 0.85asa_uncertainty_beta: float = 0.85asa_schedule_exponent: float = 3.0use_dynamic_rank: bool = Falsesvd_threshold: float = 0.1random_seed: int = 0 )
参数
- r (
int) — SVD 分解的总秩(论文中记为 R)。它决定了在聚类之前用于表示权重矩阵的奇异向量数量。较高的值能捕获原始权重中更多的信息,但需要更多的计算和内存。较低的值则提供更强的正则化效果。典型取值范围为 50 到 500。默认值为 100。 - num_subspaces (
int) — 用于将 SVD 分解后的空间聚类成的子空间数量 (K)。每个子空间学习独立的低秩更新。增加此值可以实现更细粒度的适应,但可训练参数的数量也会按比例增加。在使用 ASA(自适应子空间分配)时,此值决定了剪枝前的初始子空间数量。典型取值范围为 3 到 10。默认值为 5。 - subspace_rank (
int) — 每个可训练子空间的秩 (r_i)。它控制每个子空间学习适配的容量。较高的值会增加表达能力,但也会增加可训练参数。可训练参数的总量按 O(num_subspaces subspace_rank (in_dim + out_dim) / num_subspaces) 缩放。对于大多数任务,1-4 的值效果良好。默认值为 1。 - target_modules (
Optional[Union[list[str], str]]) — 要应用 AdaMSS 的模块名称。如果指定,则仅这些模块会被适配。可以是精确模块名称的列表,也可以是正则表达式。例如,注意力层使用['q_proj', 'v_proj'],正则匹配使用'.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$'。 - modules_to_save (
Optional[list[str]]) — 除 AdaMSS 层外,需要设置为可训练并在最终检查点中保存的模块列表。这些模块将接受完全微调(而不仅仅是低秩微调)。对于分类任务中随机初始化的头部(如classifier或score),此参数为必需项。 - init_weights (
Literal["orthogonal"]) — AdaMSS 可训练权重的初始化方法。目前仅支持 “orthogonal”,该方法对 B 矩阵(输出投影)使用正交初始化。A 矩阵初始化为零,以确保模型从预训练权重开始。从检查点加载时,将其设置为 None 可跳过初始化。默认值为 “orthogonal”。 - layers_to_transform (
Optional[Union[list[int], int]]) — 要应用 AdaMSS 的特定层索引。如果指定,则仅这些层会被适配,适用于实验哪些层从适配中获益最多。可以是单个整数或整数列表。 - layers_pattern (
Optional[Union[list[str], str]]) — 当指定了layers_to_transform时,用于匹配层名称的模式。用于从不符合常见模式的模块名称中提取层索引。 - use_asa (
bool) — 是否启用自适应子空间分配(Adaptive Subspace Allocation,ASA)。启用后,ASA 会根据梯度信息在训练过程中动态剪枝重要性较低的子空间,在保持性能的同时减少有效参数量。需要与训练回调(training callback)集成使用。默认值为 False。 - asa_target_subspaces (
int) — 启用 ASA 时,所有层中目标激活子空间的总数。ASA 会逐步剪枝子空间,直到达到此目标。值越低,剪枝越激进,可训练参数越少。应小于num_subspaces * num_target_modules。根据模型大小,典型值范围在 20 到 100 之间。默认值为 50。当use_asa=True时,必须为正整数。 - init_warmup (
int) — 开始 ASA 剪枝前需要等待的训练步数。在预热期间,所有子空间保持激活状态,以便重要性分数趋于稳定。较高的值能为准确的重要性估计提供更多时间,但会延迟剪枝。典型值范围为 50 到 200。默认值为 50。当use_asa=True时,必须小于final_warmup。 - final_warmup (
int) — ASA 完成剪枝并达到asa_target_subspaces个活跃子空间的训练步数。剪枝过程分布在init_warmup和final_warmup之间。应根据总训练步数进行设置;通常为总训练步数的 1/3 到 1/2。默认值为 1000。当use_asa=True时,必须大于init_warmup。 - mask_interval (
int) — ASA 掩码更新之间的训练步数。较小的值允许更频繁地适应,但会增加开销。较大的值在更新之间提供更稳定的重要性估计。典型值范围为 50 到 200。默认值为 100。当use_asa=True时,必须为正整数。 - asa_importance_beta (
float) — 用于平滑子空间重要性分数的指数移动平均(EMA)系数。较高的值(接近 1.0)会赋予历史重要性更高的权重,从而提供稳定性。较低的数值会使重要性对近期梯度更加敏感。典型取值范围为 0.8 到 0.95。默认值为 0.85。 - asa_uncertainty_beta (
float) — 用于平滑重要性不确定性估计的 EMA 系数。控制不确定性对梯度方差的适应速度。与 asa_importance_beta 类似,较高的值可提供更稳定的估计。典型取值范围为 0.8 到 0.95。默认值为 0.85。 - asa_schedule_exponent (
float) — 控制 ASA 预热期间从总子空间衰减至asa_target_subspaces速率的调度指数。较高的值会导致更快的初始剪枝(更激进的早期缩减),而较低的值则提供更平缓、类似线性的衰减。公式为:current_active_subspaces = asa_target_subspaces + (asa_total_subspaces - asa_target_subspaces) * (progress ** exponent)。典型取值范围为 1.0(线性)到 5.0(激进)。默认值为 3.0。当use_asa=True时,必须为正数(零或负指数要么使调度退化为永久无效操作,要么在progress恰好达到 0.0 时引发ZeroDivisionError)。 - use_dynamic_rank (
bool) — 是否根据奇异值的大小动态确定子空间秩。当为 True 时,每个子空间的秩通过统计高于阈值的奇异值数量来确定,从而允许不同子空间具有不同的有效秩。当为 False 时,所有子空间均使用固定的subspace_rank。默认值为 False。 - svd_threshold (
float) — 动态秩选择的阈值比例,仅在use_dynamic_rank=True时使用。如果奇异值大于threshold * max_singular_value,则被视为显著。较高的值会导致更低的实际秩(更激进的截断)。典型值范围为 0.05 到 0.2。默认值为 0.1(最大值的 10%)。
Adamss(自适应多子空间)方法的配置类。
AdaMSS 是一种参数高效微调方法,它使用 SVD 分解权重矩阵,并将分解后的空间聚类为多个可训练子空间。它在这些子空间内学习低秩更新,同时保持原始权重冻结。
AdamssModel
类 peft.AdamssModel
< source >( modelconfigadapter_namelow_cpu_mem_usage: bool = Falsestate_dict: Optional[dict] = None ) → torch.nn.Module
从预训练模型创建 Adamss(自适应多子空间)模型。
该方法使用 SVD 分解权重矩阵,并将分解后的空间聚类为多个可训练子空间,以实现参数高效微调。
示例:
>>> from transformers import AutoModelForImageClassification
>>> from peft import AdamssConfig, get_peft_model
>>> config = AdamssConfig(
... r=500,
... num_subspaces=5,
... target_modules=["query", "value"],
... )
>>> model = AutoModelForImageClassification.from_pretrained("google/vit-base-patch16-224")
>>> adamss_model = get_peft_model(model, config)属性:
- model (
~torch.nn.Module) — 要适配的模型。 - peft_config (AdamssConfig): Adamss 模型的配置。
更新重要性分数并应用 ASA 掩码(如果已启用)。
启用 ASA 时,应在 loss.backward() 之后、optimizer.zero_grad() 之前,在 每个 训练步骤中调用此方法。其内部执行以下操作:
- 在预热期间,每个步骤都通过 EMA 累积重要性分数。
- 在掩码间隔处,应用全局 top-K 掩码并重置重要性。
这是 ASA 的唯一入口点 – 在 HuggingFace Trainer 中使用 AdamssAsaCallback 时,只是简单地委托给此方法。对于自定义训练循环,请直接调用此方法,而不是使用回调。