午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

大模型應用系列:從Ranking到Reranking

 DuerOS布道師 2024-11-10 發(fā)布于北京

【引子】Ranking 和Reranking又是一個NLP 處理中的傳統(tǒng)技術, 那么在大模型應用中又起到怎樣的作用呢?

每個搜索引擎背后都隱藏著一個至關重要卻往往被忽視的組成部分——Reranking(重新排名)。那么,什么是Rerank呢?簡而言之,這一過程旨在優(yōu)化并調整搜索結果的順序,使之更加精準地匹配用戶的查詢需求。值得注意的是,不同情況下采用的Rerank策略差異極大,因為針對每一個具體問題都需要量身定制解決方案。以去年問世的一款名為RankGPT的先進模型為例,它利用大型語言模型對搜索結果進行重新排序,不僅效果顯著,而且無需事先針對新數據進行額外訓練即可實現。

“治學先治史”,這句話同樣適用于技術領域。深入了解Ranking技術的發(fā)展歷程對于掌握當前最先進的Rerank方法來說很有意義。通過回顧這些系統(tǒng)隨時間演變的過程,我們能夠更深刻地理解現今所采用的各種解決方案是如何設計出來的,以及它們是如何有效解決實際問題的。

1. 早期的Ranking

早期的搜索引擎,相對簡單且但功能有限。當時的技術,就像 BM25一樣,主要集中在精確的術語匹配上。這意味著,如果搜索查詢中的確切單詞沒有出現在文檔中,即使它正是你想要的,那么該文檔就不會被認為是相關的。

這些早期系統(tǒng)的核心是一個名為“TF-IDF”的公式,它基于三個關鍵因素來確定文檔的相關性,其中TF是搜索術語在文檔中出現的頻率,DF是有多少其他文檔包含相同的術語,以及文檔的長度。

為了標準化文檔長度并比較文檔與搜索的相關性,在余弦距離中使用了一種稱為“向量空間模型”的技術。雖然這種方法為早期的搜索引擎奠定了基礎,但是它有一個很大的缺點,那就是它不能理解單詞背后的意思或檢測同義詞。所有東西都必須完全匹配。

例如,如果你搜索一個“悲慘的愛情故事”,一個帶有短語“命運多舛的戀人”的文檔(如羅密歐與朱麗葉)可能不會出現,即使它正是你想要的。這個問題被稱為詞匯不匹配問題,是這些早期搜索系統(tǒng)面臨的最大挑戰(zhàn)之一。隨著語言和術語的發(fā)展,不同的術語可能指的是同一個概念,但精確匹配系統(tǒng)無法彌合這一差距。

為了克服這個詞匯不匹配的問題,出現了一些技巧:

  • 查詢擴展(Query Expansion)通過添加相關術語來擴展搜索范圍,或者通過用戶反饋,或者通過假設排名最高的文檔是相關的。它還使用 WordNet 等工具來查找同義詞。

  • 文檔增強(Document Enrichment)改進了文檔的表示方式,特別是在處理語音轉錄或短文本片段等噪音數據的時候。

  • 超越精確匹配: 早期的語義學方法,如LSA和統(tǒng)計翻譯,試圖捕捉精確詞匹配以外的意義。

然而,真正的突破來自神經網絡,它革命性地支持語義匹配,即理解單詞背后的意思的能力,即使它們不是完全匹配的搜索。

這種從精確詞匯匹配到語義匹配的轉變標志著搜索技術的一個轉折點。今天的搜索引擎結合了這兩種方法來給我們更準確的結果,即使在措辭不完全匹配的情況下,也可以提供相關的內容。

2. LTR的興起

在神經網絡時代之前,像 BM25這樣的搜索引擎和類似的方法使用無監(jiān)督的方法根據詞頻等因素對文檔進行排序。這些系統(tǒng)可以通過數據進行微調,但它們缺乏一種更精確的、基于學習的方法。LTR(Learning to Rank)依賴于從文本本身設計的特征,比如詞頻、文檔長度和 BM25得分。例如,Ranking系統(tǒng)現在可以考慮特定術語在文檔的某個距離內出現的頻率,或者它們出現在標題等關鍵領域的頻率。這些洞見使得搜索結果更加準確、相關。

