「勵(lì)銷云」平臺(tái)可以為企業(yè)提供覆蓋「獲客-篩客-管客-數(shù)字化倉(cāng)儲(chǔ)-客服運(yùn)營(yíng)」的一體化 SaaS 服務(wù)。 本文作者是上海微問(wèn)家信息技術(shù)有限公司大數(shù)據(jù)研究院的算法工程師楊沅霖、張文峰,他們的研究方向包括自然語(yǔ)言處理、計(jì)算機(jī)視覺(jué)等機(jī)器學(xué)習(xí)領(lǐng)域以及算法工程化。

讓我們一起來(lái)揭秘這套個(gè)性化推薦背后的技術(shù)原理吧!

技術(shù)背景

一般的推薦策略完全基于數(shù)據(jù)庫(kù)關(guān)鍵詞的檢索,檢索結(jié)果只能做到包含重要關(guān)鍵字,但是無(wú)法建立企業(yè)和企業(yè)之間的關(guān)聯(lián)。為了更好地理解文本語(yǔ)義,「勵(lì)銷云」需要使用一套算法模型,將描述性的信息轉(zhuǎn)化為語(yǔ)義向量,從而更好地利用語(yǔ)義信息并進(jìn)行推薦召回。

現(xiàn)在,我們已經(jīng)進(jìn)入萬(wàn)物皆可 Embedding 的時(shí)代,圖片、文本、視頻、語(yǔ)音等非結(jié)構(gòu)化數(shù)據(jù)可以通過(guò) Embedding 技術(shù)提取為特征向量,通過(guò)對(duì)特征向量的計(jì)算和相似度檢索可以實(shí)現(xiàn)智能問(wèn)答、智能推薦等場(chǎng)景。我們需要一個(gè)向量數(shù)據(jù)庫(kù)實(shí)現(xiàn)高性能的相似度檢索,實(shí)現(xiàn)對(duì)目標(biāo)企業(yè)召回對(duì)應(yīng)的相似企業(yè)。我們希望完成「數(shù)據(jù)庫(kù)+應(yīng)用」實(shí)現(xiàn)產(chǎn)品的落地,真正服務(wù)于客戶。

企業(yè)客戶智能推薦

技術(shù)思路

企業(yè)數(shù)據(jù)包括位置、類型、標(biāo)簽等基本信息,以及對(duì)應(yīng)的描述性信息。對(duì)于位置、類型等可以被結(jié)構(gòu)化的信息,「勵(lì)銷云」利用數(shù)據(jù)離散化、One-Hot 編碼等各種方式進(jìn)行處理;而對(duì)于文本等描述信息,則利用 Word2Vector、GloVe、Sentence-BERT 等進(jìn)行處理,實(shí)現(xiàn)描述信息轉(zhuǎn)為向量的過(guò)程。在這個(gè)過(guò)程中,我們先文本進(jìn)行分詞,再使用騰訊的預(yù)訓(xùn)練詞向量[1] 拼接,然后取平均,生成對(duì)應(yīng)的向量,再拼接之前結(jié)構(gòu)化數(shù)據(jù)的向量,生成最終的企業(yè)向量。在產(chǎn)生對(duì)應(yīng)的企業(yè)向量后,即可以使用相似搜索,找到目標(biāo)企業(yè)的相似企業(yè),實(shí)現(xiàn)召回的功能。

技術(shù)選型

Faiss[2] :向量化檢索開(kāi)山鼻祖的應(yīng)用,Faiss 庫(kù)是由 Facebook 開(kāi)發(fā)的適用于稠密向量匹配的開(kāi)源庫(kù)。

Vearch[3] :Vearch 是一個(gè)分布式向量搜索系統(tǒng),可用來(lái)存儲(chǔ)、計(jì)算海量的特征向量,基于 Facebook AI 研究院開(kāi)源的 Faiss 實(shí)現(xiàn)。

Milvus[4] :Milvus 向量數(shù)據(jù)庫(kù)提供完整的向量數(shù)據(jù)更新,索引與查詢框架。Milvus向量數(shù)據(jù)庫(kù)利用 GPU(Nvidia)進(jìn)行索引加速與查詢加速,能大幅提高單機(jī)性能。除了提供針對(duì)向量的近實(shí)時(shí)搜索能力外,Milvus向量數(shù)據(jù)庫(kù)可以對(duì)標(biāo)量數(shù)據(jù)進(jìn)行過(guò)濾。

