中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

舍棄Python,為什么知乎選用Go重構(gòu)推薦系統(tǒng)?

2018-12-31    來(lái)源:raincent

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

 

作者:孫付偉

知乎從問答起步,已逐步成長(zhǎng)為一個(gè)大規(guī)模的綜合性知識(shí)內(nèi)容平臺(tái),截止目前,用戶數(shù)突破 2.2 億,有超過 3000 萬(wàn)的問題被提出,并獲得超過 1.3 億個(gè)回答。同時(shí),知乎內(nèi)還沉淀了數(shù)量眾多的優(yōu)質(zhì)文章、電子書以及其它付費(fèi)內(nèi)容。

因此,在鏈接人與知識(shí)的路徑中,知乎存在著大量的推薦場(chǎng)景。粗略統(tǒng)計(jì),目前除了首頁(yè)推薦之外,我們已存在著 20 多種推薦場(chǎng)景;并且在業(yè)務(wù)快速發(fā)展中,不斷有新的推薦業(yè)務(wù)需求加入。在這個(gè)背景之下,構(gòu)建一個(gè)較通用的且便于業(yè)務(wù)接入的推薦系統(tǒng)就變成不得不做的事了。

重構(gòu)推薦系統(tǒng)需要考慮哪些因素?如何做技術(shù)選型?重構(gòu)的過程中會(huì)遇到哪些坑?希望知乎的踩坑經(jīng)驗(yàn)?zāi)芙o你帶來(lái)一些思考。

背景

 

 

在講通用架構(gòu)的設(shè)計(jì)之前,我們一起回顧一下推薦系統(tǒng)的總體流程和架構(gòu)。通常,因?yàn)槟P退杼卣骷芭判虻男阅芸紤],我們通常將簡(jiǎn)單的推薦系統(tǒng)分為召回層和 ranking 層,召回層主要負(fù)責(zé)從候選集合中粗排選擇待排序集合,之后獲取 ranking 特征,經(jīng)過排序模型,挑選出推薦結(jié)果給用戶。

 

 

簡(jiǎn)單推薦模型適合一些推薦結(jié)果要求單一,只對(duì)單目標(biāo)負(fù)責(zé)的推薦場(chǎng)景,比如新聞詳情頁(yè)推薦、文章推薦等等。但在現(xiàn)實(shí)中,作為通用的推薦系統(tǒng)來(lái)說,其需要考慮用戶的多維度需求,比如用戶的多樣性需求、時(shí)效性需求、結(jié)果的滿足性需求等。因此就需要在推薦過程中采用多個(gè)不同隊(duì)列,針對(duì)不同需求進(jìn)行排序,之后通過多隊(duì)列融合策略,從而滿足用戶不同的需求。

 

 

從我們知乎來(lái)說,也大體是這樣一個(gè)發(fā)展路線,比如今年的 7 月份時(shí),因?yàn)橐恍I(yè)務(wù)快速發(fā)展且架構(gòu)上相對(duì)獨(dú)立的歷史原因,我們的推薦系統(tǒng)存在多套,并且架構(gòu)相對(duì)簡(jiǎn)單。以其中一個(gè)推薦架構(gòu)設(shè)計(jì)相對(duì)完善的系統(tǒng)為例,其總體架構(gòu)是這樣的?梢钥闯,這個(gè)架構(gòu)已經(jīng)包含了召回層和 ranking 層,并且還考慮了二次排序。

 

 

那么存在哪些問題呢?

首先,對(duì)多路召回支持不友好,F(xiàn)有架構(gòu)的召回是耦合在一起的,因此開發(fā)調(diào)研成本高,多路召回接入相對(duì)困難。

然后,召回階段只使用 redis 作為召回基礎(chǔ)。redis 有很多優(yōu)點(diǎn),比如查詢效率高,服務(wù)較穩(wěn)定。但將其作為所有召回層的基礎(chǔ),就放大了其缺點(diǎn),第一不支持稍復(fù)雜的召回邏輯,第二無(wú)法進(jìn)行大量結(jié)果的召回計(jì)算,第三不支持 embedding 的召回。

第三點(diǎn),總體架構(gòu)在實(shí)現(xiàn)時(shí),架構(gòu)邏輯剝離不夠干凈,使得架構(gòu)抽樣邏輯較弱,各種通用特征和通用監(jiān)控建設(shè)都較困難。

