论文名称:Prefix-Tuning: Optimizing Continuous Prompts for Generation
论文地址:https://arxiv.org/pdf/2101.00190.pdf
论文代码:https://github.com/XiangLi1999/PrefixTuning
想搞prompt,看了好多篇,挑着记录一下。好快,明年就要毕业啦!
1. 简介
微调是利用大型预训练语言模型来执行下游任务时所使用的方法。但是,它会修改所有语言模型参数,因此需要为每个任务存储完整的模型。本文提出prefix-tuning,一种用于自然语言处理任务的可以替代fine-tune的轻量级方法,它冻结语言模型的参数而代之以优化一系列连续的任务特定(task-specific)向量,称之为prefix。前缀微调从提示学习中获得启发,引导后续的token关注这个prefix,就好像它是虚拟的单词一样。实验结果表明,仅需修改0.1%的参数,即可以在量和小量数据上达到不错的效果,在低数据集条件下优于微调,并且能更好地外推到训练过程中没有发现的主题的例子。
微调是利用大型预训练语言模型(LM)来执行下游任务时所使用的方法,但它需要更新和存储LM的所有参数。因此,要构建和部署依赖于预训练语言模型的NLP系统,目前需要单独为每个任务对LM参数修改后的模型进行存储。考虑到LM的大尺寸,这可能会很话费很大的存储空间。
这种问题的一个自然解决方法是轻量级微调,它冻结了大部分预训练模型的参数,并使用一个小训练模块来增强预训练模型。
极端情况下,GPT-3甚至不需要任何特定任务的finetune,就可以被使用。或者,用户仅需添加某个自然语言任务指令(例如,摘要任务中的TL;DR)以及少量的输入样例,然后就能从LM生成输出。这种方法被称为in-context learning或prompting。
在本文中,我们提出了Prefix-Tuning,一种轻量级替代方法,可以用于自然语言生成(NLG)任务。考虑生成一个数据表格的文字描述的任务,如图1所示,任务输入是表格的线性表示(例如,“name: Starbucks | type: coffee shop”),输出是文字描述(例如,“Starbucks serves coffee.”)。Prefix-tuning将一系列continuous task-specific的向量序列添加到输入中,我们称之为prefix,如图1下方所示的红色块。Prefix作为子序列字符,Transformer可以把它作为一系列“virtual tokens”进行计算,但与prompting不同,prefix完全由不对应于真实字符的参数组成。与图1上方中的微调相比,Prefix-tuning仅优化prefix参数。因此,我们只需要存储一个大型transformer模型和多个学习的任务特定的prefix参数,这对每个任务仅产生了非常小的开销。
与微调方法相比,Prefix-Tuning是模块化的:我们训练一个上游prefix,来指导下游未被修改的LM。因此,单个LM可以立即支持许多任务。在对应于不同用户的个性化任务中,我们可以仅在该用户的数据上训练出用户单独的prefix,从而避免数据交叉污染。此外,基于prefix的架构使我们甚至可以在单个batch中处理多用户或多任务数据,而这对其他轻量级fine-tuning方法是不可能的。
2. 核心要点
template的构建:不采用离散的template token,而使用连续可调的矩阵来调整template;
将prompt-tuning用于语言模型的生成任务上;
2.1 Motivation
- 传统的fine-tuning是在大规模预训练语言模型上完成的,而大规模模型非常贵。
- 一种解决这个问题的方法是采用轻量级的微调(ligthweight fine-tuning),即先固定预训练语言模型的参数,然后只对一小部分的可训练参数进行微调。
- GPT-3提出了in-context learning,不需要引入任何参数的fine-tuning方法,然而,因为Transformers 只能基于有界长度的上下文(例如,GPT3最大长度为2048个token),因此在线学习仅限于非常小的训练集。
- 受到prompt的启发,提出一种prefix-tuning方法用于生成任务上,只优化前缀。因此,我们只需要存储LM的一个副本和一个学习到的任务特定前缀,这为每个额外的任务带来非常小的开销,Prefix-tuning属于广义上的轻量级微调,即冻结大部分预训练参数,仅一小部分参数。
- 在特定的任务上,只需要保存prefix部分的参数即可。
2.2 问题描述
table-to-text任务:输入 X XX 表示一个线性的表格,输出 Y YY 表示一个短文本;
对于自回归LM,在某一时刻 i,Transformer的每一层的隐状态向量拼接起来之后用于预测下一个词;直接在输入前面拼接prefix,自回归模型表示为 z = [ prefix ; x ; y ];对于编码器-解码器LM,encoder和decoder均前置一个前缀,即z = [ prefix ; x ; prefix ′ ; y ] 。本质上,其实是在每一层每一个token的K、V向量之前拼接上一个Prefix向量:
可以将token优化为连续词嵌入,而不是优化离散标记,其效果将向上传播到所有 Transformer 激活层,然后向右传播到后续标记。 这比需要匹配真实单词嵌入的离散提示更具表现力。 同时,这不如干预所有激活层的表现力,这避免了长期依赖并包括更多可调参数。 因此,Prefix-Tuning优化了前缀部分对应的所有层参数。
3. Intuition
受到prompting的启发,我们认为具有适当的上下文可以在不改变参数的情况下来引导LM。比如我们想生成一个词,我们可以找到一个合适的上下文添加到单词前,LM为我们生成期望最高的下一个词(也可以采用束搜索),这种方法有时候会成功,有时候会失败。
直观的理解,加prompt实际上就是在改装输入x,期望可以指导它抽取我们想要的特征,然后影响encoder,最后影响结果y。但是作者认为prompt它是一个离散的值,它可能不是一个明显的instructions,于是作者的方法是用一个连续的字符来替换之前的离散的instruction,这可能更具有表现力。这方法类似于lora,在特定的任务上,我只需要选择不同训练好的prefix。
4. Method
Prefix-tuning将自回归LM的prefix添加到序列前,以获取z = [ Prefix ; x ; y ],或者为编码器和编码器都添加prefix,以获取z = [ Prefix ; x ; Prefix ′ ; y ],我们使用表示前缀索引序列,∣∣表示前缀的长度。
语言模型参数ϕ \phiϕ是固定的,而前缀参数 θ 是唯一可训练参数。