得物技術多興趣召回模型實踐

得物技術發表於2022-05-20

MIND多興趣召回在實踐過程中,經過離線和實時兩個階段去執行最終落地,中間的步驟因此記錄下來,希望他人在閱讀到此文能夠有所收穫。具體步驟:首先經過離線召回的方式從實驗資料上證明了可行性,天級別指標均置信提升:pvctr+0.36%,uvctr+0.36,dpv+0.76%,後續基於該版本開發MIND線上預估方式。最終在交易瀑布流場景取得的收益為:dpv+3.61%,人均收藏pv+2.39%,pvctr+1.95%,uvctr+0.77%。離線召回過程中,是通過類似I2I的召回方式進行的,首先訓練出模型之後,然後將單機去跑user embedding和item embedding後再通過faiss得到對應userId下的倒排召回,最終將userId作為trigger進行I2I的召回。線上預估是通過線上的實時使用者行為呼叫neuron預估服務的模型計算user embedding後,然後通過C引擎的離線item embedding計算faiss得到召回商品,目前興趣數設定為3,考慮到召回元件的超時時間,因此需要併發執行。

1、多興趣召回簡介

1.1 MIND多興趣召回

多興趣MIND召回是一種u2i召回,其提出了一種Behavior-to-Interest (B2I)動態路由,用於自適應地將使用者的行為聚合為興趣表示向量。具體的來說,多興趣模型的輸入為使用者的行為序列,該行為序列在瀑布流場景使用的是使用者的點選、收藏、分享的cspuid,輸出則是使用者的多個興趣向量(這個size可以定義,由網路的輸出維度確定),一般而言,興趣向量的區別集中在類目/品牌上。

多個興趣的使用者向量是該召回的一個亮點,因為使用者在逛瀑布流場景時,顯然不可能只有單個興趣的,往往會集中在幾個不同的興趣,可能是鞋、服裝、化妝品等等。因此單一的興趣向量往往很難去cover住使用者想要感知的。

單一興趣的召回結果往往侷限在一個類別範圍下,這種召回策略擴充套件性較差,容易越推越窄,使得候選池中的視訊頭部效應越來越明顯。

1.2 其他的一些多興趣召回方法:

(1)可以對使用者的長短期興趣、用的點選item都做召回,這樣便可以捕獲使用者過去的所有興趣,這個也是目前線上i2i的一個策略

(2)也可以利用用的點選/收藏/分享的item都做召回類似item2vec獲取item的embedding後再進行faiss索引後取topn的方式獲取使用者的所有興趣點

2、多興趣召回模型

下圖是MIND召回的整體網路框圖

對於模型, 每個樣本的輸入可以表示為一個二元組: ,其中 代表與使用者互動過的物品集, 即使用者的歷史行為序列;定義為目標物品的一些特徵, 例如商品的brand_id和類目category_id等。

  • 通過Mulit-Interest Extractor Layer 獲取多個向量表達使用者興趣的不同方面;
  • 提出了具有動態路由的多興趣網路(MIND),利用動態路由以自適應地聚合使用者歷史行為到使用者表達向量中,以處理使用者的不同興趣;
  • 開發 Label-Aware Attention 標籤感知注意力機制,用於學習具有多個興趣向量的使用者表示

具體來說就是設計了一種基於膠囊網路機制的多興趣提取層,適用於聚類歷史行為,提取不同的興趣。膠囊網路的核心思想就是“輸出是輸入的某種聚類的結果”

這裡有一個優點:如果把與使用者興趣各種相關的資訊都壓縮成為一個表達向量,這會成為使用者多樣興趣表達的瓶頸,在推薦召回階段召回候選集時,對使用者不同興趣的所有資訊混合在一起使用,會導致召回Item 的相關性大大降低。因此,採用多個向量來表達使用者不同的興趣,將使用者的歷史行為分組到多個 interest capsules 的過程, 期望屬於同一個capsules 的相關Item 共同表達使用者興趣的一個特定方面。

