简介

最近对大模型这部分内容比较感兴趣,作者最早接触大模型是22年下半年的时候。当时觉得非常amazing,并认为这是一个颠覆性的工作,目前随着开源大模型的逐渐变多。我觉得我们得学习并了解这些基础知识,以便后续在工作中可以学习并使用。在深度学习中,微调是一种重要的技术,用于改进预训练模型的性能。除了微调ChatGPT之外,还有许多其他预训练模型可以进行微调。

以下是一些微调预训练模型的方法:

  • 微调所有层:将预训练模型的所有层都参与微调,以适应新的任务。
  • 微调顶层:只微调预训练模型的顶层,以适应新的任务。
  • 冻结底层:将预训练模型的底层固定不变,只对顶层进行微调。
  • 逐层微调:从底层开始,逐层微调预训练模型,直到所有层都被微调。
  • 迁移学习:将预训练模型的知识迁移到新的任务中,以提高模型性能。这种方法通常使用微调顶层或冻结底层的方法。

目前来说,我们常用的方法一般是前三种。简单来说模型的参数就类比于,一个在大学学习到所有专业的知识的大学生,基于过往的学习经验以及对生活中的一些事情,已经有了属于自己的一套学习方法思维逻辑。而微调则是一个大学生毕业后从事某一种行业的工作,那他就要开始学习工作上的内容,来产出工作的成果。 下面我们就来介绍一些常用的微调方法。

Fine tuning

Fine tuning是一种在自然语言处理(NLP)中使用的技术,用于将预训练的语言模型适应于特定任务或领域。Fine tuning的基本思想是采用已经在大量文本上进行训练的预训练语言模型,然后在小规模的任务特定文本上继续训练它。

经典的Fine tuning方法包括将预训练模型与少量特定任务数据一起继续训练。在这个过程中,预训练模型的权重被更新,以更好地适应任务。所需的Fine-tuning量取决于预训练语料库和任务特定语料库之间的相似性。如果两者相似,可能只需要少量的Fine tuning。如果两者不相似,则可能需要更多的Fine tuning。

大模型微调方法综述_LLM

Prompt tuning

参数高效性微调方法中实现最简单的方法还是Prompt tuning(也就是我们常说的P-Tuning),固定模型前馈层参数,仅仅更新部分embedding参数即可实现低成本微调大模型

大模型微调方法综述_Fine-tuning_02

经典的Prompt tuning方式不涉及对底层模型的任何参数更新。相反,它侧重于精心制作可以指导预训练模型生成所需输出的输入提示或模板。主要结构是利用了一个prompt encoder(BiLSTM+MLP),将一些pseudo prompt先encode(离散token)再与input embedding进行拼接,同时利用LSTM进行 Reparamerization 加速训练,并引入少量自然语言提示的锚字符(Anchor,例如Britain)进一步提升效果。然后结合(capital,Britain)生成得到结果,再优化生成的encoder部分。但是P-tuning v1有两个显著缺点:任务不通用和规模不通用。在一些复杂的自然语言理解NLU任务上效果很差,同时预训练模型的参数量不能过小。

Prefix Tuning

如果分析 P-tuning,那不得不提到prefix-tuning技术,相对于fine-tuning,在调节模型的过程中只优化一小段可学习的continuous task-specific vector(prefix)而不是整个模型的参数。

Prefix Tuning针对不同的模型结构有设计不同的模式,以自回归的模型为例,不再使用token去作为前缀,而是直接使用参数作为前缀,比如一个l × d 的矩阵P 作为前缀,但直接使用这样的前缀效果不稳定,因此使用一个MLP层重参数化,并放大维度d,除了在embedding层加入这个前缀之外,还在其他的所有层都添加这样一个前缀。最后微调时只调整前缀的参数,大模型的参数保持不变。保存时只需要为每个任务保存重参数的结果即可。

大模型微调方法综述_微调_03

P-tuning v2

V2版本主要是基于P-tuning和prefix-tuning技术,引入Deep Prompt Encoding和Multi-task Learning等策略进行优化的。

实验表明,仅精调0.1%参数量,在330M到10B不同参数规模LM模型上,均取得和Fine-tuning相比肩的性能

大模型微调方法综述_LLM_04

下面是v1和v2框架对比,我们可以看到右侧的p-tuning v2中,将continuous prompt加在序列前端,并且每一层都加入可训练的prompts。在左图v1模型中,只将prompt插入input embedding中,会导致可训练的参数被句子的长度所限制。此外P-Tuning v2还包括以下改进:

  • 移除了Reparamerization加速训练方式。
  • 采用了多任务学习优化:基于多任务数据集的Prompt进行预训练,然后再适配的下游任务。
  • 舍弃了词汇Mapping的Verbalizer的使用,重新利用[CLS]和字符标签,跟传统finetune一样利用cls或者token的输出做NLU,以增强通用性,可以适配到序列标注任务。

大模型微调方法综述_微调_05

总而言之,P-tuning v2就是将Prefix-tuning应用到NLU任务上的一种方法。同时由于P-tuning v2每层插入了token,增大模型训练的改变量,所以更加适用于小一点的模型。

Lora

Lora的本质就是对所有权重矩阵套了一层“壳”,这些壳会对原来的预训练权重矩阵进行加减使其更加适合下游任务,即实现微调。他的假设前提是预训练语言模型具有低的"内在维度",因此认为在模型适配下游任务的过程中,权重更新也应该具有低的“内在秩”。

大模型微调方法综述_LLM_06

大模型微调方法综述_LLM_07

最终我们得到的一个权重文件会是各层的B A BABA,在推理时是需要计算一下W = W 0 + B A W = W_0 + BAW=W 0 +BA,就可以得到最终需要的微调之后的模型权重,该方法的好处如下所示

  1. 减少了需要推理的参数量
  2. 相较于添加adapter层的方式去微调模型,因为他并没有在模型中添加额外的层,只是在原来的权重上进行权重的加减,微调前后模型的推理时间不变
  3. 因为他最后生成的权重是各层的B A BABA,并没有改变原模型的权重参数,所以其结果相当于一个插件,可以即插即用,可以为多个不同的微调任务生成各自的lora微调权重值,也方便存储。 一般在使用lora去对模型微调的时候需要注意的参数就两个:r和lora_target_modules 。前者决定了lora微调时构造的矩阵的秩的大小(这里也可以简单的理解为矩阵B和A的大小),以及在大语言模型中应用的不同模块。后者模块的具体名称需要依据不同的模型去决定。