大模型微调实践|Prompt tuning、PET、Prefix tuning、P-tuning的原理、区别与代码解析(一)

本文针对易混淆的Prompt learning、PET做详细原理阐释,并列出其区别,最后附简易版实现代码。>>加入极市CV技术交流群,走在计算机视觉的最前沿

这几天在复现关于大模型各种微调方法的代码,被各种P字母开头的微调方法绕的有些眼花缭乱,所以整理一下相关概念、区别以及实现代码。

这个系列目录如下:

  • prompt tuning

    • 一个人工构建模板的实例:PET(Pattern-Exploiting Training)
  • prefix tuning

  • P-tuning

  • P-tuning v2

具体每个部分会分为论文、原理、实现细节以及对应关键代码进行详细介绍。

由于涉及到的内容非常多,本篇就主要讲Prompt Tuning,并以其中比较重要的PET为例,具体介绍其实现原理,后面的系列文再具体介绍prefix tuning、P-tuning、P-tuning v2,最后会做一个总结。

*论文*

Prompt tuning 里程碑式的作品:The Power of Scale for Parameter-Efficient Prompt Tuning

这篇论文主要解答的问题:Prompt Tuning比Fine-tuning在哪些情况下表现更好?

结论很简单:离散的Prompt Tuning(Prompt Design)基本不能达到fine-tuning的效果;Soft Prompt Tuning在模型增大时可以达到接近fine-tuning的效果,并且有进一步超越fine-tuning的趋势。

*原理*

Prompt tuning 其实是一个比较范围比较广的概念,主要通过调整模板来实现对模型的微调。

具体在论文中,给每个任务定义了自己的Prompt,然后拼接到数据上作为输入,但只在输入层加入prompt tokens,并且不需要加入 MLP进行调整来解决难训练的问题。

*具体实现*

这里我们来举一个通过人工构建的模版与BERT的MLM模型结合,在零样本、小样本乃至半监督下取得非常好的效果的例子——PET(Pattern-Exploiting Training)

对应论文是 It’s Not Just Size That Matters: Small Language Models Are Also Few-Shot Learners

1. MLM简介

MLM,全称“Masked Language Model”,可以翻译为“掩码语言模型”,实际上就是一个完形填空任务,随机Mask掉文本中的某些字词,然后要模型去预测被Mask的字词,示意图如下:

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=data%3Aimage%2Fsvg%2Bxml%2C%253C%253Fxml%20version%3D’1.0’%20encoding%3D’UTF-8’%253F%253E%253Csvg%20width%3D’1px’%20height%3D’1px’%20viewBox%3D’0%200%201%201’%20version%3D’1.1’%20xmlns%3D’http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg’%20xmlns%3Axlink%3D’http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink’%253E%253Ctitle%253E%253C%2Ftitle%253E%253Cg%20stroke%3D’none’%20stroke-width%3D’1’%20fill%3D’none’%20fill-rule%3D’evenodd’%20fill-opacity%3D’0’%253E%253Cg%20transform%3D’translate(-249.000000%2C%20-126.000000&pos_id=img-793wrDcB-1752733472918)’ fill=‘%23FFFFFF’%3E%3Crect x=‘249’ y=‘126’ width=‘1’ height=‘1’%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)

其中被Mask掉的部分,可以是直接随机选择的Token,也可以是随机选择连续的能组成一整个词的Token,后者称为WWM(Whole Word Masking)。

2. MLM在微调任务中的应用:将任务转为完形填空

MLM通过模板设计,将任务转为完形填空,可以用于小样本学习或半监督学习,某些场景下甚至能做到零样本学习,并达到很好效果。

怎么将我们要做的任务跟MLM结合起来呢?很简单,给任务一个文本描述,然后转换为完形填空问题即可。举个例子,假如给定句子“这趟北京之旅我感觉很不错。”,那么我们补充个描述,构建如下的完形填空:

我们限制空位处只能填一个“很”或“不”,问题就很清晰了,就是要我们根据上下文一致性判断是否满意,如果“很”的概率大于“不”的概率,说明是正面情感倾向,否则就是负面的,这样我们就将情感分类问题转换为一个完形填空问题了。