通過多興趣提取層,多個興趣膠囊從使用者行為embedding建立。在訓練期間,通過一個標籤意識注意力層讓標籤物品選擇使用過的興趣膠囊。特別的,對於每一個標籤物品,我們計算興趣膠囊和標籤物品embedding之間的相似性,並且計算興趣膠囊的權重和作為目標物品的使用者表示向量,通過相應的相容性確定一個興趣膠囊的權重,這裡和DIN中的Attention幾乎一樣,但key與value的含義不同。其中目標物品是query,興趣膠囊既是keys也是values.

其中pow定義每個元素的指數級操作,是一個可調節的引數來調整注意力分佈。當接近0,每一個興趣膠囊都得到相同的關注。當大於1時,隨著的增加,具有較大值的點積將獲得越來越多的權重。考慮極限情況,當趨近於無窮大時,注意機制就變成了一種硬注意,選關注最大的值而忽略其他值。

2.1 user embedding計算部分

MIND的核心任務是學習一個從使用者行為序列對映到多興趣向量表示的函式,使用者表示定義為:

其中為使用者的多興趣向量表示,為embedding的維度,本網路設定的維度和DSSM一樣是32,是表示興趣向量的數量。若,即其他模型(如Youtube DNN)的Embedding表示方式。

2.2 item embedding計算部分

目標商品的embedding函式為:

其中表示一個Embedding&Pooling層。

2.3 Loss function

2.4 負取樣的方式

負採用是均勻取樣了若干個cspu_id作為負樣本,這裡的cspu_id是當時做樣本是篩選出來的,都是包含點選行為的。

3、多興趣召回的實現和部署

多興趣的召回實現具體包含odps、C++引擎、dpp和neuron預估服務端

3.1 odps部分

其中odps主要執行訓練樣本的構建、模型訓練以及模型離線監控,樣本包含了兩個版本,其中第一版本是採用了演算法側的使用者行為表,第二版本考慮了第一版存在延時上報導致的線上線下不一致的問題,因此採用了dump下來的點選、收藏和分享序列,這裡只用到了cspu_id作為特徵,還沒有使用商品的原有資訊,比如淘寶使用了brand_id和category_id,這部分的會在後續的迭代中使用。

這裡採用了是視窗式的構建樣本方式,均使用了過去三天的資料。然後經過可推池進行篩選。此外,由於模型裡面採用的embedding_lookup的方式進行查詢cspu_id的embedding,因此樣本里面還單獨構建了一份cspu_id和hash_id的對映表。然後會進行模型訓練

3.2 C++引擎部分

C++引擎儲存cspu_id和hash_id的對映表、向量叢集儲存item embedding表

線上使用的過程中,需要獲取使用者的clklist畫像,然後基於clklist儲存的cspu_id去正排請求C++引起的對映表獲取hash_id,然後構建neuron的特徵。這裡只需要hash_id的序列和長度,傳輸給neuron後便可以實現預估user embedding。

拿到user embedding後通過dpp構建三個併發請求去呼叫faiss獲取每個興趣對應的召回結果,然後拼接去重再傳輸給後續層

3.2.1 一些小坑

第一是embedding的生成時間不確定,然後中間又沒有同步機制,因此neuron模型和faiss的emebdding不一致會導致效果下跌。

第二,構建embedding的任務在一個叢集內是序列執行的,那麼後續如果u2i的召回多了,會導致任務卡著。

3.3 neuron預估部分

neuron預估部分需要去構建服務,具體的說需要寫一個neuron_script指令碼,用於dpp在呼叫neuron過程中,neuron根據這個指令碼然後去進行特徵處理,然後構建模型的feed,再通過起一個tf-servering服務拉起模型,最後便輸出使用者向量返回到dpp。

4、多興趣召回模型的穩定性

線上服務的模型不僅僅是要有效果,同時需要保證其執行的穩定性,因此線上模型是需要額外的新增相應的離線監控加對應的阻斷機制,以及模型服務的線上監控,其中離線監控和阻斷機制是當模型進行天級別離線訓練的時候,如果離線指標(包含auc、pcoc、loss)不符合預期時,及時的進行阻斷並且告警出來,作為一個前置阻斷,防止影響該路召回的線上效果。模型服務的線上監控的實現判斷召回空置率、召回qps、召回漏斗的召回數和對應渠道的pvctr、uvctr等指標來進行線上監控,並且通過同環比的方式進行配置,作為後置監控,一旦出現很大的波動則會告警,然後快速響應進行相應的回滾和處理。

