LoRA 的核心思想非常巧妙,它通过引入“可训练的低秩矩阵”来微调大型预训练模型,而不是直接修改原始模型庞大的权重,这使得微调过程更加高效、灵活,并且能够轻松地在不同任务间切换。

要理解 LoRA 的参数,我们首先需要明白它的工作原理。
LoRA 工作原理简介
想象一下,你有一个巨大的预训练模型,它的权重矩阵非常大(一个 4096x4096 的矩阵),传统的微调方法会直接修改这个巨大的矩阵,计算成本和存储开销都非常高。
LoRA 的做法是:
- 冻结原始权重:预训练模型的巨大权重矩阵
W被冻结,不再参与训练。 - 注入低秩适配器:在冻结的权重
W旁边,插入一个小的“适配器”结构,这个结构由两个小的矩阵A和B组成。 - 前向传播计算:模型的输出不再是
y = Wx,而是y = Wx + BAx。Wx是预训练模型的原始输出。BAx是 LoRA 适配器新增的输出。A是一个r x d的矩阵,B是一个d x r的矩阵。r是一个远小于d的数(即低秩)。
- 只训练 A 和 B:在微调过程中,我们只训练这两个小矩阵
A和B,原始的W保持不变。
关键点:通过数学证明,当 r 足够大时,矩阵对 BA 可以很好地近似原始权重矩阵的更新量 ΔW,我们不需要存储整个巨大的 ΔW,只需要存储两个小矩阵 A 和 B,极大地减少了参数量和存储需求。

核心 LoRA 参数详解
LoRA 的性能和效率主要由以下几个核心参数决定:
r (Rank / 秩)
这是 LoRA 中最重要的参数,它定义了低秩矩阵的“维度”或“容量”。
- 定义:
r是矩阵A(维度r x d) 的行数,也是矩阵B(维度d x r) 的列数。d是原始权重矩阵W的维度(4096)。 - 作用:
- 表达能力:
r越大,BA矩阵能表达的“更新量”就越复杂,模型的表达能力越强,理论上能更好地拟合目标任务。 - 参数量:
r直接决定了 LoRA 的参数量,LoRA 的参数量约为2 * r * d(A和B的参数总和),与原始微调需要存储d * d的ΔW相比,当r << d时,参数量会急剧减少。 - 计算开销:
r越大,前向传播中BAx的计算量也越大。
- 表达能力:
- 经验值:
- 较小的
r(如 4, 8, 16) 适用于简单的任务或资源受限的场景。 - 中等
r(如 32, 64) 是一个很好的起点,在性能和效率之间取得了平衡。 - 较大的
r(如 128, 256) 适用于非常复杂的任务,但会逐渐接近全参数微调的效果和成本。
- 较小的
- 推荐:
r是第一个需要调整的超参数,通常从r=8或r=16开始尝试。
alpha (缩放因子 / Alpha)
alpha 是一个用于缩放 LoRA 更新强度的参数。
- 定义:在前向传播中,LoRA 的输出被缩放为
y = Wx + (alpha / r) * BAx。 - 作用:
- 控制更新幅度:
alpha的作用是平衡原始预训练知识 (Wx) 和新知识 (BAx) 之间的权重,较大的alpha会让 LoRA 的更新更“激进”,模型更容易偏离原始知识;较小的alpha则让更新更“保守”,模型更倾向于保留原始知识。 - 稳定训练:它有助于稳定训练过程,因为
BA矩阵的初始值通常较小,直接相加可能影响不大。alpha/r的形式可以确保无论r如何变化,LoRA 更新的整体强度都能被有效控制。
- 控制更新幅度:
- 与
r的关系:alpha通常与r成正比设置,一个常见的经验法则是alpha = 2 * r或alpha = r,这种设置方式可以保证在r增加时,LoRA 的有效更新强度保持相对稳定。 - 推荐:通常设置为
alpha = 2 * r是一个不错的默认选择。
target_modules (目标模块)
这个参数指定了在模型的哪些层(通常是 Transformer 中的注意力层)上应用 LoRA。

