偶是大橘子哇
预计阅读时间:8分钟40秒

精通 LoRA:高效的大语言模型微调机制与避免常见陷阱的策略

大语言模型微调系列 · 第二部分:效率的基本原理

0
0

本文属于搬运内容,原作者:Kuriko Iwai


引言

从零开始构建一个语言模型,通常需要依赖大规模计算集群,因为模型包含数量极其庞大的可训练参数。


但在现实世界中,显存(VRAM)是有限资源,并不是每个人都拥有由 A100 组成的计算集群,因此我们需要一种更具“外科手术式精准”的方法


LoRA(Low-Rank Adaptation) 正是为应对这一挑战而提出的:

它只训练模型中极小一部分参数,却能够在不到 1% 的计算成本下,实现与全参数微调(full fine-tuning)几乎相同的性能


本系列的第二部分将深入剖析 LoRA 的核心机制,同时重点讨论在配置与实现过程中常见的陷阱,以及如何有效避免这些问题。


什么是 LoRA

低秩适配(Low-Rank Adaptation,LoRA) 是一种微调技术:

它并不更新模型中的全部参数,而是在 Transformer 的稠密层(dense layers)中,引入并优化低秩分解矩阵

LoRA 最早由 Hu 等人 提出 [1],如今已成为**参数高效微调(Parameter-Efficient Fine-Tuning,PEFT)**方法中的核心技术之一,用于将大语言模型适配到具体的下游任务。


下图展示了 LoRA 如何应用于一个标准的仅解码器(decoder-only)Transformer 中,并以 Qwen-3–1.7B 模型为例说明其参数构成:

image.png


图 A:仅解码器 Transformer 架构,以及 Qwen-3–1.7B 模型与其 LoRA 适配器的参数分布(制图:Kuriko Iwai)

图 A 显示,该模型在整个架构中共包含 17 亿(1.7B)个参数

为了说明 LoRA 的工作机制,我们首先需要考察模型的参数分配方式


1. 词表与输入嵌入层(Vocabulary & Input Embedding Layer)

模型首先将原始文本转换为输入嵌入(input embedding)

这一过程依赖一个巨大的查找表(lookup table),其中词表中的每一个 token(单词或子词)都被分配到一个唯一的向量(图 A 中的绿色区域)。

举例来说,假设 token “cat” 被分配的 Token ID 为 1

那么这个 ID 会指向一个由若干小数构成的向量,其数值通常分布在 –1 到 1 之间,例如:

image.png


这些数值共同表示该 token 在模型**隐藏空间(hidden dimensions)**中的语义信息。


由于 Qwen-3–1.7B 模型的隐藏维度为 2,048,因此每个 token 需要用 2,048 个数值来表示


在词表规模为 151,936 的情况下,这个查找表就形成了一个 151,936 行 × 2,048 列 的矩阵:

image.png


表 1:Qwen-3–1.7B 的词表矩阵示意(制图:Kuriko Iwai)

为了存储这个词表嵌入矩阵,模型需要分配大约 3.11 亿(311M)个参数

image.png


值得注意的是,这个矩阵在模型最终解码阶段会被重复使用(图 A 中的 Linear 层),用于将模型内部的数值计算结果重新映射回人类可读的文本


2. 核心引擎 — Transformer 块

在将**位置编码(positional encodings)**加入嵌入向量后,数据会传入 Transformer 块(图 A 中粉色框),这是模型的核心计算引擎。


这些块中的参数分布如下:

  • 注意力层(Attention layers,图 A 橙色框):每层约 1,250 万(12.5M)参数
  • 前馈层(Feed-Forward layers,图 A 蓝色框):每层约 3,380 万(33.8M)参数

由于 Qwen-3–1.7B 共有 28 层堆叠

  • 注意力层总参数:

image.png


  • 前馈层总参数:

image.png


3. 最终参数总数

在得到最终预测结果时,模型会使用词表中的 3.11 亿参数进行线性变换(Linear layer),然后通过 Softmax 将结果归一化为概率分布(图 A 灰色框)。


把所有层的小参数加起来,模型总共需要 17 亿(1.7B)参数

image.png


**全量微调(Full fine-tuning)**意味着训练这 17 亿参数,这对 VRAM 和数据样本量都有极高要求,否则容易过拟合。


开发者笔记

