Bing搜尋核心技術BitFunnel原理

騰訊技術工程發表於2019-11-20

導語 從90年代中期開始,人們普遍認識,對於內容索引來說,檔案簽名技術比反向連結效果更差。最近幾年必應搜尋引擎開發與部署了一套基於位分割的標籤索引。這種索引(也稱BitFunnel)替代了之前的基於反向索引的生產系統。這項轉移背後驅動的因素是反向連結需要運轉儲存代價。本篇內容將講述這項演算法上的創新發明,改變傳統上在雲端計算框架上被認為無法使用的技術。BitFunnel演算法直接解決四項基礎位分割塊簽名的限制。同時,演算法的對映進入叢集提供了避免和其他簽名聯絡的代價。這裡會先展示這些創新產生了比傳統位分割簽名的更顯著的效率提升,然後將會進行BitFunnel與分塊化Elias-Fano索引,MG4J,和Lucene等的對比。本文根據論文《BitFunnel: Revisiting Signatures for Search》和Bing團隊實踐分享視訊,對BitFunnel原理進行分析解讀。

問題背景

假設我們一篇非常短的文件:內容僅僅“big brown dog”這三個單詞,我們可以用固定長度的位向量對這組單詞進行編碼,也稱固定長度的位向量為文件簽名或者布隆過濾器。簡單樣例這裡採取了十六位長度的位向量來進行操作,當然,在Bing系統上不會用這麼短的位向量,往往使用五千個以上的來進行表示。一開始,位向量全都是空的,因為還沒有進行資料的載入操作。

Bing搜尋核心技術BitFunnel原理

布隆過濾器初始化會設定哈稀函式的種數,哈稀函式是為了讓文件單詞對應到位向量的固定位置上。這裡我使用了三種不同的哈稀函式來對映。對映結果如下:

Bing搜尋核心技術BitFunnel原理

從上圖可知,每個單詞都對應著位向量上面的三個位置上置1,然後我們得到了這份簡易文件的文件簽名,假如我們要搜尋“cat”單詞在不在這份文件裡面,我們只需要查詢“cat”單詞經過哈稀函式對映出來的三個位置上是否都為1就可以進行判定了,很明顯,有一個不為1,所以“cat”單詞並不在這份文件裡面。

Bing搜尋核心技術BitFunnel原理

當我們搜尋"big“單詞時,我們會發現三個位置均置為1,那麼我們可以判定“big”是這份文件的可能成員。如下圖所示:

Bing搜尋核心技術BitFunnel原理

細心的你肯定注意到這裡用了可能兩個字,為什麼是可能成員呢?下圖是我們搜尋的是“house”單詞的結果:

Bing搜尋核心技術BitFunnel原理

我們會發現這個單詞的所有對映位置也都是1,但實際上我們知道文件裡並沒有“house”單詞,這個存在的原因是因為有哈稀函式對映碰撞的存在,導致其他的位置也有相對應的1在文件裡面補充了沒有為1的情況,這也是我們為什麼要用多種哈稀對映函式的原因,能夠降低這種錯誤率。

基於這樣的結構我們,假設我們儲存有十六篇文件:A-P,依次建立了簽名,那麼有搜尋需求:Query文件(包含多個單詞)進來,通過下列查詢就可以得到可能匹配文件:

Bing搜尋核心技術BitFunnel原理

這樣的思路無疑是非常直觀簡單且容易實現的,但是在網路中儲存的那些網頁,基本需要幾千位長度的位向量去表示,如果我們每一篇文件都這樣去查詢匹配,假設我們有N篇文章,用了P個位的文件簽名標記,我們的計算機CPU每次處理的位數為64位,那麼查詢一篇文章需要花費的代價就是 N*(P/64)單位時間。