LTR 模型通常根據它們處理排序任務的方式進行分類:

  • Pointwise: 這種方法查看單個文檔,將排名作為分類或回歸任務處理。這就像是在問“這份文件到底有沒有關聯”

  • Pairwise: 這種方法側重于比較查詢/文檔對,旨在優(yōu)化首選項。例如,在文檔 A 和文檔 B 都相關時,確保文檔 A 的級別優(yōu)于文檔 B。

  • Listwise: 這種方法不關注單個文檔或對,而是評估整個搜索結果列表,并直接優(yōu)化排名指標,如標準化折扣累積增益(nDCG) ,它衡量排名結果對用戶的有用性。

在2010年前后,LTR達到了頂峰?;跇涞哪P?,特別是梯度增強的決策樹,成為優(yōu)化搜索Ranking的首選解決方案。

LTR 技術為如今更先進的搜索系統(tǒng)鋪平了道路。然而,深度學習的到來把事情帶到了一個新的水平,提供了更復雜的方法來排序搜索結果,更準確和更深入地理解用戶意圖。搜索的發(fā)展還遠未結束,但 LTR 代表著這個過程中的一個重要里程碑。

XGBoost 實現了通過一組目標函數和性能指標執(zhí)行LTR。它的目標函數是rank:ndcg,基于 LambdaMART 算法,該算法是對 LambdaRank 框架的改造,以適應梯度提升樹。下面的代碼片段展示了如何實現LTR模型。

from sklearn.datasets import make_classification
import numpy as np

import xgboost as xgb

# Make a synthetic ranking dataset for demonstration
seed = 1994
X, y = make_classification(random_state=seed)
rng = np.random.default_rng(seed)
n_query_groups = 3
qid = rng.integers(0, n_query_groups, size=X.shape[0])

# Sort the inputs based on query index
sorted_idx = np.argsort(qid)
X = X[sorted_idx, :]
y = y[sorted_idx]
qid = qid[sorted_idx]

ranker = xgb.XGBRanker(tree_method="hist", lambdarank_num_pair_per_sample=8, objective="rank:ndcg", lambdarank_pair_method="topk")
ranker.fit(X, y, qid=qid)

3. 深度學習的到來: 搜索排名的新方式

隨著深度學習的興起,搜索排名向前邁進了一大步。有兩個關鍵的突破,首先,連續(xù)向量表示允許模型超越簡單地精確匹配,并理解詞之間更深層次的關系。其次,深度學習減少了對手工標注特征的需求,而特征標注在早期的LTR系統(tǒng)中是一個重大挑戰(zhàn)。

在回顧文本Ranking中的深度學習時,可以考慮兩個不同的階段:BERT 之前的模型和基于 Transformer 的模型。在2019年,BERT的引入改變了游戲規(guī)則,因為基于 BERT 模型提供了更好的性能。這種區(qū)別基本上代表著搜索排名深度學習的兩個時代。

3.1 BERT出現之前的神經網絡Ranking模型

在 BERT 之前,用于神經排序的模型主要有兩種: 基于表示的模型和基于交互的模型。

基于表示的模型分別學習了查詢和文檔的密集向量表示,并使用余弦距離等指標進行比較。一個早期的例子是深度結構化語義模型(DSSM),它使用字符 n-gram 來創(chuàng)建向量表示。后來,諸如基于 CNN 的 DSSM 和雙嵌入空間模型(DESM)通過增加上下文和預先訓練的詞語嵌入進行了改進。

基于交互的模型側重于通過使用相似矩陣來捕獲查詢和文檔中特定術語之間的關系。矩陣反映了嵌入查詢術語與文件中查詢術語的相似程度。這種方法通過使用連續(xù)向量來解決詞匯不匹配的問題,而不是依賴于精確的詞語匹配。

這些模型通常遵循兩個步驟:

  1. 特征提取: 該模型利用不同的技術分析相似度矩陣,聚合詞語的相似度。例如,DRMM 和 KNRM 這樣的模型創(chuàng)建了這些相似性的直方圖,而更高級的模型,如 MatchPyramid,PACRR 和 convknRM,則包含了位置信息來捕捉單詞序列之間的模式。

  2. 相關性評分: 在提取特征之后,該模型將它們結合起來,使用諸如池化和前饋神經網絡等技術為查詢文檔對生成相關性評分。