首个 Transformer(论文 “Attention is All You Need”)提出了隐藏维度(hidden dimension)的理想规模:

  • 小型模型(Small Models):512 或 768
  • 中型模型(Medium Models,例如 Qwen):1,024 或 2,048
  • 大型模型(Large Models,例如 Llama):4,096
  • 超大型模型(Giant Models,例如 GPT-3):12,288


Qwen-3 为例,要达到 17 亿参数,需要在 **隐藏维度(知识存储能力)层数(计算能力)**之间取得平衡。

  • 如果模型太“宽”,例如 8,192 维,只能堆叠 3 层。这种模型虽然能理解输入,但生成响应时思考深度不足。
  • 如果模型太“窄”,例如 128 维,可以堆叠 500+ 层,但处理单个词的能力不足。

最终,28 层 × 2,048 维 的组合是最优的:既能存储和处理较复杂的概念,又不会让模型在普通显存(consumer VRAM)上运行过慢。


LoRA 的工作原理 — 核心机制

LoRA 通过数学捷径(low-rank decomposition,低秩分解),在**Transformer 核心块(粉色框)**上进行微调,从而大幅优化训练效率。


低秩分解(Low-Rank Decomposition)

低秩分解是线性代数中的一个数学理论:一个大矩阵可以被近似表示为两个小矩阵的乘积

它基于 秩分解(rank factorization) 理论:任意非零向量 Z 都可以表示为两个满秩矩阵 X 和 Y 的乘积:

image.png


在标准微调的上下文中,ZZZ 代表权重更新矩阵,其大小与原始模型权重相同(例如 Qwen-3–1.7B 为 2,048 × 2,048)。

对于大型模型,权重矩阵巨大,存储和计算 X 与 Y 代价极高


LoRA 的方法

LoRA 通过低秩分解绕过这一瓶颈:

image.png


在这种方法中,低秩矩阵 A 和 B 被认为可以捕捉原矩阵 Z 的最潜在结构,前提是假设 Z 中大部分数据是冗余或相关的,因此可以忽略(图 B 灰色区域)。


image.png


图 B:低秩分解可视化(制图:Kuriko Iwai)


因此,LoRA 不再计算完整矩阵更新 Z,而是训练较小的矩阵 A 与 B,并引入一个**内秩(rank r)**来控制中间维度,从而大幅降低计算量。

这个过程可以概括如下:

image.png


其中:

  • ΔW:全秩更新矩阵(大小 d × d)
  • A:第一个低秩矩阵,大小为 d × r
  • B:第二个低秩矩阵,大小为 r × d
  • α/r:缩放因子,用于控制近似矩阵 AB 的幅度
  • r:秩(rank,LoRA 超参数,例如 r = 8)
  • α:缩放参数(LoRA 超参数,默认值为 1)

如图 B 所示,秩 r 决定 LoRA 从原始矩阵中简化的数据量


示例说明


Qwen-3(d = 2,048) 为例:

  • 全秩更新矩阵 ΔW 的参数量:2,048×2,048=4,194,304(约 420 万参数)2,048 \times 2,048 = 4,194,304 \text{(约 420 万参数)}2,048×2,048=4,194,304(约 420 万参数)
  • 全量微调意味着必须更新全部 420 万参数。

如果使用 秩为 8 的分解 r = 8,LoRA 只需微调 32,768 个参数

  • 矩阵 A:2,048 × 8 = 16,384 个参数
  • 矩阵 B:8 × 2,048 = 16,384 个参数
  • 可训练参数总数:16,384 + 16,384 = 32,768


这样,LoRA 成功地 大幅减少了可训练参数数量,同时保留了原始权重矩阵中的核心信息。


总可训练参数的通用公式

其中:

  • n_{lora}:LoRA 目标微调的总参数数量
  • d_{in}:原始层的输入维度(例如 2,048)
  • d_{out}:原始层的输出维度(例如 2,048)
  • r:秩(r « d_{in} 且 r « d_{out})

由于 LoRA 保持与全量微调相同的输出维度,因此可以将微调结果直接加到预训练权重 W_{pt} 上

image.png


其中:

  • W_{ft}:全量微调后的权重矩阵
  • W_{pt}:预训练权重矩阵
  • ΔW:全量微调的结果
  • α/r AB:LoRA 微调结果