模型的監控利用odps實現,主要是模型訓練過程中會將loss落表,然後利用規則來進行長短期的監控

4.1 模型離線指標的監控

長期監控是獲取過去30天的90%分位數和1.1倍的最大值,然後判斷如果loss小於90%的分位數則可能訓練的有點過擬合,興趣不夠發散會進行阻斷,如果大於1.1倍的最大值,則可能模型沒有完全train好,召回的結果可能太發散,會有一些bad case 。

短期監控主要是計算過去14天的均值和方差,然後loss要在(均值-3方差,均值+3方差)之間,如果不在則阻斷

監控的sql程式碼:

SELECT CUR_LOSS,MIN_LOSS,MAX_LOSS,IF (CUR_LOSS<MIN_LOSS or CUR_LOSS>MAX_LOSS,1,0) FROM (
    (
        SELECT loss AS CUR_LOSS ,1 as rn1 FROM  deal_pai_model_mind_recall_check 
        where ds=(select(regexp_replace(substr(date_sub(FROM_UNIXTIME(UNIX_TIMESTAMP()),1),1,10),'-','')))
    ) a
LEFT JOIN 
    (
        SELECT (avg(loss)-2*STDDEV(loss)) AS MIN_LOSS ,1 as rn2 FROM deal_pai_model_mind_recall_check 
        where ds<(select(regexp_replace(substr(date_sub(FROM_UNIXTIME(UNIX_TIMESTAMP()),1),1,10),'-',''))) 
        and ds>(select(regexp_replace(substr(date_sub(FROM_UNIXTIME(UNIX_TIMESTAMP()),14),1,10),'-','')))
    ) b
on a.rn1=b.rn2
LEFT JOIN 
    (
        SELECT (avg(loss)+3*STDDEV(loss)) AS MAX_LOSS ,1 as rn3 FROM deal_pai_model_mind_recall_check 
        where ds<(select(regexp_replace(substr(date_sub(FROM_UNIXTIME(UNIX_TIMESTAMP()),1),1,10),'-','')))
        and ds>(select(regexp_replace(substr(date_sub(FROM_UNIXTIME(UNIX_TIMESTAMP()),14),1,10),'-','')))
    ) c 
on a.rn1=c.rn3
);

4.3 模型阻斷機制

精排模型更新是利用odps的shell部署指令碼實現的

而neuron是在跳板機定時執行部署指令碼,判斷路徑下是否生成了模型檔案,因此這裡可以構建兩個路徑,一個是固定生產路徑,一個是給neuron的模型檔案路徑,如果模型被阻斷,也就是不會將模型push到neuron的模型檔案路徑即可。

這裡是採用了dataworks的資料質量方法,通過規則的方式一旦不符合規則則進行阻斷。阻斷的流程圖如下:

官方配置文件

正常Normal時按照正常流程走,如果異常則阻礙下游節點,使得線上模型不更新來確保模型質量。

5、多興趣召回模型總結

MIND多興趣召回的核心是基於原先應用於影像的膠囊網路然後用於推薦,然後通過動態路由演算法來捕捉使用者的多個興趣,對應的多個興趣去召回不同的商品來cover使用者想要感知的,並且線上預估會不斷的提取使用者的行為更加準確的捕捉使用者後續的興趣點,這也是為什麼線上預估會比離線預估效果要好很多的原因。

6、後期優化點

1、在使用者點選/分享/收藏行為序列內加入cspu_id的原有資訊,便於冷啟動以及可以獲取到更多商品的表示資訊來生成item embedding

2、工程側的優化 ,併發索引放在C引擎處進行,用於增加召回興趣量

3、負取樣的優化,採用類似DSSM的負樣本構建方式,而不是均為點選過的樣本去做均勻取樣

引用

https://arxiv.org/pdf/1904.08...

https://mp.weixin.qq.com/s/un...

/QC

關注得物技術,做最潮技術人!

相關文章