統一預估引擎的設計與實現

1. 背景算法

隨着互聯網的快速發展,互聯網上出現了各類海量的信息。怎麼樣爲用戶推薦感興趣的信息是個很大的挑戰?各類各樣的推薦算法、系統都涌現出來。而預估引擎能夠說是推薦系統中比較重要的一環,預估引擎效果的好壞嚴重影響了算法效果。結合oppo的業務場景,咱們的預估引擎須要解決幾個問題:數組

(1)通用性:oppo的推薦業務場景很是多,包括信息流、商店、短視頻、聯盟、鎖屏雜誌、音樂等業務,預估引擎要支持這麼多的場景,框架必定要通用。性能優化

(2)多模型預估:在廣告場景中,須要支持ocpx,須要一次請求同時預估ctr和cvr,多是多個不一樣的轉化模型(例以下載、付費等)。網絡

(3)模型的動態更新:有些模型是小時更新、有些模型是天級更新,須要作到可以無感的動態更新。框架

(4)擴展性:各個業務用到的特徵、字典、模型類型均可能不同,要作到比較容易擴展。異步

2. 定位與技術選型ide

考慮到各個業務的業務特徵差別比較大,統一預估引擎若是要支持各個業務的策略實驗和分流實驗,會讓預估引擎模塊很是臃腫,無法維護。因此最終決定預估引擎只作預估相關的事情。 從原始數據到獲得預估ctr結果,須要通過特徵提取,提取特徵以後的結果再進行模型預估。考慮到特徵提取結果比較大,一次預估須要用的特徵結果大約有2M,這麼大的數據若是經過網絡來傳輸,耗時太長。因此預估引擎整體的流程包括了兩部分:特徵提取和模型預估。性能

3. Predictor的設計與實現優化

3.1 Predictor模塊在整個推薦系統中的位置線程

圖片1.png

以oppo手機應用市場爲類來講明predictor模塊在整個系統中的位置, ranker模塊負責排序,包括各類分流實驗和各類運營策略等。它經過grpc框架與predictor模塊進行通訊。

3.2 Predictor模塊的主體流程 圖片2.png

圖中示意了兩個請求的處理流程,圖中提特徵包括多個特徵conf,每一個樣本、每一個特徵配置提取一次。預估也會是多個模型,每一個樣本、每一個conf、每一個模型會預估屢次。特徵提取依賴外部字典,預估依賴外部的模型文件,外部字典的更新、雙buf切換都是經過字典管理模塊來完成的。下面分別就字典管理模塊、分task, 提特徵,預估,merge進行詳細說明。

3.3 字典管理模塊

以下圖所示:conf1, conf2, lr_model_x0等表示磁盤上的文件,每一個文件名都是經過不一樣的字典解析類來解析,這個字典解析類負責管理這個文件的加載,雙buf切換。例如:FeatureConfDict負責解析conf1,它內部保存兩個FeatureConfList類型的buf,當conf1文件發生更新時,就用備的FeatureConfList* 進行加載,加載完成後,在加載過程當中,服務使用主的FeatureConfList*指針。加載完成後,進行主從切換,待沒有請求使用老的buf,就釋放到老的buf內存。 圖片3.png

3.4 分task邏輯

接收到一個請求,這個請求指定了多conf多模型來預估。以下圖所示: 圖片4.png

上圖表示一共有8條樣本,分別用兩個conf:conf0, conf1來提取特徵,其中conf0的結果由model0,model1來預估,conf1由model2,model3來預估。按照2個樣本一個task,拆分完task以後會獲得4個task,以下圖所示: 圖片5.png

按照樣本維度進行拆分紅4個task,丟到線程池去執行。

3.5 Merge流程

在預估完成以後,須要按照conf/model這個維度進行組織預估結果給ranker, 最終的response以下圖右子圖所示。 圖片6.png

3.6 特徵提取框架的設計

特徵提取框架線上、線下都會用到,這樣比較好保證線上線下的一致性。因此設計的時候要同時考慮到線上線下的業務場景。

線上是將請求帶來的數據與字典數據拼成一條條樣本,進行特徵提取的。而線下是編譯so,經過mapreduce來調用,樣本是經過反序列化hdfs的一條條文本獲得的。

3.6.1 特徵配置文件格式

特徵配置文件包括兩部分: schema部分,特徵算子部分。

3.6.2 schema部分

圖片7.png

上圖中有5個 schema配置

user_schema:表示當前的用戶相關信息,只在在線方式使用,由上游請求帶過來。

item_schema:表示推薦的item相關信息,只在在線方式使用,一部分由請求帶過來,一部分由字典文件中獲取。

context_schema:表示推薦的上下文相關信息,只在在線方式使用,由上游戲請求帶過來。例如:當前網絡狀態是wifi仍是4G。

