「Prompt Tuning也许会是深度学习时代的Feature Engineering问题,如何给各大任务设计合理的Prompts将会是很有意思的科学问题」–刘知远
虽然博主以前也看到了基于 Prompt-tuning 可以让GPT-3处理各种类型的任务,甚至拥有直接处理零样本和小样本学习能力。也整理过GPT,OpenAI CLIP,DALL-E 这些文章。但但但,没想到这个领域冲的好快,新范式、综述和应用都层出不穷,并且看到小伙伴的应用实验效果奇佳。便想重新整理一些文章,再重新认识一下Prompt-tuning!
GPT-3(Language Models are Few shot Learners)
众所周知GPT-3的优势在于它超级大大大大 ,可以针对特定任务来进行微调,即核心理念为:将所有自然语言处理的任务转换为语言模型任务。
所有任务都可以被统一建模,任务描述与任务输入视为语言模型的历史上下文,而输出则为语言模型需要预测的未来信息。即转变问题为根据文本的走向来 " 搞清楚 " 它们应该做什么事情,通过给模型一些提示(prompt),来让它根据任务直接学习。这种方法也被称为情境学习(in-context learning)或提示(prompting)。
Pre-train, Prompt, and Predict: A Systematic Survey of Prompting Methods in Natural Language Processing
然后直接来看大佬关于Prompt的综述。NLP技术的发展可分为4个阶段/范式,如下图。
具体“Prompt”的做法是,将人为的规则给到预训练模型,使模型可以更好地理解人的指令的一项技术,以便更好地利用预训练模型。例如,在文本情感分类任务中,输入为"I love this movie.",希望输出的是"positive/negative"中的一个标签。那么可以设置一个Prompt,形如:“The movie is ___”,然后让模型用来表示情感状态的答案(label),如positive/negative,甚至更细粒度一些的“fantastic”、“boring”等,将空补全作为输出。
Fine-tune和Prompt的区别?
prompting 更加依赖先验,而 fine-tuning 更加依赖后验。
这种方法的优点是给定一组合适的 prompt,以完全无监督的方式训练的单个 LM 就能够用于解决大量任务。然而该方法也存在一个问题——这种方法引入了 prompt 挖掘工程的必要性,即需要找出最合适的 prompt 来让 LM 解决面临的任务,即怎么做Prompt Engineering。
Fine-tune和Prompt的性能?
Prompt当然参数量要小很多啦。如下图是对于T5的两者对比图。
Fine-tune模型的每个副本都需要110亿个参数。而Prompt每个任务只需要20480个参数——减少超过5个数量级。
Prompt Engineering
主要目标是设计Prompt。比如 Overall it was a [z] movie,[z]是需要模型进行填充的空位,[z]的位置和数量决定了Prompt的类型。回顾一下CLIP就是使用的“A photo of a [z]”的prompt。
对于一些涉及多个输入的任务例如文本对分类,prompt 模板则必须包含至少两个输入的空间。人工设计模版或者自动化搜索模版一般是常用的方式。
Answer Engineering
与 prompt 工程相反,answer 工程的目的是搜索一个 answer 空间 Z 和一个到原始输出 Y 的映射,从而得到更细粒度的预测模型。比如把纯“positive”或“negative”的标签转变成选择恰当的词汇填空如“fantastic”,使情感分类任务转变为语言模型构建任务。下图是一些可参考的模版,当然此后的一些新方法都是想通过自动构建模版,以进一步释放语言模型潜能。
paper:https://arxiv.org/abs/2107.13586
Multi-prompt learning
多个prompt往往能提高效果,常见的集成方式如上图:
为什么Prompt会更有效?
实际上,prompt 可以看做是对预训练语言模型中已经记忆的知识的一种检索方式,由于 prompt 任务形式就是预训练任务,所以相比于 fine-tuning,当使用 prompt 形式向模型中输入样本时,预测时得到了“提示”,因此所需使用到的信息量是更多的。因为要用到更多的信息量,所以样本的类别分布在 prompt 视角之下都是稀疏的,这应该也是 prompt 在 few-shot 上效果显著的原因。
Prefix-Tuning: Optimizing Continuous Prompts for Generation
之前的工作如Prompting主要是人工设计模版或者自动化搜索模版(如上一篇综述所展示了很多模版)来进行预训练的,但人工设计的未知性比较影响模型性能+自动化搜索成本较高,为什么不从离散tokens转向连续的“soft prompt”呢?
因此prefix-tuning 的主要贡献是提出任务特定的trainable前缀prefix,这样直接为不同任务保存不同的前缀即可。如上图的下方,只需要不同任务设置不同的Prefix即可,因此实现上只需要存储一个大型transformer模型和多个学习的任务特定的prefix参数。
基于prompting方法的直觉,作者认为具有适当的上下文可以在不改变参数的情况下来引导LM。因此作者给模型若干的字词作为提示,比如想让模型生成“Obama”,那可以在其常见的搭配前加上上下文(例如abama的名字Barack),那么LM就会把更高的可能性分配给想要的单词,就能自动生成一个模版。符号化表示可以有两种形式:
然后其他的不变,语言模型参数固定,只更新前缀参数。这种连续性的生成方法在后续的P-tuning中也持续被探索。
paper:https://arxiv.org/abs/2101.00190
code:https://github.com/XiangLi1999/PrefixTuning
GPT Understands, Too
P-tuning V1的动机和prefix-tuning是类似的,也是探索可学习的可微模版,主要贡献是首次提出了用连续空间搜索的 embedding 做 prompt。如这篇清华文章的题目“GPT Understands, Too”,代表着它的表现想颠覆一直以来“GPT只能做生成,不能做理解”的结论。
首先关于“什么是模版”,直观上模版就是由自然语言构成的前缀/后缀。比如人工定义的话会变成类似「The capital of Britain is [MASK]」这种形式,然后也可是「Britain’ capital is [MASK]」或者「[MASK] is the capital of Britain 」等等。通过这些模版才能使得下游任务跟预训练任务一致,这样才能更加充分地利用原始预训练模型。
而P-tuning的目标是:不关心模版长什么样, 只需要知道模版由哪些 token 组成,该插入到哪里,插入后能不能完成我们的下游任务,输出的候选空间是什么就可以了。即不关心模版的“自然语言”要求,它只是为了更好地实现“一致性”但不是必须的。因此P-tuning 的做法是用上下文 x (「Britain」)、目标 y(「[MASK]」) 和去组合成一个prompt模版 t (「The capital of … is …」)。如下图,
上下文指蓝色的“Britain”,目标是红色的“[MASK]”,橘色的区域是想生成的模版。左边的图a是离散化搜索的做法,不一定是最优的。右边的是P-tuning,它通过预训练的嵌入层将一组离散输入 token (即pseudo prompts)映射到embedding,然后结合(capital,Britain)生成得到结果,再优化生成的encoder部分。这种方法可以找到更好的连续 prompt,并通过下游损失函数对连续 prompt 进行优化。
离散 vs 连续
最早研究自动模版的工作,有些是挖掘实体关系,有些需要大量样本进行基于梯度搜索(如autoprompt),在离散空间下搜索的自然语言模版。也有梯度粗筛+代入模版精筛等等。而连续的Prefix-Tuning和P-tuning 放弃了“模版由自然语言构成”这一要求,从而将其变成了可以简单梯度下降求解的连续参数问题,效果还更好。可能prompt的关键在于它是怎么用的,不在于它由什么构成。
paper:https://arxiv.org/abs/2103.10385
code:https://github.com/THUDM/P-tuning
P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks
P-tuning在一些复杂的自然语言理解NLU任务上效果很差(任务不通用)+预训练的参数量不能小(规模不通用)。因此V2版本主要是基于P-tuning和Prefix-tuning,引入Deep Prompt Encoding和Multi-task Learning等策略进行优化的。直接看模型图如下,左边是p-tuning的做法,右边是v2的改进。
对比起来主要的变动有:
paper:https://arxiv.org/abs/2110.07602
code:https://github.com/thudm/p-tuning-v2
OpenPrompt 工具包
Pipeline工具来了!先放link:
PPT: Pre-trained Prompt Tuning for Few-shot Learning
虽然Prompt-tuning非常有效,其在较小预训练模型上、在Few-shot的场景下表现一般,且相比于Model-tuning,Prompt-tuning的收敛速度较慢,需要训练更多的步数。虽然可以通过初始化soft prompts解决,那既然如此,为什么不对prompts也进行预训练呢!
这篇文章提出PPT,对prompt的预训练方法是利用把所有的分类任务分成三类:单句分类任务、句对分类任务和多项选择分类任务。然后对每一类都设计了一个自监督预训练任务,然后用预训练任务的prompts去初始化下游任务的prompts。
SPoT: Better Frozen Model Adaptation through Soft Prompt Transfer
SPOT用一个或多个源任务训练的prompts来初始化目标任务的prompts。比较重要的是,实验结论中有如下几种方式组合比较好,
https://arxiv.org/abs/2110.07904
On Transferability of Prompt Tuning for Natural Language Understanding
补一篇衡量prompt相似度的文章,细节待补,先上结论:prompt的迁移性很重要,但并不是相似度越高就越好。
https://arxiv.org/abs/2111.06719
下一篇博文将继续整理Prompt在多模态预训练中的应用,