- 定义:可以是一个模块名称的列表(如
["q_proj", "k_proj", "v_proj", "o_proj"])。 - 作用:
- 灵活性:不是所有层都需要微调,通常只对注意力机制的查询、键、值、输出投影层(
q,k,v,o)以及 MLP 层的投影层应用 LoRA 就足够了。 - 效率:只对关键层进行适配,可以进一步减少参数量和计算量。
- 效果:实验表明,对
q和v投影层应用 LoRA 通常就能取得很好的效果。
- 灵活性:不是所有层都需要微调,通常只对注意力机制的查询、键、值、输出投影层(
- 常见目标:
- 注意力层:
q_proj(查询),k_proj(键),v_proj(值),o_proj(输出)。 - MLP层:
gate_proj,up_proj,down_proj。
- 注意力层:
- 推荐:对于大多数任务,在
q_proj和v_proj上应用 LoRA 是一个高效且效果良好的起点。
lora_dropout (LoRA Dropout)
与标准的 Dropout 类似,它在 LoRA 的适配器中引入了正则化。
- 定义:一个介于 0 和 1 之间的浮点数,表示在训练期间以该概率将 LoRA 的输出置零。
- 作用:
- 防止过拟合:LoRA 的参数量虽然小,但仍然可能导致在特定数据集上过拟合,Dropout 通过随机“关闭”一部分神经元,迫使模型学习更鲁棒的特征。
- 提升泛化能力:通常能提升模型在未见过的数据上的表现。
- 推荐:一个较小的值,如
05,1或2,通常就足够了,如果数据集很小或非常嘈杂,可以适当增加。
其他重要相关参数
除了上述核心参数,还有一些与 LoRA 使用和部署相关的参数:
bias (偏置项)
- 定义:指定是否在 LoRA 适配器中学习偏置项。
- 选项:
"none"(默认,不学习偏置),"all"(学习所有偏置),"lora_only"(只学习 LoRA 层的偏置)。 - 推荐:通常使用默认的
"none"即可,因为原始模型的偏置项已经足够好,且不学习偏置可以进一步减少参数。
task_type (任务类型)
- 定义:指定微调任务的类型,库(如
peft)会据此自动配置 LoRA 的某些参数。 - 常见选项:
SEQ_2_SEQ_LM(序列到序列模型,如 T5)CAUSAL_LM(因果语言模型,如 GPT 系列)TOKEN_CLS(文本分类)SEQ_CLS(句子分类)
- 作用:对于
CAUSAL_LM,库会自动将target_modules设置为 GPT 模型的标准层名(如q_proj,v_proj等)。
modules_to_save (需要保存的模块)
- 定义:一个模块名称列表,指定除了 LoRA 适配器之外,还需要和原始模型一起保存的模块。
- 作用:当需要对模型中除 LoRA 层外的其他部分进行微调时使用,你可能想微调模型的嵌入层或分类头,默认情况下,这些模块是冻结的。
参数配置示例 (使用 Hugging Face peft 库)
下面是一个典型的 LoRA 配置示例,用于微调一个像 GPT-2 这样的因果语言模型:
from peft import LoraConfig, get_peft_model
# 假设 model 是一个已经加载好的预训练模型 (如 GPT-2)
# model = AutoModelForCausalLM.from_pretrained("gpt2")
lora_config = LoraConfig(
# --- 核心参数 ---
r=16, # 秩,控制 LoRA 的容量和参数量
lora_alpha=32, # 缩放因子,通常设置为 2 * r
lora_dropout=0.1, # LoRA 层的 Dropout 率,用于正则化
# --- 目标模块 ---
# 指定在哪些层上应用 LoRA
target_modules=[
"q_proj", # 查询投影层
"v_proj", # 值投影层
# "k_proj", # 键投影层
# "o_proj", # 输出投影层
# "c_attn", # 对于某些模型 (如 GPT-Neo), 可能是组合的注意力层
],
# --- 其他参数 ---
bias="none", # 不学习偏置项
task_type="CAUSAL_LM" # 任务类型,自动适配模型结构
)
# 将 LoRA 配置应用到模型
model = get_peft_model(model, lora_config)
# 打印模型,可以看到哪些层被 LoRA 替换了
# print(model)
# 输出类似:
# ...
# (base_model.model.h.0.lora_A): Linear(in_features=768, out_features=16, bias=False)
# (base_model.model.h.0.lora_B): Linear(in_features=16, out_features=768, bias=False)
# ...
参数选择总结与建议
| 参数 | 作用 | 推荐起点 | 如何调整 |
|---|---|---|---|
r (Rank) |
核心,控制 LoRA 的容量和参数量 | 8, 16 |
从小到大尝试,任务越复杂,数据越少,可能需要更大的 r,观察训练损失和验证集性能。 |
alpha |
控制 LoRA 更新的强度 | 2 * r |
固定 r 后调整,如果模型学得太慢/太保守,增大 alpha;如果学得太快/不稳定,减小 alpha。 |
target_modules |
指定在哪些层应用 LoRA | ["q_proj", "v_proj"] |
根据模型架构调整,先尝试关键层(如 q, v),再逐步增加,实验表明,不是所有层都需要。 |
lora_dropout |
防止 LoRA 过拟合 | 1 |
如果模型在验证集上表现不佳(过拟合),可以尝试增加到 2 或 3。 |
bias |
是否学习偏置 | "none" |
默认即可,除非有特殊需求。 |
LoRA 的参数调优是一个在模型性能、训练速度和存储开销**之间寻找最佳平衡点的过程。r 和 alpha 是最关键的调参点,而 target_modules 和 lora_dropout 则提供了进一步的优化空间,从一个小而有效的配置开始,然后根据实验结果逐步调整,是使用 LoRA 的最佳实践。