all_schema: 表示最終的樣本的schema信息。在線模式是將user_schema, item_schema,context_schema的各個字段放在all_schema的對應位置,離線模塊是將hdfs的一行行文本,按照all_schema_type指定的類型進行反序列化生成的。不論是在線仍是離線,特徵框架的樣本最終的字段順序都是按照all_schema順序存放的

all_schema_type: 離線模式纔會用到,指定了各個schema的類型,這些類型名都是事先定義好的,在離線模式下,根據schema類型來反序列化各個字段。

3.6.3 特徵算子配置部分

圖片8.png

每一個特徵包括下面這些字段:

Name: 特徵名字

Class:表示這個特徵用的哪一個特徵算子類,對應代碼裏類名

Slot: 惟一標識一個特徵

Depend: 表示該特徵依賴哪些字段, 這個字段在上述all_schema中必須存在

Args: 表示傳給特徵算子的參數, 框架會轉成float傳給算子

Str_args: 傳給特徵算子的參數,以字符串的形式傳遞。

3.6.4 特徵分group(common和uncommon)

一次預估請求裏面,全部樣本的用戶和context信息是同樣的, 考慮到有些特徵只依賴用戶和context信息,這部分特徵只須要提取一次,全部樣本共用。

特徵配置裏面一部分特徵會依賴其餘的特徵(例如組合特徵、 cvm特徵),因此須要對特徵的依賴進行分析,用來判斷一個特徵最終依賴的字段信息。

圖片9.png

i_id特徵依賴item字段的item_id,因此它是uncommon特徵

u_a/net特徵只依賴user_schema或者context字段, 不依賴item字段,因此它是common特徵 u_a-i_id組合特徵依賴i_id特徵,間隔依賴item_id,因此它是uncommon特徵,

u_a-net組合特徵只依賴u_a和network字段,因此它是common特徵,在特徵提取的時候,一次請求只算一次。

注意:這裏特徵分group是異步字典更新線程來負責計算好的,不是請求來了現算的。

3.7 預估部分

前面提到了,一個請求裏面指定了用哪一個特徵配置文件來提取特徵,用哪一個模型來預估。全部的模型都是有異步字典更新線程來負責更新。目前支持了LR, FM, DSSM, Deep&Wide等模型的預估,而且比較容易擴展。下面大概介紹下兩個根據業務場景作了深度優化的模型:

3.7.1 FM模型預估(LR相似)

圖片10.png 其中

圖片11.png

考慮到業務場景,多個樣本的user/context信息是同樣的,那麼線上FM的 預估能夠寫成這個形式:

圖片12.png

標紅部分全部樣本都是同樣的,一個請求只用計算一次。

3.7.2 DSSM(雙塔)模型

雙塔模型的網絡結構以下圖所示:

圖片13.png

實際上一共有三個塔,C(context信息),U(user信息), I(item信息), user與item子塔獲得的向量通過點積,再與C進行求和。

3.7.3 在線serving部分

考慮一些場景的item的信息變化比較慢,通常離線將item的子塔先計算好,獲得向量,經過字典的方式動態加載。

圖片14.png

在線的時候只用計算c塔,u塔, 一個請求只有一條樣本須要計算;I塔部分由查字典獲得向量。計算量相比全鏈接,大幅度減小。性能有大幅度的提高,可是因爲user信息與item只有一層點積相乘,相比全鏈接,離線auc會降低1%,因此比較適合召回或者粗排等對準確度要求不高的場景。在信息流廣告、聯盟廣告業務替換原來的統計 ctr粗排,綜合指標提高五、6個百分點。

3.8 性能優化

預估引擎模塊對時延要求很高,可是爲了達到比較好的算法效果,特徵規模又在不斷的增長,因此在設計預估引擎的時候,作了不少性能優化的考量。主要包括如下幾個方面:

(1)經過對象池來減小內存分配,提升性能。

(2) 特徵字段的依賴都事先轉化成下標,在提取特徵的時候,就直接使用下標來取對應的字段,減小計算量。

(3)有些特徵依賴其餘特徵結果,會頻繁按照slot去查詢對應結果,考慮到slot數據有限,採用數組來代替。

4. 總結

目前predictor模塊支持了大多數推薦場景,包括信息流內容、信息流廣告、應用市場、聯盟、搜索、短視頻、oppo鎖屏雜誌、音樂等場景,部署在近2000臺機器上,說明這套設計還比較穩定、擴展性比較好。目前支持業務平滑的切換到dnn模型,各個業務場景都取得必定的收益。

做者簡介

肖超 高級數據挖掘工程師

10+年的廣告系統工程落地經驗,在oppo主要負責模型的特徵提取、推理的工程落地工做。

更多精彩內容,請掃碼關注【OPPO互聯網技術】公衆號

qrcode_for_gh_7bc48466f080_258.jpg

相關文章
相關標籤/搜索