這樣的代價無疑是非常高昂的,因為現在文章的數量和長度乘積無疑是一個天文數字。一個非常巧妙的辦法就是將這個矩陣反轉過來,行列倒置,那麼我們的儲存由N*P行列矩陣就變成了P*N,很顯然,P遠遠小於N。那麼,我們的查詢文件Query對應的只需要去匹配其中位為1的對應的文件的行向量即可,過程如下:
Bing搜尋核心技術BitFunnel原理

從上圖流程可以看出,對應的只需要查詢對應為1的位向量行數的文章的情況就可以了,假設真實中查詢的文件Query的為1位數是W位,在現實查詢中,W往往是少數幾個單詞去查詢,W遠遠小於P,對應列進行並運算,結果為1則該篇位置可能匹配,這樣查詢速度就大大提升。但是,還有一個問題就是現實中 N 的數量也非常龐大。

那麼這點如何處理呢?這就引進了今天要講的重點演算法:BitFunnel。

BitFunnel發明

等級行

等級行是原始行的簡單壓縮版本,能夠提高過濾速度,但同時也帶來了更高的錯誤率,讓我們看看等級行是怎麼執行的。我們將原始行稱為0-等級行,假設原始行是32位長度,那麼1-等級行就是由0-等級行對等截成兩半進行或運算獲得,那麼長度就降低了一半,更高等級行依此進行計算獲得,如下圖舉例所示:
Bing搜尋核心技術BitFunnel原理

那麼現在我們怎麼使用我們獲取的等級行呢?假設我們有3行32列需要匹配處理,那麼我們可以考慮將第一行壓縮成2-等級行,第二行壓縮成1-等級行,第三行保持不變。如果我們沒有這樣做,我們需要將3*32=96位全部放進記憶體進行查詢處理才可以完成。而現在,(8+16+32)=56位,詳細如下圖所示:
Bing搜尋核心技術BitFunnel原理
那麼查詢的時候,我們先將得出第一行和第二行的並運算結果,僅兩列需要去與第三行在進行處理,然後平移到第三行另一邊處理,再將第一行移動到第二行的另外一邊,這時候也是兩列均為1出現,然後與第三行處理,再轉移回去處理最後一次即可得出結果,四次處理計算流程如下:
Bing搜尋核心技術BitFunnel原理
Bing搜尋核心技術BitFunnel原理
Bing搜尋核心技術BitFunnel原理
Bing搜尋核心技術BitFunnel原理
以上這樣的處理我們可以大量地利用中間結果加快計算。
頻率布隆過濾器
傳統的布隆過濾器需要花費超長度的位向量才能做到滿足較低的錯誤率,而BitFunnel則使用頻率布隆過濾器來降低記憶體總量。什麼是頻率布隆過濾器?當我們在布隆過濾器中查詢僅僅查詢一個專案時,假設整個布隆過濾器為1的密度為10%,那麼當我們只使用一個哈稀函式(假設哈稀函式是完全隨機哈稀函式),那麼對應的碰撞率為10%,那麼隨著我們哈稀函式種類的增加,我們可以計算出錯誤率,d為布隆過濾器的概率密度,但這裡我們可以進一步提出新的概念訊雜比:

Bing搜尋核心技術BitFunnel原理

noise是我們經常用的錯誤概率(假陽率: Fasle Positive Rate, FPR),然而很少人去關注訊雜比概念。讓我們舉例一些實際查詢專案下的訊雜比值:
Bing搜尋核心技術BitFunnel原理

