取代關鍵字匹配 -- Sparse Vector 與 BM42
目錄
無論是傳統搜尋或 RAG, 上次說過用關鍵字匹配 (keyword matching) 有很多缺點:
- 錯字:使用者查 strawbarry 找不到個體 strawberry
- 同義詞:查口紅,找不到唇膏
- 語意:查圓桌,但找到圓桌武士
- 分詞:查香水,但找到 「香」氛「水」氧機
都是因為字串比對很死板,不了解使用者的「意圖」
然而,傳統把文字變成 embedding 的模型,大部分都是 “latent” vector:我們完全不知每個維度代表的意義。所以有些情況想要很注重在「關鍵字」的時候, 其結果又不盡人意,甚至連 debug 都不知從何下手
最近看到 Qdrant 提出兩個方法想改進傳統的 BM25 keyword matching:
SPLADE #
SPLADE 是 Naver 提出的:訓練一個 BERT model,讓文字輸入進去(無論是文件或 query),出來一個向量,其維度是每個 vocabulary (也就是每個合法的 token)。
訓練的方式是對於 query,給定 positive 文件、negative 文件、與 in-batch negative 文件們(例如不同 query 的 positive 文件),藉由他們的 similarity 構造出 loss
這個向量會是稀疏的 (sparse) – 能夠這樣是因為
- 用 log(1 + RelU) 生出 weight – 這我不是很懂,我「猜測」是因為正數端的平緩成長跟進零端的變 0 呈現兩種極端,讓一些 weight 會先變 0 (不會訓練不起來嗎)
- 加了 regularization loss (FLOPs regularizer)
SPLADE 的優勢就變成了
- 可解釋性:因為維度代表著 token
- 擴充性:有可能 query 內沒提到的字,但是變成向量後在其他 token 的維度變成非零了
BM42 #
BM42 則是 Qdrant 提出,單純是取代 BM25 ,所以仍有 keyword matching 所有的缺點
儘管如此,概念還滿有趣的:用 attention 取代 BM25 的 TF 項
BM25 是 query 內每個字的 TF 項乘上 IDF 項(兩項都是變種公式), 其中 TF 項會考慮文件長度:文件越長值越低,可以想成關鍵字佔文件的資訊密度,太花心的就不要
然而如果場景是限於 RAG:文件多半會切 chunk – 且通常長度都一樣,所以只剩真實的 term frequency 有影響
(這邊 Qdrant 宣稱 term frequency 不是 1 就是 0 ,但我不這麼認為,尤其通常也不會做 unique )
然而 term_frequency (關鍵字, 文件)
能否代表這文件真的很注重這關鍵字(就算在 IDF 修正之下)?也不見得
於是他們想到可以用 Transformer 模型最後一層的 [CLS]
那個位置的 attention weight – 從 input 的每個 token 來的,來代表該 token 在這串文字的重要程度
不過 query 每個字可能會有多個 token 組起來,就單純把 attention weight 加起來就好。這就真的可以取代掉 BM25 裡的 TF 項,亦即可解釋性
注意到,上面的方法完全沒提到把 query / 關鍵字換掉:也就是 keyword matching 的缺點幾乎沒解決(除了語意),只是從關鍵字數數變成有考慮 context 的權重
然而,這方法可能還是有得玩
- Transformer model 可以用自己的任務微調,說不定更符合自己的場景
- 承上,說不定因此解決查詢「購買圓桌」匹配到「圓桌武士桌遊」文件的語意問題:期待模型能偵測出「圓桌武士桌遊」內的「圓桌」並不重要