今天會在分析眾多優秀解法後,從本次賽題的經驗,總結建立一個 RAG 系統最重要的幾個要點。
📢 作者有話要說:(10/5更新)我在 Day 20 補充第五名的多階層作法,並補充第一名作法的更多細節以及圖解,其中關於 "cross-information" 的設計既高效又有用,歡迎各位回去看看呦
(*´∀`)~♥
在開始前,還是先放上這張架構圖,因為今天要介紹的各種解法,也還是圍繞 Database, Retriever, Answer Model 來設計呦~
經過他們的 pilot study,他們發現檢索的品質取決於 database 是否涵蓋足夠豐富與乾淨的 wiki 文本。他們和第一名一樣使用來自 Cirrussearch dump 的 Wikipedia 資料,裡面有完整包含 wiki page 裡面的信息,包含數字公式等等,他們把這些內容根據 sentence 切成 context chunk ,儲存在他們自己搭建的 Elasticsearch Local Server 中。
他們採用兩階段的檢索策略:
Stage I.
在階段一,使用 Elasticsearch 來進行基本的關鍵詞檢索,這是一個基於倒排索引的高效全文檢索系統。具體步驟如下:
在 Stage I 中會粗略篩選 n 個 candidate contexts 傳到 stage II。
msmarco-bert-base-dot-v5
來計算問題提示和 Wikipedia 句子之間的語義嵌入,並使用 all-mpnet-base-v2
來計算選項與 Wikipedia 句子之間的語義嵌入。上下文根據語義相似度進行排序。最後傳給 answer model 的 enhanced context,會是使用以上三種不同方式找到的 candidate contexts 的組合~
他們使用 Deberta v3 Large
作為他們的 Answer Model ,並在討論區公開的一份用 chatgpt 以及合併其他科學相關主題的 dataset 的方式擴增的訓練數據集,結合他們上面的多策略 Retriever,來 fine-tuned deberta 分類模型。(對擴增訓練集建立的方法感興趣的朋友,可以看看我在[Day17]寫的一篇介紹文呦)
訓練 deberta multi-class classifier 的部分就不再贅述了,值得注意的是,他們發現主辦方公布的那兩百筆訓練數據,對模型來說,非常非常的簡單!
如果用這筆資料當作 validation set,隨便訓練的answer model就可可以在這個資料集上拿到 0.99 的 MAP@3。於是他們不再使用這200筆資料集當他們的 validation set,反而從網友擴增的 40K 和 60K 的訓練集中,抽取 2000 筆 data 當作 validation set。
CV vs. LB Validation Test
因為是額外生成的假資料,在這部分,他們很小心地檢查這份 validation set 得出的 CV Score 和 LB 的 correlation:
發現用這 2000 筆資料當作 validation set 所計算出的 CV 分數,和 LB 的分數有高的相關性。我想這部份他們應該也是反覆做實驗,去檢查擴增資料集中,哪部分的 data 和 LB 的 correlation 比較高,再選這些資料作為自己的 validation set。
這是個很不錯的比賽技巧,可以卻確保開發用的驗證資料集和測試資料集不會有太大的誤差!
最後他們也是採用各種 ensemble deberta 的方式來建構他們的 answer model。
這部分也不再贅述,ensemble deberta 模型可以有很多策略,像是在不同 cross-validation 的 dataset 上訓練、採用不同 pooling 的方式等等,有興趣的朋友可以參考我前兩個賽題的解法分享。(Day5, Day9~Day10)
他們在 LB 上取得 0.9276 左右的成績~
與其在encoder-only還是decoder-only好的路線之爭上糾結,不如全都用!
(👆圖片來源)
接下來會開始介紹一些混合兩種架構的模型作為其 answer model 的策略~
總結這個團隊的作法就是:
他們主要有兩個來源:Wiki 和 MB 270K,這是一個較大規模的技術和學術文本資料集。
他們把每 256 個 token 切成一個 chunk。
這邊他們也在兩種不同資料來源上,採用多種不同的 retrieval 策略:
WIKI
他們會預先把每篇文章的 context chunk 用 gte-small
這個 embedding model 轉成向量,把全部的 context chunk 平均起來的向量當成該篇文章的向量。
檢索的時候,先檢索和當前 question 相關的文章,再用 TF-IDF 的方式將文章中的各個 context chunk 編碼成 tf-idf vector,接著找到和當前問題最為相關的 5 個 context chunk。
MB
對 MB Dataset 他們也是採用 embedding similarity 和 TF-IDF 兩種方式個別找出 candidate context。
你會發現在這次比賽中,有不少人使用像是 BM25, TF-IDF 或是關鍵字匹配的方式,先當作檢索的第一步。
這是因為這次的賽題,似乎比較像一個「檢索大賽」。
重點不在怎麼訓練一個優秀的 answer model 讓它學會本來它預訓練時沒學過的知識;所有的「微調」,似乎都只是讓模型學會根據我們要求的格式輸出。
我們最重要的訓練目標是,給他合理的參考資料,使模型可以「調動」它在預訓練階段學過的知識與推理能力,並根據格式規範來回答我們的問題。
例如問題中時常詢問一些專有名詞、事件等等,這很明顯就用關鍵字匹配就能找到非常相關的參考資料了!
一開始,他們想要全部都用 7B 以上的 LLM 當作他們的 Answer Model 主體。
但後來發現這些LLM inference真的好花時間,所以他們也採用和第五名一樣的「多階層 Hierarchical Inference 策略」:
先把簡單的問題交給 deberta model,如果某些難題 deberta 做不好,那就挑出來交給比較大型、複雜的 LLM 再做一次。
在開始介紹他們的策略前,還是提一下,他們是採用 "Multi-Class" 的方式來 formulate 問題:
### Input: <context>\n\n### System: Answer the following multiple choice question by giving the most appropriate response. Answer should be one among [A, B, C, D, E]. Use the input text above as a reference for your answers if needed.### Question: <prompt>\nA) <option A>\nB) <option B>\nC) <option C>\nD) <option D>\nE) <option E>\n\n### Answer:
使用 deberta-large-v3
以及 Mistral-7B
的不同 instruction-tuning 版本,和 OpenOrca-Platypus2-13B
、Llama2-chat-AYT-13B
作為他的 answer model。
在 LLM fine-tuned 的部分,一樣使用 QLoRA 進行微調。
下面是他測試 single model 在 LB 的表現:
StageI. 先讓一個 DeBERTa-V3 large 模型,根據從 WIKI retrieve 回來的參考資料回答問題。挑出信心值小於 0.95 的題目,送入第二階段。
Stage II. 用同樣的 Deberta-V3 large 模型,使用 TF-IDF 的方式,從 MB 270K retrieve 相關資料來回答問題。挑出信心值小於 0.90 的題目,送入第三階段。
Stage III.現在用兩個不同最大長度的 deberta,根據不同來源、不同 retrieval 策略找出來的參考資料來回答問題。繼續挑出信心值小於 0.7 的題目,送入最後一個階段。
Stage IV. 最後這個階段使用三種不同的 LLM,由他們各自根據不同檢索策略找到的參考資料來回答問題。
最終他們在 LB 得到 0.9251 的分數~
雖然第十九名已經不在金牌搖滾區中了,但是他採用訓練自己的 deberta 模型,並混合 zero-shot 70B LLM 的方式來建構他的 answer model,有別於前面介紹的,都是要fine-tuned就全部都tuned的方法。個人覺得滿有趣的,就也挑出來介紹~
他們也採用兩階段檢索:分別利用 Embedding Similarity 的 Dense Retrieval 以及利用 TF-IDF 的 Sparse Retrieval 策略來做他整體的 retrieval 系統。
效果也很不錯,在 LB 上有 0.9178 的分數。
同時,他也做了很詳盡的 Ablation Study,了解到底只使用 Encoder-only 的模型、只 Zero-Shot 一個 70B LLM,與兩者 ensemble 起來,對 LB 什麼影響。
我們一起來看看:
下表的 Encoder 指的是 Deberta V3
模型;Decoder 指的是 orca-mini-v3-70b
模型。
Method | Public Score | Private Score |
---|---|---|
Encoder w/o any retrieval | 0.822 | 0.805 |
Encoder w/ dense retrieval | 0.889 | 0.884 |
Decoder w/ dense retrieval | 0.897 | 0.889 |
Decoder w/ dense+sparse retrieval | 0.904 | 0.906 |
Decoder+Encoder w/ dense retrieval | 0.906 | 0.901 |
Decoder+Encoder w/ dense+sparse retrieval | 0.921 | 0.917 |
可以從檢索 Retrieval 和模型兩種角度去分析上面的實驗結果:
到這邊,終於把這個賽題分析完了(呼~
在看過這麼多比賽團隊的方案後,可以大致得出在這個賽事中,要建立一個優秀的 RAG 系統,重點在下面這三點:
📌 建立一個乾淨並且豐富的 database。 Database 一定要包含 WIKI 的內容,但還可以增加其他科學相關的資料來源,重點在盡可能涵蓋各式各樣的內容,並且保留數學公式、數值等和領域高度相關的資訊。
📌 多樣化的 retrieve 策略。 使用 Dense 或 Sparse Retrieval、使用不同 embedding model,採用各式各樣的檢索方式,並在訓練answer model時增加擾動,提升泛化能力。
📌 Answer Model。其實我覺得這個比賽的 answer model 反而不是什麼重點,要用 encoder-only 還是 decoder-only 的都可以,但還是 ensemble 不同架構、pre-trained 的模型效果最佳。
當然過程中我們也有討論到一些廣泛使用的 answer model 的設計技巧,包含:
另外在 ensemble 不同 answer model 上也有技巧!
被很多組別使用的是「多階層推理策略」,也就是使用準確度、複雜度不同的模型,來處理對應難度的問題。
透過一層一層的篩選,使得難題可以被不同模型進行多次預測,得到比較 robust 的預測結果。(具體怎麼做,可以參考昨天第五名的作法,以及今天第七名的作法)
接下來,回應我們一開始的問題:
(1). 結合外掛資料庫,用擴增訓練資料集訓練傳統的BERT-style(ex:Deberta)答題模型
(2). 結合外掛資料庫,用擴增訓練資料集訓練 GPT-Style (ex:一些常見的 LLM)的答題模型
(3). 結合外掛資料庫,用 zero-shot 或是 few-shot 以不改變模型權重的方式問 LLM 答案
🤔哪一種路線被廣泛應用於本次賽事的金牌解法中呢?
Method | 數量 |
---|---|
Fine-tune Decoder-only model(LLM) | 2 |
Zero-Shot Decoder-only model(LLM) | 0 |
Fine-tune Encoder-only model(Deberta) | 4 |
Hybrid | 5 |
經過統計,金牌區中大部分的方案還是採用 emsemble deberta 加上 7B/13B/70B 等大語言模型作為其 Answer Model 的主體,其次才是只使用 Encoder-only(Deberta)的作法。
🤔那麼既然每個人都有用到 embedding model 作為他們的 retriever,到底哪些 embedding model 被廣泛應用於本次賽事呢?
答案是:e5家族, gte家族, bge家族, all-MiniLM-L6-v2
, msmarco-bert-base-dot-v5
, instructor-xl
,這些 embedding model 最常被 cue 到呦!
至於 LLM 的話,最常被使用的大型語言模型有這些:Llama-2-7b
、Mistral-7B-v0.1
、xgen-7b-8k-base
、 Llama-2-13b
、Platypus2-70b
、orca-mini-v3-70b
。
最後,我想總結一下 database 的建立經驗。
好的 database 才有後面 retriever 與 answer model 發揮的空間。在這麼多解法中,他們建立 database 的方式有什麼異同之處呢?
其實我們可以總結一下下面這三種最常被使用到的 dataset 及這些 dataset 的小缺點,其實很多優勝的組別都是在分析現有 dataset 的issue後,決定自己手搓一個符合要求的高品質數據庫~
Dataset | Parser | Page | Text Info |
---|---|---|---|
Kaggle published dataset by @jjinhojjinho/wikipedia-20230701 | wikitextparser |
Some pages are dropped | All templates are dropped.All the “\n” are dropped (difficult to read by human). |
Huggingface dataset- wikipedia- graelo/wikipedia | mwparserfromhell |
Better coverage | All templates are dropped.<math> , <ref> , <table> tags are dropped. |
cirrussearch | Wikipedia Cirrus Extractor |
Better coverage | All the “\n” are dropped (difficult to read by human). |
自己做一個 | Wikipedia Cirrus Extractor |
Better coverage | {val} and {math} templates text are kept (Other templates are dropped). |
Keep <math> tag, but <ref> , <table> tags are dropped. |
有很多人在建構 database 時,會反反覆覆回去檢查現在資料庫的問題,發現例如缺乏數字、缺乏攻公式、缺乏某些文章,這些都是和 domain knowlege 息息相關的issue。大部分金牌團隊,都花很多時間在建立自己的資料庫,可能是去找merge其他來源,或是自己利用https://github.com/attardi/wikiextractor 去爬wiki重新去整理。
總之,我覺得這類的經驗很重要,RAG系統很需要根據當前任務的需求細心篩檢 database 的內容,天下沒有白吃的午餐,公開、通用的資料,往往有些美中不足,直接拿來應用到自己的領域任務上總是會有各式各樣的問題QQ
LLM-Science Exam 的賽題解析到這邊終於結束啦!
嗚嗚沒想到都第 21 天了,我竟然還在寫這個賽題的解法,整個進度大 delay ╮(╯_╰)╭
明天我們就會進入新的賽題囉~
大家明天見!
謝謝讀到最後的你,希望你會覺得有趣!
如果喜歡這系列,別忘了按下訂閱,才不會錯過最新更新,也可以按讚⭐️給我鼓勵唷!
如果有任何回饋和建議,歡迎在留言區和我說✨✨
(Kaggle - LLM Science Exam 解法分享系列)