3.2 Transformer時代的Reranking

隨著像 BERT 這樣的Transformer模型的興起,搜索系統(tǒng)中的Ranking已經變得更加復雜,以便提供更加準確和相關的結果。現代信息檢索系統(tǒng)通常遵循兩個步驟來平衡速度和準確性,其工作原理如下:

  1. 初始檢索是一種輕量級、高效的方法,比如 BM25或 DPR,可以快速檢索一小組候選文檔。這些方法不需要大量的計算,可以快速處理大量的數據。然而,它們的準確性是有限的,因為它們對文檔和查詢都沒有深入的理解。

  2. Reranking: 一旦初始文檔被選中,一個更強大的基于神經網絡的模型被用來重新排序這些候選項。這些重新排序模型通?;谥T如 BERT 之類的 Transformers,因為它們更深入地分析文檔和查詢之間的關系,所以更加精確。然而,由于它們的計算成本很高,因此從一開始就在大型數據集上使用它們將花費太長的時間。因此,它們只應用于在第一階段檢索到的較小文檔集。

這種兩階段方法由于兼顧了效率和準確性而被廣泛使用。通過首先檢索較小的文檔集,系統(tǒng)避免了神經網絡的高計算成本,同時仍然受益于它們在Reranking中的高精度。

4. Reranking的實現方法

雖然有許多方法可以應用于Reranking,但基本上可以分為3類:相關性分類、 提煉查詢和文檔的表示和稠密式表達。

4.1 基于相關性分類的Reranking

一個最簡單的方法來處理文本排序是把它作為一個文本分類問題。這個想法是將每個文本分為“相關”和“不相關”兩類,然后根據每個文本屬于“相關”類別的可能性對結果進行排序。實際上,我們正在訓練一個模型來估計給定文本與用戶查詢相關的概率,然后根據這些概率對文本進行排序。

對于給定的查詢 q 和候選文本 d,該模型計算一個代表相關性的得分 s_i,表示為:

但是這些候選文本是從哪里來的呢?考慮到典型文本語料庫的大小,將這個過程應用到語料庫中的每個文檔,這在計算上是不可行的。對每個用戶查詢的數百萬個文檔運行神經網絡推理,這將非常緩慢而且成本高昂。

大多數搜索系統(tǒng),包括那些使用 BERT 的系統(tǒng),都遵循檢索和Reranking的方法。這意味著系統(tǒng)不會對語料庫中的所有文檔運行 BERT,而是首先使用更快、更傳統(tǒng)的方法(比如 BM25,它依賴于關鍵字匹配)檢索一組更小的候選文本。這個初始階段稱為候選生成或第一階段檢索。

一旦檢索到候選項,BERT 就會通過計算每個候選項的相關性得分對他們進行重新排序。這個重新排名的步驟為搜索增加了更深層次的內容和理解,與最初的基于關鍵字的ranking相比,提高了搜索結果的質量。

例如,使用monoBert模型對查詢和每個候選文本進行結構化分析來實現關聯分類。對于每個查詢 q 和一個候選文檔 d,輸入序列的結構如下:

其中,CLS是BERT 用來表示整個輸入的特殊標記;q是用戶的查詢,已有分詞標記;SEP用于分隔段的特殊標記;d _ i: 候選文本的token。這種結構化的輸入被稱為輸入模板,是BERT處理文本的關鍵部分。BERT然后為該序列中的每個token生成上下文向量表示。

MonoBERT 聚焦于 CLS 令牌的表示,它捕獲查詢和候選文本之間的總體關系。該表示方法通過一個單層完全連通的神經網絡生成候選文檔的相關分數 s _ i。有趣的是,monoBERT 只使用 CLS 令牌的表示來計算相關性得分,而忽略了其他令牌的表示。這使模型既簡單又有效。