第四點(diǎn),我們知道,在推薦系統(tǒng)中,特征日志的建設(shè)是非常重要的一個(gè)環(huán)節(jié),它是推薦效果好壞的重要基礎(chǔ)之一。但現(xiàn)有推薦系統(tǒng)框架中,特征日志建設(shè)缺乏統(tǒng)一的校驗(yàn)和落地方案,各業(yè)務(wù)『各顯神通』。

第五點(diǎn),當(dāng)前系統(tǒng)是不支持多隊(duì)列融合的,這就嚴(yán)重限制了通用架構(gòu)的可擴(kuò)展性和易用性。

因此,我們就準(zhǔn)備重構(gòu)知乎的通用推薦服務(wù)框架。

重構(gòu)之路

在重構(gòu)前的考慮

第一,語(yǔ)言的選擇。早期知乎大量的服務(wù)都是基于 Python 開發(fā)的,但在實(shí)踐過程中發(fā)現(xiàn) Python 資源消耗過大、不利用多人協(xié)同開發(fā)等各種問題,之后公司進(jìn)行了大規(guī)模的重構(gòu),現(xiàn)在知乎在語(yǔ)言層面的技術(shù)選型上比較開放,目前公司內(nèi)部已有 Python、Scala、Java、Golang 等多種開發(fā)語(yǔ)言項(xiàng)目。那么對(duì)于推薦系統(tǒng)服務(wù)來(lái)說,由于其重計(jì)算,多并發(fā)的特點(diǎn),語(yǔ)言的選擇還是需要考慮的。

第二,架構(gòu)上的考慮,要解決支持多隊(duì)列混排和支持多路召回的問題,并且其設(shè)計(jì)最好是支持可插拔的。

第三,召回層上,除了傳統(tǒng)的 redis 的 kv 召回(部分 cf 召回,熱門召回等等應(yīng)用場(chǎng)景),我們還需要考慮一些其他索引數(shù)據(jù)庫(kù),以便支持更多索引類型。

首先我們先看語(yǔ)言上的選擇,先總體上比較一下各種語(yǔ)言的特點(diǎn),我們簡(jiǎn)單從如下幾個(gè)方面進(jìn)行比較。

從性能上,依照公開的 benchmark,Golang 和 Java、Scala 大概在一個(gè)量級(jí),是 Python 的 30 倍左右。其次 Golang 的編譯速度較快,這點(diǎn)相對(duì)于 Java、Scala 具有比較明顯的優(yōu)勢(shì),再次其語(yǔ)言特性決定了 Golang 的開發(fā)效率較高,此外因?yàn)槿狈?trycatch 機(jī)制,使得使用 Golang 開發(fā)時(shí)對(duì)異常處理思考較多,因此其上線之后維護(hù)成本相對(duì)較低。但 Golang 有個(gè)明顯缺陷就是目前第三方庫(kù)較少,特別跟 AI 相關(guān)的庫(kù)。

 

 

那么基于以上優(yōu)缺點(diǎn),我們重構(gòu)為什么選擇 Golang?

1、Golang 天然的優(yōu)勢(shì),支持高并發(fā)并且占用資源相對(duì)較少。這個(gè)優(yōu)勢(shì)恰恰是推薦系統(tǒng)所需要的,推薦系統(tǒng)存在大量需要高并發(fā)的場(chǎng)景,比如多路召回,特征計(jì)算等等。

2、知乎內(nèi)部基礎(chǔ)組件的 Golang 版生態(tài)比較完善。目前我們知乎內(nèi)部對(duì)于 Golang 的使用越來(lái)越積極,大量基礎(chǔ)組件都已經(jīng) Golang 化,包括基礎(chǔ)監(jiān)控組件等等,這也是我們選擇 Golang 的重要原因。

但我需要強(qiáng)調(diào)一點(diǎn),語(yǔ)言的選擇不是只有唯一答案的,這是跟公司技術(shù)和業(yè)務(wù)場(chǎng)景結(jié)合的選擇。

講完語(yǔ)言上的選擇,那么為了在重構(gòu)時(shí)支持多隊(duì)列混排和支持多路召回,我們架構(gòu)上是如何來(lái)解決的?

