当前位置: 首页 > news >正文

云服务器上基于lora微调Qwen2.5-VL-7b-Instruct模型之Lora微调代码讲解


在之前的项目在云服务器上基于lora微调Qwen2.5-VL-7b-Instruct模型的train.py文件中,配置Lora的代码如下。下面对它进行讲解:

完整代码回顾

config = LoraConfig(task_type=TaskType.CAUSAL_LM,target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],inference_mode=False,  # 训练模式r=64,                # Lora 秩lora_alpha=16,       # Lora alphalora_dropout=0.05,   # Dropout 比例bias="none",
)

这是一段使用 peft 库(Parameter-Efficient Fine-Tuning)创建 LoRA(Low-Rank Adaptation) 微调配置的代码。它的作用是:告诉模型“我要在哪些模块上添加可训练的小型低秩矩阵”,从而实现 高效、节省显存的微调


一、什么是 LoRA?(背景知识)

原理简述:

传统全参数微调(Full Fine-tuning)要更新所有 70 亿参数,显存消耗极大。

LoRA 的核心思想是

❝ 不直接修改原始权重 WWW,而是引入一个低秩分解的增量 ΔW=A⋅B\Delta W = A \cdot BΔW=AB,只训练 AAABBB

数学表达:
输出=x⋅(W+ΔW)=x⋅W+x⋅(A⋅B)\text{输出} = x \cdot (W + \Delta W) = x \cdot W + x \cdot (A \cdot B) 输出=x(W+ΔW)=xW+x(AB)

其中:

  • WWW: 原始冻结的大矩阵(如 attention 中的 q_proj)
  • A∈Rd×r,B∈Rr×kA \in \mathbb{R}^{d \times r}, B \in \mathbb{R}^{r \times k}ARd×r,BRr×k:两个小矩阵,r≪dr \ll drd
  • rrr 就是 r=64,称为 LoRA 秩(rank)

优势:

  • 显存节省 70%+
  • 训练速度快
  • 可以保存多个 LoRA 适配器,切换任务灵活

二、逐参数详解

1. task_type=TaskType.CAUSAL_LM

task_type=TaskType.CAUSAL_LM
含义:

指明当前任务类型是 因果语言建模(Causal Language Modeling),也就是典型的自回归生成任务:

给定前面的词,预测下一个词(比如 GPT、Qwen 都属于这类)

为什么选这个?

因为 Qwen 是一个 decoder-only 的大模型,做的是文本生成任务(图像描述生成),所以属于 CAUSAL_LM

其他常见选项:
类型用途
SEQ_CLS文本分类
TOKEN_CLS命名实体识别等 token 级任务
QUESTION_ANS问答任务

对于多模态生成任务(图文对话),仍然是 CAUSAL_LM,因为最终输出是自回归文本。


2. target_modules=[...]

target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]
含义:

指定要在哪些模块上添加 LoRA 适配层。

这些名字对应 Transformer 中的关键线性层:

模块所属结构功能
q_proj, k_proj, v_projSelf-AttentionQuery, Key, Value 投影
o_projSelf-AttentionOutput 投影
gate_proj, up_proj, down_projMLP/Feed-ForwardQwen 使用 GLU 结构(门控线性单元),所以有 gate 和 up/down

🔍 Qwen 系列模型使用的是 SwiGLU 激活函数 的 FFN 层,结构如下:

FFN(x)=down_proj(Swish(gate_proj(x))⊗up_proj(x))\text{FFN}(x) = \text{down\_proj}(\text{Swish}(\text{gate\_proj}(x)) \otimes \text{up\_proj}(x)) FFN(x)=down_proj(Swish(gate_proj(x))up_proj(x))

所以这三个都需要加 LoRA 才能有效微调。

为什么选这些?

实验证明:在 注意力层(QKV)FFN 层(up/gate/down) 添加 LoRA,能覆盖模型最主要的参数流动路径,效果最好。

如何知道该写哪些模块?

可以打印模型结构查看:

print(model)
# 或
for name, module in model.named_modules():if "dense" in name or "proj" in name:print(name)

也可以让 PEFT 自动检测目标模块(但不推荐用于大模型):

from peft import LoraConfig, get_peft_modelconfig = LoraConfig(task_type=TaskType.CAUSAL_LM,# target_modules="all-linear",  # 自动选择所有线性层(慎用!太重)...
)

注意:不要设为 "all-linear",否则会把 embedding、layernorm 也都加上 LoRA,浪费资源且可能不稳定。


3. inference_mode=False

inference_mode=False  # 表示当前是训练模式
含义:
  • False:训练模式 → 创建可训练的 LoRA 参数(A 和 B)
  • True:推理模式 → 不创建新参数,只加载已有的 LoRA 权重
什么时候用 True?

在测试阶段加载 .bin 权重时使用,例如你后面的代码:

val_peft_model = PeftModel.from_pretrained(model, "./output/checkpoint-124", config=val_config)

那时就可以设为 inference_mode=True,因为不需要再训练了。


4. r=64(LoRA 秩)

r=64
含义:

LoRA 矩阵分解的秩(rank),即中间维度大小。

比如原始 q_proj[4096 -> 4096],LoRA 添加两个小矩阵:

  • AAA: [4096 x 64]
  • BBB: [64 x 4096]

总参数量从 40962≈16.7M4096^2 ≈ 16.7M4096216.7M4096×64×2≈0.52M4096×64×2 ≈ 0.52M4096×64×20.52M,减少约 97%

如何选择 r
r 值特点推荐场景
8~16参数少、速度快、显存低快速实验、小数据集
32~64性能较好,平衡点多数情况下推荐
128+接近全量微调效果数据量大、追求 SOTA

Qwen 官方建议:r=64 或 r=128 效果较好。

