爲什麼 RAG 一定需要 Rerank?

今天和大家講一下檢索增強生成(RAG)裏面的 Rerank。

RAG 給人帶來無限期待,尤其是在結合了 LLM 之後,大家都想着:這下終於能搞定那些複雜的問答任務了吧!但現實往往是骨感的。很多人開發完一個 RAG 流程後都會疑惑:爲什麼它的效果沒有達到預期呢?

其實,和大多數工具一樣,RAG 用起來簡單,但想要精通卻很難。事實上,RAG 不只是把文檔存入向量數據庫,然後在上面添加一個 LLM 那麼簡單。那樣做 有可能 行得通,但並不總是有效。

所以今天這篇文章,咱們就聊聊當現成的 RAG 不起作用時該怎麼辦。如果你經常遇到 RAG 表現欠佳的情況,這裏有一個最容易、最快實施的解決方案——重排序 Rerank

召回率與上下文窗口

當然,在介紹解決方案之前,咱們先聊聊單純 RAG 存在的問題。使用 RAG 時,我們要對許多文本文檔進行 語義搜索 ——這些文檔可能從數萬篇到數百億篇不等。

爲了確保大規模搜索時的速度夠快,我們通常會使用向量搜索。也就是說,把文本轉換成向量,將它們都放入一個向量空間,然後使用像餘弦相似度這樣的相似性度量來比較它們與查詢向量的接近程度。

要讓向量搜索起作用,我們需要向量。這些向量本質上是將某些文本背後的 “含義” 壓縮成(通常是)768 維或 1024 維的向量。由於我們把這些信息壓縮成了單個向量,所以會有一些信息丟失。

因爲這種信息丟失,我們經常會發現,例如,向量搜索返回的前三篇文檔可能會遺漏相關信息。相關信息可能會在我們設置的 top_k 閾值之外被檢索到。

如果位置靠後的相關信息能幫助我們的 LLM 給出更好的回覆,那該怎麼辦呢?最簡單的方法就是增加返回的文檔數量(提高 top_k 值),然後把這些文檔都傳給 LLM。

這裏我們衡量的指標是 召回率 ,意思是 “我們檢索到了多少相關文檔” 。召回率不考慮檢索到的文檔總數,所以我們可以通過返回 所有 文檔來 “操縱” 這個指標,從而得到 完美 的召回率。

可惜的是,我們不能返回所有文檔。LLM 對於能接收的文本量是有限制的,我們把這個限制稱爲 上下文窗口 。有些 LLM 的上下文窗口很大,比如 Anthropic 的 Claude,它的上下文窗口有 100K 個 Token 。有了這麼大的窗口,我們可以放入幾十頁的文本。

那麼,我們能不能返回很多文檔(雖然不能是全部),然後 “塞滿” 上下文窗口來提高召回率呢?

答案還是不行。我們不能使用上下文填充的方法,因爲這會降低 LLM 的 召回性能 。注意,這裏說的是 LLM 的召回率,和我們之前討論的檢索召回率是不一樣的。

當在上下文窗口中間存儲信息時,與一開始就不提供該信息相比,LLM 回憶該信息的能力會變差

研究表明,隨着我們在上下文窗口中放入更多的標記,LLM 召回率會降低。當我們塞滿上下文窗口時,LLM 也不太可能遵循指令,所以上下文填充不是個好主意。

那麼問題來了:我們可以增加向量數據庫返回的文檔數量來提高檢索召回率,但如果把這些文檔都傳給 LLM,就會損害 LLM 的召回率。怎麼辦?

解決這個問題的辦法是,通過檢索大量文檔來最大化檢索召回率,然後通過 最小化 傳給 LLM 的文檔數量來最大化 LLM 召回率。要做到這一點,我們需要對檢索到的文檔重新排序,只保留對 LLM 最相關的文檔,而實現這個操作,我們就要用到 Rerank 。

Rerank 的強大之處

重排序模型,也被稱爲 交叉編碼器 ,是一種模型,給定一個查詢和文檔對,它會輸出一個相似度分數。我們用這個分數根據文檔與查詢的相關性對文檔進行重新排序。

一個兩階段檢索系統。向量數據庫步驟通常會包括一個雙編碼器或稀疏嵌入模型。

我們都知道現在搜索工程師們在兩階段檢索系統中使用 Rerank 已經有 很長時間 了。在這些兩階段系統中,第一階段的模型(一個嵌入模型 / 檢索器)從更大的數據集中檢索出一組相關文檔。然後,第二階段的模型(Rerank)用來對第一階段模型檢索到的那些文檔進行重新排序。

我們採用兩階段的方式,是因爲從大數據集中檢索出一小部分文檔比重新排序一大部分文檔要快得多。簡單來說,Rerank 運行速度慢,而檢索器運行 速度快 。

爲什麼要用 Rerank?

如果 Rerank 速度這麼慢,那爲什麼還要用它們呢?答案是,Rerank 比嵌入模型要準確得多。

雙編碼器準確性較差的原因在於,雙編碼器必須把一個文檔所有可能的含義壓縮成一個單一向量,這就意味着我們會丟失信息。此外,雙編碼器在查詢方面沒有上下文信息,因爲在收到查詢之前,我們並不知道查詢內容(我們在用戶查詢之前就創建了嵌入)。

另一方面,Rerank 可以將原始信息直接輸入到模型中計算,這意味着信息丟失更少。因爲我們是在用戶查詢時運行 Rerank,所以還有一個額外的好處,那就是可以根據用戶查詢來分析文檔的特定含義,而不是試圖生成一個通用的、平均的含義。

Rerank 避免了雙編碼器的信息丟失問題,但它們也有另一個代價—— 時間 。

一個雙編碼器模型將文檔或查詢的含義壓縮成一個單一向量。請注意,雙編碼器在用戶查詢時,以與處理文檔相同的方式處理我們的查詢。

假設你有 4000 萬條記錄,如果我們在 V100 GPU 上使用像 BERT 這樣的  型重排序模型,那麼爲了返回一個查詢結果,我們可能要等上 50 多個小時 。而使用編碼器模型和向量搜索,同樣的操作可以在不到 100 毫秒內完成。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/qUBVRIt-QNgxLW8HHqybMw