TikTok 推薦引擎強大的祕密

作者:Heorhii Skovorodnikov

深入研究TikTok令人驚歎的實時推薦系統的內部工作原理,瞭解是什麼使它成爲該領域最好的產品之一。

爲什麼TikTok的feed如此讓人上癮?祕訣在於他們的推薦引擎,這正是使TikTok成爲最大的社交媒體平臺之一的原因。

似乎feed可以讀取你的思想,讓你在應用程序中停留更長時間。最近,TikTok決定讓每個人都知道一個祕密,並在一篇題爲 “Monolith:帶有無碰撞嵌入表的實時推薦系統[https://arxiv.org/pdf/2209.07663.pdf]” 的論文中發佈了它的模型Monolith。

在線推薦系統是一種算法,用於根據用戶的興趣和喜好向用戶提供個性化的建議。這些系統通常被在線零售商和媒體公司用於向用戶推薦產品或內容。

在這篇文章中,我們將深入研究TikTok令人驚歎的推薦系統的內部工作原理,並瞭解是什麼,讓它成爲該領域最好的系統之一.

目前的設計存在什麼問題?

構建可擴展的實時推薦系統對於許多企業在其產品或網站中構建良好的體驗至關重要。然而,目前的深度學習框架(TensorFlow或PyTorch)不能很好地用於實時生產場景。這是因爲:

  • 在依賴動態稀疏特徵的推薦系統中,基於靜態參數和密集計算的模型更新並不適合較好的推薦性能。
  • 常見的方法是將批量訓練階段和服務階段(在用戶與產品交互期間)完全分開設計,防止模型與客戶反饋實時交互。

TikTok的團隊通過3個步驟解釋了他們的解決方案:

  • 他們製作了一個無碰撞的嵌入表,同時通過添加可exponable embedding 和 frequency filtering(頻率過濾)來進一步優化它,以減少其內存消耗,讓其高效,並適合分發到用戶;
  • 他們提供了一個可用於生產環境的,且具有高容錯性在線訓練架構;
  • 他們通過實驗證明,系統的可靠性可以與實時學習來互相平衡;

聽起來有點嚇人嗎? 不要擔心,我們將通過對每個組件的拆解分析,在本文結束時,你將有信心地理解,爲什麼你可以在應用程序中浪費大量時間。準備好了嗎? 我們要發車啦。

Embeddings and Hash maps

TikTok的研究人員觀察到,對於推薦系統來說,數據大多是categorical(分散) 和sparse(稀疏)的

這意味着,如果我們使用像單詞嵌入這樣的ML方法嵌入數據,我們將無法通過推薦數據提供的獨特特性數量來實現,相比之下,由於詞彙量有限,語言模型可以做到這一點。

根據YouTube和Instagram推薦系統的實際經驗,哈希技巧被認爲是大規模推薦系統的最佳方法。讓我們深入研究《Monolith》中所使用的細節。

那麼HashMap呢?

哈希映射是一種數據結構,它允許通過一個特殊的哈希函數將數據片段快速映射到一個值。

哈希映射速度很快,被大型平臺用於高效編碼數據,那麼單體應用如何使其更好呢? 哈希映射有一個固有的權衡,這個數據結構的原始設計稱爲碰撞(collision)。

image

當兩個或多個數據通過哈希函數映射到相同的輸出值時,就會發生衝突。當使用哈希函數索引數據時,這可能會導致問題,因爲多個數據塊將被映射到相同的位置。TikTok的團隊開發了一個 cuckoo hashmap,來解決這個問題。

image

在 cuckoo hashmap 中,就像在標準hash map中一樣,每個數據都被分配一個唯一的鍵,並且鍵被哈希以確定它在數組中的位置。如果該位置已經被另一段數據佔據,則現有數據將被“踢出”(類似於現實生活中杜鵑對巢中蛋的行爲),並且必須使用第二個哈希函數在數組中找到一個新的位置。這個過程將繼續,直到所有數據都成功插入數組,或者直到達到最大迭代次數爲止。上面給出了一個例子。這裏兩個哈希表T0和T1用於存儲哈希數據。值A被散列並插入到T0中,但是由於B已經佔據了這個位置,然後將其逐出,並試圖將其插入到T1中,這個過程將重複,直到插入所有值或重新散列以避免循環插入。這個過程可以避免碰撞,對生產模型的性能有重要影響。

爲了完成他們的embedding系統設計,研究人員添加了一些附加功能來進一步優化過程,特別是減少哈希所需要的內存需求:

  • 用於過濾hashmap中的id的概率過濾器。由於一個重要的觀察是,在來自TikTok id的數據中,id是長尾分佈的,熱門id可能出現數百萬次,而不受歡迎的id出現不超過10次,因此可以合理地假設它們不會影響最終的模型質量,因此可以清除。

  • 一個ID存在計時器,控制舊ID和過期ID的刪除。這可能是由於用戶不再活躍,或短視頻過時。爲這些id存儲嵌入不能以任何方式幫助模型,因此清除內存是明智的。

image

在線訓練

現在,由於我們已經瞭解了數據在模型中是如何表示的,我們需要了解如何訓練和更新數據。Monolith在線訓練的系統架構的總體示意圖如下:

image

它看起來很複雜,但實際上,它都圍繞着一個非常簡單的過程,這個過程是更大架構的基礎,推動了整個訓練系統架構的核心。

TensorFlow的分佈式Worker-ParameterServer(或簡稱PS)模型是以分佈式方式訓練機器學習模型的一種方式,其中多臺機器(或一臺機器上的進程)一起工作來訓練模型,如下圖所示:

image

在這個模型中,有兩種類型的進程:工作進程和參數服務器進程。

  • 工作進程負責執行訓練模型所需的計算,例如計算梯度或更新模型參數。
  • 參數服務器負責存儲模型的當前狀態,例如模型權重或偏差。

訓練分爲批量訓練和在線訓練兩個階段:

  • 批量訓練階段。 該階段的工作原理如下:在每個訓練步驟中,訓練工作者從存儲中讀取一個小批量的訓練樣例,向PS請求參數,計算向前和向後傳遞,最後將更新後的參數推入訓練PS。當需要修改模型架構並重新訓練模型時,批量訓練對於訓練歷史數據非常有用;

  • 在線訓練階段。 模型部署到在線服務後,訓練不會停止,而是進入在線訓練階段。訓練工作者不再從存儲中讀取小批量示例,而是實時地使用實時數據並更新訓練PS,訓練PS定期將其參數同步到服務PS,這將立即在用戶端生效。

Streaming引擎

爲了確保Monolith能夠在批量訓練和在線訓練之間無縫切換,它使用了一個Streaming引擎組件:

image

爲了收集實時用戶反饋,研究團隊使用Kafka隊列,其中一個隊列記錄用戶操作(點擊,點贊等),另一個隊列記錄來自模型服務器的功能。然後使用Apache Flink joiner連接兩個,這些打包的數據被轉換成訓練數據,然後由另一個Kafka隊列讀取,這些訓練示例用於批處理訓練和在線訓練:

  • 在批量訓練過程中,Kafka隊列中的數據被轉儲到Hadoop分佈式文件存儲(HDFS)中,在積累了一定數量的訓練數據後,再發送給訓練工作者
    -在線訓練的過程更簡單:數據直接從Kafka隊列中讀取

訓練操作完成後,PS收集參數,並根據選定的同步計劃更新服務PS,而服務PS又更新用戶端的模型。

在線 Joiner

Joiner 過程實際上有點複雜,我們應該注意一些事情:

image

內存緩存和KV(Key-Value)存儲,是兩個有助於穩定用戶操作和來自服務器的功能之間的延遲的組件,這是因爲它們都到達,而不考慮彼此的到達時間,因此需要緩存來正確地配對它們。但是如果用戶需要很長時間才能完成一個操作呢? 那麼緩存就不是一個好主意,因此一些值存儲在磁盤上,以便再次配對。當用戶操作日誌到達時,它首先查找內存中的緩存,然後查找鍵值存儲,以防缺少緩存。

還要注意最後一步,即 負例採樣(Negative Sampling)。因爲在訓練過程中有積極和消極的例子。在推薦系統中,正例是用戶喜歡或表現出興趣的項目,而負例是用戶不喜歡或表現出興趣的項目。但是它們的數量可能是不平衡的,因此糾正數據集中的這種偏差是很重要的。

就是這樣。你已經瞭解了Monolith中的所有組件。現在是最後一個部分,研究人員證明了在線學習的有效性。

實時學習

在這裏,團隊還比較了模型,在不同同步時間間隔下的性能,以驗證其性能:

image

正如我們在上面看到的,在線訓練,對於具有動態反饋的推薦系統擁有更好的性能,是至關重要的。

寫在最後

感謝閱讀我對TikTok實時推薦系統工作原理的深入研究。

我希望你覺得有趣,並學到了一點新的東西。

原文https://www.shaped.ai/blog/the-secret-sauce-of-tik-toks-recommendations

論文:Monolith:帶有無碰撞嵌入表的實時推薦系統,https://arxiv.org/pdf/2209.07663.pdf

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章