一 傳統方法
之前的文章已經介紹過向量資料庫在RAG(Retrieval Augmented Generative)中的應用,本文將會討論另一個重要的工具-Embedding模型。
一般來說,構建生產環境下的RAG系統是直接使用Embedding模型對使用者輸入的Query進行向量化表示,並且從已經構建好的向量資料庫中檢索出相關的段落使用者大模型生成。但是這種方法很明顯會受到Embedding模型效能的影響,比如是否支援多語言、跨語言檢索、訓練資料的質量等。因此,以改進Embedding模型為目標提升RAG系統效能一般會有兩種做法:
方法1,在使用向量模型獲取密集向量後,再使用Cross-encoder作為精排模型,對第一次召回的結果進行重排,以提高最終結果的質量。
方法2,使用稀疏向量搭配密集向量進行召回。密集向量即對整個文字進行向量化表示產生的向量,稀疏向量則是對原始文字的編碼表示,如TF-IDF,BM25等。其中,稀疏向量可以幫助識別和捕捉特定的語義資訊,比如文字中的關鍵詞,而密集向量則可以提供更豐富的語義表達,是透過大量長文字學習而來的。透過同時將這兩種向量進行召回,可以獲得更豐富、更全面的資訊,從而提升 RAG 的效果。
方法1和方法2既可以獨立使用,也可以搭配使用,這就大大增加了演算法工程師的武器庫,透過搭積木的方式來提高RAG系統的效果。
二 Reranker模型剖析
本文主要討論二階段檢索的方法,對於稀疏向量的討論不在本文範圍之內。
使用精排模型的原因
原因之一,向量資料庫中儲存大量的向量資料,而想要從大量資料中精確地檢索出最相似的向量勢必會帶來極大的延遲,這在任何應用中都是無法接受的,因此向量資料庫一般都會透過建立索引來最佳化查詢過程,這實際上是一種近似檢索而非精確檢索,是準確與效率的折衷方案。如果資料庫中沒有那麼多的向量,或者全表檢索的時間損耗能夠接受,則完全沒必要用近似檢索,但這在實際生產系統中是不可能的。
其二,LLM受限於上下文長度的限制,所以能利用到的向量片段數量是有限的,儘管現在越來越多的研究使得LLM的上下文視窗越來越長,如改進位置編碼或者注意力機制等,但也有實驗表明再長的上下文輸入給大模型總會由遺失或者處理不好的情況,稱為“Lost in middle”現象。因此,更好的辦法是把更有用的上下文篩選出來,重點在於提升質而不是量。
精排模型結構
下面有兩個模型,分別是Bi-Encoder和Cross-Encoder。左邊的Bi-Encoder實際上就是我們常見的向量化模型,需要注意的是模型的結構並不是有2個Bert,而是隻有1個Bert模型,但是對於兩個句子分別做了向量化表示,最終比較這兩個向量的相似度。這裡‘Bi’表示的是處理的過程,而不是實際的結構。
而精排模型用到的Cross-Encoder結構則是把兩個句子的輸入concat到一起,最終預測這兩個句子是否相關,有點類似於Bert訓練時的next sentence prediction(NSP)。不難發現,這實際上就是一個分類模型,而且並不會產生具體的向量表示,只會產生一個介於0和1之間的值,用於表示句子對的相似性。而且,在使用時,需要將Query與待查詢的句子拼接到一起再輸入給模型,所以這就決定了輸入的句子對數量不能太多,否則帶來的計算耗時將會是無法估量的。
精排模型的本質
直觀上來講,用Bi-Encoder“目的更加通用”,是為了得到輸入的向量化表示,這些向量不僅有大小,還有方向,因此就有這麼一個學習向量化時遇到的經典例子:$國王-男人=女王-女人$。
而使用了Cross-Encoder的精排模型,因為輸入部分包含了兩個原始的句子,因此是從文字空間直接表示句子的相似度,而不是到了向量空間再表示。具體而言就是:傳統的向量是經過了模型輸出之後再根據不同的運算元計算向量之間的相似度,而這個模型是句子對由模型得到端到端的結果。
能否再使用一次向量比較?或者說一階段後再對檢索出的向量計算精確的相似度有意義嗎?
意義不大。因為這時候就算再計算精確的向量相似度,也只是在經過轉換後的向量空間進行比較,因為這個空間比較“通用”,必定有所損失,無法在某種程度上準確表示所有的向量。
精排模型為什麼準呢?
如前面說的,Bi-Encoder必須將所有的文件都對映到一個向量中,這個過程會丟失資訊。而且,檢索時query和已有的向量是沒有互動的,是離線的狀態,只是透過額外的相似度計算方法得到比較相似的向量,對query來說,缺乏必要的上下文資訊。
而剛好精排模型是同時對兩個句子進行編碼的,這時候對query來說會含有上下文資訊,而且從原始空間對映到隱空間是一個句子對而不是單獨的句子,也更保證最終得到的相似度包含使用者查詢的文件資訊。但是相對的,精排模型的結構決定了它的計算是實時的,而且計算量會比單純的相似度計算大不少。
現有的精排模型
現有開源的Reranker模型已經非常多了,國內比較出門的有Jina-8k、bge-reranker以及bce-reranker等,且更新得非常快,目前看起來就是哪個最新用哪個,基本差異不大。值得一提的是Jina的模型是基於Alibi改進的注意力機制,所以能支援8K的上下文視窗,而bce本身只支援512k的上下文視窗,但是對較長的上下文進行切分,並且以其中一段最好的得分作為最終的相似度。bge模型沒看過原始碼,等以後有時間針對這幾個模型再研究一番。
總結
雖然目前二階段方法用來提升RAG的效能表現越來越受到關注,但是具體來看,其中所含的技術都是早就有的內容。Cross-Encoder這種架構在當時顯得比較雞肋,只能用來比較句子的相似度,甚至無法輸出向量,在大部分自然語言處理場景中都不受待見,誰能想到在如今又煥發生機了呢?