PEFT DeLoRA 实战指南:通过解耦角度与幅度实现有界低秩微调
2026/9/20 13:46:44 网站建设 项目流程
  • 人工智能
  • 大模型
  • 微调
  • LoRA

【免费下载链接】peft

🤗 PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.

项目地址:https://gitcode.com/gh_mirrors/pe/peft
点击查看免费下载

DeLoRA(Decoupled Low-Rank Adaptation,解耦低秩自适应)是 PEFT 库中新增的一种参数高效微调方法,其核心思想是在 Frobenius 范数有界(Frobenius-norm bounded)的设置下进行微调,通过对低秩矩阵 BA 进行归一化、引入可学习的缩放因子 λ、以及按层对原始权重范数 ‖W‖ 进行缩放,从而将"更新方向(角度)"与"更新强度(幅度)"的学习解耦,防止模型偏离预训练权重过远。本文以 examples/delora_finetuning/README.md 为主体,结合 DeloraConfig 源码、DeloraLayer 实现 与完整可运行的 delora_finetuning.py 示例脚本,从原理、API、训练、推理到调参实践,为你提供一份可直接上手的完整指南。

DeLoRA 的动机与核心机制

为什么需要"有界"微调

主流 PEFT 方法(如 LoRA)在超参数选择不恰当或训练轮次过长时,容易出现对超参数敏感、微调后模型偏离预训练分布过远的问题。而 ETHER 等有界方法虽然鲁棒性更好,但仅限于极低秩和固定强度变换,表达力受限。DeLoRA 的出发点正是在两者之间取得平衡:显式约束权重更新的 Frobenius 范数上界,在不牺牲表达力的前提下提升鲁棒性。

三项关键设计

根据原文档,DeLoRA 通过三个步骤实现上述目标(详见 DeloraLayer._compute_delta):

  1. BA 低秩矩阵归一化:对 A 矩阵的行范数与 B 矩阵的列范数进行归一化,从而为权重更新 ΔW 施加 Frobenius 范数边界;
  2. 可学习缩放参数 λ(delora_lambda):控制更新的边界/幅度,替代 LoRA 中的lora_alpha,对每次更新的最大范数设上限;
  3. 按层缩放 ‖W‖(delora_w_norm):在初始化时冻结记录每个被适配层原始权重的逐列范数,将更新幅度适配到原始权重的量级,避免"小范数层被大更新淹没"或反之。

从源码看,前向传播中的 ΔW 计算可以拆解为(对应 layer.py 的 forward 实现):

h = (x * w_norm) @ A.T # 步骤 1:逐输入通道按原始权重范数缩放 scaling = (λ / r) / (‖A_i‖ · ‖B^j‖) # 步骤 2:对角缩放矩阵 diag(λ/r / (‖A_i‖·‖B^j‖)) h = h @ B.T # 步骤 3:投影回输出空间

其中An = clamp(‖A‖行范数, min=1e-4)Bn = clamp(‖B‖列范数, min=1e-4)用于数值稳定性,最终 ΔW = B · diag(λ/r/(‖A_i‖·‖B^j‖)) · A,再乘以冻结的 w_norm。与 LoRA 的固定alpha/r缩放不同,这里的缩放因子随训练中 A、B 的范数动态变化,从而持续约束更新范数。

DeLoRA 与 DoRA 的对比

DoRA 与 DeLoRA 都旨在解耦"角度(方向)"与"幅度(magnitude)"的学习,但存在关键差异(原文档明确说明):

维度DoRADeLoRA
归一化/缩放作用对象全量微调后的权重W + ΔW权重更新ΔW本身
归一化空间权重矩阵的列空间内部的低维空间
防发散效果较弱直接在更新上设界,更好防止偏离预训练模型

简言之,DeLoRA 把边界约束直接加在更新量上,因此对"偏离预训练模型"的抑制更强。

快速开始:在 PEFT 中使用 DeLoRA

最小化训练示例

将标准的LoraConfig替换为DeloraConfig即可。注意:lora_alphadelora_lambda取代,它给权重变化的 Frobenius 范数设置上界。原文档给出的完整示例(训练 + 推理):

import torch from peft import DeloraConfig, get_peft_model from transformers import AutoTokenizer, AutoModelForCausalLM from trl import SFTConfig, SFTTrainer from datasets import load_dataset model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3-8B", dtype=torch.bfloat16, device_map="auto") tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B") tokenizer.pad_token_id = tokenizer.eos_token_id delora_config = DeloraConfig(r=32, delora_lambda=15) peft_model = get_peft_model(model, delora_config) peft_model.print_trainable_parameters() dataset = load_dataset("imdb", split="train[:1%]") training_args = SFTConfig(dataset_text_field="text", max_length=128) trainer = SFTTrainer( model=peft_model, args=training_args, train_dataset=dataset, processing_class=tokenizer, ) trainer.train() peft_model.save_pretrained("delora-llama-3-8b")

加载微调后的 DeLoRA 模块

微调产物与 LoRA 完全兼容同一套 PEFT 加载机制:

