深入浅出剖析 LoRA 技术原理

大猿搬砖简记.
学会计出身的码农,和大家一起学习 。
【点击】加入大模型技术交流群
关于LORA部分的讲解,我们将分为“原理篇”和“源码篇” 。
在原理篇中,我们将通过图解的方式,详细分析LoRA怎么用、为什么能奏效、存在哪些优劣势等核心问题 。特别是当你在学习LoRA时,如果对“秩”的定义和作用方式感到迷惑,那么本文也许能提供一些具象化的解读方式 。
在源码篇中,我们将一起剖析微软LoRA源码,并帮助大家在 colab平台上使用免费GPU,搭建LoRA微调环境,使得每个人可以亲自动手跑一遍原生LoRA代码,加深对LoRA运作机制的理解(不要钱的快乐才是真快乐) 。
一、全参数微调
我们知道,微调的含义,就是把已经训练好的模型( model)拿来,给它特定的下游任务数据,使得模型在预训练权重上继续训练,直至满足下游任务性能标准 。预训练模型就像一个特征提取器,能够基于先前训练数据中学到的经验,为我们提取有效的特征,大大提升下游任务的训练效果和收敛速度 。
全量微调指的是,在下游任务的训练中,对预训练模型的每一个参数都做更新 。例如图中,给出了的Q/K/V矩阵的全量微调示例,对每个矩阵来说,在微调时,其d*d个参数,都必须参与更新 。
【深入浅出剖析 LoRA 技术原理】全量微调的显著缺点是,训练代价昂贵 。例如GPT3的参数量有175B,我等单卡贵族只能望而却步,更不要提在微调中发现有bug时的覆水难收 。同时,由于模型在预训练阶段已经吃了足够多的数据,收获了足够的经验,因此我只要想办法给模型增加一个额外知识模块,让这个小模块去适配我的下游任务,模型主体保持不变()即可 。
那这样的知识小模块,具体要怎么添加呢?
二、 与
我们来看在LoRA出现前,两种主流的局部微调办法: 与。这也是LoRA的原始论文中,重点比对的两种微调方式 。
2.1
的方法有很多种,这里我们举出 et al. ,2019提出的方法,这也是LoRA论文中提及这项技术时所引用的第一篇文章 。
图例中的左边是一层 Layer结构,其中的就是我们说的“额外知识模块”;右边是的具体结构 。在微调时,除了的部分,其余的参数都是被冻住的(),这样我们就能有效降低训练的代价 。的内部架构不是本文所述的重点,这里我们就不再介绍了 。
但这样的设计架构存在一个显著劣势:添加了后,模型整体的层数变深,会增加训练速度和推理速度,原因是:
2.2
的方法也有很多种,这里我们选取Li&Liang,2021这一篇进行简述 。在这篇中,作者通过对输入数据增加前缀()来做微调 。当然,也可以不止加载输入层,还可以加在 Layer输出的中间层,感兴趣的朋友可以查找论文自行研究 。
如图所示,对于GPT这样的生成式模型,在输入序列的最前面加入 token,图例中加入2个 token,在实际应用中,token的个数是个超参,可以根据模型实际微调效果进行调整 。对于BART这样的-架构模型,则在x和y的前面同时添加 token 。在后续微调中,我们只需要冻住模型其余部分,单独训练 token相关的参数即可,每个下游任务都可以单独训练一套 token 。
那么的含义是什么呢?的作用是引导模型提取x相关的信息,进而更好地生成y 。例如,我们要做一个的任务,那么经过微调后,就能领悟到当前要做的是个“总结形式”的任务,然后引导模型去x中提炼关键信息;如果我们要做一个情感分类的任务,就能引导模型去提炼出x中和情感相关的语义信息,以此类推 。这样的解释可能不那么严谨,但大家可以大致体会一下的作用 。