作者:Sebastian Raschka
机器之心编译
编辑:赵阳
LoRA 微调方法,随着大模型的出现而走红。
进NLP群—>加入NLP交流群
最近几个月,ChatGPT 等一系列大语言模型(LLM)相继出现,随之而来的是算力紧缺日益严重。虽然人人都想打造专属于自己的大模型,但是能负担得起上亿参数模型训练的机构却寥寥无几。在快速发展的人工智能领域,以高效和有效的方式使用大型语言模型正变得越来越重要。LoRA(Low-Rank Adaption,低秩自适应) 作为微调 LLMs 一种比较出圈的技术,其额外引入了可训练的低秩分解矩阵,同时固定住预训练权重,从而大大减少了下游任务的可训练参数数量。本文中,来自 Lightning AI 首席人工智能教育家 Sebastian Raschka 将带你了解如何以高效的方式用 LoRA 来微调 LLM。下面是全文内容。为什么要进行微调?预训练大语言模型通常被称为基础模型,这样称呼的原因是:大语言模型在各种任务中表现良好,可以将它们用作对目标任务进行微调的基础。正如 Sebastian Raschka 在上一篇博文《Understanding Parameter-Efficient Finetuning of Large Language Models: From Prefix Tuning to LLaMA-Adapters》中所讨论的,微调能够使模型适应目标域和目标任务。尽管如此,大模型在计算上的成本可能非常昂贵 —— 模型越大,更新其网络层的成本就越高。如果不想将网络中所有的层都进行更新,可以使用诸如前缀微调和适配器之类的高效调参方法。如今,有一种更流行的微调技术:Hu 等人提出的低秩自适应(LoRA)。什么是 LoRA?它是如何工作的?它与其他流行的微调方法相比如何?本文将回答所有这些问题。 提高权重更新效率论文《 LoRA: Low-Rank Adaptation of Large Language Models》提出将权重变化 ΔW 分解为秩较低的表示。(LoRA 不会直接分解矩阵,而是通过反向传播来学习分解的矩阵)。在仔细研究 LoRA 之前,我们先简要解释一下规则微调期间的训练程序。首先是权重变化 ΔW。假设 W 表示给定神经网络层中的权重矩阵。然后,使用常规反向传播,我们可以获得权重更新 ΔW,它通常被计算为损失乘以学习率的负梯:然后,得到 ΔW 后,原始权重按如下公式更新:W'=W+ΔW。如下图所示(为了简单起见,省略了偏置矢量)。或者,我们可以保持权重更新矩阵分离,并按如下公式计算输出:h=Wx+ΔWx:
其中 x 表示输入,如下所示:
当在神经网络中训练全连接(即 dense)层时,如上所示,权重矩阵通常具有全秩,这意味着矩阵不具有任何线性相关(即冗余)的行或列。相比之下,与全秩相比,低秩意味着矩阵具有冗余的行或列。 因此,尽管预训练模型的权重是满秩矩阵,但根据 Aghajanyan 等人的说法,LoRA 的作者指出预训练的大型语言模型在适应新任务时具有较低的内在维度。低内在维度意味着数据可以由低维度空间有效地表示或近似,同时保留其大部分基本信息或结构。换句话说,这意味着可以将适应任务的新权重矩阵分解为低维(较小)矩阵,而不会丢失太多重要信息。例如,假设 ΔW 是 A×B 维权重矩阵的权重更新矩阵,这个权重更新矩阵可以分解为两个较小的矩阵:ΔW=W_A W_B,其中 W_A 是 A×r 维矩阵,W_B 是 r×B 维矩阵。在这里,我们保持原始权重 W 冻结,并且只训练新的矩阵 W_A 和 W_B。如下图所示。选择秩上图中的 r 是超参数,指定用于自适应的低秩矩阵的秩。r 越小,低秩矩阵越简单,在自适应过程中需要学习的参数越少,训练就更快,计算需求会相应的减少。然而,r 变小的弊端是,低秩矩阵捕获任务特定信息的能力降低。这可能导致较低的自适应质量,并且与较高的 r 相比,模型在新任务上可能表现不佳。总之,在 LoRA 中确定 r 的取值,需要在模型复杂性、自适应能力和拟合不足或拟合过度的风险之间进行权衡。因此,重要的是用不同的 r 值进行实验,以找到正确的平衡,从而在新任务中满足所需的性能。 LoRA 实战LoRA 的使用很直接,可以将其视为 LLM 中全连接层的前向传递修正版。伪代码如下所示:
在上面的伪代码中,alpha 是一个缩放因子,用于调整组合结果的大小(原始模型输出加上低秩自适应)。这平衡了预训练模型的知识和新的任务特定适应 —— 默认情况下,alpha 通常设置为 1。还要注意,当 W_A 被初始化为小的随机权重时,W_B 被初始化为 0,从而使得,这意味着需要从原始权重开始训练。参数效率接下来说一说最棘手的问题:如果引入新的权重矩阵,参数如何才能有效?新的矩阵 W_A 和 W_B 可以非常小。例如,假设 A=100,B=500,那么 ΔW 的大小为 100×500=50000。如果将其分解为两个较小的矩阵,一个 100×5 维矩阵 W_A 和一个 5×500 维矩阵 W_B。这两个矩阵总共只有 5×100+5×500=3000 个参数。 减少推理开销在实践中,如果在如上所示的训练后保持原始权重 W 以及矩阵 W_A 和 W_B 处于分离状态,推理过程中就会额外产生效率损失,因为引入了额外的计算步骤。相反可以在训练后通过 W’=W+W_A・W_B 更新权重,这类似于前面提到的 W’=W+ΔW。然而,保持权重矩阵 W_A 和 W_B 分离也可能有些优势。例如,假设希望保留预训练的模型作为各种客户的基础模型,并且希望从基础模型开始为每个客户创建一个微调的 LLM。在这种情况下,就不需要为每个客户存储完整的权重矩阵 W’。不然存储模型的所有权重 W’=W+W_A W_B 对于 LLM 来说可能非常大,因为 LLM 通常具有数十亿到数万亿的权重参数。因此,可以保留原始模型 W,只需要存储新的轻量级矩阵 W_A 和 W_B。用具体的数字来说明的话,一个完整的 7B LLaMA checkpoint 需要 23 GB 的存储容量,而选择 r=8 的秩,则 LoRA 权重可以小到 8 MB。 实践效果LoRA 在实践中有多好,与完全微调和其他参数有效方法相比如何?根据 LoRA 的论文,在几个特定任务的基准测试中,使用 LoRA 的模型的建模性能略好于使用 Adapters、prompt tuning 或 prefix tuning 的模型。通常,LoRA 的性能甚至比微调所有层更好,如下面 LoRA 论文的注释表所示。值得注意的是,LoRA 与其他微调方法正交,这意味着它也可以与 Adapters 或 prefix tuning 相结合。LoRA & LLaMA现在,让我们使用 LoRA 来微调 Meta 提出的 LLaMA 模型。除了用于训练和运行 LLaMA 本身的代码(使用原始的 Meta-LLaMA 权重)外,还包含用于使用 LLaMA Adapter 和 LoRA 微调 LLaMA 的代码。作者建议使用以下操作方法文件:
下载预训练的权重:https://github.com/Lightning-AI/lit-llama/blob/main/howto/download_weights.md
使用 LoRA 进行微调:https://github.com/Lightning-AI/lit-llama/blob/main/howto/finetune_lora.md
使用适配器进行微调:https://github.com/Lightning-AI/lit-llama/blob/main/howto/finetune_adapter.md(可选,用于比较研究)
下一节将比较 7B LLaMA 基础模型与使用 LoRA 和 LLaMA Adapter 微调的 7B LLaMA 基础模型。(请注意,需要具有至少 24 GB RAM 的 GPU)。计算性能基准本节中,作者将比较 LLaMA 7B 基础模型与使用 LoRA 和 LLaMA Adapter 微调的基础模型的计算性能。微调数据集是 Alpaca 52k 指令数据集,其结构如下:
数据集是按照 Self-Instruct 论文中描述的方法生成的,由 49759 个训练样本和 2000 个验证样本组成。Self-Instruct 的流程可总结为 4 个步骤:
种子任务池,包含一组人工编写的指令(本例中为 175 条)和样本指令;
使用预训练的 LLM(如 GPT-3)来确定任务类别;
给定新指令,让预训练的 LLM 生成响应结果;
在将响应结果添加到任务池之前,先收集、剪枝和筛选响应结果。
全部0条评论
快来发表一下你的评论吧 !