文章來源 | 恒源云社區
原文地址 |未聞Prompt名
原文作者 | Mathor
前言:
個人覺得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
對于輸入文本 ,存在一個函數
Prompt
,將
轉化成
的形式,即
該函數通常會進行兩步操作:
- 使用一個模板,模板通常為一段自然語言句子,并且該句子包含兩個空位置:用于填輸入
的位置
、用于生成答案文本
的位置
- 把輸入
填到
的位置
以前文提到的例子為例,在文本情感分類任務中,假設輸入是
x = "I love this movie"
使用的模板是
[X]. Overall, it was a [Z] movie
那么得到的 就應該是
I love this movie. Overall, it was a [Z] movie
在實際情況中,Prompt 來填充答案的位置一般在句中或句末。如果在句中,一般稱這種 Prompt 為 Cloze Prompt;如果在句末,一般稱這種 Prompt 為 Prefix Prompt。 和
的位置、數量以及使用模板句的不同,都有可能對結果造成影響,因此需要靈活調整
上面講的都是簡單的情感分類任務的 Prompt 設計,讀者看到這里自然而然的會想到,其他 NLP 任務的 Prompt 如何設計呢?實際上劉鵬飛大神在他的論文中給我們提供了一些參考
Text Generation 中摘要任務里有一個關鍵字
TL;DR
,這其實是Too Long; Don't Read
的縮寫
Prompt 的選擇非常重要且困難
有上述 Prompt 的基礎后,我們可以得知 Prompt 的設計主要包含兩部分:
-
模板 T:例如
[X]. Overall, It was [Z]
-
標簽詞映射:即
位置預測輸出的詞匯集合與真實標簽
構成的映射關系。例如,標簽 positive 對應單詞 great,標簽 negative 對應單詞 terrible
在基于 Prompt 的微調方法中,不同的模板和標簽詞對最終結果影響很大,下圖是陳丹琦團隊論文中的實驗結果
從上圖我們可以看出兩點:
- 使用相同的「模板」,不同的「標簽詞」會產生不一樣的效果。例如
great/terribel
和cat/dog
這兩組標簽詞的效果不一樣,而且即便是相同標簽詞,互換順序也會導致最終效果有所變化,例如cat/dog
和dot/cat
- 使用相同「標簽詞」,對「模板」進行小改動(例如增刪標點)也會呈現不同的結果
Prompt 的設計
Prompt 大概可以從下面三個角度進行設計:
- Prompt 的形狀
- 人工設計模板
- 自動學習模板
Prompt 的形狀
Prompt 的形狀主要指的是 和
的位置和數量。上文提到的 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
是原始的輸入句子 xinp,紅色的 Trigger tokens 是由 inp「激發」的相關詞匯集合
trig,根據 Template
的配置,將
trig 和
inp 組合起來構造最終的輸入
prompt,送入 Masked LM 預測情感標簽。下面的表格增加了很多 NLP 其他任務的例子
關于如何生成
trig 集合,實際上主要使用的是 HotFlip 和對抗訓練的思想,感興趣的同學可以看原論文以及 HotFlip: White-box adversarial examples for text classification、Universal Adversarial Triggers for Attacking and Analyzing NLP 這兩篇論文
Prompt Generation 是陳丹琦團隊的一項工作,主要是把 Seq2Seq 預訓練模型 T5 應用到模板搜索的過程。T5 基于多種無監督目標進行預訓練,其中最有效的一個無監督目標就是:利用 或
替換一個或多個連續 span,然后生成對應輸出。例如:
Thank you <X> me to your party <Y> week
T5 會在 <X> 生成 for inviting
,在 生成
last
。很顯然,T5 這種方式很適合生成模板,而且不需要指定模板的 token 數。具體來說,有三種可能的生成方式
<> <span>→</span> <
>
<
> <
>
<> <span>→</span> <
><
>
<
>
<> <
><span>→</span> <
> <
>
<
> <
>
具體的模板生成過程如下圖所示:
首先在標簽詞前后添加填充位 和
(上面提到的三種生成方式),然后將其送入 T5 模型中,T5 會自動在填充位生成序列,最后將標簽詞(great 或 terribel)轉換為 [MASK] 標簽,形成多個模板。具體過程中采用 Beam Search 的方法生成多個候選模板,然后對每一個候選模板利用 dev 集進行微調,選擇其中一個最佳模板
我還想說一下這篇論文中另外一個有意思的點,最后送入模型進行預測的句子還拼接上了每種類別的「示例」(Demonstration),如下圖所示
這種 Prompt 的設計有點像是在做語義相似度任務, 為原始 Input 句子,已知
為正例,
為負例,構造了如下形式的輸入:
X是[MASK]例?Y為正例;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(自回歸)模型上采用的是 的方式,在 T5 類的 Encoder-Decoder 模型上采用的是
′
的方式
輸入部分 的 Position id 分別記作
。Prefix Tuning 初始化一個可訓練的矩陣,記作
θ
|Pidx|×dim?(hi),其中
上述公式的含義是,索引 如果屬于前綴的部分,則從
中抽取向量;
如果不是前綴部分,則由參數固定的預訓練模型生成對應的向量。訓練目標為:
θ本質上是一個矩陣,而生成一個矩陣的方法又很多,可以用
nn.Embedding()
,或者nn.Linear()
同樣是在連續空間上搜索 Prompt,OptiPrompt 構建的「模板」并不局限于前綴,也可以在句子的中間
首先根據 AutoPrompt 定義一個 Prompt 模板:
其中 為一個連續型向量(與 BERT 的輸入維度一致)。OptiPrompt 還考慮以人工構建的離散 Prompt 作為起點,在連續空間上進行搜索以構建較優的 Prompt。例如
可以轉換為
將 is
和 citizen
對應的 input Embedding 作為 和
的初始化
Hard-Soft Prompt Hybrid Tuning 方法可以說是人工設計和自動學習的結合,它通常不單純使用可學習的 Prompt 模板,而是在人工設計的模板中插入一些可學習的 Embedding。實際上有了上面的基礎我們都知道,連續的 Prompt 要比離散的 Prompt 好一點,但是在此基礎上還有什么改進的余地嗎?Liu 等人提出的 P-Tuning 解決了 Prompt token 之間的關聯性問題
之前連續的 Prompt 生成方式無非都是訓練一個矩陣,然后通過索引出矩陣的某幾行向量拼起來。坦白地說,我們希望這些 prompt token Embedding 之間有一個比較好的關聯性,而不是獨立地學習,為了解決這個問題,P-Tuning 引入了一個 Prompt Encoder(如下圖 b 所示)
上圖 a 是傳統的離散型 Prompt,我們把生成離散 Prompt token 的東西叫做 Prompt Generator;上圖 b 首先傳入一些 Virtual(Pseudo)token,例如 BERT 詞表中的 [unused1],[unused2],... 當然,這里的 token 數目是一個超參數,插入的位置也可以調整。將這些 Pseudo token 通過一個 Prompt Encoder 得到連續的向量 ,其中
即,Prompt Encoder 是由 BiLSTM+MLP 組成的一個簡單網絡。作者還發現加入一些 anchor token(領域或者任務相關的 token)可以有助于 Template 的優化。例如文本蘊含任務,輸入是前提和假設,判斷是否蘊含。一個連續的模版是
在其中加入一個anchor token:[?]
效果會更好,此時模板變成
大家可能想問,如何優化 P-tuning?實際上根據標注數據量的多少,分兩種情況討論
-
標注數據比較少。這種情況,我們固定 PLM 的參數,只優化
這幾個 token 的 Embedding。換句話說,我們只是要更新 Prompt Encoder 的參數
- 標注數據很充足。這種情況直接放開所有參數微調
就在 P-Tuning 方法提出不久后,Liu 等人又提出了 P-Tuning v2,主要解決 P-Tuning 的兩個問題:
- 當預訓練模型的參數量低于 100 億(10B)時,Prompt tuning 會比傳統的 Fine-tuning 差
- 諸如序列標注這樣對推理和理解要求高的任務,prompt tuning 效果會變差
Liu 等人認為先前的 P-Tuning 只用了一層 BiLSTM 來編碼 Pseudo token,這是其推理能力不足的原因之一,因此 v2 版本提出 Deep Prompt Tuning,用 Prefix Tuning 中的深層模型替換 BiLSTM,如下圖所示
P-Tuning v2 相比于 P-Tuning,區別在于:
- 取消 Reparameterization:以前的方法利用重參數化功能來提高訓練速度和魯棒性(例如,用于 Prefix-Tuning 的 MLP 和用于 P-Tuning 的 LSTM)。在 P-Tuning v2 中,作者發現重參數化的改進很小,尤其是對于較小的模型,同時還會影響模型的表現
- Multi-task Learning:Deep Prompt Tuning 的優化難題可以通過增加額外的任務數據或者無標注數據來緩解,同時可微調的 Prefix Continuous Prompt 也可以用來做跨任務的知識共享。例如在 NER 中,可以同時訓練多個數據集,不同數據集使用不同的頂層 Classifier,但是 Prefix Continuous Prompt 是共享的
- 取消 verbalizer:v2 取消了標簽映射,完全變為生成模型,可以在 [CLS] 部分輸出句子級別的標簽(Sentence-level label),也可以在每個 token 位置輸出 token 級別的標簽(Token-level label),直接輸出真實標簽
關于 P-Tuning 還有一些碎碎念,主要是從各個博客上看到的,匯總在這里。首先是 v1 版本的 LSTM,實際上引入 LSTM 目的是為了幫助「模板」生成的 token(某種程度上)更貼近自然語言,或者說 token 之間的語義更流暢,但更自然的方法應該是在訓練下游任務的時候,不僅預測下游任務的目標 token(例如 "great"、"terrible"),還應該同時做其他 token 的預測
比如,如果是 MLM 模型,那么也隨機 MASK 掉其它的一些 token 來預測,如果是 LM 模型,則預測完整的序列,而不單單是目標詞。這樣做的理由是:因為我們的 MLM/LM 都是經過自然語言預訓練的,所以我們認為它能夠很好的完成序列的重構,即便一開始不能,隨著迭代輪數的增加,模型也能很好完成這項任務。所以這本質上是讓模型進行「負重訓練」
* 為什么要引入 Prompt?
在標準的 Fine-tune 過程中(如上圖 b 所示),新引入的參數量可能會很大(獨立于原始預訓練模型外的參數),例如基于 RoBERTa-large 的二分類任務會新引入 2048 個參數(nn.Linear(1024, 2)
),如果你僅有例如 64 個標注數據這樣的小樣本數據集,微調會非常困難
為解決這一問題,Prompt 應運而生(如上圖 a 所示),直接將下游任務轉換為輸出空間有限的 MLM 任務。值得注意的是:上述方法在預訓練參數的基礎上進行微調,并且沒有引入任何新參數,同時還減少了微調和預訓練任務之間的差距。總的來說,這可以更有效地用于小樣本場景
Prompt 的挑戰與展望
盡管 Prompt 研究搞得如火如荼,但目前仍存在許多問題值得研究者們去探究
- Prompt 的設計問題。目前使用 Prompt 的工作大多集中于分類任務和生成任務,其它任務則較少。另外,「模板」和「答案」的聯系也亟待解決。模型的表現同時依賴于使用的「模板」和「答案」的映射,如何同時搜索或者學習出兩者聯合的最好效果仍然很具挑戰性
- Prompt 的理論分析和可解釋性。盡管 Prompt 方法在很多情況下都取得了成功,但是目前 Prompt-based Learning 理論分析還很少,人們很難了解 Prompt 為什么能達到好的效果,又為什么在自然語言中意義相近的 Prompt 有時效果卻相差很大
- Prompt 在 PLM debias 方面的應用。由于 PLM 在預訓練過程中見過了大量的人類世界的自然語言,所以很自然地會受到一些影響。舉一個簡單的例子,比如說訓練語料中有非常多 "The capital of China is Beijing",導致模型每次看到 "capital" 的時候都會預測出 "Beijing",而不是去分析到底是哪個國家的首都。在應用的過程中,Prompt 還暴露了 PLM 學習到的很多其它 bias,比如種族歧視、性別對立等。這也許會是一個值得研究的方向
One More Thing
最后我還想提一個實際 Code 過程中存在的問題。我們知道 MLM 任務會輸出句子中 [MASK] 位置最有可能的詞,而 Prompt 也類似的,例如下面的例子
這是一條__新聞。中國足球出線的可能性只有0.001%,留給中國隊的時間不多了
這是一個新聞分類問題,真實標簽有 "體育"、"財經"、"娛樂" 等,上面的樣本很明顯是一條體育新聞,因此我們希望模型對 [MASK] 部分輸出 "體育",但事實真的如此嗎?實際情況模型的輸出可能是 "足球",但你認為模型預測的 "足球" 有問題嗎?好像也沒啥毛病,因此這就引申出了 Prompt 的一個問題,是否應該限制模型的輸出空間?
還是上面新聞分類的例子,我們是否應該限制模型輸出的空間,讓他固定只能預測 "體育"、"財經"、"娛樂" 這幾個標簽?或者我們干脆把這幾個標簽換成索引,那就是讓模型從 0,1,2 這三個數字選一個。Wait Wait Wait,如果這么做的話,和 Fine-Tune 有什么區別,Fine-Tune 也是把標簽轉換成索引,讓模型看了句子之后,從這幾個索引中選一個作為預測值
這么說的話,那我們就不應該限制模型的輸出空間,可是這樣的話 [MASK] 位置的輸出就限制的太死了,必須一定是 "good"、"財經" 才算對,如果輸出 "nice"、"財政" 就算錯。實際上輸出近義詞或者相似詞,在零樣本的情況下會經常出現,但是如果你用一些有標簽的樣本去訓練,模型自己就會慢慢固定輸出空間。例如 "財經",它不會預測成 "財政",只會預測成其它類型的新聞,例如 "體育"
References
- P-tuning:自動構建模版,釋放語言模型潛能
- 必須要 GPT3 嗎?不,BERT 的 MLM 模型也能小樣本學習
- NLP 新寵 —— 淺談 Prompt 的前世今生
- 超大規模新型預訓練模型詳解:少樣本學習等近十個數據集取得第一
- GPT-3 的最強落地方式?陳丹琦提出小樣本微調框架 LM-BFF,比普通微調提升 11%~
- 基于 Prompt 的 MLM 文本分類
- Prompt-based Language Models:模版增強語言模型小結
- 鵬飛大神的 Pre-train, Prompt, and Predict
- P-tuning:用 “連續提示微調” 來增強 “超大規模語言模型” 的下游能力
- Prompting: Better Ways of Using Language Models for NLP Tasks
- Prompt Based Task Reformulation in NLP 調研
- PromptPapers