import torch from peft import PeftModel from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained( "meta-llama/Meta-Llama-3-8B", dtype=torch.bfloat16, device_map="auto" ) peft_model = PeftModel.from_pretrained(model, "delora-llama-3-8b")

保存的权重包含delora_Adelora_Bdelora_lambda以及持久化的delora_w_normbuffer(见 DeloraLayer 的参数定义),可直接用于推理或继续训练。

DeloraConfig 参数详解

以下是DeloraConfig的完整参数清单(依据 config.py 源码):

参数类型默认值说明
rint8DeLoRA 适配器的秩,必须是正整数(r <= 0会抛ValueError
delora_lambdaint15边界 λ 的初始值,给权重变化的 Frobenius 范数设上界,防止微调模型偏离原始模型过远
module_dropoutfloat0.0训练中随机禁用 DeLoRA 模块的丢弃概率(不同于常规 dropout)
target_modulesOptional[Union[list[str], str]]None应用适配器的模块名;传字符串按正则匹配,传列表按精确/后缀匹配;'all-linear'匹配除输出层外所有 linear/Conv1D;不指定时按架构自动选择(未知架构会报错,需手动指定)
exclude_modulesOptional[Union[list[str], str]]None需要排除的模块名,规则同target_modules
biasLiteral["none", "all", "delora_only"]"none"DeLoRA 的偏置训练策略;注意设为all/delora_only后,即使禁用适配器,模型输出也不会与基座模型完全一致
init_weightsboolTrue为 True 时 A 用 kaiming uniform 初始化、B 用零初始化(初始 ΔW=0);为 False 时 A、B 均为 kaiming uniform,立即产生非零增量,一般不建议
layers_to_transformOptional[Union[list[int], int]]None只对指定索引的层施加适配器
layers_patternOptional[Union[list[str], str]]None配合layers_to_transform使用,指向模型的nn.ModuleList(常为'layers''h');指定了layers_pattern却未指定layers_to_transform会报错
rank_patterndict{}按层名/正则指定不同秩,如{'^model.decoder.layers.0.encoder_attn.k_proj': 16}
lambda_patterndict{}按层名/正则指定不同 λ,如{'^model.decoder.layers.0.encoder_attn.k_proj': 16}
modules_to_saveOptional[list[str]]None除适配器层外需要设为可训练并保存的模块(如分类头的classifier/score

另外两点来自源码的约束校验:

  • target_modules传入字符串(正则)时,不能同时使用layers_to_transform,否则抛ValueError(config.py 第 154-155 行);
  • peft_type会被自动设为PeftType.DELORA,与LoraConfig等一同在 PeftConfig 体系 中注册。

当前实现约束

根据 docs/source/package_reference/delora.md 与 model.py 的_create_new_module,DeLoRA 目前有以下限制:

  • 仅支持torch.nn.Linear,其他层类型会抛出TypeError
  • 不支持量化层(如 bitsandbytes 的 4/8 bit 层);
  • 若你的场景不满足上述约束,请改用其他 PEFT 方法(如标准 LoRA)。

使用完整脚本微调 Llama 系模型

仓库提供了开箱即用的命令行训练脚本 examples/delora_finetuning/delora_finetuning.py(基于 randlora 示例脚本改造),内部使用DeloraConfig+transformers.Trainer完成因果语言建模微调。

完整训练命令

原文档给出的完整参数示例:

python delora_finetuning.py \ --base_model "PATH_TO_MODEL" \ --data_path "PATH_TO_DATASET" \ --output_dir "PATH_TO_OUTPUT_DIR" \ --batch_size 1 \ --num_epochs 3 \ --learning_rate 3e-3 \ --cutoff_len 512 \ --val_set_size 500 \ --eval_step 10 \ --save_step 100 \ --device "auto" \ --rank 32 \ --delora_lambda 15 \ --module_dropout 0.1 \ --target_modules "q_proj,v_proj" \ --hub_model_id "YOUR_HF_REPO" \ --push_to_hub

命令行参数与脚本默认值

结合 脚本 argparse 定义,各参数说明如下:

参数默认值说明
--base_modelhuggyllama/llama-7b基座模型路径或 HF 名称
--data_pathtimdettmers/openassistant-guanaco数据集路径或名称
--output_dirpath/to/output微调产物输出目录
--batch_size1每设备批大小
--num_epochs1训练轮数
--learning_rate3e-3学习率
--cutoff_len512分词截断长度
--val_set_size500验证集大小
--eval_step10评估间隔步数
--save_step100保存间隔步数
--deviceauto设备;auto时优先用torch.accelerator.current_accelerator(),否则回退cuda
--rank32DeLoRA 基秩
--delora_lambda640边界 λ 初始值(注意:脚本默认 640,原文档示例用 15,按需调整)
--module_dropout0.05DeLoRA 模块丢弃率
--target_modulesNone逗号分隔的目标模块列表;为 None 时按架构默认映射
--hub_model_idpath/to/repo推送到 HF Hub 的仓库名
--push_to_hubFalse(store_true)是否推送到 HF Hub

脚本内部实现要点

  • 混合精度自动选择:脚本检测当前设备是否支持 bf16(device_module.is_bf16_supported()),支持则用torch.bfloat16,否则回退torch.float32(脚本第 47-50 行);
  • DeLoRA 配置DeloraConfig(r=rank, delora_lambda=delora_lambda, target_modules=..., module_dropout=..., bias="none")(脚本第 59-65 行);
  • 训练参数:warmup 设为总步数的 10%,gradient_accumulation_steps=16weight_decay=0.0save_total_limit=2(脚本第 91-107 行);
  • 保存:无论是否推送 Hub,都会在本地保存模型与 tokenizer(脚本第 129-131 行)。

自定义适配层:target_moduleslambda_pattern

默认情况下(不指定target_modules),DeLoRA 使用与 LoRA 相同的架构映射(见 src/peft/utils/constants.py 第 67-108 行),例如 Llama/Mistral/Qwen 系列默认只适配q_projv_proj。如果需要在更多层上添加适配器(注意会增加显存占用),可以显式指定,例如原文档中的:

python examples/delora_finetuning/delora_finetuning.py \ --base_model meta-llama/Meta-Llama-3-8B \ --target_modules "q_proj,k_proj,v_proj,o_proj"

不同层还可以使用不同的 λ:通过lambda_pattern按层名或正则指定,例如{"^model.decoder.layers.0.encoder_attn.k_proj": 16};源码中通过get_pattern_key对当前层名匹配rank_pattern/lambda_pattern来决定该层实际的rdelora_lambda(见 model.py 的_create_and_replace)。同理可用rank_pattern为不同层设置不同秩。

调参最佳实践

原文档明确给出了两条经验法则:

  1. 使用比标准 LoRA 大 10~100 倍的学习率(典型值在 1e-3、1e-2 量级)。因为 DeLoRA 的更新范数被 λ 显式约束,较大的学习率不会导致更新失控,反而能加快收敛;
  2. λ 的初始值不要设得太小(典型值在 10、15 附近)。λ 是更新范数的上界,设得过小会过度限制表达力,导致欠拟合;同时可以为不同层分配不同的 λ 以获得更精细的控制。

官方文档(delora.md)还补充了超参数鲁棒性的设计目标:由于角度与幅度学习被解耦,DeLoRA 对超参数选择和训练时长的鲁棒性优于 LoRA,官方评估覆盖了主题驱动图像生成、自然语言理解与指令微调等任务。

源码中的实现细节与验证

权重初始化与 λ 的冻结记录

reset_delora_parameters(layer.py 第 128-154 行)完成三件事:

  • init_weights=True时:A 用kaiming_uniform_(a=sqrt(5)),B 用零初始化,保证初始 ΔW = 0(与 LoRA 类似,训练开始时模型行为与基座一致);
  • delora_lambda填充为配置的初始值(一个可学习标量nn.Parameter);
  • torch.no_grad()冻结记录基座权重W的逐列范数到delora_w_norm(meta 张量场景下退化为全 1),该值在训练中不参与梯度更新

合并与解合并

DeloraLinear.merge/unmerge(layer.py 第 173-224 行)支持把适配器权重合入基座权重(safe_merge=True时先复制权重并检查 NaN)。这与 LoRA 的合并语义一致,方便在推理部署时零额外开销地使用微调结果。

多适配器支持

DeloraLayer继承自BaseTunerLayer,支持多适配器并存:delora_Adelora_Bdelora_lambda均为ParameterDict,前向传播时遍历active_adapters累加各适配器输出(layer.py 第 242-262 行);新增非激活适配器时自动requires_grad_(False)(model.py 第 89-91 行)。

测试覆盖

仓库测试对 DeLoRA 有较完整覆盖,可作行为参考:

  • tests/test_initialization.py 第 2801-2827 行:验证init_weights=True/False两种初始化路径;
  • tests/test_custom_models.py 第 1151-1154 行:自定义 MLP 上target_modules的字符串/列表/正则三种写法;
  • tests/regression/test_state_dict.py 第 246 行:DeloraConfig参与 state_dict 回归测试;
  • 同时出现在 tests/test_decoder_models.py、tests/test_encoder_decoder_models.py、tests/test_seq_classifier.py 等模型族测试中,验证其对主流架构的兼容性。

引用

DeLoRA 论文(ICLR 2025):

@inproceedings{bini2025decouplinganglesstrengthlowrank, title={Decoupling Angles and Strength in Low-rank Adaptation}, author={Massimo Bini and Leander Girrbach and Zeynep Akata}, year={2025}, booktitle={International Conference on Learning Representations (ICLR)}, }

更多 API 细节可查阅 docs/source/package_reference/delora.md(含论文摘要与DeloraConfig/DeloraModel的 autodoc)。

  • 人工智能
  • 大模型
  • 微调
  • LoRA

【免费下载链接】peft

🤗 PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.

项目地址:https://gitcode.com/gh_mirrors/pe/peft
点击查看免费下载

相关推荐

上一篇:FreeAskInternet:如何打造完全免费且保护隐私的本地AI搜索助手
下一篇:【亲测免费】 Arduino-HomeKit-ESP8266 开源项目教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询