Zero-shot、One-shot以及Few-shot讓人傻傻分不清,讀了很多文章,也沒搞清楚他們的差別,究竟什么叫zero-shot,其在應用過程中的no gradient update是什么含義,zero-shot是否為一個偽命題,成為了一些有趣的問題。???????
目前,直接使用以chatgpt為代表的大模型進行nlp任務處理成為了一個潮流,直接拼接prompt進行問答,就可拿到相應答案,例如最近的文章《ChatGPT+NLP下的Prompt模板工具:PromptSource、ChatIE代表性開源項目介紹》中所介紹的chatie,直接來解決zeroshot的任務。
但是,我們發現,如果引入incontext-learning這一思想,作為一個fewshot任務來提升ChatIE這類模型的性能,可能是一個很好的思路,在此基礎上個配上一個開源項目進行解釋能夠增強了解。?????????????????????????????????????????
因此,帶著這個問題,本文先談談Zero-shot、One-shot以及Few-shot、從ChatIE:面向REEENER三種任務的偽zero-shot prompt說起、從偽zeroshot看In-Context Learning類比學習、將In-Context Learning引入偽zero-shot完成信息抽取任務四個方面進行介紹,供大家一起參考。
一、先談談Zero-shot、One-shot以及Few-shot
1、Zero-shot
Zero-shot就是希望模型能夠對其從沒見過的類別進行分類,是指對于要分類的類別對象,一次也不學習。
也就是說,只有推理階段,沒有訓練階段。這個常見于chatgpt中qa形式,直接通過問題prompt,基于已訓練好的大模型,進行直接預測。
2、Few-shot與One-shot
如果訓練集中,不同類別的樣本只有少量,則成為Few-shot,如果參與訓練學習,也只能使用較少的樣本數。?????????
如果訓練集中,不同類別的樣本只有一個,則成為One-shot, 屬于Few-shot的一種特殊情況。
但其中的“no gradient update讓人費解”,后面想了想,有2種理解:
1)單次微調,參數更新,但微調后模型不保存。???????????
LLM由于參數量巨大,導致更新起來困難(費錢--費卡)。因此很少對訓練好的LLM做微調。但是為了在特殊任務上有較好的表現(微調效果肯定要好于不微調的),但是又不固定微調后的模型,所以提出了one-shot、few-shot的方式,通過加入偏置,影響模型的最終輸出。
而one-shot、few-shot可以變相的理解成用一個/多個example進行模型微調,但是微調后的模型不保存。每次提供inference都要微調一遍(輸入一個example或者多個example來模擬微調過程),No gradient updates are performed.就是說提供inference的模型參數保持不變,但這其實是tuning的范疇。
2)直接不微調,參數直接不更新??????
如果不更新參數,那么這種學習就是瞬間的,不構成learning。預訓練模型自身訓練完后本身有一套參數,finetune就是在預訓練基礎上繼續訓練,肯定會有梯度更新,因為finetune后參數會變,參數變了梯度必然會更新。直接推理出答案,后臺梯度也不更新。
不過,需要注意的是,如果以這個模型到底有沒有見過標注樣本,來劃分zero-shot與其他的差別,就是主要見過,無論是在推理階段(作為prompt)用【不更新梯度】,還是加入finetune階段參與訓練【更新參數】,那就肯定不是zero-shot,否則就是數據泄漏。
這也就是說,如果在prompt中是否加入一個或者多個正確的例子,例如分類任務中,加入一些正確的任務描述例子,都不能算作是zero-shot,但是問題是你怎么能保證模型訓練沒有用過這些數據,他們當時訓練就可能搜集到了,模型說不定都見過,也就是說至少不存在嚴格意義的zero shot。
二、從ChatIE:面向REEENER三種任務的偽zero-shot prompt說起
最近有篇文章《Zero-Shot Information Extraction via Chatting with ChatGPT》很有趣,該工作將零樣本IE任務轉變為一個兩階段框架的多輪問答問題(Chat IE),并在三個IE任務中廣泛評估了該框架:實體關系三元組抽取、命名實體識別和事件抽取。在兩個語言的6個數據集上的實驗結果表明,Chat IE取得了非常好的效果,甚至在幾個數據集上(例如NYT11-HRL)上超過了全監督模型的表現。
其實現基本原理為,通過制定任務實體關系三元組抽取、命名實體識別和事件抽取,并為每個任務設計了2個步驟的prompt-pattern,第一步用于識別類型,第二步用于識別指定類型的值。將抽取的任務定義(抽取要素)進行prompt填充,然后調用chatgpt接口,在取得結果后進行規則解析,結構化相應答案。
例如,關系抽取的具體執行步驟包括:針對每類prompt,分別調用prompt-pattern,得到相應結果,以事件抽取prompt為例,
1)任務要素定義:
df_eet={ 'chinese':{'災害/意外-墜機':['時間','地點','死亡人數','受傷人數'],'司法行為-舉報':['時間','舉報發起方','舉報對象'],'財經/交易-漲價':['時間','漲價幅度','漲價物','漲價方'],'組織關系-解雇':['時間','解雇方','被解雇人員'],'組織關系-停職':['時間','所屬組織','停職人員'],'財經/交易-加息':['時間','加息幅度','加息機構'],'交往-探班':['時間','探班主體','探班對象'],'人生-懷孕':['時間','懷孕者'],'組織關系-辭/離職':['時間','離職者','原所屬組織'],'組織關系-裁員':['時間','裁員方','裁員人數'],'災害/意外-車禍':['時間','地點','死亡人數','受傷人數'], '人生-離婚':['時間','離婚雙方'],'司法行為-起訴':['時間','被告','原告'],'競賽行為-禁賽':['時間','禁賽時長','被禁賽人員','禁賽機構'],'人生-婚禮':['時間','地點','參禮人員','結婚雙方'],'財經/交易-漲停':['時間','漲停股票'],'財經/交易-上市':['時間','地點','上市企業','融資金額'],'組織關系-解散':['時間','解散方'],'財經/交易-跌停':['時間','跌停股票'],'財經/交易-降價':['時間','降價方','降價物','降價幅度'],'組織行為-罷工':['時間','所屬組織','罷工人數','罷工人員'],'司法行為-開庭':['時間','開庭法院','開庭案件'], '競賽行為-退役':['時間','退役者'],'人生-求婚':['時間','求婚者','求婚對象'],'人生-慶生':['時間','生日方','生日方年齡','慶祝方'],'交往-會見':['時間','地點','會見主體','會見對象'],'競賽行為-退賽':['時間','退賽賽事','退賽方'],'交往-道歉':['時間','道歉對象','道歉者'],'司法行為-入獄':['時間','入獄者','刑期'],'組織關系-加盟':['時間','加盟者','所加盟組織'],'人生-分手':['時間','分手雙方'],'災害/意外-襲擊':['時間','地點','襲擊對象','死亡人數','襲擊者','受傷人數'],'災害/意外-坍/垮塌':['時間','坍塌主體','死亡人數','受傷人數'], '組織關系-解約':['時間','被解約方','解約方'],'產品行為-下架':['時間','下架產品','被下架方','下架方'],'災害/意外-起火':['時間','地點','死亡人數','受傷人數'],'災害/意外-爆炸':['時間','地點','死亡人數','受傷人數'],'產品行為-上映':['時間','上映方','上映影視'],'人生-訂婚':['時間','訂婚主體'],'組織關系-退出':['時間','退出方','原所屬組織'],'交往-點贊':['時間','點贊方','點贊對象'],'產品行為-發布':['時間','發布產品','發布方'],'人生-結婚':['時間','結婚雙方'],'組織行為-閉幕':['時間','地點','活動名稱'], '人生-死亡':['時間','地點','死者年齡','死者'],'競賽行為-奪冠':['時間','冠軍','奪冠賽事'],'人生-失聯':['時間','地點','失聯者'],'財經/交易-出售/收購':['時間','出售方','交易物','出售價格','收購方'],'競賽行為-晉級':['時間','晉級方','晉級賽事'],'競賽行為-勝負':['時間','敗者','勝者','賽事名稱'],'財經/交易-降息':['時間','降息幅度','降息機構'],'組織行為-開幕':['時間','地點','活動名稱'],'司法行為-拘捕':['時間','拘捕者','被拘捕者'],'交往-感謝':['時間','致謝人','被感謝人'],'司法行為-約談':['時間','約談對象','約談發起方'], '災害/意外-地震':['時間','死亡人數','震級','震源深度','震中','受傷人數'],'人生-產子/女':['時間','產子者','出生者'],'財經/交易-融資':['時間','跟投方','領投方','融資輪次','融資金額','融資方'],'司法行為-罰款':['時間','罰款對象','執法機構','罰款金額'],'人生-出軌':['時間','出軌方','出軌對象'],'災害/意外-洪災':['時間','地點','死亡人數','受傷人數'],'組織行為-游行':['時間','地點','游行組織','游行人數'],'司法行為-立案':['時間','立案機構','立案對象'],'產品行為-獲獎':['時間','獲獎人','獎項','頒獎機構'],'產品行為-召回':['時間','召回內容','召回方']}, 'english':{'Justice:Appeal':['Defendant','Adjudicator','Crime','Time','Place'],'Justice:Extradite':['Agent','Person','Destination','Origin','Crime','Time'],'Justice:Acquit':['Defendant','Adjudicator','Crime','Time','Place'],'Life:Be-Born':['Person','Time','Place'],'Life:Divorce':['Person','Time','Place'],'Personnel:Nominate':['Person','Agent','Position','Time','Place'],'Life:Marry':['Person','Time','Place'],'Personnel:End-Position':['Person','Entity','Position','Time','Place'], 'Justice:Pardon':['Defendant','Prosecutor','Adjudicator','Crime','Time','Place'],'Business:Merge-Org':['Org','Time','Place'],'Conflict:Attack':['Attacker','Target','Instrument','Time','Place'],'Justice:Charge-Indict':['Defendant','Prosecutor','Adjudicator','Crime','Time','Place'],'Personnel:Start-Position':['Person','Entity','Position','Time','Place'],'Business:Start-Org':['Agent','Org','Time','Place'],'Business:End-Org':['Org','Time','Place'], 'Life:Injure':['Agent','Victim','Instrument','Time','Place'],'Justice:Fine':['Entity','Adjudicator','Money','Crime','Time','Place'],'Justice:Sentence':['Defendant','Adjudicator','Crime','Sentence','Time','Place'],'Transaction:Transfer-Money':['Giver','Recipient','Beneficiary','Money','Time','Place'],'Justice:Execute':['Person','Agent','Crime','Time','Place'],'Justice:Sue':['Plaintiff','Defendant','Adjudicator','Crime','Time','Place'], 'Justice:Arrest-Jail':['Person','Agent','Crime','Time','Place'],'Justice:Trial-Hearing':['Defendant','Prosecutor','Adjudicator','Crime','Time','Place'],'Movement:Transport':['Agent','Artifact','Vehicle','Price','Origin'],'Contact:Meet':['Entity','Time','Place'],'Personnel:Elect':['Person','Entity','Position','Time','Place'],'Business:Declare-Bankruptcy':['Org','Time','Place'],'Transaction:Transfer-Ownership':['Buyer','Seller','Beneficiary','Artifact','Price','Time','Place'], 'Justice:Release-Parole':['Person','Entity','Crime','Time','Place'],'Conflict:Demonstrate':['Entity','Time','Place'],'Contact:Phone-Write':['Entity','Time'],'Justice:Convict':['Defendant','Adjudicator','Crime','Time','Place'],'Life:Die':['Agent','Victim','Instrument','Time','Place']}, }
2)構造prompt的pattern:
ee_s1_p={ 'chinese':'''給定的句子為:"{}" 給定事件類型列表:{} 在這個句子中,可能包含了哪些事件類型? 請給出事件類型列表中的事件類型。 如果不存在則回答:無 按照元組形式回復,如(事件類型1, 事件類型2, ……):''', 'english':'''Thegivensentenceis"{}" Givenalistofeventtypes:{} Whateventtypesinthegivenlistmightbeincludedinthisgivensentence? Ifnotpresent,answer:none. Respondasatuple,e.g.(eventtype1,eventtype2,......):''' } ee_s2_p={ 'chinese':'''事件類型"{}"對應的論元角色列表為:{}。 在給定的句子中,根據論元角色提取出事件論元。 如果論元角色沒有相應的論元內容,則論元內容回答:無 按照表格形式回復,表格有兩列且表頭為(論元角色,論元內容):''', 'english':'''Thelistofargumentrolescorrespondingtoeventtype"{}"is:{}. Inthegivensentence,extracteventargumentsaccordingtotheirrole. Iftheargumentroledoesnothaveacorrespondingargumentcontent,thentheargumentcontentanswer:None Respondintheformofatablewithtwocolumnsandaheaderof(argumentrole,argumentcontent):''' }
三、從偽zeroshot看In-Context Learning類比學習
In Context Learning(ICL)的關鍵思想是從類比中學習。《A Survey on In-context Learning》一文(https://arxiv.org/pdf/2301.00234.pdf)對In Context Learning(ICL)進行了綜述。
該工作認為,ICL的強大性能依賴于兩個階段:(1)培養LLMsICL能力的訓練階段,以及LLMs根據特定任務演示進行預測的推理階段。就訓練階段而言,LLMs直接接受語言建模目標的訓練,如從左到右的生成,并將整個研究分成了訓練和推理兩個部分,如下圖所示。
如下圖所示:給出了一個描述語言模型如何使用ICL進行決策的例子。首先,ICL 需要一些示例來形成一個演示上下文。這些示例通常是用自然語言模板編寫的。然后 ICL 將查詢的問題(即你需要預測標簽的 input)和一個上下文演示(一些相關的 cases)連接在一起,形成帶有提示的輸入,并將其輸入到語言模型中進行預測。
值得注意的是,首與需要使用后向梯度來更新模型參數的訓練階段的監督學習不同,ICL不進行參數更新,而是直接對語言模型進行預測。
四、將In-Context Learning引入偽zero-shot完成信息抽取任務
開源項目中,借鑒In-Context Learning思想,給出了一個基于GLM-6B的zero-shot信息抽取方案,最終效果如下:
其本質思想在于,針對zero-shot問題,使用同一個大模型,對不同任務設計其獨有的 prompt,以解決不同的任務問題針對信息抽取任務,則采用2輪問答的方式進行抽取,首先進行實體類型分類,給定句子以及實體類別,要求識別出其中的實體類型,其次根據識別出的實體類型,再進行實體屬性要素抽取。在構造prompt的過程中,通過列舉一些正確的例子,作為In-Context Learning學習的上下文。(按照第一節的理解,這其實不能算作zero-shot,已經是fewshot)
因此,如何設計指定任務的promt,以及如何合理的引入In-Context是整個工作的一個核心。
1、調用chatglm6b進行推理抽取
加載chatglm-6b模型,對模型進行預測,下面是使用huggingface調用chatglm6b的代碼:
fromtransformersimportAutoTokenizer,AutoModel tokenizer=AutoTokenizer.from_pretrained("THUDM/chatglm-6b",trust_remote_code=True) model=AutoModel.from_pretrained("THUDM/chatglm-6b",trust_remote_code=True).half().cuda() response,history=model.chat(tokenizer,"你好",history=[]) print(response) response,history=model.chat(tokenizer,"晚上睡不著應該怎么辦",history=history) print(response)
其中,整個history會作為一個部分,拼接進行prompt當中,從中可以看到,多輪對話最多做到8輪。
defbuild_prompt(history): prompt="歡迎使用ChatGLM-6B模型,輸入內容即可進行對話,clear清空對話歷史,stop終止程序" forquery,responseinhistory: prompt+=f" 用戶:{query}" prompt+=f" ChatGLM-6B:{response}" returnprompt defmain(): history=[] print("歡迎使用ChatGLM-6B模型,輸入內容即可進行對話,clear清空對話歷史,stop終止程序") whileTrue: query=input(" 用戶:") ifquery=="stop": break ifquery=="clear": history=[] os.system(clear_command) print("歡迎使用ChatGLM-6B模型,輸入內容即可進行對話,clear清空對話歷史,stop終止程序") continue count=0 forresponse,historyinmodel.stream_chat(tokenizer,query,history=history): count+=1 ifcount%8==0: os.system(clear_command) print(build_prompt(history),flush=True) os.system(clear_command) print(build_prompt(history),flush=True)
最后,我們對模型進行推理,將上述構造的兩個任務作為history
definference(sentence,custom_settings): withconsole.status("[boldbright_green]ModelInference..."): sentence_with_cls_prompt=CLS_PATTERN.format(sentence) cls_res,_=model.chat(tokenizer,sentence_with_cls_prompt,history=custom_settings['cls_pre_history']) ifcls_resnotinschema: print(f'Thetypemodelinferenced{cls_res}whichisnotinschemadict,exited.') exit() properties_str=','.join(schema[cls_res]) schema_str_list=f'“{cls_res}”({properties_str})' sentence_with_ie_prompt=IE_PATTERN.format(sentence,schema_str_list) ie_res,_=model.chat(tokenizer,sentence_with_ie_prompt,history=custom_settings['ie_pre_history']) ie_res=clean_response(ie_res) print(f'>>>[boldbright_red]sentence:{sentence}') print(f'>>>[boldbright_green]inferenceanswer:') print(ie_res) deftest(): console=Console() device='cuda:0' tokenizer=AutoTokenizer.from_pretrained("THUDM/chatglm-6b",trust_remote_code=True) model=AutoModel.from_pretrained("THUDM/chatglm-6b",trust_remote_code=True).half() model.to(device) sentence='張譯(原名張毅),1978年2月17日出生于黑龍江省哈爾濱市,中國內地男演員。1997年至2006年服役于北京軍區政治部戰友話劇團。2006年,主演軍事勵志題材電視劇《士兵突擊》。', custom_settings=init_prompts() inference(sentence,custom_settings )
2、第一步:實體類型識別
先做實體類型識別(這個有點像事件抽取中的事件檢測),其中需要構造
1)sentence_with_cls_prompt
sentence_with_cls_prompt = CLS_PATTERN.format(sentence),先對句子進行實體類型識別,構造prompt:
CLS_PATTERN=f"“{{}}”是{class_list}里的什么類別?"
例如,針對句子:“張譯(原名張毅),1978年2月17日出生于黑龍江省哈爾濱市,中國內地男演員。1997年至2006年服役于北京軍區政治部戰友話劇團。2006年,主演軍事勵志題材電視劇《士兵突擊》。”
構造prompt后變為:
“張譯(原名張毅),1978年2月17日出生于黑龍江省哈爾濱市,中國內地男演員。1997年至2006年服役于北京軍區政治部戰友話劇團。2006年,主演軍事勵志題材電視劇《士兵突擊》。”是 ['人物','書籍','電視劇']里的什么類別?
2)cls_pre_history實體類型識別的例子
利用cls_pre_history作為incontext-learning學習的上下文,進行拼接,例如,cls_pre_history形式為:
cls_pre_history: [ ("現在你是一個文本分類器,你需要按照要求將我給你的句子分類到:['人物', '書籍', '電視劇']類別中。",'好的。'), ( "“岳云鵬,本名岳龍剛,1985年4月15日出生于河南省濮陽市南樂縣,中國內地相聲、影視男演員。2005年,首次登臺演出。2012年,主演盧衛國執導的喜劇電影《就是鬧著玩的 》。2013年在北京舉辦相聲專場。”是['人物', '書籍', '電視劇']里的什么類別?", '人物' ), ( "“《三體》是劉慈欣創作的長篇科幻小說系列,由《三體》《三體2:黑暗森林》《三體3:死神永生》組成,第一部于2006年5月起在《科幻世界》雜志上連載,第二部于2008年5 月首次出版,第三部則于2010年11月出版。”是['人物', '書籍', '電視劇']里的什么類別?", '書籍' ), ( "“《狂飆》是由中央電視臺、愛奇藝出品,留白影視、中國長安出版傳媒聯合出品,中央政法委宣傳教育局、中央政法委政法綜治信息中心指導拍攝,徐紀周執導,張譯、 張頌文、李一桐、張志堅、吳剛領銜主演,倪大紅、韓童生、李建義、石兆琪特邀主演,李健、高葉、王驍等主演的反黑刑偵劇。”是['人物', '書籍', '電視劇']里的什么類別?", '電視劇' ) ]
3、第2步:實體屬性抽取
根據識別的實體類型結果做實體屬性抽取(這個有點像事件抽取中的事件要素抽取),
根據上一步得到的實體類型,進一步生成問句sentence_with_ie_prompt和in-context learning上下文,其中:
1)sentence_with_ie_prompt
sentence_with_ie_prompt指的是對任務的描述,其中需要用到不同實體對應的屬性schema以及問題的promt模版。
schema如下:
schema={ '人物':['姓名','性別','出生日期','出生地點','職業','獲得獎項'], '書籍':['書名','作者','類型','發行時間','定價'], '電視劇':['電視劇名稱','導演','演員','題材','出品方'] }
屬性抽取的prompt如下:
IE_PATTERN="{} 提取上述句子中{}類型的實體,并按照JSON格式輸出,上述句子中不存在的信息用['原文中未提及']來表示,多個值之間用','分隔。"
變成:
張譯(原名張毅),1978年2月17日出生于黑龍江省哈爾濱市,中國內地男演員。1997年至2006年服役于北京軍區政治部戰友話劇團。2006年,主演軍事勵志題材電視劇《士兵突擊》。 提取上述句子中“人物”(姓名,性別,出生日期,出生地點,職業,獲得獎項)類型的實體,并按照JSON格式輸出,上述句子中不存在的信息用['原文中未提及']來表示,多個值之間用','分隔。
2)ie_pre_history屬性抽取的例子
ie_pre_history屬性抽取的例子給定了一些正確抽取的實際例子,如下所示:
[ ( "現在你需要幫助我完成信息抽取任務,當我給你一個句子時,你需要幫我抽取出句子中三元組,并按照JSON的格式輸出,上述句子中沒有的信息用['原文中未提及']來表示,多 個值之間用','分隔。", '好的,請輸入您的句子。' ), ( "岳云鵬,本名岳龍剛,1985年4月15日出生于河南省濮陽市南樂縣,中國內地相聲、影視男演員。 提取上述句子中“人物”(姓名, 性別, 出生日期, 出生地點, 職業, 獲得獎項)類型的實體,并按照JSON格式輸出,上述句子中不存在的信息用['原文中未提及']來表示,多個值之間用','分隔。", '{"姓名":["岳云鵬"],"性別":["男"],"出生日期":["1985年4月15日"],"出生地點":["河南省濮陽市南樂縣"],"職業":["相聲演員","影視演員"],"獲得獎項": ["原文中未提及"]}' ), ( "《三體》是劉慈欣創作的長篇科幻小說系列,由《三體》《三體2:黑暗森林》《三體3:死神永生》組成,第一部于2006年5月起在《科幻世界》雜志上連載,第二部于2008年5月首 ,第三部則于2010年11月出版。 提取上述句子中“書籍”(書名, 作者, 類型, 發行時間, 定價)類型的實體,并按照JSON格式輸出,上述句子中不存在的信息用['原文中未提及']來表示,多個值之間用','分隔。", '{"書名":["《三體》"],"作者":["劉慈欣"],"類型":["長篇科幻小說"],"發行時間":["2006年5月","2008年5月","2010年11月"],"定價":["原文中未提及"]}' ) ]
3、第三步:對模型輸出進行后處理
defclean_response(response:str): if'```json'inresponse: res=re.findall(r'```json(.*?)```',response) iflen(res)andres[0]: response=res[0] response.replace('、',',') try: returnjson.loads(response) except: returnresponse
總結
本文先談談Zero-shot、One-shot以及Few-shot、從ChatIE:面向REEENER三種任務的偽zero-shot prompt說起、從偽zeroshot看In-Context Learning類比學習、將In-Context Learning引入偽zero-shot完成信息抽取任務四個方面進行介紹,供大家一起參考。
審核編輯:劉清
-
icl
+關注
關注
0文章
28瀏覽量
17267 -
CLS
+關注
關注
0文章
9瀏覽量
9730 -
nlp
+關注
關注
1文章
489瀏覽量
22110 -
ChatGPT
+關注
關注
29文章
1570瀏覽量
8067
原文標題:基于GLM-6B對話模型的實體屬性抽取項目實現解析:對Zero-shot與In-Context Learning的若干思考
文章出處:【微信號:zenRRan,微信公眾號:深度學習自然語言處理】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論