MonBERT 的ranking模型通過輸入查詢和待評分的候選文本(由適當的特殊標記包圍) ,使 BERT 適用于相關性分類。MonoBERT 接受一個文本序列作為輸入。這個序列包括特殊的標記和需要比較的內容。具體來說,它看起來像這樣:

[CLS], query, [SEP], document, [SEP]

CLS 和 SEP 是 BERT 使用的特殊標記,用于識別輸入的不同部分在哪里開始和結束。查詢是用戶輸入的文本,而文檔是被評估相關性的候選文本。查詢標記完全按照用戶輸入的內容獲取。當我們探索表達搜索的不同方式時,這個細節(jié)變得非常重要,比如搜索是一個簡單的標題還是一個更長的描述。查詢被標記為段 A,文檔被標記為段 B,這有助于模型理解每個段的角色。

一旦這個輸入序列準備好了,它就被傳遞給 BERT,它處理整個序列并為序列中的每個標記或單詞生成一個“上下文表示”。BERT 的工作是根據單詞出現的上下文來捕捉它們的意思。在 monoBERT 中,[ CLS ]充當整個序列的模型摘要。最后一步是將這個[ CLS ]令牌輸入一個簡單的神經網絡,以預測文檔與查詢的相關程度。輸出是一個分數,告訴我們該文檔匹配的可能性。

這個將查詢和文檔傳遞給 BERT 進行比較的過程,稱為交叉編碼方法。雖然 monoBERT 使用[ CLS ]令牌進行相關性評分,但它忽略了其他token的表示。

要實現交叉編碼器reranking,可以參照以下步驟:

  1. 安裝必需庫,提供使用交叉編碼器所必需的工具。
    pip install -U sentence-transformers

  2. 導入并加載交叉編碼器, 器并加載預先訓練好的模型

  3. 文檔對進行打分: 創(chuàng)建查詢和檢索到的文檔對,然后使用交叉編碼器為它們打分

  4. 文檔reranking: 根據文檔的分數重新排序文檔,優(yōu)先排序最相關的文檔

from sentence_transformers import CrossEncoder 
cross_encoder = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2'
pairs = [[query, doc]
for doc in retrieved_documents]
scores = cross_encoder.predict(pairs)
print("Scores:")
for score in scores:
print(score)
print("New Ordering:")
for o in np.argsort(scores)[::-1]:
print(o+1)

MonoBERT 的一個局限是它難以處理較長的輸入文本。monoBERT有一個固定的輸入長度,這意味著它最適合于較短的文本。因此,雖然 monoBERT 可以有效地對段落長度的文本進行排序,但它還是難以處理完整的新聞文章等較長的文檔。它只能處理多達512個token的序列。由于它依賴于位置嵌入來理解令牌的順序,任何長于512個令牌的輸入都會丟失信息,并被視為一個隨機的單詞集合,從而導致模型失去對文本流動的感知。

BERT 的長度限制給長文本排序帶來了兩大挑戰(zhàn)——

(1)訓練

在訓練過程中最大的問題是,我們應該將文檔的哪一部分輸入到模型中?設想一個文檔,其中有幾個相關的句子分散在整個文檔中,或者整個文檔感覺像一個完整的包一樣相關。我們如何訓練 monoBERT 來處理這些不同的情況?如果想建立不同層次的相關性模型,就更為棘手。

由于查詢通常很短,而文檔很長,我們必須截斷文檔以適應模型。但如果我們切掉最重要的部分呢?雖然我們可以使用一些技巧,比如只向 BERT 提供文檔中包含查詢術語的部分,但這仍然讓我們猜測我們向模型提供的訓練數據是否實際上是文檔中最相關的部分。

(2)推理

在推理過程中,當根據搜索查詢對文檔進行排序時,我們面臨相同的長度限制。如果一個文檔太長,我們不能簡單地將它全部輸入 BERT。我們必須將文檔分割成塊并決定如何處理它們。例如,我們應該把它分成固定大小的部分,還是像句子一樣使用自然分割?這些塊應該重疊多少?

一旦我們有了塊,我們仍然需要一種方法來組合來自文檔不同部分的相關性得分。有兩種常見的方法: 

  • 分數聚合: 我們得到每個組塊的相關性分數并將它們組合(例如,通過獲得最高分)。

  • 表征聚合: 我們首先結合每個段落的表征,然后預測一個單一的相關分數。

