尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PEFT 中的 OLoRA 初始化:原理、快速上手与转换为标准 LoRA 的完整实战指南

PEFT 中的 OLoRA 初始化:原理、快速上手与转换为标准 LoRA 的完整实战指南 PEFT 中的 OLoRA 初始化原理、快速上手与转换为标准 LoRA 的完整实战指南【免费下载链接】peft PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.项目地址: https://gitcode.com/gh_mirrors/pe/peft本篇指南聚焦 PEFT 中基于QR 分解的正交低秩适配OLoRA从论文思想与源码实现出发讲解如何通过init_lora_weightsolora一行配置完成初始化覆盖快速训练脚本、量化QLoRA、DDP/CPU 运行以及利用path_initial_model_for_weight_conversion将 OLoRA 适配器无损转换为标准 LoRA 以支持多适配器共存的完整流程。读完你将掌握 OLoRA 的底层原理、可复现的运行参数与迁移避坑要点。引言为什么需要 OLoRAOLoRAOrthonormal Low Rank Adaptation 是针对大语言模型微调的一种新型参数高效初始化方法。与默认 LoRA 实现不同的是OLoRA 通过QR 分解将原始权重矩阵分解为 $\mathbf{Q}$ 与 $\mathbf{R}$ 两部分随后用 $\mathbf{R}$ 的前rank行初始化低秩矩阵 $\mathbf{A}$用 $\mathbf{Q}$ 的前rank列初始化低秩矩阵 $\mathbf{B}$。这种基于正交分解的初始化带来三个直接收益显著更快的收敛速度适配器从残差中继承的信息更接近真实低秩结构训练前期即可快速进入有效更新方向更稳定的训练过程$\mathbf{Q}$ 为正交矩阵天然具备数值稳定性更优的最终性能原始权重中的主导信息被保留在适配器内微调更具表达能力。从源码看PEFT 将 OLoRA 视为LoraConfig.init_lora_weights的一个可选初始化策略与gaussian、pissa、corda、loftq、eva等并列见 src/peft/tuners/lora/config.py 中对各取值语义的完整说明。核心原理QR 分解与权重突变OLoRA 初始化在 src/peft/tuners/lora/layer.py 的olora_init中实现关键步骤如下获取基座层权重W支持float32/float16/bfloat16也支持 bitsandbytes 的 4-bit / 8-bit 量化权重内部先反量化再计算对W执行torch.linalg.qr(W)得到正交矩阵 $\mathbf{Q}$ 与上三角矩阵 $\mathbf{R}$取 $\mathbf{Q}$ 的前r列与 $\mathbf{R}$ 的前r行分别写入lora_B与lora_A注意 PEFT 中lora_A与lora_B的存储方向关键差异从原始权重中扣除适配器乘积即W - scaling * B A使残差权重变为 $W_{res} W - \frac{\alpha}{r} B_0 A_0$这就是文档中强调的OLoRA 会突变mutates原始权重。从数学上可以理解为$W \approx W_{res} A_0 B_0$微调前的模型输出保持不变但信息被重新分配到了适配器中。由于它修改了基座权重PEFT 在 src/peft/peft_model.py 的_check_new_adapter_config中会提示OLoRA changes the base weights of the model and should thus not be used with other adapters即默认情况下不应与其他适配器混用——这正是后文转换为 LoRA场景的动机。快速开始一行配置接入标准 LoRA 流程OLoRA 的最大便利是完全兼容标准 LoRA 训练流程唯一的改动是在LoraConfig中指定init_lora_weightsoloraimport torch from peft import LoraConfig, get_peft_model from transformers import AutoTokenizer, AutoModelForCausalLM from trl import SFTConfig, SFTTrainer from datasets import load_dataset model AutoModelForCausalLM.from_pretrained(facebook/opt-350m, dtypetorch.bfloat16, device_mapauto) tokenizer AutoTokenizer.from_pretrained(facebook/opt-350m) dataset load_dataset(imdb, splittrain[:1%]) lora_config LoraConfig( init_lora_weightsolora ) peft_model get_peft_model(model, lora_config) training_args SFTConfig(dataset_text_fieldtext, max_length128) trainer SFTTrainer( modelpeft_model, train_datasetdataset, processing_classtokenizer, ) trainer.train() peft_model.save_pretrained(olora-opt-350m)除init_lora_weightsolora外无需对常规 LoRA 流程做任何额外改动。训练完成后保存与加载方式和普通 PEFT 模型完全一致from peft import PeftModel model AutoModelForCausalLM.from_pretrained(facebook/opt-350m) tokenizer AutoTokenizer.from_pretrained(facebook/opt-350m) olora_model PeftModel.from_pretrained(model, olora-opt-350m)初始化参数细节init_lora_weights的取值不仅限于布尔值可用的字符串选项来自 src/peft/tuners/lora/config.py包括取值含义True默认微软参考实现的标准初始化lora_B置零训练前适配器为恒等no-opFalseA、B 均随机初始化仅用于调试gaussian高斯初始化按秩缩放适合不支持 OLoRA 的量化模型见下文oloraOLoRA 初始化本文主题pissa/pissa_niter_[n]PiSSA / 快速 SVD PiSSA 初始化corda、loftq、eva、orthogonal、mica对应的数据驱动或 SVD 类初始化值得注意的是源码中对olora的大小写不敏感init_lora_weights.lower() olora测试 tests/test_initialization.py 也验证了OLoRA与olora均可正常工作。训练脚本与命令行参数详解仓库提供了开箱即用的训练脚本 examples/olora_finetuning/olora_finetuning.py基于datasetstransformers.Trainer实现指令微调流程并内置了 OLoRA 支持。直接运行python3 examples/olora_finetuning/olora_finetuning.py --base_model facebook/opt-350m该脚本的全部命令行参数如下与脚本内argparse定义一一对应参数默认值说明--base_modelpath/to/model基座模型名称或本地路径--data_pathyahma/alpaca-cleaned训练数据集Hugging Face Hub 名称--output_dirolora输出目录--batch_size16每设备训练 batch size--num_epochs1训练轮数--learning_rate3e-4学习率--cutoff_len256序列截断长度--val_set_size16验证集大小--quantize关开启 4-bit 量化QLoRA--eval_step100评估间隔--save_step100保存间隔--device_mapauto设备映射策略--lora_r32LoRA 秩--lora_alpha16LoRA alpha--lora_dropout0.05LoRA dropout--lora_target_modulesNone目标模块未指定时按架构自动选择--dtypefloat16模型精度float16/bfloat16/float32等--init_lora_weightsolora初始化方式默认为 OLoRA--seedNone随机种子量化QLoRA支持OLoRA 原生支持 bitsandbytes 量化。使用 4-bit 量化训练python3 examples/olora_finetuning/olora_finetuning.py --base_model facebook/opt-350m --quantize脚本内部在开启--quantize时构造BitsAndBytesConfig(load_in_4bitTrue, bnb_4bit_compute_dtypetorch.bfloat16, bnb_4bit_use_double_quantTrue, bnb_4bit_quant_typenf4)见 examples/olora_finetuning/olora_finetuning.py。也可以直接传入一个已量化好的模型而不必使用--quantize标志。源码层面olora_init会通过get_bnb_param_type检测基座权重类型并对 4-bit / 8-bit 量化参数执行反量化 → QR 分解 → 扣除适配子 → 重新量化回残差的完整链路src/peft/tuners/lora/layer.py保证训练后的残差模型仍以量化形式保存。GPU 测试 tests/test_gpu_examples.py 还验证了OLoRA 初始化能显著降低量化误差将 OLoRA 初始化后的适配器叠加到残差模型上再合并其相对基座模型的误差要小于普通 LoRA 的量化误差测试约定误差至少下降 3%。注意AWQ、GPTQ 等不支持 OLoRA 初始化方法的量化模型请改用高斯初始化见下节。分布式训练与 CPU 运行若要通过accelerate运行 DDP先执行accelerate config配置 DDP 环境然后accelerate launch examples/olora_finetuning/olora_finetuning.py --base_model facebook/opt-350m脚本会在WORLD_SIZE/PMI_SIZE大于 1 且未显式指定device_mapcpu时自动将设备映射设置为{: Accelerator().process_index}以适配 DDP见 examples/olora_finetuning/olora_finetuning.py。如果想在 CPU 上微调请追加--device_map cpupython3 examples/olora_finetuning/olora_finetuning.py --base_model facebook/opt-350m --device_map cpu不支持 OLoRA 的量化模型对 AWQ、GPTQ 这类不支持 OLoRA 初始化方法的量化模型请改用高斯初始化python3 examples/olora_finetuning/olora_finetuning.py --base_model hugging-quants/Meta-Llama-3.1-8B-Instruct-AWQ-INT4 --init_lora_weights gaussian这对应于源码中reset_lora_parameters的gaussian分支lora_A以标准差 $1/r$ 的正态分布初始化、lora_B置零src/peft/tuners/lora/layer.py。将 OLoRA 转换为标准 LoRAOLoRA 会突变基座权重因此默认不推荐与其他适配器混用PEFT 会在加载时给出 warning见 src/peft/peft_model.py。要同时使用多个适配器可以借助save_pretrained的path_initial_model_for_weight_conversion选项把训练好的 OLoRA 适配器无损转换为传统 LoRA。完整模板如下与原文档一致可直接套用base_model AutoModel.from_pretrained(facebook/opt-350m) olora_config LoraConfig( ... init_lora_weightsolora # Initialize the model with OLoRA ) olora_model get_peft_model(base_model, olora_config) init_path path-to-untrained-olora-model olora_model.save_pretrained(init_path) # Save the model *before* performing any training # Train the model train(olora_model) # Your training loop # Save the model after training olora_model.save_pretrained(output_dir, path_initial_model_for_weight_conversioninit_path)关键点训练前先把未训练的 OLoRA 模型保存到init_path它记录初始的 $A_0, B_0$完成训练后在save_pretrained中传入path_initial_model_for_weight_conversioninit_path转换后的模型即可当作普通 LoRA 使用支持多适配器共存。转换的底层数学转换逻辑在 src/peft/tuners/lora/model.py 的subtract_mutated_init中实现核心推导源码 docstring 中原样给出初始化时$W W_{res} A_0 B_0$OLoRA 初始化后残差 适配器恢复原权重训练后$W \Delta W W_{res} A B$推导得到 $\Delta W A B - A_0 B_0 [A \mid A_0] \times [B \mid -B_0]^T$。实现上正是将lora_A与初始lora_A按行拼接、lora_B与负的初始lora_B按列拼接从而构造出等价的标准 LoRA 权重。转换完成后普通PeftModel.from_pretrained即可加载且前向输出与转换前保持一致。转换的约束条件注意若rslora与rank_pattern或alpha_pattern组合使用则不支持此转换。源码在 src/peft/tuners/lora/model.py 中显式抛出ValueErrorif peft_config.use_rslora and (peft_config.rank_pattern or peft_config.alpha_pattern): raise ValueError(...)测试 tests/test_initialization.py 分别验证了use_rsloraTrue搭配rank_pattern或alpha_pattern时调用该转换会抛出异常。与此同时tests/test_initialization.py 中的多个测试确认了以下场景下转换前后输出完全一致torch.allclose通过默认 OLoRA 转换test_olora_conversion_same_output_after_loading带rank_pattern的 OLoRA 转换带alpha_pattern的 OLoRA 转换带use_rsloraTrue的 OLoRA 转换。此外转换时初始适配器的init_lora_weights必须为True否则load_adapter会再次扣除分解值导致数值错误src/peft/tuners/lora/model.py对非 PiSSA/CorDA/OLoRA/LoRA-GA 的配置传入该参数时PEFT 会给出 warning 提示该选项仅用于上述初始化方法。使用建议与注意事项小结适用场景追求更快收敛、更稳定训练和更好下游性能的标准 LoRA 微调/QLoRA 场景仅需在LoraConfig中改一行init_lora_weightsolora。多适配器场景OLoRA 会修改基座权重默认不可与其他适配器混用请先按上文模板转换为标准 LoRA再挂载多个适配器。量化组合bitsandbytes 4-bit/8-bit 模型可直接使用 OLoRA建议配合--quantize或直接传入量化模型AWQ/GPTQ 等模型请改用--init_lora_weights gaussian。转换限制use_rslora与rank_pattern/alpha_pattern组合时不支持转换为 LoRA。分布式与 CPUDDP 请先accelerate config再accelerate launchCPU 微调请追加--device_map cpu。引用本方法时可使用原论文的 BibTeXmisc{büyükakyüz2024olora, title{OLoRA: Orthonormal Low-Rank Adaptation of Large Language Models}, author{Kerim Büyükakyüz}, year{2024}, eprint{2406.01775}, archivePrefix{arXiv}, primaryClass{cs.CL} }【免费下载链接】peft PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.项目地址: https://gitcode.com/gh_mirrors/pe/peft创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表