訊雜比給我們的啟示是:假設我們查詢的是"with"單詞,出現的頻次約為50%,如果只有一種哈稀函式,那麼它對應的訊雜比分數為(0.5/((1-0.5)*${0.1}^1$)約為10.2,那麼,當“info”單詞,頻率約為10%時,那麼錯誤率與頻率相等下,訊雜比下降,隨著頻率的下降,布隆過濾器密度會突出,提高了這些稀少單詞的錯誤率,因此就需要為這些稀少單詞增加更多的哈稀函式從而才能保持與高頻詞一致的訊雜比,舉例只是到了“sawmill”單詞,但現實網際網路情況下,更小頻率出現的單詞非常多,往往需要10個以上的哈稀函式才能保持可接受的錯誤率。

就像查詢DNA裡面的特定稀少片段,傳統的布隆過濾器做法是預設設定許多的哈稀函式和佔用大量位數空間才能保障準確率。因此BitFunnel使用 Frequency Conscious Bloom Filter , 不同頻次的單詞使用不同種數的哈稀函式搜尋匹配。

那麼等級行在這種應用下怎麼使用從而降低搜尋時間?BitFunnel結合了搜尋單詞的頻率和錯誤率的概念,提出了一種新的處理方案。

Bing搜尋核心技術BitFunnel原理

處理方案事實上就是用等級行數來關聯我們單詞:假設單詞"with"的反向文件頻率為0.29,那麼用單條長度的原始行表示即可,“info”的為1,則用單條原始行還有一條1-等級行表示,後面則越稀缺的單詞,其IDF越高,我們就用更多的行來表示其解決方案。你可能會問這些單詞專案處理方案後面是不是存在簡單的模式?然而我們也不知道具體答案,我們過去使用BF演算法來通過確定的訊雜比排序處理方案,同時也權衡查詢時間和記憶體總量。最終出現了十億中不同的解決方案,我們只評價了每種方案的IDF值,這一步花費了幾秒鐘,然後配置在系統中。

那麼,讓我們試試搜尋一下“treacherous movies”是怎麼進行查詢的:


Bing搜尋核心技術BitFunnel原理

取出這兩個單詞的配置解決方案,然後將這兩個解決方案組合起來獲得下圖(形狀如漏斗):

Bing搜尋核心技術BitFunnel原理

那麼我們就可以簡單直接地看出BitFunnel為什麼能夠這麼快了:

Bing搜尋核心技術BitFunnel原理
 
假設行的概率密度為0.1,那麼我們可以迅速前面四行就忽略了95%的列數。

叢集間分享
以上的兩種概念(等級行以及 Frequency Conscious Bloom Filter)讓我們節約了大量的記憶體空間以及提高了查詢效率。現實中我們的文字物料在現在網際網路上已經是一個龐大的天文數字,以前還可以在單機上處理,現在已經無法單機處理,我們需要將龐大的矩陣切割出來放到不同的叢集上處理,那麼我們怎麼做呢?

假設我們還是一共有十六篇文件和十六位的表示,那麼矩陣表示為16*16,同時我們反轉得到了十六位*十六篇,我們可以知道,短文章的文件裡面為1的個數還是相當少的,屬於稀疏矩陣,會浪費相當大的空間儲存,而長篇的文章裡面1的個數相當高,其對應的錯誤率也很高。在BitFunnel中,叢集間按不同文章的長度進行切割分享,下面例子切割成了三部分,實際上會按其他十到十五種不同組。
Bing搜尋核心技術BitFunnel原理
Bing搜尋核心技術BitFunnel原理
當按長度分好組後,我們就可以對稀疏部分進行壓縮儲存,密集的文章進行擴充位數儲存,降低錯誤率。
Bing搜尋核心技術BitFunnel原理
那麼隨之我們跟之前一樣就可以,當我們的查詢文件Query對應只有三位為1是,我們分別對這三組的對應行求與運算即可得出結果:

Bing搜尋核心技術BitFunnel原理
這樣的計算方式實際上在90年代的時候就提出來了,但是一直不被認可。為什麼?當時普遍都還是在單個計算機上進行各種演算法操作,那麼在一臺機器上又將資料如上圖一樣切割成三部分分別進行處理很明顯代價得不償失。原本只需要進行一遍操作的流程被複雜化了,而且事實上也不僅僅分割成三部分,往往是十幾類。而隨著時代的發展,我們現在擁有了分散式的叢集,我們可以將不同的機器處理不同文章長度種類的文件:
Bing搜尋核心技術BitFunnel原理

其次還有不同的是記憶體技術的發展,以前我們用每GB的花費金錢來衡量其中的成本是錯誤的方式:
Bing搜尋核心技術BitFunnel原理
傳統衡量方式上,硬碟獲得儲存1GB的空間只需要0.05美元,而DDR4需要7.44美元,導致了大量企業認為能夠增加儲存就不斷往硬碟上堆積,但這種方式很明顯是錯誤的。

假設公司有儲存資料總量為D,然後服務上需要查詢的文件總量設定為Q,如果我們使用快速的機器,Q個查詢很快就完成了(Q量可以通過廣播的方式放進記憶體去各個資料分塊中快速查詢然後累計返回):

Bing搜尋核心技術BitFunnel原理

如果我們用儲存大但是處理速度慢的機器,我們仍需要遍歷所有的資料才能獲得想要的資料總量:
Bing搜尋核心技術BitFunnel原理

如果我們採用BitFunnel的方式來處理,那麼,查詢量Q可以用(頻寬/總量)表示,引入這樣的概念就可以講之前硬碟和DDR4換一種計算方式,用每秒查詢頻寬量以及每美金每秒查詢頻寬量來表示之間能力差別,結果如下:

Bing搜尋核心技術BitFunnel原理

我們需要179倍的硬碟才能比得上DDR4,價格是DDR4的76倍代價。

處理錯誤率

最後我們來聊聊如何處理錯誤率,傳統上我們為了降低匹配錯誤率大幅度地提高了儲存代價。這樣做真的有意義麼?實際上我們網頁搜尋的目標並不是獲取與關鍵詞真的都完全匹配的網頁,而是獲取到內容最相符合的網頁。必應有一個Ranking Oracle系統,能夠計算一個查詢和文件之間的符合分數來衡量文件與使用者目標的價值。這個系統考慮了上千種訊號進行處理,甚至其中一些都不知道它是怎麼起作用的,因為這是基於機器學習在高維空間中學習所獲取的結果,同時也非常執行的代價也相當高。
Bing搜尋核心技術BitFunnel原理

假設我們有無限的查詢時間和查詢物料傳送給Ranking Oracle,讓它返回十項最相關的文件資料,這將怎麼處理?幸運的是,我們有很好的解決方案。Bellevue Washington有一個大廈裡面有上千名的工程師,他們的主要工作就是避免網路傳來相同的文件,主要策略的技術是通過過濾那些不能匹配布隆過濾器的檔案。
 
Bing搜尋核心技術BitFunnel原理
在BitFunnel發明之前,主要採用反向索引。採用了BitFunnel之後執行的速度更快, 但也同樣會生成錯誤樣本傳遞Ranking Oracle,BitFunnel之所以勝出在於能夠將錯誤樣本變少的同時保證時間效率。
Bing搜尋核心技術BitFunnel原理

對比
Bing搜尋核心技術BitFunnel原理
Bing搜尋核心技術BitFunnel原理

可以看出:BitFunnel的優勢在於速度和DQ低,但是有一定的錯誤率。

最後,是Bing使用BitFunnel後的效果圖:
Bing搜尋核心技術BitFunnel原理

希望各位技術牛人能夠從這Bing搜尋BitFunnel技術實現文章中收穫並運用到實際工作中。

參考附錄:

[1] BitFunnel: Revisiting Signatures for Search,Bob Goodwin,Michael Hopcroft,Dan Luu,SIGIR 2017 https://www.youtube.com/watch?v=1-Xoy5w5ydM

[2] An Experimental Study of Bitmap Compression vs. Inverted List Compression, Wang, Jianguo and Lin, Chunbin and Papakonstantinou, Yannis and Swanson, Steven, SIGMOD 2017

[3] Weighted bloom filter. Jehoshua Bruck, Jie Gao, and Anxiao Jiang. In 2006 IEEE International Symposium on Information theory. IEEE.

[4] BitFunnel官方部落格:http://bitfunnel.org/

相關文章