快轉到主要內容

取代關鍵字匹配 -- Sparse Vector 與 BM42

無論是傳統搜尋或 RAG, 上次說過用關鍵字匹配 (keyword matching) 有很多缺點:

  • 錯字:使用者查 strawbarry 找不到個體 strawberry
  • 同義詞:查口紅,找不到唇膏
  • 語意:查圓桌,但找到圓桌武士
  • 分詞:查香水,但找到 「香」氛「水」氧機

都是因為字串比對很死板,不了解使用者的「意圖」

然而,傳統把文字變成 embedding 的模型,大部分都是 “latent” vector:我們完全不知每個維度代表的意義。所以有些情況想要很注重在「關鍵字」的時候, 其結果又不盡人意,甚至連 debug 都不知從何下手

最近看到 Qdrant 提出兩個方法想改進傳統的 BM25 keyword matching:

  1. SPLADE: 用 Sparse Vector 而非 latent Vector (文章)
  2. BM42: 取代 BM25 (文章 – 感謝大數軟體的分享)

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 可以用自己的任務微調,說不定更符合自己的場景
  • 承上,說不定因此解決查詢「購買圓桌」匹配到「圓桌武士桌遊」文件的語意問題:期待模型能偵測出「圓桌武士桌遊」內的「圓桌」並不重要

若您覺得有趣, 請 追蹤我的Facebook 或  Linkedin, 讓你獲得更多資訊!