公式 1.4 数学上证明了 LoRA 过程没有引入非线性


与传统 Adapter 方法的对比

  • 传统 Adapter 方法通常会引入激活函数(activation function),这会让模型更复杂、参数量增加。
  • LoRA 则可以 保持模型原始架构,在推理(inference)阶段不会增加延迟或计算成本。


<0.7% 的数学原理:为什么 LoRA 在计算上更高效

从图 A 可以看出,当 LoRA 的秩 r = 8 时,仅需训练 820 万个参数,约占 17 亿总参数的 0.7%

下面我们结合公式(Eq 1)来具体看看这是如何实现的。


LoRA 作用于注意力层(Attention Layers)

Qwen-3–1.7B 在注意力层中包含:

  • 16 个 Query head
  • 8 个 Key-Value(KV)head

在最常见的设置中,LoRA 会作用于注意力层中的四个核心投影矩阵:

  • W_q(Query)
  • W_k(Key)
  • W_v(Value)
  • W_out(Output)

在这种配置下,单个注意力层中 LoRA 的可训练参数总数为 114,688

image.png

表 2–1:Qwen-3–1.7B 单个注意力层中,总参数量与 LoRA 可训练参数量对比

(由 Kuriko IWAI 制作)

由于模型共有 28 层,因此注意力层中的 LoRA 可训练参数总数为:

  • 约 320 万参数
  • 仅占注意力层全部参数的 0.9%

image.png


LoRA 作用于前馈层(FF Layers)

与注意力层类似,我们同样可以拆解前馈层(Feed-Forward Layers)的参数计算方式。

Qwen-3–1.7B 使用的是 SwiGLU 架构,前馈计算由三个线性层组成:

  1. Gate layer
  2. Up layer
  3. Down layer

当 LoRA 同时作用于这三个层时,单个 FF 层的可训练参数总数为 181,248

image.png

表 2–2:Qwen-3–1.7B 单个 FF 层中,总参数量与 LoRA 可训练参数量对比

(由 Kuriko IWAI 制作)

因此,在 28 个 FF 层中:

  • LoRA 共训练 约 510 万参数
  • 仅占 FF 层总参数量的 0.3%

image.png

综合注意力层和前馈层:

  • LoRA 总共仅微调约 820 万参数
  • 占整个 17 亿参数模型的 不到 0.7%


LoRA 的调优策略 —— 超参数设计

尽管 LoRA 非常灵活,但其 超参数的选择至关重要,因为这决定了新知识与预训练知识之间的平衡。

主要有三个关键变量:

  1. 层选择(Layer Selection):在哪些全连接层上应用 LoRA
  2. 秩 r(Rank):LoRA 近似能力的强度
  3. 缩放参数 α(Scaling Parameter):平衡预训练权重与 LoRA 适配结果


层选择(Layer Selection)

在最初的 LoRA 论文 [1] 中,LoRA 主要被设计用于 注意力层(图 A 中的橙色部分),尤其是:

  • Query 投影(W_q)
  • Value 投影(W_v)

其核心逻辑是:

注意力层是捕捉任务特定逻辑的关键模块,同时又能保持极低的可训练参数量。

不过,论文也指出:LoRA 可以应用于任何全连接层。因此,许多现代实现会同时在 注意力层和 FF 层中使用 LoRA,以获得更好的性能。

实践中的常见选择包括:

  • 仅作用于注意力层
  • 仅作用于 FF 层
  • 同时作用于注意力层和 FF 层


开发者注释

一些实现默认 只对 Query(q_proj)和 Value(v_proj) 使用 LoRA。

这种做法虽然节省 VRAM,但会限制模型在复杂推理任务上的适应能力。


当模型表现不理想时,可以尝试扩展目标模块,包括:

  • Key(k_proj)
  • Output(o_proj)
  • FF 层中的 gate_proj 或 up_proj


秩(Rank)

r 决定了模型对新知识的学习能力:

  • 较高的 r:提升知识存储和泛化能力
  • 较低的 r:显著降低计算与显存开销(见公式 1.2)

常见的折中选择是:

  • r = 8
  • r = 16

这两者通常在性能和效率之间取得良好平衡。

较高的秩(如 r = 64 或 r = 128)适用于以下场景:

  • 极其复杂的任务适配(例如罕见疾病诊断),需要更强的建模能力
  • 训练样本较少,但对泛化能力要求很高

