前言
ChatGPT的出現鼓舞了NLP的科研人員和工作者,大模型的涌現讓AI在即將退潮時又掀起了層層巨浪。大家似乎看到了黎明的曙光,剎那間百“模”大戰打響,各大高校、科研機構、企業紛紛“自研”大模型,好不熱鬧。說到底,這個自研大多來自于開源模型,對垂直領域的數據進行清洗加數據增強,再用前沿的調優算法(LoRA、Adapter Tuning、Prefix Tuning、Prompt Tuning等)來進行調優,然后得到該領域的大模型。
以此種方式,在海量數據的加持下,確實可以在領域內獲得不錯的表現能力。但此種方式也并非長久之計,因為領域內的數據總是在更新,每次數據更新迭代之后再進行微調似乎并不理想。說到底,現在模型似乎并不具備像人一樣,擁有一直學習的能力。現在看上去就是把大部分知識在短時間內都塞到模型中,而那些沒有見過的知識,便很難推理出來。那么從0到1訓練大模型的成本是難以接受的,微調大模型的方式或許還能接受,但是通過檢索已有知識庫,再讓大模型(接口)分析數據,并進行問答,或許是一個較優的選擇。
背景介紹
Sentence Bert (雙塔模型)
傳統信息檢索工具ES基于Term召回的方式在語義接近但Term Difference比較大的情況下表現不佳。SBert(Sentence Bert)為架構的訓練方式提升了句子和句子之間的召回準確率。如下圖,左邊是對句子進行進行一層Bert輸出,經過Pooling得到對應A、B句的向量u、v,再通過concatenate u,v, |u-v| 再乘以一個可訓練的權重經過softmax的到最后的結果(公式如下)。右邊是推理的過程,用模型進行推理得到A、B向量, u、v再進行余弦相似度計算,通過設定一定的閾值求出最優的結果。
Sentence Bert (又稱雙塔模型) 這種框架有兩種實現,Bi-encoder 和 Dual-encoder。
Bi-encoder 首先將Query和Candidate輸入到共享的Transformer編碼器中,將其分別編碼成向量表示,然后通過計算兩個向量之間的相似度得分,來判斷Query和Candidate的匹配程度。典型的有近期Moka AI發布的M3E模型,在s2s(sentence to sentence)和s2p(sentence to passage)任務上表現不俗,超過了之前比較優秀的text2vec模型 (large的模型可以看這里),具體可以看一下hugging face的介紹。
Dual-encoder模型的基本架構是將Query和Candidate分別輸入不同的Transformer編碼器中,分別編碼成向量表示,然后計算Query和Candidate的相似度得分,來判斷Query和Candidate的匹配程度。這種適用于兩種句子維度不一樣的匹配任務,類似于query匹配文檔,query匹配答案等。
在Bi-encoder模型中,Query和Candidate共享了同一個編碼器,因此它們在表示空間中具有相同的維度和分布。而Dual-encoder模型則使用了兩個獨立的編碼器,因此它們在表示空間中具有不同的維度和分布。這種差異可能對模型的表現產生一定的影響。同時,由于Dual-encoder模型中的兩個編碼器具有獨立的參數空間和狀態空間,因此Dual-encoder模型可以對Query和Candidate的特征進行更靈活的處理和提取。然而,由于需要用到兩個編碼器,Dual-encoder模型的訓練和推理成本通常比Bi-encoder模型高。
CoSENT
通過語言模型提取特征,再計算余弦相似度進行分類。這樣的做法存在訓練和預測不一致的問題,如果直接優化目標cos值,效果往往特別差。蘇神提出的CoSENT一種新的訓練方式,就是對比正負樣本的余弦值相對差距。想要了解的同學可以去官博看一下。
Cross Encoder
上述的文本匹配方式Bi-Encoder的方式為特征式(Representation-based)匹配,而另外一種為交互式(Interaction-based)。交互式匹配方案如下右圖,將兩段文本拼接在一起當成單個文本進行分類,交互式由于使得兩個文本能夠進行充分的比較,所以它準確性通常較好,但在檢索場景中使用效率低下,因為需要現場推理向量,而特征式可以提前將所有的Candidates進行計算并緩存,在檢索過程中只需要對Query進行向量推理,然后匹配所有的Candidates就行了,但相對而言,特征式交互程度較淺,效果通常比交互式要差。
Multi-stage Retrieval
上面提到的方案都是簡單的單召回方式,類似與LangChain-ChatGLM即從海量的文檔向量庫對當前的query的向量進行向量相似度計算,找出最接近的文檔,然后通過Prompt Template進行渲染構造Prompt輸送給大模型,最后接受大模型生成的答案。
這種單階段召回的方式是最為基礎的,后面調研了MS MARCO這個數據集的Leaderboard發現了一些比較有見解的方案,現在也一起總結到本文中。
Paddle-pipelines
百度的Paddle-pipelines主要是通過兩階段進行排序,首先將文檔集合離線轉變為向量存儲在向量索引庫,一階段利用進行向量匹配召回Top N,二階段用高精度的交叉模型候選Top K進行排序,最后召回答案。這樣可以提升模型的準確率。
百度在離線階段使用的是Dual-Encoder方式,訓了兩個模型,一個是query-encoder, 一個是passage-encoder; 二階段使用的cross-encoder精排,對于頭部的召回可以提升不少,詳情可以參考github上給出的指標。
RocketQA
百度使用的模型是RocketQA系列,具體的原理如下:
由于Dense passage retrieval下的訓練和推理之間的差異,即訓練過程中只是選取了部分的樣本作為負例,而推理過程中則是對所有的樣本進行比較。同時,在進行訓練的過程中negative samples往往存在了大量的false negative samples,即標注為非答案文本的文段也是可以作為答案的。
針對上面這兩個問題,文章提出了三個優化策略Cross-batch negatives, Denoised Hard Negatives, Data Augmentation.
Cross-batch negatives主要做的就是將m臺上的GPU機器上的n個samples都進行embeddings計算,然后下發到每一個GPU機器上,那么每一個訓練樣本都有m*n-1個負樣本,對比之前的in-batch negatives的n-1個負樣本,這樣極大地增加了負例樣本的學習。
Denoised Hard Negatives,先train一個dual encoder來召回negatives, 然后再訓練一個cross encoder來去除false negatives,這樣讓模型學習到負樣本盡可能是對的,相當于是做了一次數據清洗。
Data Augmentation就是用已經訓練好的cross encoder對一些未標注數據進行標注,類似于semi-supervised learning,來增大數據量。
這種方式在測評數據集上的表現不俗,但是對于機器的要求比較高,就比如第一步的Cross-batch negatives來說,這需要盡可能地增加機器的數目,同時對于單個GPU機器來說,增加了大批量的negatives,對于GPU的顯存來說是一個很大的挑戰。后面的train dual encoder的方式也是一個多階段的訓練,相對來說訓練的成本比較高。
coCondenser
后面看到了MS MARCO的Document Retrieval Top 1方案--coCondenser。作者做的事情簡單但有效,即他認為最后一層的【CLS】的向量并沒有有效的聚合整個輸入的所有信息,于是提出一個新的訓練架構--Condenser,Condenser一共由六層的Transformer blocks組成,一共是三組,early backbone encoder、late backbone encoder以及head,最下面的為輸入層,頭部拼接了一個special token 【CLS】。
同時,跳連early layers,可以消除了編碼局部信息和輸入文本句法結構的負擔,將CLS重點放在輸入文本的全局含義上,Condenser 被迫學習將信息聚合到 CLS 中,然后 CLS 將參與 LM 預測。利用 MLM 產生的豐富有效的訓練信號,Condenser 學習利用強大的 Transformer 架構來生成密集的 CLS 表示。我們假設通常用于訓練token表示的 LM 目標現在放在密集的 CLS 表示上,學習到的 LM 獲得了更好的抗噪聲魯棒性。
【CLS】雖然可以通過head進行非線性表征,但是這些向量的內積依然是不具備語義信息的。作者提出加入對比的loss來提升語義表達。這種方式在introduction部分提到了,就是抽取文檔中的片段,這些片段形成了一個訓練批次集,將 表示為 ,loss的計算公式如下圖。
這里的核心思想就是同一篇文章里的片段的分布應該是盡可能相似的,而不同文章的片段應該有不同的空間表達。最后的loss就是masked loss?span LM losss。
最后和RocketQA的效果進行了對比,從表格中我們可以看出,RocketQA的batch size和本文使用的batch size的差距還是很明顯的,但是從結果上來看coCondenser再加入Hard negatives之后,在MS-MARCO上的表現要優于RocketQA。
HLATR
HLATR是當前Passage Retrieval的Top 1方案,核心思想是認為一階段的召回和二階段的排序的結果可以進行藕合來提升整體的性能。
這里作者提到兩個模型雖然都是進行排序,但是模型的關注的點不一樣,表征式的模型(retriever)偏向于粗顆粒度特征,交互式的模型(interaction)偏向于query和document之間的信息交互。同時作者做了一個簡單的weighted combination,就是給予召回和排序這兩個階段不同的權重,對于整體的召回效果也是有提升的。
文章的思路其實比較簡單,就是通過對一階段召回的順序的位置編碼和二階段輸出的logits的向量,來做非線性組合,相當于是融合吧。
這里的d1dz是一階段召回的個數,然后v1vz是二階段對應的logits向量,通過對位置編碼進行加和在通過Layer Norm,再通過transformer層進行注意力機制交互。
最后再對結果進行一個全連接層輸出一個分數,排序。
這里用的是Contrastive Loss。
從實驗結果上看,作者針對不同的Retrieval和二階段進行了對比,Retrieval的話是選用了Sparse-BM25,Dense的話用的是coConderser和ANCE,公開的checkpoint。結果如下,WCR指的是Weighted Combination of two-stage Ranking models。從整體上看,WCR的方式會比二階段的Reranking好一些,而相比下來HLATR的效果是最好的。
之后作者對于HLATR的架構進行了探究,即將多層的transformers替換成2-layer的MLP(多層感知機)這樣的效果只是下降了0.2pp,但還是從另外一個角度說明了transformers模型比MLP發現不同文檔中的互信息中表現的更好(個人覺得整體而言transformers)。 而將loss換成了binary cross-entropy loss之后整體性能下降了0.9pp,說明以對比學習為目標的文本排序任務會更加適合,究其原因還是因為排序任務是一個數據不平衡的優化問題,對于輸入序列來說,負樣本遠比正樣本要大得多,而對比學習在數據不平衡的情況下會更有優勢。
整體上來說之前的一階段召回和二階段排序都是文檔之間相互獨立的,并不直接進行對比,而只是通過向量之間的相似度,或者說是輸出的分數進行一個排序。當時從人的直觀來看,對于相關的排序,往往建立在對于query的理解,還有對所有doc的綜合考慮來做的,而孤立doc偏離了似乎偏離了這一想法。作者用HLATR第三層排序以位置編碼的形式引入了召回特征,以及文檔特征矩陣引入了排序特征,最后通過transformers或者MLP進行交互,相當于是進行了doc之間的信息融合,最后給出了一個分數。
LLM4Retrieval
這里利用Paddle-pipelines搭建了一個文檔檢索環境,一階段使用的分別是rocketqa-zh-base-query-encoder&rocketqa-zh-base-para-encoder召回個數為100,二階段用的是rocketqa-base-cross-encoder,排序之后展示最終的Top2。數據集使用的是醫療科普知識閱讀理解數據集。
這里我們先輸入“如何預防老年癡呆”作為我們的query,召回的具體信息我放在文章最下面了,之后我們將使用不同的prompt來構建我們真實的query,來讓大模型作答。(由于字數超限,所以刪除了原文段的部分文字,不影響做答。)
zero-shot
簡單粗暴,直接把信息丟給ChatGPT進行整合。語法用的是 jinja 寫的,可以支持多種語言渲染。
參考信息
{% for info in context %}
{{loop.index}}. {{info}}
{% endfor%}
Instruction
請參考上面的參考信息,回答下面的問題。
問題
{{query}}
回答
GPT答案如下,看起來有點生硬了,沒有加入身份信息看起來就是正常的科普文。
下面試試看加入身份信息。
參考信息
{% for info in context %}
{{loop.index}}. {{info}}
{% endfor%}
Instruction
你是一名經驗豐富的皮膚科醫生,現在你要求回答下面的問題,你需要基于你多年的從醫經驗并參考上面的信息,你的回復應盡可能詳細,并給出原因。
問題
病人: {{query}}
回答
醫生:
GPT答案如下,整體上看來回答要比之前豐富,而且細節上也更完整,看起來更像是人在交流。
Few-shot
Few-shot的概念就是在zero-shot的基礎上給模型一些示例,有點教模型如何使用參考信息的感覺。
Chain Of Thought
Chain of thought (CoT) 是基于few-shot的改進,指的是從一個問題演化到另一個問題,或者是從一個普遍思想或論據演變出更有深度的思考或論據的過程,即用邏輯連貫的方式進行思維。在example中提供對問題的思考方式、觀察結果以及如何解決問題的細節,能夠豐富模型的最終生成答案,從而將相關點連接起來,結合創造新的思想來推動思考。
時效性
大模型強依賴于訓練數據,實時性的信息和新知識相關的問題是無法準確回答的,那么這個時候可以在通過爬蟲的方式,找到問題相關信息并通過一個額外的閱讀理解(摘要)模型來提取關鍵信息。然后作為參考信息來做為真實輸入的一部分,讓模型具備時效性信息答復能力。
結語
對于大模型在信息檢索上的應用現在還在探索階段,只是停留在閱讀理解的階段是不盡人意的,希望之后LLM能夠具備過目不忘能力,能夠實時更新模型權重以回答時效性問題,新的知識。
謝謝您的耐心觀看,喜歡的話幫忙支持點贊 ?? ? 收藏 ??。
參考
- 風飏:讓天下沒有難Tuning的大模型-PEFT技術簡介
- 吃果凍不吐果凍皮:紅杉資本發布大語言模型應用開發的技術棧預測
- Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks
- moka-ai/m3e-base · Hugging Face
- GanymedeNil/text2vec-large-chinese · Hugging Face
- shibing624/text2vec-base-chinese · Hugging Face
- CoSENT(一):比Sentence-BERT更有效的句向量方案 - 科學空間|Scientific Spaces
- CoSENT(二):特征式匹配與交互式匹配有多大差距? - 科學空間|Scientific Spaces
- GitHub - imClumsyPanda/langchain-ChatGLM: langchain-ChatGLM, local knowledge based ChatGLM with langchain | 基于本地知識庫的 ChatGLM 問答
- MS MARCO
- Maple小七:神經搜索落地曙光——百度RocketQA工具包初體驗
- Condenser: a Pre-training Architecture for Dense Retrieval
- https://arxiv.org/pdf/2205.10569.pdf
- https://github.com/PaddlePaddle/PaddleNLP/tree/develop/pipelines/benchmarks
- 山野閑人:信息檢索:論文精讀【1】coCondenser
- 山野閑人:信息檢索:論文精讀【2】RocketQA
- 山野閑人:信息檢索:論文精讀【3】Dense Passage Retrieval
- 山野閑人:信息檢索:論文精讀【4】HLATR: Enhance Multi-stage Text Retrieval with Hybrid List Aware Transformer Reranking
- 醫療科普知識閱讀理解數據集 - 飛槳AI Studio
- Jinja - Jinja Documentation (3.1.x)
- CoT - 搜索結果 - 知乎
參考信息
- 老年癡呆癥,又叫阿爾次海默病。老年癡呆,一般是指大腦中產生記憶和進行推理的腦功能出現功能衰退的現象。這會嚴重影響到老年人群的日常生活能力,使他們無法正常參加一些活動。更嚴重的是,老年癡呆人群無法自己正常生活,會發生尿失禁導致死亡的現象。隨著年齡的老齡化越來越嚴重,我們應該開始重視老年人群的保健方面。老年癡呆癥對老年人的健康有很大的危害,所以老人們應該及時預防老年癡呆癥。怎樣可以有效預防老年癡呆啊?下面讓我們來一起看看吧!在吃飯前多多用腦。我們每個人一天基本是吃三餐飯,如果老年人能在這三餐飯之間多多動一下腦筋,讓大腦時刻保持活躍的狀態,就可以很有效的預防老年癡呆癥。根據美國老年癡呆癥協會研究發現,如果老年人能夠進行大腦的訓練,就可以防止得老年癡呆癥。要多吃水果蔬菜。根據研究報告顯示,多吃水果蔬菜可以降低大腦衰老的速度。一個著名研究項目曾經對幾十名老人進行了六年的跟蹤,得出的結果是,如果老年人每天吃五份以上的水果蔬菜,大腦的認知能力下降的速度會比其他的低40%。多吃堅果和粗糧,要少吃高熱量的食物。粗糧堅果中含有豐富的維生素E,而且可以讓身體吸收足夠的歐米伽3脂肪酸,它對我們大腦的健康有很大的幫助。跟許多養生的道理都一樣,預防老年癡呆癥,也對我們身體各個地方有很大的好處。吃完飯后做一件事。大多數的人都喜歡吃完飯后看電視,其實這只會讓我們越來越笨。有專家研究發現,如果電視看得越久,特別是在吃完飯后,就會讓我們的腦細胞越來越僵化,會導致我們的思維能力越來越慢。所以在吃完飯后也要多多活活躍我們的大腦。上面所說的就是一些可以預防老年癡呆癥的方法。現在我們的生活越來越舒適,導致很多人有很多不好的生活習慣,到了老年就很容易患上老年癡呆癥。所以我們要養成良好的生活習慣,有效預防老年癡呆癥。
- 概述帕金森病又叫做老年癡呆癥。帕金森病是由老年性疾病,因為它的發病年齡平均在60歲以上。一般40歲以下發病的帕金森病癥是比較少見的。為了防止出現這種情況,下面我給大家介紹一下帕金森癥如何治。帕金森癥如何治第一:普通患有帕金森的患者,疾病的病癥都是先從單側開端發病的,然后病癥就會逐步涉及到對側肢體,藥物治療的效果也逐步降低,反作用越來越明顯。到中晚期會影響到吞咽發聲,晚上翻身艱難,失眠等。嚴重的患者到晚期會由于肌肉攣縮、關節強直而臥床。第二:患有帕金森的患者隨著病程時間的延長,所以患者的病情也就越來越重,而一旦病情加重就會使患者的家庭面臨越來越繁重的人力和經濟擔負,病人從開端的偶然需求人照顧逐漸開展到需求一個以至兩個特地的人來照顧病人的根本生活。第三:患有帕金森的患者,在患病后會呈現肢體的震顫、行動的不便的等病癥,由于這些病癥,患者怕同事或朋友見笑,所以就不盲目將本人封鎖起來,遠離了原先熟習的生活、工作圈。整天待在家中。這樣,疾病在停頓,病癥在加重,心情也隨之變得異常不好,很多帕金森患者存在不同水平的抑郁、焦慮病癥。注意事項目前治療帕金森建議患者可以采取物理加中醫的治療方法,通過把傳統中醫學與現代西方腦細胞科技完美結合,治療方針制定康復效果最佳的治療方案。