写在前面,写这篇小文主要是为了记录一下本人在阅读中国人民大学的LLMBook的时候写的随笔,有的东西觉得比较重要就写了下来,后续会继续更新。
7.1
什么叫指令微调?
使用自然语言形式的数据对预训练后的大语言模型进行参数微调。也被叫做有监督微调、多任务提示训练。
可以这样理解,对于中译英任务,原始数据集是一行中文输入以及对应的英文输出,为了生成指令化的训练数据,就需要对上述的数据添加任务描述信息,比如“请把这个中文句子翻译成英文“,这样子就可以把一个NLP任务的数据实例通过自然语言形式进行表达。
指令微调的好处?
模型可以学习到”指令遵循“的能力,进而解决其他没有见过的NLP任务。
两个典型的指令数据合成技术:
Self-Instruct:生成更多的指令数据
1.指令数据生成:先选取少量指令数据作为示例,然后让GPT来生成新的微调数据,节约人工成本。
2.过滤与后处理:正如它的名字,提出低质量或者重复的生成实例。
Self-Instruct技术目前已经成为一种合成指令的基础方法,原始论文合成了Self-Instruct-52K数据集,之后有人又在此基础上合成了更多的指令数据(例如Alpaca)。
Evol-Instruct: 一种基于大模型的指令数据复杂化技术,该方法本身是基于初始指令数据集(如Alpaca指令数据集)进行拓展的。
1.指令演化:大语言模型作为指令演化器,进行深度演化(指令变得更复杂化、更难以解决)和广度演化(拓展指令主题范围、指令涉及的能力范围以及整体数据集的多样性)。
2.数据后处理:有点像Self-Instruct的二阶段,它会移除部分实例以保证数据集合的整体质量和多样性。
指令微调的作用:
指令微调旨在使用人工构建的指令数据集对大语言模型进行进一步训练,从而提升或解锁大语言模型的能力、并使得任务求解能力增强,有时无需下游任务的训练样本或者示例就可以解决在训练中从未见过的任务、并进行领域专业化适配。
基本上不同规模的语言模型都可以从指令微调中受益,提升的性能随着参数的规模增加而增加,而且有些经过指令微调过的小模型,甚至比有些没有经过微调的大模型更加出色!除了参数规模外,指令微调在不同的模型架构、预训练目标和模型微调方法上都可以获得比较稳定的收益。而且,相比于预训练,指令微调所需要的数据量非常少,可能只有万分之一甚至更少。
7.2
指令微调的训练策略:
在训练方式上和预训练比较相似,很多设置包括数据的组织形式都可以使用在预训练阶段采用的技术。下面是一些不同之处:
目标函数
预训练:采用语言建模损失,优化模型在每一个词元上的损失。
指令微调:序列到序列的损失,仅仅在输出部分计算损失,不计算输入的损失。
批次大小和学习率
预训练:已经学到了比较好的模型参数。
指令微调:对批次大小进行缩减,学习率进行小幅度的调整。
多轮对话数据的高效训练
预训练:对于一个多轮对话数据,一般是把多个对话拆分成多个不同的单独对话。
指令微调:在因果解码器架构中,输入输出没有明显的分界,所以可以直接把这个多轮对话数据直接一次性输入模型,通过设计损失掩码来针对每轮对话的模型输出部分的损失计算。更高效。
7.3
参数高效的模型微调,也被叫做轻量化微调(Linght Fine-tuning)
以LoRA(低秩适配微调技术)为例,由于大语言模型包含大量线性变换层,其中的参数矩阵往往维度很高,且往往是过参数化的,LoRA提出在预训练模型的参数矩阵上添加低秩分解矩阵来近似每层的参数更新,从而减少适配下游任务所需的训练参数。简单来说就是冻结原参数矩阵,对于新引入的A、B两个低秩矩阵,其中的参数会被训练,最终把训练得到的A和B转置相乘与被冻结的参数矩阵相加合并。
有两个LoRA的变种AdaLoRA和QLoRA,前者根据每个参数矩阵对训练结果的不同重要程度来赋予秩的高低(动态低秩适应技术),后者则是继续降低了微调所需要的显存大小。
LoRA技术在大语言模型中被应用的十分广泛,相比于此,适配器微调、前缀微调、提示微调在预训练语言模型中被较多地使用,但是在大模型语言中应用较少。