大家好,我叫李茶,來自虎牙直播的推薦工程組,主要負(fù)責(zé)虎牙直播的推薦架構(gòu)工作。
直播推薦是一個頭部主播比較集中的場景,比較注重關(guān)系鏈、詞語以及長期的價值,業(yè)務(wù)訴求可能和其他推薦場景有所不同,這一點(diǎn)在工程架構(gòu)上也會有所體現(xiàn)。本文將和大家分享下虎牙直播的推薦架構(gòu),包括以下幾方面內(nèi)容:
- 業(yè)務(wù)背景
- 業(yè)務(wù)架構(gòu)
- 向量檢索
- 精排
- 總結(jié)和展望
01
業(yè)務(wù)背景
首先和大家分享下虎牙直播的業(yè)務(wù)背景?;⒀乐辈サ耐扑]場景主要有以下三個:首頁的直播推薦、廣場的視頻推薦以及直播間的廣告推薦,當(dāng)然還有很多小的場景,在這里就不展開講了。
直播是一個頭部主播比較集中的場景,比較注重關(guān)系鏈、詞語以及長期的價值,業(yè)務(wù)訴求和其他推薦場景有所不同,在工程架構(gòu)上會有所體現(xiàn)。但整體推薦模塊和流程與業(yè)界主流推薦架構(gòu)基本一致。
02
業(yè)務(wù)架構(gòu)
接下來和大家介紹下虎牙直播的業(yè)務(wù)架構(gòu)。
虎牙直播推薦架構(gòu)中涉及的模塊和流程與業(yè)界主流通用的一些推薦架構(gòu)基本一致,部分模塊會有一些定制化的設(shè)計。接入層用來做透傳的工作,提供融合、降級、去重的功能;畫像層提供用戶和主播長期、短期以及實(shí)時特征的能力,還有一些召回、排序、重排模塊以及一些周邊的平臺支持。
現(xiàn)在舉例說明下虎牙直播的推薦業(yè)務(wù)特點(diǎn)以及和通常的圖文、視頻推薦業(yè)務(wù)的區(qū)別。拿接入層的去重來說,一般的圖文、視頻推薦業(yè)務(wù)有比較強(qiáng)的去重需求,比如用戶看過了某篇文章、某個視頻,大概率是不希望看到相同或者相似的內(nèi)容。業(yè)界常用的做法是用一個布隆過濾器來做長期的去重。在虎牙直播推薦場景,主播的標(biāo)簽或信息會有比較大的不確定性,很多都是在開播的時候才能確定。例如打游戲的主播可能下一時刻會做才藝類型的直播。所以在這個場景下的去重對時效性的要求比較高,同時需要不斷的優(yōu)化調(diào)整。
在后面的分享中,我將會從向量檢索和精排兩個方向詳細(xì)介紹下虎牙直播的推薦架構(gòu)。這兩塊涉及到了推薦系統(tǒng)中的大部分技術(shù)點(diǎn),并且它們之間聯(lián)系得也比較緊密。
03
向量檢索
- 背景
2016年,谷歌分享了youtube視頻推薦和搜索的向量檢索架構(gòu),同時該架構(gòu)的落地取得了比較不錯的收益,目前很多推薦系統(tǒng)也都在嘗試通過優(yōu)化embedding來提升業(yè)務(wù)指標(biāo),實(shí)際效果也非??捎^。
虎牙直播早期由于主播數(shù)量較少,主要是通過暴力檢索。隨著業(yè)務(wù)的發(fā)展,基于成本和性能的考慮,暴力檢索已經(jīng)沒有辦法滿足業(yè)務(wù)需求,于去年年初開始投入人力進(jìn)行向量檢索方向的調(diào)研和落地。
我們調(diào)研了Facebook開源的向量檢索框架Faiss和谷歌開源的向量檢索框架ScaNN,ScaNN在算法上做了一些優(yōu)化。
如上面兩圖所示,經(jīng)過數(shù)據(jù)的驗(yàn)證以及ann-benchmarks的壓測,ScaNN在性能和準(zhǔn)召率都是表現(xiàn)較好的。由于ScaNN是相對較新的檢索庫,也很難找到其他企業(yè)開源的成功應(yīng)用案例,但是經(jīng)過部門同學(xué)的二次開發(fā)和封裝,使ScaNN能夠相對較好地集成到現(xiàn)有架構(gòu)中去,方便使用。
- 技術(shù)挑戰(zhàn)
向量檢索的技術(shù)挑戰(zhàn)主要有以下三點(diǎn):
生產(chǎn)環(huán)境需要一個高吞吐、低延時、高可用的系統(tǒng);
結(jié)合向量檢索的業(yè)務(wù)訴求,數(shù)據(jù)需要快速更新,系統(tǒng)需要具備一定的容錯能力;
需要提升數(shù)據(jù)構(gòu)建的效率,保證線上服務(wù)的質(zhì)量。
- 架構(gòu)落地
基于前面提到的挑戰(zhàn),我們設(shè)計了如下的讀寫分離、文件化的架構(gòu):
索引builder構(gòu)建:文件化;易調(diào)試、準(zhǔn)召保證。索引builder構(gòu)建主要負(fù)責(zé)向量的生產(chǎn)和索引文件的構(gòu)建。使用npy二進(jìn)制的文件格式,減少文件體積并易于調(diào)試。索引builder使用SDK與模型和特征進(jìn)行交互,同時在調(diào)試時也可以使用,有比較好的可復(fù)用性。
分發(fā)系統(tǒng)使用了阿里開源的Dragonfly,支持P2P的分發(fā),打通了公司的文件系統(tǒng)。
在線Server部分在架構(gòu)上拆解為檢索引擎和算子模塊,使用SDK接入。
檢索引擎:防抖動;多文件;多版本。檢索引擎目前支持ANN檢索和暴力檢索,采用通用的API執(zhí)行流程,包含加載、卸載、雙buffer切換等環(huán)節(jié)。開啟實(shí)驗(yàn)時,實(shí)驗(yàn)組和新增的引擎做好關(guān)聯(lián)即可,
算子模塊組:易擴(kuò)展;靈活。算子模塊組是按照通用的算子執(zhí)行邏輯設(shè)計的,使用的是標(biāo)準(zhǔn)的輸入輸出,比較方便擴(kuò)展和復(fù)用。
上線流程通過管理平臺來配置,提升了系統(tǒng)的迭代效率。
下面介紹下向量在線檢索的過程,業(yè)務(wù)方集成的SDK通過用戶的id信息進(jìn)行畫像的查詢,同時進(jìn)行一些特征處理,然后請求模型生成向量,最后通過向量來進(jìn)行檢索,根據(jù)請求的數(shù)量返回topk。SDK支持跳過以上的任意步驟,比如直接通過向量來進(jìn)行檢索。滿足算法同學(xué)的調(diào)試需求和線上的實(shí)際使用需求。
在線檢索的時候,通過索引文件雙buffer的無鎖加載,支持批量查詢,保證了系統(tǒng)的高吞吐;通過純內(nèi)存計算、LRU cache以及指令集優(yōu)化保證了系統(tǒng)的低延時;通過builder和server的分離、存算一體(啟動速度加快)以及服務(wù)無狀態(tài)(方便快速擴(kuò)容)保證了系統(tǒng)的高可用。同時,在服務(wù)啟動的時候也加了一些保護(hù),比如:只有在數(shù)據(jù)加載完成后,才能注冊到名字服務(wù)中,提供對外服務(wù)的能力。
向量檢索系統(tǒng)的數(shù)據(jù)加載是非常快的,下面介紹下數(shù)據(jù)更新的相關(guān)邏輯。首先,在配置中指定數(shù)據(jù)源和模型名稱,builder進(jìn)行定時調(diào)度獲取任務(wù)信息,關(guān)聯(lián)公司其他平臺的任務(wù)產(chǎn)出,利用SDK來生成向量、構(gòu)建索引文件,并把文件推送到P2P的源數(shù)據(jù)節(jié)點(diǎn)。P2P的管理節(jié)點(diǎn)會定時檢測源數(shù)據(jù)目錄的文件產(chǎn)出。在線的server會啟動dfagent進(jìn)程,定時和P2P集群的管理節(jié)點(diǎn)同步心跳,獲取管理節(jié)點(diǎn)上需要同步的資源列表。管理節(jié)點(diǎn)將需要同步的節(jié)點(diǎn)組成p2p集群,進(jìn)行P2P的分發(fā)。200w數(shù)據(jù)集能在5s內(nèi)完成內(nèi)存化,在10s內(nèi)完成分發(fā)。另外文件是以時間戳為版本,在線支持多版本,加載前會校驗(yàn),和攔截告警,整體流程1分鐘內(nèi)生效。
在離線構(gòu)建部分也做了一些優(yōu)化以實(shí)現(xiàn)效能提升和安全保障。為了保證性能和準(zhǔn)召率,我們開發(fā)了一些半自動的尋參工具,通過設(shè)置少量的參數(shù)和一些我們預(yù)設(shè)的經(jīng)驗(yàn)參數(shù),進(jìn)行自動化的評估,對比結(jié)果輸出最優(yōu)的參數(shù)來提供線上使用。不過目前這個工具是一個單獨(dú)的離線工具,后續(xù)的話會集成到平臺。builder節(jié)點(diǎn)支持橫向擴(kuò)展,通過分布式鎖來進(jìn)行任務(wù)的搶占和執(zhí)行。單個builder節(jié)點(diǎn)支持多進(jìn)程的并行構(gòu)建,提升構(gòu)建速度。針對每個構(gòu)建任務(wù)的都支持一些定制化的一些指標(biāo)校驗(yàn),校驗(yàn)的指標(biāo)主要是耗時、準(zhǔn)召率、召回成功率等。目前,索引數(shù)據(jù)檢索Top20準(zhǔn)召0.99的覆蓋率達(dá)到90%,攔截異常數(shù)據(jù)次數(shù)達(dá)15次以上,3個builder節(jié)點(diǎn)支持50個以上的任務(wù),能在分鐘級完成構(gòu)建。
最后介紹下系統(tǒng)的擴(kuò)展性,目前我們在服務(wù)、數(shù)據(jù)、引擎三個方向都做到了不錯的擴(kuò)展性。在服務(wù)層面,服務(wù)無狀態(tài)、離線builder通過分布式鎖來搶占保證了擴(kuò)展性。在數(shù)據(jù)層面,在線server通過配置來加載不同的數(shù)據(jù)分片,離線builder也可以通過一些調(diào)整來保證擴(kuò)展性。在引擎層面,主要同過以下三點(diǎn)來保證擴(kuò)展性:
標(biāo)準(zhǔn)數(shù)據(jù)讀接口API,算子邏輯支持自定義;
存算一體,對數(shù)據(jù)管理的通用抽象;
多元異構(gòu)數(shù)據(jù)的文件分發(fā)。
04
精排
- 數(shù)據(jù)流
數(shù)據(jù)流主要包含離線訓(xùn)練、在線打分、特征處理三個部分。特征處理主要通過離線和實(shí)時任務(wù)挖掘用戶或主播長期、短期的興趣以及實(shí)時的反饋特征,數(shù)據(jù)的來源和更新頻率差異很大。用戶畫像服務(wù)主要對接用戶的存儲和公司內(nèi)外部的第三方接口,出于性能的考慮,用戶畫像設(shè)置了LRU緩存以及必要的降級策略,同時為了進(jìn)一步提升本地緩存命中率,在上游調(diào)用的時候使用了一致性hash校驗(yàn)。針對主播畫像,因?yàn)橐淮握倩貢泻芏嗟闹鞑?,讀放大很嚴(yán)重,也采用了業(yè)界通用的本地化緩存方案,早期主播的數(shù)量較少,采用的直接異步同步存儲信息到本地構(gòu)建雙buffer,數(shù)據(jù)完整性很難保證,正在往向量檢索架構(gòu)上進(jìn)行遷移。
- 特征
為了能夠同時支持分析和訓(xùn)練,我們也設(shè)計了明文特征向tfrecord轉(zhuǎn)換的過程和格式,使用ProtocolBuffers協(xié)議進(jìn)行schema的校驗(yàn)和管理。離線特征處理通過JNI調(diào)用extractor來實(shí)現(xiàn)和在線特征處理邏輯的一致性。
- 推理
最后分享下在推理服務(wù)上的優(yōu)化,主要做了以下幾個事情:
適配公司的生態(tài)繼承。推理服務(wù)默認(rèn)是gRPC協(xié)議,我們做了編譯的集成,以動態(tài)庫的形式集成到服務(wù)里面,使推理服務(wù)能夠更加適配公司的生態(tài)。
采用了社區(qū)通用的優(yōu)化方案,對模型進(jìn)行預(yù)熱和并對模型服務(wù)提供獨(dú)立的線程池。
分發(fā)優(yōu)化:高峰期通過帶寬限制,控制模型的下載帶寬。
輸入優(yōu)化:一般的精排做法會帶來很多user側(cè)的特征復(fù)制,在數(shù)據(jù)傳輸上會有比較大的壓力,我們將用戶特征拷貝遷移至推理服務(wù),減小了帶寬,取得了不錯的收益。
最終,經(jīng)過我們對精排服務(wù)的優(yōu)化,服務(wù)的穩(wěn)定性能夠達(dá)到4個9,數(shù)據(jù)傳輸帶寬節(jié)省了50%以上。
05
總結(jié)和展望
最后,分享一下我們的未來展望。我們的架構(gòu)還有很多需要優(yōu)化的地方,我們會緊跟業(yè)務(wù)的前沿,不斷優(yōu)化架構(gòu),持續(xù)完善我們的平臺,提升系統(tǒng)的迭代效率。
今天的分享就到這里,謝謝大家。
本文經(jīng)授權(quán)發(fā)布,不代表增長黑客立場,如若轉(zhuǎn)載,請注明出處:http://m.gptmaths.com/cgo/product/59384.html