当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > Transformers用LoRA做参数高效微调

Transformers用LoRA做参数高效微调

来源:17golang原创 2026-11-15 12:33:26 0浏览 收藏

全量微调需要为每个模型参数保存梯度和优化器状态,显存与检查点都会迅速变大。Transformers 配合 PEFT 使用 LoRA 时,可以冻结预训练底座,只在指定线性层旁训练低秩适配器;训练结束后保存的是一套轻量权重,而不是再复制一份完整模型。

官方文档:https://huggingface.co/docs/transformers/peft

要点速览
  • r 决定低秩更新的容量,target_modules 决定把适配器挂在哪里。
  • get_peft_model 会把底座改造成带适配器的模型,Trainer 只更新可训练参数。
  • 适配器要和兼容的底座一起加载;是否合并权重取决于部署时是否还要切换适配器。

先把训练边界定清楚:底座冻结,LoRA只改适配器

LoRA 的核心不是缩小原模型,而是在目标模块上增加两个低秩矩阵,用它们表达训练产生的增量。原始权重保持冻结,优化器只跟踪适配器参数,因此训练状态更轻,也便于为同一个底座保存多个领域适配器。

Transformers LoRA 结构说明图:冻结底座、注意力投影和可训练低秩适配器之间的关系
图1:结构说明图,展示冻结底座与 LoRA 适配器的边界关系,不是运行截图或训练结果。
参数作用判断思路
r低秩矩阵的秩越大容量越高,也会增加可训练参数
lora_alpha适配器缩放因子与 rank 一起观察更新幅度,不要脱离任务调参
lora_dropout适配器分支的 dropout小数据集可用来缓和过拟合
target_modules注入适配器的模块名必须匹配具体模型的层命名,不能照抄别的架构

用LoraConfig把训练范围写成代码

先以因果语言模型为例。下面的配置使用常见的 query/value 投影名;实际模型应先查看模块命名,再决定目标模块。get_peft_model 会原地改造模型对象,重复调用前要确认没有再次注入同一适配器。

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, TaskType, get_peft_model

model_id = "facebook/opt-350m"  # 示例底座;生产环境固定可复现的模型版本
tokenizer = AutoTokenizer.from_pretrained(model_id)  # 分词器必须与底座保持一致
model = AutoModelForCausalLM.from_pretrained(model_id)  # 先加载完整但尚未训练的底座

lora_config = LoraConfig(
    r=16,  # 用较小秩控制适配器容量
    lora_alpha=32,  # 控制 LoRA 更新的缩放
    lora_dropout=0.05,  # 小数据集上给适配器分支保留正则化
    target_modules=["q_proj", "v_proj"],  # 只在模型真实存在的投影层注入
    task_type=TaskType.CAUSAL_LM,  # 告诉 PEFT 当前任务是因果语言建模
    bias="none",  # 不额外训练底座 bias,减少更新范围
)

model = get_peft_model(model, lora_config)  # 注入低秩适配器并冻结底座
model.print_trainable_parameters()  # 用参数比例检查配置是否生效

这里最容易出错的是 target_modules。不同架构可能使用不同的投影命名;如果名称不存在,配置并没有覆盖你以为的注意力层。打印可训练参数只是第一层检查,还要在小批量数据上观察 loss 是否能正常下降。

交给Trainer训练,并只保存适配器

带适配器的模型可以像普通 Transformers 模型一样交给 Trainer。由于底座参数的 requires_grad 为关闭状态,Trainer 只会更新 LoRA 分支;检查点通常包含 adapter_model.safetensors 和 adapter_config.json,底座权重仍由部署侧单独提供。

Transformers Trainer 与 LoRA 适配器保存关系说明图:数据集、冻结底座、训练器和适配器检查点的静态关系
图2:关系说明图,展示 Trainer 训练后适配器权重与配置的保存边界,不是运行截图或实际指标。
from transformers import Trainer, TrainingArguments

training_args = TrainingArguments(
    output_dir="./lora-output",  # 只把适配器检查点写入这个目录
    num_train_epochs=3,  # 训练轮数仍需结合数据规模和验证集调整
    per_device_train_batch_size=4,  # 显存不足时先降低单卡 batch
    save_strategy="steps",  # 保留可恢复训练的检查点
    save_steps=200,  # 生产任务应配合磁盘空间设置间隔
)

trainer = Trainer(
    model=model,  # 这里传入的是已经注入 LoRA 的模型
    args=training_args,
    train_dataset=dataset,  # dataset 需提前完成分词和标签整理
)
trainer.train()  # Trainer 只对可训练的适配器参数反向传播
model.save_pretrained("./lora-output/final-adapter")  # 保存最终适配器及配置

加载与合并的选择

恢复时必须使用兼容的底座,再从适配器目录加载参数。保留适配器的好处是可以在同一个底座上切换多个领域版本;只有部署链路不再需要切换、并且希望减少运行时组合逻辑时,才考虑合并权重。合并会改变交付物形态,不能把它当成训练成功的必要步骤。

from transformers import AutoModelForCausalLM
from peft import PeftModel

base = AutoModelForCausalLM.from_pretrained("facebook/opt-350m")  # 先恢复同一底座
model = PeftModel.from_pretrained(base, "./lora-output/final-adapter")  # 再加载适配器

# 只有部署不再切换适配器时才合并;合并后不便于继续管理独立适配器
# merged = model.merge_and_unload()

常见问题

LoRA 的 rank 越大效果一定越好吗?

不一定。rank 增大只代表更新容量和显存开销上升,数据规模、目标模块和训练步数同样影响结果。应从较小配置开始,用验证集比较。

为什么训练后的目录没有完整模型文件?

这是参数高效微调的预期行为。适配器目录记录增量权重和配置,推理时需要先准备对应底座,再加载适配器。

什么时候应该改用 QLoRA?

当底座模型本身难以放入显存时,可以把量化底座与 LoRA 结合,但量化 dtype、训练器和硬件约束需要单独核对,不能只替换一个参数。

判断这套方案是否合适,可以回到三个问题:目标层名称是否真实存在,训练数据是否足以区分领域增量,部署时是否需要同时保留多个适配器。三点都明确后,再调 rank 和缩放,通常比盲目扩大 LoRA 容量更稳。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Transformers streaming逐步输出生成文本Transformers streaming逐步输出生成文本
上一篇
Transformers streaming逐步输出生成文本
Transformers量化模型降低显存占用
下一篇
Transformers量化模型降低显存占用
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    1036次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    1034次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1178次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1139次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    981次使用