LoRA:大型语言模型的低秩适配
随着大型语言模型(LLM) (如GPT 、LLaMa 、Claude 2 等)的推出,机器学习与自然语言处理(NLP)领域取得了长足进步。这些模型在从文本生成到语言理解的诸多应用中展现出非凡能力。
然而,这些模型在实际部署与微调 方面面临巨大挑战,主要源于其规模和复杂性。
这正是低秩适配(LoRA)大显身手之处,它为上述挑战提供了行之有效的解决方案。
本教程旨在从理论与实践两方面,帮助您理解 LoRA 是什么,以及如何从中获益。
背景
LoRA 的诞生可追溯至 2021 年初、GPT-3 发布之后。微软与 OpenAI 在合作中面临一个难题:如何让像 GPT-3 这样的大模型具备商业可行性。
他们发现,仅靠一次性提示(one-shot prompting)不足以在生产环境中获得最佳表现,尤其是在将自然语言翻译为代码等复杂任务上。由此,他们开始探索既具成本效益又高效的微调方法。
LoRA 的发明源于产品需求:在运行时实现大语言模型的快速、高效、低成本微调,以支持领域专用、高效任务切换或用户切换。
LoRA 研究论文 由微软研究团队于 2021 年 10 月发表。
为何需要 LoRA?
在了解 LoRA 及其解决方案之前,让我们先厘清问题本身。
GPT-4、Claude 2、LLaMA 70b 等大型语言模型能力强大,但也非常通用且庞大。若要将这些模型用于医护、银行等特定领域,或用于将文本转换为代码等特定任务,我们需要对其进行微调。
微调是指在特定的小型数据集上训练预训练模型,使其在特定任务或领域上表现更佳。随着模型规模不断增大(例如 GPT-3 具有 1750 亿参数),全量微调(即重新训练所有模型参数)在时间、成本和资源上愈发不可行。
LoRA 是一种用于微调大模型的技术。
LoRA 的工作原理
从高层来看,LoRA 的工作方式如下:
它保持原始模型不变,并在模型的每一层添加一些体量很小且可训练的组件。这样可以显著减少可训练参数的数量,进而降低训练过程中的 GPU 显存需求——这也是微调或训练大模型时的另一大难题。
例如,全量微调 GPT-3 需要训练 1750 亿个参数。使用 LoRA 后,GPT-3 的可训练参数大约可减少 1 万倍,GPU 显存需求也可降低三倍。
归根结底,LoRA 解决了以下问题:
速度 ——更少的可训练参数意味着更快的训练速度
算力资源 ——更少的可训练参数意味着所需算力更低,使大模型微调在经济上更可行
内存效率 ——更少的可训练参数可缓存在内存中,无需进行低效的磁盘读取
低秩矩阵
在深入 LoRA 细节之前,让我们先理解低秩矩阵这一概念。
低秩矩阵源自数学中的线性代数。简单来说,矩阵的秩衡量了该矩阵所代表数据的“信息量”或“维度”。具体可分解如下:
矩阵: 矩阵是一个由数字构成的长方形数组。例如,3×3 矩阵有 3 行和 3 列。
矩阵的秩 矩阵的秩由其中线性无关的行或列的数量决定。线性无关意味着任一行(或列)都不能由其他行(或列)的线性组合得到。 若所有行(或列)线性无关,则矩阵满秩。 若某些行(或列)可由其他行(或列)组合得到,则矩阵为低秩。
低秩矩阵: 若一个矩阵的秩小于其在给定规模下的最大可能值,则该矩阵为低秩。例如,在 3×3 矩阵中,若秩小于 3,即为低秩矩阵。
示例:
考虑一个 3 × 3 矩阵:
这里,第二行只是第一行的 2 倍,第三行是第一行的 3 倍。这意味着各行并非线性无关。该矩阵的秩为 1(因为只有第一行是独立的),小于 3×3 矩阵的最大秩 3。因此,这是一个低秩矩阵。
低秩矩阵在诸多应用中具有重要意义,例如数据压缩:降低矩阵秩有助于在尽可能保留信息的同时压缩数据。
矩阵的秩对行与列同样适用。关键在于,无论基于行还是列来计算,矩阵的秩都是相同的。这源于线性代数中的一个基本性质——秩-零化度定理(Rank-Nullity Theorem)。
通俗地说,该定理表示矩阵的行空间(由各行张成的空间)与列空间(由各列张成的空间)具有相同维度,而这个共同的维度即为矩阵的秩。
因此,在上述 3 × 3 矩阵的例子中,秩为 1,意味着只有一行线性无关,同样也只有一列线性无关。
什么是 LoRA?
简单来说,LoRA 利用低秩矩阵的思想,使模型训练过程极其高效且快速。
大型模型拥有大量参数。例如,GPT-3 有 1750 亿个参数。这些参数就是存储在矩阵中的数字,存储它们需要极大的空间。
全量微调意味着要训练所有参数,这将需要海量算力资源,对于 GPT 这类规模的模型,成本轻易就可达数百万美元。
与需要调整整个模型的传统微调不同,LoRA 专注于修改更小的一组参数(低秩矩阵) ,从而降低计算与内存开销。
LoRA 基于对大型模型本质上具有低维结构的理解。通过利用低秩矩阵,LoRA 能够高效地对这些模型进行适配。其核心思想在于:模型的显著变化可以用更少的参数来表示,从而让适配过程更高效。
来源:微调 LLM:LoRA 还是全量参数?基于 Llama 2 的深入分析
那么它具体如何运作?
首先,使用前述的低秩分解技术,将大型权重矩阵分解为更小的矩阵。这会大幅减少可训练参数的数量。以 GPT-3 为例,可训练参数可减少 1 万倍。也就是说,应用 LoRA 后,不再需要训练 1750 亿参数,而只需训练 1750 万参数。
我们不会更改预训练模型的任何参数,而只训练低秩矩阵。由于参数更少,这一过程会快得多。
权重是可加的。这意味着在推理阶段,只需将低秩矩阵的权重与预训练权重相加即可,不会引入额外的时延。低秩矩阵本身也很小,因此易于在不同任务和不同用户之间装载与卸载。
LoRA 的优势
使用 LoRA 进行微调有多重优势:
1. 训练与部署高效
LoRA 降低了计算负担,使模型能够更快适配。由于需要的可训练参数更少,即便在算力较弱的硬件上也能对大模型进行微调。
2. 保持模型质量与推理速度
尽管参数数量减少,LoRA 仍能保持原始模型的质量与推理速度。
3. 检查点体积显著降低
LoRA 能显著缩小模型检查点的大小。例如,在 GPT-3 上,检查点大小可从 1 TB 降至仅 25 MB。
4. 无额外推理时延
LoRA 在推理阶段不会引入额外时延。低秩矩阵仅用于训练,推理时与原始参数合并,因此不会变慢。这也使运行时的快速模型切换成为可能,而不增加推理时延。
5. 通用性强
LoRA 适用于任何使用矩阵乘法的模型(如支持向量机),可广泛应用于许多其他场景。事实上,LoRA 在 Stable Diffusion 等图像模型中被广泛用于将风格注入到大型图像模型中。
Stable Diffusion 中的 LoRA
LoRA 技术也在 Stable Diffusion 等图像模型中被广泛采用。
思路与语言模型基本一致。与其对 Stable Diffusion 等大型模型进行全量微调,不如仅在小数据集上训练低秩矩阵。
在语言模型中,目标是领域专用;而在图像模型中,最典型的用途是生成图像时采用某种风格或保持角色一致性。
这些低秩矩阵被称为适配器(adapter),体量很小。互联网上有成千上万的适配器可供下载,您可以将它们加载到基础的 Stable Diffusion 模型之上,生成特定风格的图像。
LoRA 在 Stable Diffusion 中的常见用途包括:
风格专化 ——如二次元风格、油画风格等
角色专化 ——稳定生成马里奥、海绵宝宝等角色形象
质量提升 ——更高细节、更佳人脸等
您可以组合多个 LoRA,以获得兼具多种专化效果的输出。
Stable Diffusion 模型的不同适配器(图片来源 )
如果您想学习如何用个人照片成功微调 Stable Diffusion XL,请查看 Datacamp 上的使用 DreamBooth 和 LoRA 微调 Stable Diffusion XL 一文。
将 LoRA 与 Prefix-Tuning 结合
Prefix tuning 是一种轻量方法,通过优化称为“前缀”的连续向量,并将其添加到每个 Transformer 层的输入中。模型以去前缀的方式训练,只关注这些向量。
前缀微调的优势:
每个任务只需存储小型前缀向量,而非微调后模型的完整副本
便于任务切换与个性化
与全量微调相比表现良好,尤其是在小数据场景中
计算成本更低,因为训练期间只更新前缀
LoRA 与前缀微调可在 PEFT(参数高效微调)框架中结合使用:
LoRA 降低总体参数量,而前缀微调提供任务级控制
二者配合可在最少数据与算力下完成专用微调
非常适合使用有限领域数据对大型 LLM 进行领域适配
这种模块化微调为算力受限的用户释放大型 LLM 的全部潜力
使用 Python 中的 Loralib 库实现 LoRA 的示例
要实现 LoRA,您可以使用微软的 Loralib 库 。安装方式:
pip install loralib
技术支持
采用 LoRA 后,您平常训练神经网络的方式基本无需改变。
import loralib as lora
layer = lora. Linear( in_features, out_features, r= 16 )
技术支持
在训练循环开始前,您只需添加:
import loralib as lora
model = YourNeuralNetwork( )
lora. mark_only_lora_as_trainable( model)
for batch in dataloader:
. . .
技术支持
保存检查点时,您可以只生成包含 LoRA 参数的 state_dic。
torch. save( lora. lora_state_dict( model) , checkpoint_path)
技术支持
如果您对神经网络了解不多,也不必担心。请查阅如何用 PyTorch 训练 LLM 一文,从环境搭建到最终实现,全面掌握使用 PyTorch 训练大型语言模型的流程。
致谢:代码示例转载自 Microsoft/LoRA GitHub 。
结语
LoRA 成为应对大型模型规模与复杂性所带来重大挑战的不可或缺技术。
通过利用低秩矩阵,LoRA 提供了更高效且具成本效益的模型适配途径,显著减少可训练参数与 GPU 显存需求,从而加速训练并提升内存效率。
LoRA 的应用超越语言模型,也能用于 Stable Diffusion 等图像模型,以便在图像生成中实现风格专化与角色一致性。
如果您对这些技术能构建什么充满好奇,欢迎阅读我们的指南:5 个可用生成式 AI 模型构建的项目 以进一步了解。
LoRA:大型语言模型的低秩适配
随着大型语言模型(LLM)(如GPT、LLaMa、Claude 2等)的推出,机器学习与自然语言处理(NLP)领域取得了长足进步。这些模型在从文本生成到语言理解的诸多应用中展现出非凡能力。
然而,这些模型在实际部署与微调方面面临巨大挑战,主要源于其规模和复杂性。
这正是低秩适配(LoRA)大显身手之处,它为上述挑战提供了行之有效的解决方案。
本教程旨在从理论与实践两方面,帮助您理解 LoRA 是什么,以及如何从中获益。
背景
LoRA 的诞生可追溯至 2021 年初、GPT-3 发布之后。微软与 OpenAI 在合作中面临一个难题:如何让像 GPT-3 这样的大模型具备商业可行性。
他们发现,仅靠一次性提示(one-shot prompting)不足以在生产环境中获得最佳表现,尤其是在将自然语言翻译为代码等复杂任务上。由此,他们开始探索既具成本效益又高效的微调方法。
LoRA 的发明源于产品需求:在运行时实现大语言模型的快速、高效、低成本微调,以支持领域专用、高效任务切换或用户切换。
LoRA 研究论文由微软研究团队于 2021 年 10 月发表。
为何需要 LoRA?
在了解 LoRA 及其解决方案之前,让我们先厘清问题本身。
GPT-4、Claude 2、LLaMA 70b 等大型语言模型能力强大,但也非常通用且庞大。若要将这些模型用于医护、银行等特定领域,或用于将文本转换为代码等特定任务,我们需要对其进行微调。
微调是指在特定的小型数据集上训练预训练模型,使其在特定任务或领域上表现更佳。随着模型规模不断增大(例如 GPT-3 具有 1750 亿参数),全量微调(即重新训练所有模型参数)在时间、成本和资源上愈发不可行。
LoRA 是一种用于微调大模型的技术。
LoRA 的工作原理
从高层来看,LoRA 的工作方式如下:
它保持原始模型不变,并在模型的每一层添加一些体量很小且可训练的组件。这样可以显著减少可训练参数的数量,进而降低训练过程中的 GPU 显存需求——这也是微调或训练大模型时的另一大难题。
例如,全量微调 GPT-3 需要训练 1750 亿个参数。使用 LoRA 后,GPT-3 的可训练参数大约可减少 1 万倍,GPU 显存需求也可降低三倍。
归根结底,LoRA 解决了以下问题:
低秩矩阵
在深入 LoRA 细节之前,让我们先理解低秩矩阵这一概念。
低秩矩阵源自数学中的线性代数。简单来说,矩阵的秩衡量了该矩阵所代表数据的“信息量”或“维度”。具体可分解如下:
矩阵是一个由数字构成的长方形数组。例如,3×3 矩阵有 3 行和 3 列。
矩阵的秩由其中线性无关的行或列的数量决定。线性无关意味着任一行(或列)都不能由其他行(或列)的线性组合得到。
若所有行(或列)线性无关,则矩阵满秩。
若某些行(或列)可由其他行(或列)组合得到,则矩阵为低秩。
若一个矩阵的秩小于其在给定规模下的最大可能值,则该矩阵为低秩。例如,在 3×3 矩阵中,若秩小于 3,即为低秩矩阵。
示例:
考虑一个 3 × 3 矩阵:
这里,第二行只是第一行的 2 倍,第三行是第一行的 3 倍。这意味着各行并非线性无关。该矩阵的秩为 1(因为只有第一行是独立的),小于 3×3 矩阵的最大秩 3。因此,这是一个低秩矩阵。
低秩矩阵在诸多应用中具有重要意义,例如数据压缩:降低矩阵秩有助于在尽可能保留信息的同时压缩数据。
矩阵的秩对行与列同样适用。关键在于,无论基于行还是列来计算,矩阵的秩都是相同的。这源于线性代数中的一个基本性质——秩-零化度定理(Rank-Nullity Theorem)。
通俗地说,该定理表示矩阵的行空间(由各行张成的空间)与列空间(由各列张成的空间)具有相同维度,而这个共同的维度即为矩阵的秩。
因此,在上述 3 × 3 矩阵的例子中,秩为 1,意味着只有一行线性无关,同样也只有一列线性无关。
什么是 LoRA?
简单来说,LoRA 利用低秩矩阵的思想,使模型训练过程极其高效且快速。
大型模型拥有大量参数。例如,GPT-3 有 1750 亿个参数。这些参数就是存储在矩阵中的数字,存储它们需要极大的空间。
全量微调意味着要训练所有参数,这将需要海量算力资源,对于 GPT 这类规模的模型,成本轻易就可达数百万美元。
与需要调整整个模型的传统微调不同,LoRA 专注于修改更小的一组参数(低秩矩阵),从而降低计算与内存开销。
LoRA 基于对大型模型本质上具有低维结构的理解。通过利用低秩矩阵,LoRA 能够高效地对这些模型进行适配。其核心思想在于:模型的显著变化可以用更少的参数来表示,从而让适配过程更高效。
来源:微调 LLM:LoRA 还是全量参数?基于 Llama 2 的深入分析
那么它具体如何运作?
首先,使用前述的低秩分解技术,将大型权重矩阵分解为更小的矩阵。这会大幅减少可训练参数的数量。以 GPT-3 为例,可训练参数可减少 1 万倍。也就是说,应用 LoRA 后,不再需要训练 1750 亿参数,而只需训练 1750 万参数。
我们不会更改预训练模型的任何参数,而只训练低秩矩阵。由于参数更少,这一过程会快得多。
权重是可加的。这意味着在推理阶段,只需将低秩矩阵的权重与预训练权重相加即可,不会引入额外的时延。低秩矩阵本身也很小,因此易于在不同任务和不同用户之间装载与卸载。
LoRA 的优势
使用 LoRA 进行微调有多重优势:
1. 训练与部署高效
LoRA 降低了计算负担,使模型能够更快适配。由于需要的可训练参数更少,即便在算力较弱的硬件上也能对大模型进行微调。
2. 保持模型质量与推理速度
尽管参数数量减少,LoRA 仍能保持原始模型的质量与推理速度。
3. 检查点体积显著降低
LoRA 能显著缩小模型检查点的大小。例如,在 GPT-3 上,检查点大小可从 1 TB 降至仅 25 MB。
4. 无额外推理时延
LoRA 在推理阶段不会引入额外时延。低秩矩阵仅用于训练,推理时与原始参数合并,因此不会变慢。这也使运行时的快速模型切换成为可能,而不增加推理时延。
5. 通用性强
LoRA 适用于任何使用矩阵乘法的模型(如支持向量机),可广泛应用于许多其他场景。事实上,LoRA 在 Stable Diffusion 等图像模型中被广泛用于将风格注入到大型图像模型中。
Stable Diffusion 中的 LoRA
LoRA 技术也在 Stable Diffusion 等图像模型中被广泛采用。
思路与语言模型基本一致。与其对 Stable Diffusion 等大型模型进行全量微调,不如仅在小数据集上训练低秩矩阵。
在语言模型中,目标是领域专用;而在图像模型中,最典型的用途是生成图像时采用某种风格或保持角色一致性。
这些低秩矩阵被称为适配器(adapter),体量很小。互联网上有成千上万的适配器可供下载,您可以将它们加载到基础的 Stable Diffusion 模型之上,生成特定风格的图像。
LoRA 在 Stable Diffusion 中的常见用途包括:
您可以组合多个 LoRA,以获得兼具多种专化效果的输出。
Stable Diffusion 模型的不同适配器(图片来源)
如果您想学习如何用个人照片成功微调 Stable Diffusion XL,请查看 Datacamp 上的使用 DreamBooth 和 LoRA 微调 Stable Diffusion XL一文。
将 LoRA 与 Prefix-Tuning 结合
Prefix tuning 是一种轻量方法,通过优化称为“前缀”的连续向量,并将其添加到每个 Transformer 层的输入中。模型以去前缀的方式训练,只关注这些向量。
前缀微调的优势:
LoRA 与前缀微调可在 PEFT(参数高效微调)框架中结合使用:
使用 Python 中的 Loralib 库实现 LoRA 的示例
要实现 LoRA,您可以使用微软的 Loralib 库。安装方式:
采用 LoRA 后,您平常训练神经网络的方式基本无需改变。
在训练循环开始前,您只需添加:
保存检查点时,您可以只生成包含 LoRA 参数的
state_dic。如果您对神经网络了解不多,也不必担心。请查阅如何用 PyTorch 训练 LLM一文,从环境搭建到最终实现,全面掌握使用 PyTorch 训练大型语言模型的流程。
致谢:代码示例转载自 Microsoft/LoRA GitHub。
结语
LoRA 成为应对大型模型规模与复杂性所带来重大挑战的不可或缺技术。
通过利用低秩矩阵,LoRA 提供了更高效且具成本效益的模型适配途径,显著减少可训练参数与 GPU 显存需求,从而加速训练并提升内存效率。
LoRA 的应用超越语言模型,也能用于 Stable Diffusion 等图像模型,以便在图像生成中实现风格专化与角色一致性。
如果您对这些技术能构建什么充满好奇,欢迎阅读我们的指南:5 个可用生成式 AI 模型构建的项目以进一步了解。