這點(diǎn)在設(shè)計(jì)模式比較常見,就是『抽象工廠模式』:首先我們構(gòu)建隊(duì)列注冊(cè)管理器,將回調(diào)注冊(cè)一個(gè) map 中,并將當(dāng)前服務(wù)所有隊(duì)列做成 json 配置的可自由插拔的模式,比如如下配置,指定一個(gè)服務(wù)所需要的全部隊(duì)列,存入 queues 字段中,

 

 

通過 name 來(lái)從注冊(cè)管理器的 map 中調(diào)取相應(yīng)的隊(duì)列服務(wù),

 

 

之后呢我們就可以并發(fā)進(jìn)行多隊(duì)列的處理。

 

 

對(duì)于多路召回,及整個(gè)推薦具體流程的可插拔,與上面處理手法類似,比如如下隊(duì)列

 

 

我們可以指定所需召回源,指定 merger 策略等等,當(dāng)某個(gè)過程不需處理,會(huì)按自動(dòng)默認(rèn)步驟處理,這樣在具體 Queue 的實(shí)現(xiàn)中就可以通過如下簡(jiǎn)單操作進(jìn)行自由配置。

 

 

我們講完了架構(gòu)上一些思考點(diǎn)和具體架構(gòu)實(shí)現(xiàn)方案,下面就是關(guān)于召回層具體技術(shù)選型問題。

我們先回顧一下,在常用的推薦召回源中,有基于 topic(tag)的召回、實(shí)體的召回、地域的召回、CF(協(xié)同過濾)的召回以及 NN 產(chǎn)生的 embedding 召回等等。那么為了能夠支持這些召回,技術(shù)上我們應(yīng)該如何來(lái)實(shí)現(xiàn)呢?

我們先從使用角度看一下常用的 NoSQL 數(shù)據(jù)庫(kù)產(chǎn)品,Redis 是典型的 k-v 存儲(chǔ),其簡(jiǎn)單、并且高性能使得其在業(yè)內(nèi)得到大量使用,但不支持復(fù)雜查詢的問題也讓 Redis 在召回復(fù)雜場(chǎng)景下并不占優(yōu),因此一般主要適用于 kv 類的召回,比如熱門召回,地域召回,少量的 CF 召回等等。而 HBase 作為海量數(shù)據(jù)的列式存儲(chǔ)數(shù)據(jù)庫(kù),有一個(gè)明顯缺點(diǎn)就是復(fù)雜查詢性能差,因此一般適合數(shù)據(jù)查詢量大,但查詢簡(jiǎn)單的場(chǎng)景,比如推薦系統(tǒng)當(dāng)中的已讀已推等等場(chǎng)景。而 ES 其實(shí)已經(jīng)不算是一個(gè)數(shù)據(jù)庫(kù)了,而是一個(gè)通用搜索引擎范疇,其最大優(yōu)點(diǎn)就是支持復(fù)雜聚合查詢,因此將其用戶通用基礎(chǔ)檢索,是一個(gè)相對(duì)適合的選擇。

 

 

我們上面介紹了通用召回的技術(shù)選型,那么 embedding 召回如何來(lái)處理呢,我們的方案是基于 Facebook 開源的faiss封裝,構(gòu)建一個(gè)通用 ANN(近似最近鄰)檢索服務(wù)。faiss 是為稠密向量提供高效相似度搜索和聚類的框架。其具有如下特性:1、提供了多種 embedding 召回方法;2、檢索速度快,我們基于 python 接口封裝,影響時(shí)間在幾 ms-20ms 之間;3、c++ 實(shí)現(xiàn),并且提供了 python 的封裝調(diào)用;4、大部分算法支持 GPU 實(shí)現(xiàn)。

從以上介紹可以看出,在通用的推薦場(chǎng)景中,我們召回層大體是基于 ES+Redis+ANN 的模式進(jìn)行構(gòu)建。ES 主要支持相對(duì)復(fù)雜的召回邏輯,比如基于多種 topic 的混合召回;redis 主要用于支持熱門召回,以及規(guī)模相對(duì)較小的 CF 召回等;ANN 主要支持 embedding 召回,包括 nn 產(chǎn)出的 embedding、CF 訓(xùn)練產(chǎn)出的 embedding 等等。