為了處理 BERT 的長度限制,Dai 和 Callan 在2019年提出了一個解決方案,基本想法是這樣的:

  • 訓練: 將文件分成重疊的段落,并將相關文件中的每一段落視為相關文件,將不相關文件中的每一段落視為不相關文件。

  • 推理: 使用與上面相同的方法,將文檔分割成小塊,評估每個小塊的相關性,然后組合得分。

具體而言,文檔被劃分為150個單詞的片段,每個片段之間有75個單詞的重疊。對于每個段 ,模型像 monoBERT 一樣處理它: 查詢和段被合并并輸入 BERT,使用最終的[ CLS ]標記對段進行評分。在給每篇文章打分之后,我們可以用三種方法把分數組合起來:

  1. BERT–MaxP: 從任何一篇文檔中取得最高分。

  2. BERT–FirstP: 使用第一段的分數。

  3. BERT–SumP: 把所有段落的分數加起來。

通過將文檔分割成可管理的塊,然后聚合結果,我們可以對整個文檔進行排序,同時保持在 BERT 的輸入長度限制內。

在 monoBERT和 BERT-MaxP 等早期模型中,只使用[ CLS ]標記作為 BERT 用于匯總輸入的特殊標記。它用于計算文檔與查詢的匹配程度。但是,BERT 為查詢和文檔中的所有單詞生成了上下文嵌入。忽略這些嵌入看起來像是錯失良機,這正是 MacAvaney 在2019在開發(fā) CEDR (Leveraging Contextual Embedding Ranking)所解決的問題。

CEDR 通過保留和使用 BERT 生成的上下文嵌入,這些嵌入可以提供關于文檔不同部分與查詢相關性的更細微信號。

為了處理超過 BERT 512 token限制的文檔,CEDR 將文檔分成更小的、可管理的塊。這些塊(包括查詢和特殊的分隔符標記)由 BERT 逐個處理。處理完所有數據塊后,CEDR 從每個數據塊獲取[ CLS ]表示,并對它們進行平均,以創(chuàng)建文檔級[ CLS ]表示(一種稱為平均池的技術)。CEDR 不僅僅使用[ CLS ]令牌,還保留每個塊的上下文嵌入,將這些內容連接起來,形成整個文檔的上下文嵌入完整序列。

一旦創(chuàng)建了文檔級嵌入,CEDR 通過比較每個文檔項的嵌入和每個查詢項的嵌入來構造相似矩陣。這些矩陣捕獲文檔不同部分與查詢不同部分的匹配程度,比單獨使用[ CLS ]令牌提供了更深入的相關性理解。

通過將 BERT 強大的嵌入到現有的神經排序模型中,CEDR 可以一塊一塊地處理較長的文檔,同時仍然保持模型端到端的可訓練性。這不僅解決了 BERT 的長度限制,而且允許 CEDR 充分利用 BERT 提供的豐富上下文信息,使其在文檔排序任務中具有優(yōu)勢。

4.2. 提煉查詢和文檔的表示

信息檢索中最大的挑戰(zhàn)之一是詞匯不匹配問題,即搜索內容和文檔使用不同的詞來描述同一個概念。

依賴于精確匹配的傳統(tǒng)ranking模型,如 BM25,如果相關文檔不包含查詢中的確切單詞,則無論相關性如何,都不會檢索到該文檔?;谏窠浘W絡的ranking模型,特別是那些使用連續(xù)向量表示的模型,通過學習“軟”匹配提供了一個潛在的解決方案。他們不依賴于精確的詞語匹配,而是能夠識別詞語之間的語義關系。

然而,在這些模型中仍然存在一個主要的瓶頸即初始候選項生成階段。大多數Ranking系統(tǒng)使用多階段過程,第一階段檢索候選文檔(通常使用像 BM25這樣的精確匹配系統(tǒng)) ,第二階段使用更強大的模型(如 BERT)對候選文檔進行Reranking。但是,如果第一階段由于缺乏匹配的術語而無法檢索到相關文檔,那么無論Reranking多么優(yōu)秀,都無法檢索到一開始沒有出現的內容。