上述问题可以用MLM模型给出预测结果,而MLM模型的训练可以不需要监督数据,因此理论上这能够实现零样本学习了。
上面是二分类的例子,再举一个多分类的例子,比如新闻分类。

理论上,一个好的MLM模型应当能预测出“体育”二字来。

3. 模板的设计(Pattern-Exploiting)

那么其实我们可以总结一些规律了,就是给输入的文本增加一个前缀或者后缀描述,并且Mask掉某些Token,转换为完形填空问题,这样的转换在原论文中称为Pattern,这个转换要尽可能与原来的句子组成一句自然的话,不能过于生硬,因为预训练的MLM模型就是在自然语言上进行的。

我们需要构建预测Token的候选空间,并且建立Token到实际类别的映射,这在原论文中称为Verbalizer,比如情感分类的例子,我们的候选空间是 {很,不} ,映射关系是 很→正面,不→负面,候选空间与实际类别之间不一定是一一映射,比如我们还可以加入“挺”、“太”、“难”字,并且认为{很,挺,太}→正面以及{不,难}→负面,等等。

不少NLP任务都有可能进行这种转换,但显然这种转换一般只适用于候选空间有限的任务,说白了就是只用来做选择题,常见任务的就是文本分类。

那么我们再用比较书面的话来重新阐述总结一下,PVP的概念就变得比较容易理解了。下面这段摘自这篇很出名的五万字综述 [Prompt-Tuning:深度解读一种新的微调范式]

PET详细地设计了Prompt-Tuning的重要组件——Pattern-Verbalizer-Pair(PVP),并描述了Prompt-tuning如何实现Few-shot/Zero-shot Learning,如何应用在全监督和半监督场景(iPET)。

PET设计了两个很重要的组件:

  • Pattern(Template):也叫Template,其为额外添加的带有[mask]标记的短文本,通常一个样本只有一个Pattern(因为我们希望只有1个让模型预测的[mask]标记)。上文也提到,不同的任务、不同的样本可能会有其更加合适的pattern,因此 如何构建合适的pattern是Prompt-Tuning的研究点之一
  • Verbalizer :标签词的映射,对于具体的分类任务,需要选择指定的标签词(label word)。例如情感分析中,我们期望Verbalizer可能是positive和negative是类标签。同样,不同的任务有其相应的label word,但需要注意的是,Verbalizer的构建需要取决于对应的Pattern。因此,如何构建Verbalizer是另一个研究挑战

上述两个组件被称为Pattern-Verbalizer-Pair(PVP),一般记作 ,在后续的大多数研究中均采用这种PVP组件。

4. 论文微调方法

由于同一个任务可以有多种不同的Pattern,原论文是这样处理的:

1、对于每种Pattern,单独用训练集Finetune一个MLM模型出来;

2、然后将不同Pattern对应的模型进行集成,得到融合模型;

3、用融合模型预测未标注数据的伪标签;

4、用伪标签数据Finetune一个常规的(非MLM的)模型

*代码详解*

因为PET主要是人工来构建模板,所以核心是模板怎么构建、以及训练数据如何构造。这里就借苏神的代码来讲解一下。

1. 模板设计

首先来构造实验模板,我们采用一个固定前缀 满意 ,其中空位处候选词语都为很和不:

P:____满意。

构造示例:__满意。这趟北京之旅我感觉很不错。

对应代码:

# 对应的任务描述  
# 为什么mask_idx是1,因为第0位是'[CLS]'标记,这里的mask_id为1就是替换'很满意。'中的第一个字符'很'  
prefix = u'很满意。'  
mask_idx = 1                           
pos_id = tokenizer.token_to_id(u'很')  
neg_id = tokenizer.token_to_id(u'不')

2. 数据构造