介紹完以上思考點(diǎn),我們總體的架構(gòu)就基本成型了,具體如下圖所示。該框架可以支持多隊(duì)列融合,并且每個(gè)隊(duì)列也支持多路召回,從而對(duì)于不同推薦場(chǎng)景能夠較好的支持,另外,我們召回選擇了 ES+Redis+ANN 的技術(shù)棧方案,可以較好支持多種不同類型召回,并達(dá)到服務(wù)線上的最終目的。

 

 

重構(gòu)遇到的一些問題及解決方案

1、離線任務(wù)和模型的管理問題。我們做在線服務(wù)的都有體會(huì),我們經(jīng)常容易對(duì)線上業(yè)務(wù)邏輯代碼更關(guān)注一些,而往往忽視離線代碼任務(wù)的管理和維護(hù)。但離線代碼任務(wù)和模型在推薦場(chǎng)景中又至關(guān)重要。因此如何有效維護(hù)離線代碼和任務(wù),是我們面臨的第一個(gè)問題。

2、特征日志問題。在推薦系統(tǒng)中,我們常常會(huì)遇到特征拼接和特征的『時(shí)間穿越』的問題。所謂特征時(shí)間穿越,指的是模型訓(xùn)練時(shí)用到了預(yù)測(cè)時(shí)無(wú)法獲取的『未來(lái)信息』,這主要是訓(xùn)練 label 和特征拼接時(shí)時(shí)間上不夠嚴(yán)謹(jǐn)導(dǎo)致。如何構(gòu)建便捷通用的特征日志,減少特征拼接錯(cuò)誤和特征穿越,是我們面臨的第二個(gè)問題。

3、服務(wù)監(jiān)控問題。一個(gè)通用的推薦系統(tǒng)應(yīng)該在基礎(chǔ)監(jiān)控上做到盡可能通用可復(fù)用,減少具體業(yè)務(wù)對(duì)于監(jiān)控的開發(fā)量,并方便業(yè)務(wù)定位問題。

4、離線任務(wù)和模型的管理問題。

在包括推薦系統(tǒng)的算法方向中,需要構(gòu)建大量離線任務(wù)支持各種數(shù)據(jù)計(jì)算業(yè)務(wù),和模型的定時(shí)訓(xùn)練工作。但實(shí)際工作中,我們往往忽略離線任務(wù)代碼管理的重要性,當(dāng)時(shí)間一長(zhǎng),各種數(shù)據(jù)和特征的質(zhì)量往往無(wú)法保證。為了盡可能解決這樣的問題,我們從三方面來(lái)做,第一,將通用推薦系統(tǒng)依賴的離線任務(wù)的代碼統(tǒng)一到一處管理;第二,結(jié)合公司離線任務(wù)管理平臺(tái),將所有任務(wù)以通用包的形式進(jìn)行管理,這樣保證所有任務(wù)的都是依賴最新包;第三,建設(shè)任務(wù)結(jié)果的監(jiān)控體系,將離線任務(wù)的產(chǎn)出完整監(jiān)控起來(lái)。

 

 

5、特征日志問題。

Andrew Ng 之前說過:『挖掘特征是困難、費(fèi)時(shí)且需要專業(yè)知識(shí)的事,應(yīng)用機(jī)器學(xué)習(xí)其實(shí)基本上是在做特征工程!晃覀兝硐胫械耐扑]系統(tǒng)模型應(yīng)該是有干凈的 Raw Data,方便處理成可學(xué)習(xí)的 Dataset,通過某種算法學(xué)習(xí) model,來(lái)達(dá)到預(yù)測(cè)效果不斷優(yōu)化的目的。

 

 

但現(xiàn)實(shí)中,我們需要處理各種各樣的數(shù)據(jù)源,有數(shù)據(jù)庫(kù)的,有日志的,有離線的,有在線的。這么多來(lái)源的 Raw Data,不可避免的會(huì)遇到各種各樣的問題,比如特征拼接錯(cuò)誤,特征『時(shí)間穿越』等等。

 

 