雖然相關文檔與查詢沒有重疊的情況并不常見,但遺漏關鍵術語的情況很常見。這個問題的強力解決方案是簡單地增加在第一階段檢索到的候選文檔的數量,希望相關文檔最終會出現在更深入的結果中。但這種解決方案有其自身的缺點,即延遲的增加。隨著需要處理的候選文檔越來越多,Reranking變得越來越慢。

真正的解決方案是改進或增強查詢和文檔的表示方式,這樣它們就能更緊密地與用戶的搜索意圖保持一致。這可以通過諸如查詢擴展和文檔擴展等技術來實現。文檔擴展通過向文檔添加額外的術語來更充分地表示其內容或將其與潛在查詢聯系起來。它將同義詞或相關術語添加到查詢本身,可以增加查找可能使用不同單詞的相關文檔的機會。查詢擴展則相反,它將同義詞或相關術語添加到查詢本身,同樣可以增加找到可能使用不同單詞的相關文檔的機會。

這兩種方法都有助于解決詞匯表不匹配的問題,因為它們都增加了查詢和相關文檔之間匹配的可能性。

在大模型應用中,可以通過提示詞完成Query 變換(詳見大模型應用系列:Query 變換的示例淺析)。其中,一個Query改寫的示例如下:

rewrite_prompt= ChatPromptTemplate.from_template("""Provide a better search query for web search engine to answer the given question, end the queries with ’**’. Question: {x} Answer:""")

def parse_rewriter_output(message):
return message.content.strip('"').strip("**")
rewriter = rewrite_prompt| llm| parse_rewriter_output

@chain
def qa_rrr(input):
# rewrite the query
new_query = rewriter.invoke(input)
# fetch relevant documents
docs = retriever.get_relevant_documents(new_query)
# format prompt
formatted = prompt.invoke({"context": docs, "question": input})
# generate answer
answer = llm.invoke(formatted)
return answer
# run
qa_rrr.invoke("what is langchain?")

請注意,示例中用一個LLM將用戶初始查詢重寫為更清晰的查詢,然后被傳遞給檢索器以獲取最相關的文檔。這種方法的缺點是,它在鏈中引入了額外的延遲,需要按順序執(zhí)行兩個LLM調用。

與query變換相比,使用查詢預測進行文檔擴展提供了一種不同的方法。文檔擴展并不新鮮,它已經存在了幾十年,但是2019年 Nogueira 等人引入 doc2query 后,使用神經網絡進行了演進。

Doc2query 使用序列到序列模型(一種為語言翻譯等任務設計的神經網絡) ,獲取一段文本并生成與文檔相關的查詢。這些查詢基于真實世界的數據,這些數據中成對的查詢和相關文檔被用來訓練模型。一旦模型得到訓練,它就可以預測語料庫中每個文檔的有哪些查詢。然后,這些預測的查詢將被添加到原始的文檔文本中。這些“擴展文檔”現在不僅包含原始內容,還包含潛在的搜索查詢,這提高了它們在初始搜索階段被檢索到的機會。在對這些擴展文檔進行索引和檢索時,系統(tǒng)能夠更好地檢索相關信息。這種技術可以無縫地集成到任何多階段排序流水線的第一階段檢索中,并且可以與我們前面討論的Reranking模型完美地一起工作。

Doc2query的實現示例代碼如下所示:

sample_doc = "xxx"

import pyterrier_doc2query
doc2query = pyterrier_doc2query.Doc2Query()
doc2query([{"docno" : "d1", "text" : sample_doc}])

Doc2Query 對象有一個 change ()函數,它接受每個文檔的文本,并為該文本提出問題。生成的數據框架將有一個額外的“ querygen”列,其中包含生成的查詢。有很多方法可以將 Doc2query 引入 PyTerrier 檢索過程。我們可以通過傳遞另一個huggingface 模型名稱(或文件系統(tǒng)上模型的路徑)作為第一個參數來加載另一個T5模型。

