千萬量級圖片視頻快速檢索,輕鬆配置設計師的靈感挖掘神器

作者介紹:

James Zhang,飛書深諾集團的算法工程師 ,畢業於芬蘭坦佩雷大學,感興趣的方向包括自然語言處理、計算機視覺等機器學習相關領域以及算法工程化。

飛書深諾集團是專注海外數字營銷解決方案的綜合服務集團,爲中國出海企業提供可定製組合的全鏈路服務產品,滿足遊戲、APP、電商、品牌等典型出海場景需求。

Milvus 在電商場景中的千萬量級素材搜索實踐

項目背景

在服務電商客戶的場景下,創意部門常常要爲客戶製作素材,如:廣告圖、宣傳視頻、宣傳文案等。創意部門往往通過以圖搜圖、以視頻搜視頻、文本搜文本的方式發掘素材,爲設計師們提供創意上的參考。同時,熱度、效果值等其他條件也可以用來輔助搜索,幫助創意部門充分選擇合適的素材。此項目的動機正是利用 Milvus 向量數據庫在內的一系列技術,爲創意部門提供一個素材的綜合搜索系統。

技術選型

由於業務接口需要實時返回,並承受一定程度的併發負載,因此我們認爲 Milvus 是比較合適的向量檢索工具。它對 FAISS、ANN 等工具進行了封裝,建立自己的存儲文件結構,同時提供了方便的服務化接口,可以算得上“開箱即用”了。在保持檢索速度快的同時,Milvus 可以通過參數設置,對向量檢索的準確性、資源佔用做一定的 Trade-off,比較適合在實際工程中使用。

我們在返回相似向量的同時,還需要圖片/視頻的一些對應信息,我們通過 KV(Key-Value)的形式將這些信息放在 Redis 緩存裏,加快獲取的速度。在 Web 接口封裝方面,考慮到團隊內大部分爲 Python 程序員,因此我們選用了 Nginx + Flask + Gunicorn + supervisor 的 Web 經典套餐。

使用到的各工具和框架

  • Milvus(圖片/視頻/文本的向量相似檢索)
  • Redis(業務緩存)
  • Nginx(負載均衡)
  • Flask + Gunicorn (Web 框架 + 併發服務)
  • Supervisor(服務的進程啓動與異常自動重啓)
  • Docker(容器隔離部署)

項目實現

在我們的項目中,圖片使用 EfficientNet 來提取特徵向量;視頻通過提取關鍵幀之後,再將每一幀圖片進行向量提取之後疊加;文本採用 BERT 做特徵提取。

架構示意如下圖所示:

選擇合適的索引:

在得到圖片/視頻/文本向量檢索結果後,上層調用還要做一些業務操作,留給向量檢索的接口的時間就不能太多,系統需要做到 1s 內返回。由於向量檢索對速度的要求比較高,同時服務部署的機器內存又有一定的限制,我們選用了 IVF_PQ 作爲向量索引。

IVF_PQ 是一種有損壓縮的向量索引,它將所有向量分解成 m 段,每一小段分別進行聚類,每小段由所屬的聚類中心來表示,稱爲索引值,用 Codebook (碼錶)來表示 。舉例說明這種壓縮方式:一個 D=128 維的原始向量被切分成了 M=8 個 D=16 維的短向量,同時每個 16 維短向量都對應一個量化的索引值,索引值即該短向量距離最近的聚類中心的編號,每一個原始向量就可以壓縮成 8 個索引值構成的壓縮向量,即每個向量都用這 8 個索引值來表示,相對於原始值有一定的誤差。

在實際使用的時候,IVF_PQ 這種索引方法預先計算好的各個聚類中心間的距離,通過查找表得出兩個向量索引值的距離,來近似替代兩個向量的真實距離,這種方法加快了計算速度;在使用中可以通過參數 m 的設置,使得向量壓縮成很小的比例,也大量減少了內存佔用(約爲向量原始空間大小的 5%~10%)。下圖爲 IVF_PQ 索引壓縮示例:

根據 Milvus 官方提供的公式:

單個數據段計算量可估算爲:目標向量數量 × (nlist+ (段內向量數 ÷nlist)× nprobe)

數據段的數量可估算爲:集合數據總量 ÷ index_file_size

對集合查詢所需的計算總量則爲:單個數據段計算量 × 數據段數量

我們計算得出合適的索引參數是 nlist=1024,m=8。

使用分區提高速度:

目前素材中,圖片總量接近 4kw,視頻總量大約 1kw,文本總量大約 3kw,爲了提高檢索速度,分區變得十分必要。我們通過一些業務屬性,根據屬性值做笛卡爾積操作來建立分區:

例如,我們向量對應的 Item 有兩個屬性:

  • 對於屬性 A,取值 1,2,3,4

  • 對於屬性 B,取值 1,2,3

建立分區 A1_B1,A1_B2,A1_B3,A2_B1,A2_B2,A2_B3,...... ,A4_B3,一共 12 個。通過分區操作,我們將每個分區的向量規模控制在 500w 以下,進一步提高了檢索速度。

需要注意的是,用來建立分區的屬性應該是不會變動的基本屬性。因爲如果發生變動,重新建立分區、導入數據和建立索引將是非常漫長的過程,所以分區確定之後不要輕易改變。另外,分區及屬性值不能太多,否則各個屬性值相乘(笛卡兒積)會讓數量變得非常龐大,使程序變得過於複雜。如果要實現更多的素材屬性檢索或篩選,我們在 Milvus 向量搜索的結果上另外封裝一層業務接口來實現。

系統效果

向量檢索服務以 REST 接口的形式對外提供,前端團隊調用接口,將結果展示在界面上。(請自行腦補一下谷歌的以圖搜圖,百度的以影搜影等等……)

性能指標 目前我們的圖片總量大約在 3kw+,視頻總量大約在 1kw,向量維數爲 2048 維,文本總量爲 3kw 左右,向量維數爲 768 維。圖片檢索耗時 0.2s 左右;視頻檢索耗時 0.1s 左右;文本向量檢索耗時 <0.1s。

關於 Milvus 的一些經驗與總結 Milvus 集成各種常見向量索引,能滿足工程中大部分的需求,存儲操作和檢索速度都達到了工業級的水準,提供服務化的接口,基本上做到了開箱即用。不過 Milvus 目前還不支持其他類型(字符型、整型)的屬性檢索,官方表示新版本目前正在研發當中,期待早日上線。

總體來說,對於需要快速構建向量檢索服務、又不想花太大成本構造的輕量級項目來說,Milvus 是一個很好的選擇。

參考文獻

[1] Product quantization for nearest neighbor search. Hervé Jégou, Matthijs Douze, Cordelia Schmid

[2] https://Milvus.io/cn/docs/v1.1.1/tuning.md

Arch Meetup 深圳站開始報名啦,點擊查看活動議程!

GitHub @Milvus-io|CSDN @Zilliz Planet|Bilibili @Zilliz-Planet

Zilliz 以重新定義數據科學爲願景,致力於打造一家全球領先的開源技術創新公司,並通過開源和雲原生解決方案爲企業解鎖非結構化數據的隱藏價值。

Zilliz 構建了 Milvus 向量數據庫,以加快下一代數據平臺的發展。Milvus 數據庫是 LF AI & Data 基金會的畢業項目,能夠管理大量非結構化數據集,在新藥發現、推薦系統、聊天機器人等方面具有廣泛的應用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章