开发者注释

秩陷阱(Rank Trap)

“秩越高越好”并不总是成立。

高秩 LoRA 更容易:

  • 发生过拟合
  • 很快达到性能提升的上限
  • 消耗更多 VRAM

实用策略是:

  • 从 低秩 r = 8 开始
  • 只有在模型明显无法学习新知识时,才逐步提高秩

缩放参数(Scaling Parameter)


缩放参数 α 用于定义新学习内容预训练知识之间的权重平衡。

默认情况下,缩放参数取 1(α = 1),这意味着在前向传播时,预训练权重与低秩权重(即新学习的部分)被等权相加

缩放因子(α / r)的调整取决于具体任务策略:

image.png

(表 3:不同应用场景下的缩放因子示例,由 Kuriko IWAI 绘制)


安全性与漏洞:LoRA 真的是“防弹”的吗?

除了配置不当之外,LoRA 本身也存在对抗性安全漏洞,主要体现在以下三个层面:

  • 学习过程
  • 超参数
  • 架构本身


学习过程中的漏洞 —— 以数据为中心的攻击(Data-Centric Attacks)

由于 LoRA 的低秩矩阵结构相对简单,其行秩矩阵容易学习到噪声。

数据中心攻击是最常见的一类攻击方式,攻击者通过向训练数据中注入噪声,误导 LoRA 适配器的学习过程。


典型例子包括:

  • 对抗式微调(Adversarial Fine-tuning,LoFT)
  • 后门投毒(Backdoor Poisoning,LoRATK)
  • 非定向数据(噪声)投毒

应对方式:

  • 使用谱签名(spectral signatures)
  • 在数据进入 LoRA 适配器之前,检测并剔除被投毒的训练样本


超参数层面的漏洞 —— 以参数为中心的攻击(Parameter-Centric Attacks)

此类攻击利用 LoRA 的超参数或配置缺陷进行破坏。


典型方式包括:

  • 权重放大攻击(Weight Amplification,LoBAM):将缩放参数设置为极端值
  • 梯度组装投毒(Gradient Assembly Poisoning,GAP) [2]: 用统计特性相同的矩阵替换 A 与 B,使其乘积 AB 在整体权重空间中产生恶意偏移


应对方式:

  • 实施乘积空间验证(product-space validation)
  • 服务器端重建 AB,并在合并到全局模型前验证其谱特性


架构层面的漏洞 —— 提取攻击(Extraction Attacks)

由于 LoRA 结构小且简单,适配器本身可能被用来泄露训练数据。


典型攻击包括:

  • 成员推断攻击(Membership Inference,LoRA-Leak): 通过 LoRA 适配器的损失分布反推出训练数据
  • 模型提取攻击(Model Extraction,StolenLoRA): 克隆 LoRA 适配器的功能,从而模仿基座模型的行为

应对方式:

  • 对 LoRA 更新直接引入差分隐私(Differential Privacy, DP)
  • 确保无法从适配器权重中重构单个训练样本


总结(Wrapping Up)

LoRA 是一种高效的 Transformer 语言模型微调技术,在合理调参与规范实现的前提下,能够兼顾性能与资源效率。

下表给出了 不同 LoRA 秩对应的 VRAM 需求对比

image.png

(表 4:LoRA 配置与全参数微调的对比,由 Kuriko IWAI 绘制)


全参数微调(表 4 最左列)中,模型的每一个参数都会被更新,因此:

  • 需要大量训练样本以避免过拟合
  • 需要显著更多的 VRAM 来计算与存储权重


当 LoRA 覆盖更多层、并提升秩 r 时:

  • 对训练样本数量的需求增加
  • VRAM 使用量上升(因为优化器需要维护更多参数状态)


但即便是在高秩(r = 64)且覆盖全部层的 LoRA 配置下(表 4 最右列),其资源需求的增长仍然显著低于全参数微调(例如:约 2 万样本 vs 5 万样本)。


参考文献

[1] Hu et al., LoRA: Low-Rank Adaptation of Large Language Models, 2021

[2] Dong et al., Low Rank Comes with Low Security: Gradient Assembly Poisoning Attacks against Distributed LoRA-based LLM Systems, 2025

评论
Copyright Created by DataER | 沪ICP备2024052789号-5 | 沪公网安备31010402336337号