這里邊反應(yīng)的一個(gè)本質(zhì)問題是特征處理流程的規(guī)范性問題。那么我們是如何來(lái)解決這一點(diǎn)呢,首先,我們用在線代替了離線,通過在線落特征日志,而不是 Raw Data,并統(tǒng)一了特征日志 Proto,如此就可以統(tǒng)一特征解析腳本。

 

 

6、服務(wù)監(jiān)控問題。

在監(jiān)控問題上,知乎搭建了基于 StatsD + Grafana + InfluxDB 的監(jiān)控系統(tǒng),以支持各種監(jiān)控日志的收集存儲(chǔ)及展示;谶@套系統(tǒng),我們可以便捷的構(gòu)建自己微服務(wù)的各種監(jiān)控。

 

 

我們這里不過多介紹通用監(jiān)控系統(tǒng),主要介紹下,基于推薦系統(tǒng)我們監(jiān)控建設(shè)的做法。首先先回顧一下我們推薦系統(tǒng)的通用設(shè)計(jì)上,我們采用了『可插拔』的多隊(duì)列和多召回的設(shè)計(jì),那么可以在通用架構(gòu)設(shè)計(jì)獲取到各種信息,比如業(yè)務(wù)線名,業(yè)務(wù)名,隊(duì)列名,process 名等等。如此,我們就可以將監(jiān)控使用如下方式實(shí)現(xiàn),這樣就可以通用化的設(shè)計(jì)監(jiān)控,而不需各個(gè)推薦業(yè)務(wù)再過多設(shè)計(jì)監(jiān)控及相關(guān)報(bào)警。

 

 

 

 

按照如上實(shí)現(xiàn)之后,我們推薦系統(tǒng)的監(jiān)控體系大概是什么樣子?首先各個(gè)業(yè)務(wù)可以通過 grafana 展示頁(yè)面進(jìn)行設(shè)置。我們可以看到各個(gè) flow 的各種數(shù)據(jù),以及召回源的比例關(guān)系,還有特征分布,ranking 得分分布等等。

 

 

未來(lái)挑戰(zhàn)

講完了遇到的一些問題之后,我們來(lái)看一下未來(lái)的挑戰(zhàn)。隨著業(yè)務(wù)的快速發(fā)展,數(shù)據(jù)和規(guī)模還在不斷擴(kuò)張,架構(gòu)上還需要不斷迭代;第二點(diǎn),隨著推薦業(yè)務(wù)越來(lái)越多,策略的通用性和業(yè)務(wù)之間的隔離如何協(xié)調(diào)一致;第三點(diǎn),資源調(diào)度和性能開銷也需要不斷優(yōu)化;最后,多機(jī)房之間數(shù)據(jù)如何保持同步也是需要考慮的問題。

總結(jié)

最后,我們做個(gè)簡(jiǎn)單總結(jié):第一點(diǎn),重構(gòu)語(yǔ)言的選擇,關(guān)鍵要跟公司技術(shù)背景和業(yè)務(wù)場(chǎng)景結(jié)合起來(lái);第二點(diǎn),架構(gòu)盡量靈活,并不斷自我迭代;第三點(diǎn),監(jiān)控要早點(diǎn)開展,并盡可能底層化、通用化。

團(tuán)隊(duì)介紹

我們是知乎的推薦技術(shù)團(tuán)隊(duì),屬于知乎的技術(shù)中臺(tái),主要為公司各個(gè)業(yè)務(wù)方提供完整的推薦服務(wù),其中包括問題路由、知乎大學(xué)的推薦和搜索、回答推薦、文章推薦、視頻推薦、和知乎個(gè)性化 Push 等多個(gè)推薦場(chǎng)景。在這里,我們除了建設(shè)通用推薦服務(wù)架構(gòu)之外,還不斷將最新的推薦算法應(yīng)用到具體推薦業(yè)務(wù)中,提升用戶體驗(yàn),滿足用戶需求。

標(biāo)簽: 代碼 機(jī)房 腳本 數(shù)據(jù)庫(kù) 搜索 搜索引擎

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:IDC與百度聯(lián)合發(fā)報(bào)告:預(yù)測(cè)2019年人工智能十大趨勢(shì)

下一篇:11 月份最熱門的機(jī)器學(xué)習(xí)開源項(xiàng)目及 Reddit 討論 TOP 5