r=64 是一个非常合理的选择,在性能和效率之间取得良好平衡。


5. lora_alpha=16

lora_alpha=16
含义:

LoRA 中的缩放系数 α\alphaα。最终的增量是:
ΔW=αr⋅A⋅B\Delta W = \frac{\alpha}{r} \cdot A \cdot B ΔW=rαAB

这相当于一个“学习权重的权重”。

为什么需要 alpha?
  • 控制 LoRA 更新的强度
  • r 很小时,ΔW\Delta WΔW 可能太弱,用 alpha 放大它
  • 通常保持 alpha / r 比值恒定(比如 16/64 = 0.25)
推荐设置:
ralphaalpha/r
8162.0 ❌ 太强
32321.0 ✅ 常见
64160.25 ✅ 保守
64320.5 ✅ 平衡
64641.0 ✅ 强

设置:r=64, alpha=16 → 缩放因子 = 16/64 = 0.25,属于 较保守 设置,适合防止过拟合,尤其在小数据集上更稳定。

如果发现模型学得慢或欠拟合,可以尝试调高 alpha(如 32 或 64)。


6. lora_dropout=0.05

lora_dropout=0.05
含义:

在 LoRA 的 A 矩阵输出上应用 dropout,防止过拟合。

  • 0.05 表示 5% 的概率随机丢弃 LoRA 的更新信号
  • 在训练时启用,推理时自动关闭
为什么加 dropout?

虽然 LoRA 参数很少,但在小数据集上仍可能过拟合。加入轻量 dropout 可提高泛化能力。

推荐值:
  • 小数据集(<1k 样本):0.1 ~ 0.3
  • 中等数据集(1k~10k):0.05 ~ 0.1
  • 大数据集(>10k):0.0 ~ 0.05

设置 0.05 是标准做法,很合理。


7. bias="none"

bias="none"
含义:

是否对 LoRA 中的 bias 参数进行微调。

选项:

  • "none":不训练任何 bias(最常用)
  • "all":训练所有 bias
  • "lora_only":只训练 LoRA 层内部的 bias
为什么选 "none"
  • 偏置项本身参数量小
  • 微调 bias 效果不明显,反而增加复杂度
  • 多数论文和实践中都设为 "none"

最佳实践就是 bias="none",无需改动。


三、总结:你的配置为何合理?

参数当前值是否合理原因
task_typeCAUSAL_LM对应生成任务
target_modulesQ/K/V/O + Gate/Up/Down覆盖主要模块,适配 Qwen 结构
inference_modeFalse训练模式正确
r64平衡性能与效率
lora_alpha16⚠️ 偏保守缩放系数 0.25,可尝试 32 提速
lora_dropout0.05小幅正则化,防过拟合
bias"none"标准做法

四、常见问题与优化建议

Q1: 我能不能只微调 attention 层?(去掉 gate/up/down)

可以,但效果通常较差。
因为 Qwen 的 FFN 层(尤其是 SwiGLU)也承载了大量语义信息,必须微调。

建议:保留全部 target_modules


Q2: r=64 太大了,显存不够怎么办?

你可以尝试:

  • 降为 r=32r=16
  • 减少 target_modules(比如只保留 q_proj, v_proj
  • 使用 gradient_checkpointing=True(你已开启)

Q3: 如何选择最优的 r 和 alpha?

可以用 消融实验(ablation study):

实验编号ralpha结果(BLEU/训练速度/显存)
Exp11616快但欠拟合
Exp23232平衡
Exp36432效果最好 ✅

推荐优先试 r=64, alpha=32(缩放比 0.5),比你当前更强一点。


Q4: 为什么不用 IA³ 或 Adapter?

因为 LoRA 是目前最成熟、兼容性最好、性能最强的 PEFT 方法,尤其适合大模型。
Qwen 官方也推荐使用 LoRA。

http://www.dtcms.com/a/304615.html

相关文章:

  • Netty中InternalThreadLocalMap的作用
  • Rust实现GPU驱动的2D渲染引擎
  • Vue3 学习教程,从入门到精通, Vue3 自定义指令语法知识点及案例(20)
  • c++ nlohmann/json读写json文件
  • JavaWeb学习打卡18(JDBC案例详解)
  • ansible 使用更高版本的python版本
  • Python中的决策树机器学习模型简要介绍和代码示例(基于sklearn)
  • 【牛客网C语言刷题合集】(五)——主要二进制、操作符部分
  • GO 开发环境安装及配置
  • Claude Code 使用教程(对接智谱模型)
  • 84、【OS】【Nuttx】【启动】栈溢出保护:asm 关键字(下)
  • SpringBoot集成Quzrtz实现定时任务
  • 【目标检测】小样本度量学习
  • 记录一个TI DSP编译器的Bug
  • CentOS安装ffmpeg并转码视频为mp4
  • 预过滤环境光贴图制作教程:第四阶段 - Lambert 无权重预过滤(Stage 3)
  • 预过滤环境光贴图制作教程:第一步 - HDR 转立方体贴图
  • Android Compose 自定义组件完全指南
  • 对College数据进行多模型预测(R语言)
  • 《React与Vue构建TODO应用的深层逻辑》
  • 【lucene】SegmentCoreReaders
  • linux_前台,后台进程
  • LeetCode热题100——155. 最小栈
  • (LeetCode 面试经典 150 题) 150. 逆波兰表达式求值 (栈)
  • 电脑主机显示的python版本是3.8.6,但是我在控制面板没有找到,想删除不知道怎么操作怎么办
  • 《 java 随想录》| LeetCode链表高频考题
  • 【LeetCode】大厂面试算法真题回忆(111)--身高排序
  • 鱼皮项目简易版 RPC 框架开发(五)
  • 2.oracle保姆级安装教程
  • 逐渐走进Ai世界~