关键词:
文章来源 | 恒源云社区(专注人工智能/深度学习GPU免费加速平台,官方体验网址:https://gpushare.com)
原文作者 | Mathor
原文地址 | https://gpushare.com/forum/topic/681/%E6%9C%AA%E9%97%BBprompt%E5%90%8D?_=1635736812393&lang=zh-CN
个人觉得2021年NLP最火的两个idea,一个是对比学习(Contrastive Learning),另一个就是Prompt
浅谈我对PROMPT的理解
Prompt说简单也简单,看了几篇论文以及博客后发现其实就是构建一个语言模版,从而实现无监督训练。但是细想起来又觉得复杂,因为总感觉里面还有很多细节,因此本文就来从头梳理一下Prompt(Prompt很多地方会翻译成「范式」,但是「范式」这个词本身也不好理解,因此读者把他看作是「模板」即可)
今天我还与室友讨论预训练模型(例如BERT)到底做了什么,我给出的回答是
预训练模型提供了一个非常好的初始化参数,这组参数在预训练任务上的表现非常好(预训练损失非常低),但是由于下游任务千奇百怪,我们需要在这组参数的基础上进行Fine-tune以适应我们的下游任务(使得下游任务的损失值非常低)
上面这段话其实隐含了目前做NLP任务的大致流程,即"Pre-train, Fine-tune",而对我们来说实际上大部分时候都是直接拿别人预训练好的模型做Fine-tune,并没有Pre-train这一步
融入了Prompt的模式大致可以归纳成"Pre-train, Prompt, and Predict",在该模式中,下游任务被重新调整成类似预训练任务的形式。例如,通常的预训练任务有MLM(Masked Language Model),在文本情感分类任务中,对于"I love this movie"这句输入,可以在后面加上Prompt:“the movie is ___”,组成如下这样一句话:
I love this movie, the movie is ___
然后让预训练模型用表示情感的答案(例如"great"、"terrible"等)做完形填空,最后再将该答案转换为情感分类的标签。这样一来,我们就可以通过构造合适的「模板」,控制模型的输出空间,从而训练一个完全无监督的预训练模型来解决各种各样的下游任务
注意,Prompt设计的这种完形填空和MLM任务是有区别的,二者虽然都是都是词分类,但是候选集不同,MLM的候选词是整个词库,不过如果是生成任务,那么Prompt和MLM的候选集就是一样的,都是整个词库
如何构建PROMPT
对于输入文本
x
x
x,存在一个函数
f
Prompt
(
x
)
f_\\textPrompt(x)
fPrompt(x),将
x
x
x转化成
x
‘
x ‘
x‘的形式,即
x
’
=
f
Prompt
(
x
)
x^’=f_\\textPrompt(x)
x’=fPrompt(x)
该函数通常会进行两步操作:
- 使用一个模板,模板通常为一段自然语言句子,并且该句子包含两个空位置:用于填输入 x x x的位置[X]、用于生成答案文本 z z z的位置[Z]
- 把输入 x x x填到[X]的位置
以前文提到的例子为例,在文本情感分类任务中,假设输入是
x = "I love this movie"
使用的模板是
[X]. Overall, it was a [Z] movie
那么得到的 x ′ x ′ x′就应该是
I love this movie. Overall, it was a [Z] movie
在实际情况中,Prompt来填充答案的位置一般在句中或句末。如果在句中,一般称这种Prompt为Cloze Prompt;如果在句末,一般称这种Prompt为Prefix Prompt。 [ X ] [X] [X]和 [ Z ] [Z] [Z]的位置、数量以及使用模板句的不同,都有可能对结果造成影响,因此需要灵活调整
上面讲的都是简单的情感分类任务的Prompt设计,读者看到这里自然而然的会想到,其他NLP任务的Prompt如何设计呢?实际上刘鹏飞大神在他的论文中给我们提供了一些参考
Text Generation中摘要任务里有一个关键字TL;DR,这其实是Too Long; Don’t Read的缩写
PROMPT的选择非常重要且困难
有上述Prompt的基础后,我们可以得知Prompt的设计主要包含两部分:
- 模板T:例如
[X]. Overall, It was [Z]
- 标签词映射:即 [ Z ] [Z] [Z]位置预测输出的词汇集合与真实标签yyy构成的映射关系。例如,标签positive对应单词great,标签negative对应单词terrible
在基于Prompt的微调方法中,不同的模板和标签词对最终结果影响很大,下图是陈丹琦团队论文中的实验结果
从上图我们可以看出两点:
- 使用相同的「模板」,不同的「标签词」会产生不一样的效果。例如
great/terribel
和cat/dog
这两组标签词的效果不一样,而且即便是相同标签词,互换顺序也会导致最终效果有所变化,例如cat/dog
和dot/cat
- 使用相同「标签词」,对「模板」进行小改动(例如增删标点)也会呈现不同的结果
PROMPT的设计
Prompt大概可以从下面三个角度进行设计:
- Prompt的形状
- 人工设计模板
- 自动学习模板
Prompt的形状
Prompt的形状主要指的是 [ X ] [X] [X]和 [ Z ] [Z] [Z]的位置和数量。上文提到的Cloze Prompt与Maksed Language Model的训练方式非常类似,因此对于MLM任务来说,Cloze Prompt更合适;对于生成任务或者使用自回归LM解决的任务,Prefix Prompt更合适
人工设计模板
Prompt的模板最开始是人工设计的,人工设计一般基于人类的自然语言知识,力求得到语义流畅且高效的「模板」。例如,Petroni等人在著名的LAMA数据集中为知识探针任务人工设计了Cloze Templates;Brown等人为问答、翻译和探针等任务设计了Prefix Templates。人工设计模板的优点是直观,但缺点是需要很多实验、经验以及语言专业知识。下图是GPT Understands, Too论文中的一个实验结果
可以看到不同的Prompt只有细微的区别,有的甚至只是增加减少一个词,但是最后的结果会差几十个点
自动学习模板
为了解决人工设计模板的缺点,许多研究员开始探究如何自动学习到合适的模板。自动学习的模板又可以分为离散(Discrete Prompts)和连续(Continuous Prompts)两大类。离散方法主要包括:Prompt Mining,Prompt Paraphrasing,Gradient-based Search,Prompt Generation和Prompt Scoring;连续的则主要包括Prefix Tuning,Tuning Initialized with Discrete prompts,Hard-Soft Prompt Hybrid Tuning,P-Tuning v2
离散Prompts
简单说一下上述几种方法,首先是离散的Prompt Mining,这篇文章发表在TACL 2020,讲的是如何拿预训练语言模型当作「知识库」使用,并且引入了依存树和Paraphrase(转述)等方法来挖掘更好的「模板」,下图是实验结果
可以看到,被挖掘出来的若干「连接谓词」相比于人工设计的「模板」结果提升还是很明显的
有很多种方法可以实现Prompt Paraphrsing,例如「回译」,我们通过DeepL翻译看个例子:
这样我们就得到了x shares a border with y
的一个Prompt Paraphrasing:x and y share a boundary
论文BARTScore干脆给我们提供了一张表,里面有各种词组的同义替换,这个我再熟悉不过了,因为以前英语考试我也背过类似的东西
Gradient-based Search(基于梯度的搜索)是由论文AUTOPROMPT提出的,这篇文章发表在EMNLP 2020,它的主要思想用下面这张图就可以表示
上图中,a real joy
是原始的输入句子
x
i
n
p
xinp
xinp ,红色的Trigger tokens是由
x
i
n
p
xinp
xinp「激发」的相关词汇集合
x
t
r
i
g
x trig
xtrig ,根据
T
e
m
p
l
a
t
e
λ
Template λ
Templateλ的配置,将
x
t
r
i
g
xtrig
xtrig和
x
i
n
p
xinp
xinp 组合起来构造最终的输入
x
p
r
o
m
p
t
xprompt
xprompt,送入Masked LM预测情感标签。下面的表格增加了很多NLP其他任务的例子
关于如何生成 x t r i g xtrig xtrig集合,实际上主要使用的是HotFlip和对抗训练的思想,感兴趣的同学可以看原论文以及HotFlip: White-box adversarial examples for text classification、Universal Adversarial Triggers for Attacking and Analyzing NLP这两篇论文
Prompt Generation是陈丹琦团队的一项工作,主要是把Seq2Seq预训练模型T5应用到模板搜索的过程。T5基于多种无监督目标进行预训练,其中最有效的一个无监督目标就是:利用 < X > <X> <X>或 < Y > <Y> <Y>替换一个或多个连续span,然后生成对应输出。例如:
Thank you <X> me to your party <Y> week
T5会在
<
X
>
<X>
<X>生成for inviting
,在
<
Y
>
<Y>
<Y>生成last
。很显然,T5这种方式很适合生成模板,而且不需要指定模板的token数。具体来说,有三种可能的生成方式
<
S
1
S_1
S1> → <
X
X
X>
M
(
y
)
M(y)
M(y) <
Y
Y
Y> <
S
1
S_1
S1>
<
S
1
S_1
S1> → <
S
1
S_1
S1><
X
X
X>
M
(
y
)
M(y)
M(y) <
Y
Y
Y>
<
S
1
S_1
S1> <
S
2
S_2
S2>→ <
S
1
S_1
S1> <
X
X
X>
M
(
y
)
M(y)
M(y) <
Y
Y
Y> <
S
2
S_2
S2>
具体的模板生成过程如下图所示:
首先在标签词前后添加填充位
<
X
>
<X>
<X>和
<
Y
>
<Y>
<Y>(上面提到的三种生成方式),然后将其送入T5模型中,T5会自动在填充位生成序列,最后将标签词(great或terribel)转换为[MASK]标签,形成多个模板。具体过程中采用Beam Search的方法生成多个候选模板,然后对每一个候选模板利用dev集进行微调,选择其中一个最佳模板
我还想说一下这篇论文中另外一个有意思的点,最后送入模型进行预测的句子还拼接上了每种类别的「示例」(Demonstration),如下图所示
这种Prompt的设计有点像是在做语义相似度任务,
X
X
X为原始Input句子,已知
Y
Y
Y为正例,
Z
Z
Z为负例,构造了如下形式的输入:
X是[MASK]例?Y为正例;Z为负例
这有点像是编程语言中的三目运算符,或者说相当于让模型比较 X X X与 Y Y Y、 Z Z Z的语义相似度。这里我们自然而然会想问: Y Y Y、 Z Z Z是如何挑选出来的?实际上是依据下面两条规则:
- 对于每个原始输入句子,从每个类别中随机采样一个样本「示例」拼接到Prompt中
- 对于每个原始输入句子,在每个类别中,通过与Sentence-BERT进行相似度计算,从相似度最高的前50%样本中随机选择一个样本「示例」
连续Prompts
构造Prompt的初衷是能够找到一个合适的方法,让Pre-trained Language Model(PLM)更好地输出我们想要的结果,但其实并不一定要将Prompt的形式设计成人类可以理解的自然语言,只要机器理解就行了。因此,还有一些方法探索连续型Prompts——直接作用到模型的Embedding空间。连续型Prompts去掉了两个约束条件:
- 模版中词语的Embedding可以是整个自然语言的Embedding,不再只是有限的一些Embedding
- 模版的参数不再直接取PLM的参数,而是有自己独立的参数,可以通过下游任务的训练数据进行调整
Prefix Tuning最开始由Li等人提出,这是一种在输入句子前添加一组连续型向量的方法,该方法保持PLM的参数不动,仅训练前缀(Prefix)向量。Prefix Tuning的提出主要是为了做生成任务,因此它根据不同的模型结构定义了不同的Prompt拼接方式,在GPT类的Auto-Regressive(自回归)模型上采用的是
[
P
r
e
f
i
x
;
x
;
y
]
[Prefix;x;y]
[Prefix;x;y]的方式,在T5类的Encoder-Decoder模型上采用的是
[
P
r
e
f
i
x
;
x
;
P
r
e
f
i
x
[Prefix;x;Prefix
[Prefix;x;Prefix′
;
y
]
;y]
;y]的方式
输入部分
P
r
e
f
i
x
,
x
,
y
Prefix,x,y
Prefix,x,y的Position id分别记作
P
i
d
x
Pidx
Pidx,
X
i
d
x
Xidx
Xidx,
Y
i
d
x
Yidx
Yidx。Prefix Tuning初始化一个可训练的矩阵,记作
P
P
Pθ$∈R
∣P idx ∣×dim(h i ) ,其中
上述公式的含义是,索引iii如果属于前缀的部分,则从
P
θ
Pθ
Pθ中抽取向量;
i
i
i如果不是前缀部分,则由参数固定的预训练模型生成对应的向量。训练目标为:
max
ϕ
log
p
ϕ
(
y
∣
x
)
=
∑
i
∈
Yidx
log
p
ϕ
(
z
i
∣
h
<
i
)
\\mathop\\textmax\\limits_\\phi \\ \\log p_\\phi(y\\mid x) = \\sum\\limits_i\\in \\textY\\textidx \\log p\\phi (z_i\\mid h_<i)
ϕmax logpϕ(y∣x)=i∈Yidx∑logpϕ(zi∣h<i)
关于硕士毕业论文capstone项目的学习笔记(代码片段)
离我的硕士毕业论文的到来还有半年时间,目前我也已经完成了硕士阶段将近一半课程的学习,而学校的要求是我必须要在论文编写之前修够21个学分,GPA平均3.0,目前我已经修够了16个学分,并且GPA也能保持... 查看详情
论文笔记系列:轻量级网络--repvgg(代码片段)
...域初学者及研究者学习。➡️点击跳转到网站。RepVGG笔记论文名称:RepVGG:MakingVGG-styleConvNetsGreatAgain论 查看详情
mysql学习笔记2(代码片段)
表的相关操作1ALTERTABLE表名ADD字段名数据类型约束属性(字段);1添加字段2ALTERTABLE表名DROP字段名;2删除字段3ALTERTABLE表名MODIFY字段名数据类型字符集;3修改字段4ALTERTABLE旧表名RENAMETO新表名;4更改表名5ALTERTABLECHANGE旧字段名新字段名数... 查看详情
linux学习笔记2022-11-12---------linux基础(代码片段)
...支持编程3.6Shell是一种脚本语言4.修改主机名5.命令提示符prompt6.执行命令6.1Linux命令的执行过程是怎样的?6.2Linux命 查看详情
机器学习笔记-yolov7论文简述与推理(代码片段)
...xff0c;YOLOv7(正常)模型实现了51%以上的mAP。 论文 查看详情
论文笔记optiprompt:用prompt提取预训练模型中的客观事实
目录引言论文介绍1.Continuousprompt2.Prompt是否真的有用思考总结引言像BERT这样的预训练模型学习了大规模语料的词分布,同时也学习了语料中的客观事实。基于这样的直觉,Petronietal.(2019)提出LAMA模型,首次从BERT中以完... 查看详情
论文笔记系列:经典主干网络--vgg(代码片段)
✨写在前面:强烈推荐给大家一个优秀的人工智能学习网站,内容包括人工智能基础、机器学习、深度学习神经网络等,详细介绍各部分概念及实战教程,通俗易懂,非常适合人工智能领域初学者及研究者学... 查看详情
inductiverepresentationlearningonlargegraphs论文/graphsage学习笔记(代码片段)
1动机1.1过去的方法现存的方法大多是transductive的,也就是说,在训练图的时候需要将整个图都作为输入,为图上全部节点生成嵌入,每个节点在训练的过程中都是可知的。举个例子,上一次我学习了GCN模型... 查看详情
2021-10-22js学习笔记(代码片段)
JS学习笔记JavaScript基础<!--2.内嵌式的js--><script>//alert('沙漠骆驼');</script><!--3.外部jsscript双标签--><scriptsrc="my.js"></script>输入输出框//这是一个输入框prompt('请输 查看详情
sass学习笔记(代码片段)
旧版本//声明变量$mainColor:red.navwidth:100pxheight:100pxcolor:$mainColorulpadding:0margin:0文件后缀名sass新版本$mainColor:red;.navwidth:100px;height:100px;color:$mainColor;ulpadding:0;margin:0;文件后缀名scss声明变量$max 查看详情
segnet论文笔记及其创新点代码解析(代码片段)
论文名称:SegNet:ADeepConvolutionalEncoder-DecoderArchitectureforImageSegmentation论文链接:SegNet项目地址:SegNetcaffe版本Motivation1、深度学习需提取图像的高阶语义特征,需要连续的下采样,连续的下采样会导致图像边界信... 查看详情
卷积神经网络笔记--吴恩达深度学习课程笔记(代码片段)
...的的讲解主要参考1998年计算机科学家YannLeCun发布的一篇论文《Gradientbasedlearningappliedtodocument-recognition》大家可以找到这篇论文结合学习,针对该网络,首先大家需要了解一下图像中的常用操作卷积,卷积这个词是信号... 查看详情
d3.js学习笔记(代码片段)
...五月病犯了,不想看书,不想写代码,不想看论文,不想写论文,虽然什么事情都不想做,不过还是找点事情做吧 查看详情
最为详细的卷积神经网络笔记--吴恩达深度学习课程笔记(代码片段)
...的的讲解主要参考1998年计算机科学家YannLeCun发布的一篇论文《Gradientbasedlearningappliedtodocument-recognition》大家可以找到这篇论文结合学习,针对该网络,首先大家需要了解一下图像中的常用操作卷积,卷积这个词是信号... 查看详情
golang学习笔记5——接口(代码片段)
接口的声明golang中的接口声明方式如下:type接口名interface 方法名(参数)返回值例子://Writer接口typeWriterinterface //Write方法,参数为一个字符串 Write(sstring)//Stringer接口typeStringerinterface //String方法,参数为空, 查看详情
[ai助力]cs143学习笔记1(代码片段)
...lowchart流程图AIflashcards抽认卡AI费曼学习法workflow总结关于prompt相关资源之后想做的以下笔记为AI生成+我部分修改,详见workflowAIsummaryAlecturebyProfessorAlexatStanfordUniversityonthetopicofcompilersandinterpreters.Thelecturediscussesthedifferencesbetwe... 查看详情
go语言学习笔记—函数:匿名函数——没有函数名的函数(代码片段)
go语言支持匿名函数,即在需要使用函数时,再定义函数。1.匿名函数没有函数名,只有函数体声明匿名函数func(参数列表)(返回参数列表)函数体在声明时调用匿名函数func(dataint)fmt.Println("hello",data)(100)//(100)表示... 查看详情
text一组jupyter笔记本依赖没有prompt-toolkit版本冲突。(代码片段)