Faiss 不能開(kāi)箱即用,在生產(chǎn)環(huán)境中使用涉及更多的開(kāi)發(fā)、維護(hù)成本;Milvus 向量數(shù)據(jù)庫(kù)和 Vearch 向量搜索系統(tǒng)是兩款開(kāi)箱即用的應(yīng)用。Milvus 數(shù)據(jù)庫(kù)在實(shí)現(xiàn)基本的相似計(jì)算功能的基礎(chǔ)上,加強(qiáng)服務(wù)整體易用性、穩(wěn)定性[5] ,部署更簡(jiǎn)單。經(jīng)過(guò)一系列測(cè)試和對(duì)比分析,最終我們選擇了 Milvus 作為我們的向量數(shù)據(jù)庫(kù)。

項(xiàng)目實(shí)現(xiàn)

1. 基于 Kubernetes 搭建分布式 Milvus[6]

首先,要為 Milvus 數(shù)據(jù)庫(kù)、MySQL 數(shù)據(jù)庫(kù)配置數(shù)據(jù)存儲(chǔ)(PersistentVolume)。為了方便快速地實(shí)現(xiàn)項(xiàng)目搭建,以 type 的類型為 local 作為示例:

然后,從 GitHub 倉(cāng)庫(kù)(https://github.com/milvus-io/milvus-helm.git)上拉取項(xiàng)目。

進(jìn)入 milvus-helm/charts/milvus 目錄,利用 Helm 安裝。在我們的項(xiàng)目中,我們將 readonly.replicas 設(shè)為 6,readonly.cache.cacheSize設(shè)為50G (緩存配置和 PV 配置無(wú)關(guān))。可根據(jù)機(jī)器配置和項(xiàng)目需求調(diào)大 cacheSize、readonly 等參數(shù),從而加速搜索。

接著,將服務(wù)對(duì)外暴露,可以在測(cè)試集群上簡(jiǎn)單使用如下命令完成簡(jiǎn)單的對(duì)外暴露。

2. 相關(guān)表的創(chuàng)建:

創(chuàng)建時(shí),可以參考官方文檔[7] 設(shè)置 INDEX_FILE_SIZE 大小以優(yōu)化搜索速度。可根據(jù)業(yè)務(wù)需求,在表內(nèi)實(shí)現(xiàn)各種分區(qū)。

3. 插入數(shù)據(jù):

在構(gòu)造數(shù)據(jù)時(shí),在此將企業(yè)的 ID 映射為 64 位的 int 作為向量的 ID,方便后續(xù)搜索時(shí)使用。

4. 創(chuàng)建索引:

我們選擇了 IndexType.IVF_SQ8 索引[8] ,因?yàn)樵撍饕阉魉俣瓤?占用內(nèi)存少。

5. 加載數(shù)據(jù):

調(diào)用 load_collection 的 API 將數(shù)據(jù)和索引加載到內(nèi)存中。

6. 基于 Flask 快速完成 RESTFUL 接口開(kāi)發(fā),配合 Gunicorn[9] 實(shí)現(xiàn)服務(wù)的并發(fā),完成服務(wù)上線。

項(xiàng)目效果

Milvus 數(shù)據(jù)庫(kù)中有多個(gè)集合,最大的集合下有 3000w+ 企業(yè)向量,在 topK=512、nprobe=256 的情況下,最大集合單向量搜索耗時(shí)為 100ms 左右。隨著搜索的向量越多,耗時(shí)呈線性增長(zhǎng)。但在 topK 為 100W 的極端情況下,Milvus 數(shù)據(jù)庫(kù)依然在秒級(jí)內(nèi)完成了相似企業(yè)的搜索。

在項(xiàng)目初期,我們也重試過(guò)直接在 Faiss 上進(jìn)行二次開(kāi)發(fā),但是由于數(shù)據(jù)量的逐漸增加與所需功能的增加,開(kāi)發(fā)所需時(shí)間和質(zhì)量無(wú)法得到保證。在轉(zhuǎn)向使用 Milvus 數(shù)據(jù)庫(kù)后,我們?cè)谝粋€(gè)月內(nèi)完成了初期相關(guān)理論驗(yàn)證與開(kāi)發(fā)上線工作,測(cè)試情況良好。并且在這過(guò)程中,當(dāng)我們遇到問(wèn)題,社區(qū)和官方的技術(shù)支持會(huì)在 24 小時(shí)內(nèi)協(xié)助解決,非常感謝!