大规模语言模型高效参数微调--BitFit/Prefix/Prompt 微调系列( 二 )


Prefix Tuning在 Prefix Tuning 之前的工作主要是人工设计离散的模版或者自动化搜索离散的模版 。对于人工设计的模版, 模版的变化对模型最终的性能特别敏感,加一个词、少一个词或者变动位置都会造成比较大的变化 。而对于自动 化搜索模版 ,  成本也比较高;同时,以前这种离散化的 token 搜索出来的结果可能并不是最优的 。除此之外,传 统的微调范式利用预训练模型去对不同的下游任务进行微调 ,  对每个任务都要保存一份微调后的模型权重,一 方面微调整个模型耗时长;另一方面也会占很多存储空间 。基于上述两点,Prefix Tuning 提出固定预训练 LM,为LM 添加可训练, 任务特定的前缀, 这样就可以为不同任务保存不同的前缀, 微调成本也?。?nbsp;同时, 这种 Prefix  实际就是连续可微的 Virtual Token  (Soft Prompt/Continuous Prompt),相比离散的 Token  , 更好优化,效果更好 。
那么 prefix 的含义是什么呢?prefix 的作用是引导模型提取 x 相关的信息 ,  进而更好地生成 y 。例如,我们 要做一个 summarization 的任务 ,  那么经过微调后,prefix 就能领悟到当前要做的是个“总结形式”的任务 ,  然后 引导模型去 x 中提炼关键信息;如果我们要做一个情感分类的任务,prefix 就能引导模型去提炼出 x 中和情感相 关的语义信息,以此类推 。这样的解释可能不那么严谨,但大家可以大致体会一下 prefix 的作用 。
Prefix Tuning 是在输入 token 之前构造一段任务相关的 virtual tokens 作为 Prefix , 然后训练的时候只更新 Prefix 部分的参数,而 PLM 中的其他部分参数固定 。针对不同的模型结构,需要构造不同的 Prefix:

  • 针对自回归架构模型:在句子前面添加前缀, 得到 z = [PREFIX; x; y] , 合适的上文能够在固定 LM 的情况 下去引导生成下文(比如:GPT3 的上下文学习) 。
  • 针对编码器-解码器架构模型:Encoder 和 Decoder 都增加了前缀,得到 z = [PREFIX; x; PREFIX0; y] 。Encoder 端增加前缀是为了引导输入部分的编码,Decoder 端增加前缀是为了引导后续 token 的生成 。

大规模语言模型高效参数微调--BitFit/Prefix/Prompt 微调系列

文章插图
图片
上部分的微调更新所有 Transformer 参数(红色框) , 并且需要为每个任务存储完整的模型副本 。下部分 的 Prefix Tuning 冻结了 Transformer 参数并且只优化前缀(红色框)
该方法其实和构造 Prompt 类似,只是 Prompt 是人为构造的“显式”的提示,并且无法更新参数, 而 Prefix 则是可以学习的“隐式”的提示 。同时 , 为了防止直接更新 Prefix 的参数导致训练不稳定和性能下降的情况,在 Prefix 层前面加了 MLP 结构, 训练完成后, 只保留 Prefix 的参数 。除此之外, 通过消融实验证实 ,  只调整 embedding 层的表现力不够,将导致性能显著下降,因此,在每层都加了 prompt 的参数,改动较大 。
Prefix Tuning 虽然看起来方便 , 但也存在以下两个显著劣势:
Prompt Tuning大模型全量微调对每个任务训练一个模型,开销和部署成本都比较高 。同时, 离散的 prompts  (指人工设计 prompts 提示语加入到模型) 方法,成本比较高,并且效果不太好 。Prompt Tuning 通过反向传播更新参数来学习 prompts,而不是人工设计 prompts;同时冻结模型原始权重,只训练 prompts 参数,训练完以后,用同一个模型 可以做多任务推理 。
大规模语言模型高效参数微调--BitFit/Prefix/Prompt 微调系列

文章插图
图片
模型调整需要为每个任务制作整个预训练模型的特定任务副本下游任务和推理必须在分开批次 。Prompt Tuning 只需要为每个任务存储一个小的特定于任务的提示,并且使用原始预训练模型启用混合任务推理 。
Prompt Tuning 可以看作是 Prefix Tuning 的简化版本 , 它给每个任务定义了自己的 Prompt,然后拼接到数据 上作为输入,但只在输入层加入 prompt tokens , 并且不需要加入 MLP 进行调整来解决难训练的问题 。
通过实验发现,随着预训练模型参数量的增加,Prompt Tuning 的方法会逼近全参数微调的结果 。同时 ,  Prompt Tuning 还提出了 Prompt Ensembling,也就是在一个批次(Batch) 里同时训练同一个任务的不同 prompt  (即采用 多种不同方式询问同一个问题)  , 这样相当于训练了不同模型,比模型集成的成本小多了 。除此之外 ,  Prompt Tuning 论文中还探讨了 Prompt token 的初始化方法和长度对于模型性能的影响 。通过消融实验结果发现,与随机 初始化和使用样本词汇表初始化相比,Prompt Tuning 采用类标签初始化模型的效果更好 。不过随着模型参数规 模的提升,这种 gap 最终会消失 。Prompt token 的长度在 20 左右时的表现已经不错(超过 20 之后,提升Prompt token 长度 ,  对模型的性能提升不明显了),同样的,这个 gap 也会随着模型参数规模的提升而减小(即对于超大 规模模型而言,即使 Prompt token 长度很短,对性能也不会有太大的影响) 。


推荐阅读