class data_generator(DataGenerator):  
    """数据生成器  
    """    def __iter__(self, random=False):
        batch_token_ids, batch_segment_ids, batch_output_ids = [], [], []  
        for is_end, (text, label) in self.sample(random):  
            if label != 2:  #只有带标注的需要
                text = prefix + text  
            token_ids, segment_ids = tokenizer.encode(text, maxlen=maxlen)  

            source_ids, target_ids = token_ids[:], token_ids[:]  
            if label == 0:  
                source_ids[mask_idx] = tokenizer._token_mask_id  
                target_ids[mask_idx] = neg_id  
            elif label == 1:  
                source_ids[mask_idx] = tokenizer._token_mask_id  
                target_ids[mask_idx] = pos_id  
            batch_token_ids.append(source_ids)  
            batch_segment_ids.append(segment_ids)  
            batch_output_ids.append(target_ids)  
            if len(batch_token_ids) == self.batch_size or is_end:  
                batch_token_ids = sequence_padding(batch_token_ids)  
                batch_segment_ids = sequence_padding(batch_segment_ids)  
                batch_output_ids = sequence_padding(batch_output_ids)  
                yield [  
                    batch_token_ids, batch_segment_ids, batch_output_ids  
                ], None
                batch_token_ids, batch_segment_ids, batch_output_ids = [], [], []

完整实现代码及相关数据集可以直接去苏神的github下载:https://github.com/bojone/Pattern-Exploiting-Training/tree/master

*引申*

Prompt tuning确实是一个很宽泛的概念,因为在PVP这一块有很多可探索的空间,因此学术界已经涌现出一批基于Prompt-Tuning的方案试图探索如何自动构建PVP。

这里主要总结几种成熟的Pattern(Template)构建方法。可以罗列为如下几点:

  • 人工构建(Manual Template):类似于PET;
  • 启发式法(Heuristic-based Template):通过规则、启发式搜索等方法构建合适的模板;
  • 生成(Generation):根据给定的任务训练数据(通常是小样本场景),生成出合适的模板;
  • 词向量微调(Word Embedding):显式地定义离散字符的模板,但在训练时这些模板字符的词向量参与梯度下降,初始定义的离散字符用于作为向量的初始化;
  • 伪标记(Pseudo Token):不显式地定义离散的模板,而是将模板作为可训练的参数;

前面3种也被称为离散的模板构建法(记作 Hard Template、 Hard Prompt、 Discrete Template 、 Discrete Prompt),其旨在直接与原始文本拼接显式离散的字符,且在训练中 始终保持不变 。这里的保持不变是指 这些离散字符的词向量(Word Embedding)在训练过程中保持固定 。通常情况下,离散法不需要引入任何参数

后面2种则被称为连续的模板构建法(记作 Soft Template 、 Soft Prompt、 Continuous Template、 Continuous Prompt ),其旨在让模型在训练过程中根据具体的上下文语义和任务目标对模板参数进行连续可调。这套方案的动机则是认为离散不变的模板无法参与模型的训练环节,容易陷入局部最优,而如果将模板变为可训练的参数,那么不同的样本都可以在连续的向量空间中寻找合适的伪标记,同时也增加模型的泛化能力。因此, 连续法需要引入少量的参数并让模型在训练时进行参数更新

其实我们后面具体介绍的prefix tuning、P-tuning、P-tuning v2都属于连续的模板构建,通过把传统人工设计模版中的真实token替换成可微的virtual token,转换为模型中可以学习的参数进行更新,只是他们之间存在细微差别,具体原理与区别、代码详解我们将在下一篇系列文中阐述。

零基础入门AI大模型

今天贴心为大家准备好了一系列AI大模型资源,包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

有需要的小伙伴,可以点击下方链接免费领取【保证100%免费

点击领取 《AI大模型&人工智能&入门进阶学习资源包》

1.学习路线图

在这里插入图片描述

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己整理的大模型视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

在这里插入图片描述

在这里插入图片描述

(都打包成一块的了,不能一一展开,总共300多集)

3.技术文档和电子书

这里主要整理了大模型相关PDF书籍、行业报告、文档,有几百本,都是目前行业最新的。
在这里插入图片描述

4.LLM面试题和面经合集

这里主要整理了行业目前最新的大模型面试题和各种大厂offer面经合集。
在这里插入图片描述

👉学会后的收获:👈

• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集

5.免费获取

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码或者点击以下链接都可以免费领取【保证100%免费】

点击领取 《AI大模型&人工智能&入门进阶学习资源包》

在这里插入图片描述

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