doc2query = pyterrier_doc2query.Doc2Query('some/other/model')
import pyterrier as pt
pt.init()
dataset = pt.get_dataset("irds:abc")
import pyterrier_doc2query
doc2query = pyterrier_doc2query.Doc2Query(append=True) # append generated queries to the orignal document text
indexer = doc2query >> pt.IterDictIndexer(index_loc)
indexer.index(dataset.get_corpus_iter())

4.3 Reranking的稠密表達

深度學習給文本排名帶來的最大突破之一,是從依賴稀疏信號(主要依賴精確的關鍵詞匹配)轉向能夠捕捉單詞背后含義的連續(xù)密集表示。這一飛躍使我們能夠更自然、更靈活地建立相關性模型,解決諸如詞匯不匹配這樣的挑戰(zhàn)。

在基于稠密表達的檢索技術中,Ranking直接在矢量表示(通常由Transformer生成)上執(zhí)行?;诔砻鼙磉_檢索通過比較語義內容,本質上就是比較嵌入在這些向量中的“意義”,而不是僅僅匹配出現在查詢和文本中的詞,這代表了面向基于關鍵字檢索的一個重大轉變。

自從詞嵌入出現以來,稠密表達已經顯示出它們的潛力,這引發(fā)了我們現在所說的自然語言處理(NLP)中的“神經網絡革命”。單詞嵌入表明機器能夠理解單詞之間的關系,證明語言可以用一種捕捉意義的方式來表示,而不僅僅是表面量上的匹配。

然而,當我們把這個概念從單個單詞擴展到更大的文本塊(如短語、句子或整個文檔)時,事情就變得復雜起來,同樣的挑戰(zhàn)也出現在文本ranking/reranking中。

5. 基于大模型的Reranking實現示例

隨著大模型應用的普及,我們可以利用 GPT-4或國內的其他大語言模型以更細致的方式評估文檔的相關性,實現Reranking?;?LLM 的Reranking工作流程如下:

  1. 初始檢索: 系統(tǒng)根據查詢檢索一組初始文檔。

  2. 查詢/文檔對的創(chuàng)建: 每個檢索到的文檔都與查詢配對。

  3. 得分: LLM 評估每一對并分配一個相關得分。

  4. reranking: 根據分數對文檔進行排序。

  5. 選擇: 選擇得分最高的文檔作為最終答復。

基于 LLM 的Reranking實現示例如下:

from langchain.docstore.document import Document
from langchain_openai import ChatOpenAI
from typing import List
from pydantic import BaseModel, Field
from langchain import PromptTemplate

class RatingScore(BaseModel):
relevance_score: float = Field(..., description="The relevance score of a document to a query.")

def rerank_documents(query: str, docs: List[Document], top_n: int = 3) -> List[Document]:
prompt_template = PromptTemplate(
input_variables=["query", "doc"],
template="""On a scale of 1-10, rate the relevance of the following document to the query. Consider the specific context and intent of the query, not just keyword matches.
Query: {query}
Document: {doc}
Relevance Score:"""
)

llm = ChatOpenAI(temperature=0, model_name="gpt-4", max_tokens=4000)
llm_chain = prompt_template | llm.with_structured_output(RatingScore)

scored_docs = []
for doc in docs:
input_data = {"query": query, "doc": doc.page_content}
score = llm_chain.invoke(input_data).relevance_score
try:
score = float(score)
except ValueError:
score = 0 # Default score if parsing fails
scored_docs.append((doc, score))

reranked_docs = sorted(scored_docs, key=lambda x: x[1], reverse=True)
return [doc for doc, _ in reranked_docs[:top_n]]

在本示例中,LLM 評估每個文檔與查詢的相關性,對它們進行評分,并根據這些評分選擇最高的文檔。

6. 小結

通過回顧信息檢索的歷史,我們可以了解到從Ranking到Reranking的演進過程。如今,Reranking是大模型應用中RAG 系統(tǒng)的一個非常關鍵的步驟,其核點是提高最初檢索到的文件的相關性和質量。在最初的檢索過程之后,對這些文檔進行重新排序和重新組織,目標是確定最相關信息的優(yōu)先次序,確保在作出回應或決策時使用盡可能好的數據。

    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多