大模型高效微调:LoRA 技术原理与实战经验总结
增加数据量和模型的参数量是公认的提升神经网络性能最直接的方法。目前主流的大模型的参数量已扩展至千亿级别,「大模型」越来越大的趋势还将愈演愈烈。
这种趋势带来了多方面的算力挑战。想要微调参数量达千亿级别的大语言模型,不仅训练时间长,还需占用大量高性能的内存资源。
为了让大模型微调的成本「打下来」,微软的研究人员开发了低秩自适应(LoRA)技术。LoRA 的精妙之处在于,它相当于在原有大模型的基础上增加了一个可拆卸的插件,模型主体保持不变。LoRA 随插随用,轻巧方便。
对于高效微调出一个定制版的大语言模型来说,LoRA 是最为广泛运用的方法之一,同时也是最有效的方法之一。
LoRA 简介
由于 GPU 内存的限制,在训练过程中更新模型权重成本高昂。
例如,假设我们有一个 7B 参数的语言模型,用一个权重矩阵 W 表示。在反向传播期间,模型需要学习一个 ΔW 矩阵,旨在更新原始权重,让损失函数值最小。
权重更新如下:
W_updated = W + ΔW
如果权重矩阵 W 包含 7B 个参数,则权重更新矩阵 ΔW 也包含 7B 个参数,计算矩阵 ΔW 非常耗费计算和内存。
由 Edward Hu 等人提出的 LoRA 将权重变化的部分 ΔW 分解为低秩表示。确切地说,它不需要显示计算 ΔW。相反,LoRA 在训练期间学习 ΔW 的分解表示,这就是 LoRA 节省计算资源的奥秘。

如上所示,ΔW 的分解意味着我们需要用两个较小的 LoRA 矩阵 A 和 B 来表示较大的矩阵 ΔW。如果 A 的行数与 ΔW 相同,B 的列数与 ΔW 相同,我们可以将以上的分解记为 ΔW = AB。(AB 是矩阵 A 和 B 之间的矩阵乘法结果。)
这种方法节省了多少内存呢?还需要取决于秩 r,秩 r 是一个超参数。例如,如果 ΔW 有 10,000 行和 20,000 列,则需存储 200,000,000 个参数。如果我们选择 r=8 的 A 和 B,则 A 有 10,000 行和 8 列,B 有 8 行和 20,000 列,即 10,000×8 + 8×20,000 = 240,000 个参数,比 200,000,000 个参数少约 830 倍。
当然,A 和 B 无法捕捉到 ΔW 涵盖的所有信息,但这是 LoRA 的设计所决定的。在使用 LoRA 时,我们假设模型 W 是一个具有全秩的大矩阵,以收集预训练数据集中的所有知识。当我们微调 LLM 时,不需要更新所有权重,只需要更新比 ΔW 更少的权重来捕捉核心信息,低秩更新就是这么通过 AB 矩阵实现的。
LoRA 的一致性
虽然 LLM,或者说在 GPU 上被训练的模型的随机性不可避免,但是采用 LoRA 进行多次实验,LLM 最终的基准结果在不同测试集中都表现出了惊人的一致性。对于进行其他比较研究,这是一个很好的基础。

请注意,这些结果是在默认设置下,使用较小的值 r=8 获得的。实验细节可以在相关开源社区找到。
QLoRA 计算 - 内存权衡
QLoRA 是由 Tim Dettmers 等人提出的量化 LoRA 的缩写。QLoRA 是一种在微调过程中进一步减少内存占用的技术。在反向传播过程中,QLoRA 将预训练的权重量化为 4-bit,并使用分页优化器来处理内存峰值。
我发现使用 LoRA 时可以节省 33% 的 GPU 内存。然而,由于 QLoRA 中预训练模型权重的额外量化和去量化,训练时间增加了 39%。
默认 LoRA 具有 16 bit 浮点精度:
- 训练时长:1.85 小时
- 内存占用:21.33GB
具有 4 位正常浮点数的 QLoRA:
- 训练时长为:2.79h
- 内存占用为:14.18GB
此外,我发现模型的性能几乎不受影响,这说明 QLoRA 可以作为 LoRA 训练的替代方案,更进一步解决常见 GPU 内存瓶颈问题。












