編者按:隨著互聯網內容數量的急劇增長,個性化推薦已成為各大科技公司的核心競爭力之一。那么,如何構建一個可靠、高效的基于嵌入技術的推薦系統,使其能夠在實際生產環境中正常運行呢?這是所有從業者都關心的問題。
本文是Embedding技術與應用的最后一篇,探析 Embedding 應用工程的文章。作者認為,要讓一個推薦系統項目取得成功,不能僅僅停留在算法層面,更需要從工程實現的角度進行全面的考量和設計。
文章詳細闡述了一個推薦系統從零到一的完整流程,包括:生成嵌入、存儲嵌入、處理與迭代嵌入、檢索嵌入、更新與版本控制嵌入、推理與延遲優化、在線與離線評估等多個方面。這些都是構建一個可靠、高效推薦系統必須解決的關鍵問題。作者還指出,從業務角度來看,要讓一個基于機器學習的項目成功實施,需要數據、技術和產品相互配合,不能單純依靠算法本身。
這篇文章為我們深入剖析了工程實現對推薦系統的重要性,讓我們更全面地認識到機器學習項目不僅需要出色的算法,還需要考量數據、技術構建、產品匹配等多方面因素,方能取得成功。本文為從業者提供了很好的工程思路與指導,具有重要的參考價值。
以下是譯文,enjoy!
作者 | Vicki Boykis
編譯?|?岳揚
🚢🚢🚢歡迎小伙伴們加入AI技術軟件及技術交流群,追蹤前沿熱點,共探技術難題~
01 將嵌入的應用視為工程問題
通常情況下,機器學習工作流程(machine learning workflows)會給整個應用工程系統增加巨大的復雜度和開銷,原因有很多[1]。首先,這個工作流程會將數據混合,而這些數據需要在下游進行監測,以防產生漂移。其次,它們的輸出是不確定的,這意味著需要非常小心地跟蹤這個工作流,因為我們通常不會對數據進行版本控制。第三,它們會導致處理管道(processing pipeline)出現混亂。
處理管道(processing pipeline)的混亂是膠水代碼(glue code)的一種特殊情況,通常出現在數據準備流程中。隨著新的信號被識別和新的信息源被添加,這些管道可以有機地演變。如果不加注意,為了以機器學習友好的格式準備數據所構建的系統,這個系統通常由多個數據處理步驟組成,包括數據抓取、數據清洗、數據轉換、數據合并等,而且這些步驟之間可能存在多個依賴關系和中間文件輸出。如果不加注意,這個系統可能會變得非常復雜和難以維護
從PinnerSage和Wide and Deep等模型的系統架構圖中可看出,生產環境中使用嵌入的推薦系統[2],都有許多可活動組件。
圖1 PinnerSage和Wide and Deep模型的系統架構圖
您可能還記得我們在這張圖中討論了推薦系統的基礎階段。
圖2 在上下文中處理嵌入的通用流程
如果考慮一個成功的推薦系統在生產環境中的所有要求,實際生產環境中的推薦系統通常包含以下階段:
? 生成嵌入(Generating embeddings)
? 存儲嵌入(Storing embeddings)
? 嵌入特征工程和迭代(Embedding feature engineering and iteration)
? 工件檢索(Artifact retrieval)
? 更新嵌入(updating embeddings)
? 對嵌入進行版本控制和數據漂移(versioning embeddings and data drift)
? 推理和延遲情況(Inference and latency)
? 在線(A/B測試)和離線(度量指標掃描)模型評估(Online (A/B test) and offline (metric sweep) model evaluation)
如果要考慮到我們上面關注的這些問題,任何生產環境中的推薦系統的系統架構圖都會看起來像下面這樣:
圖3 將推薦系統作為一個機器學習問題來看待
02 生成嵌入(Generating embeddings)
通過前文,我們已經了解到,嵌入通常是訓練神經網絡模型時生成的副產品,一般是在添加用于分類或回歸的最終輸出層之前使用的倒數第二層。一般有兩種方法來生成嵌入。一種方法是訓練私有化的模型,就像YouTube、Pinterest和Twitter所做的那樣。現在也越來越多人對訓練私有化大語言模型表現出興趣[3]。
然而,深度學習模型的一個重要的優點是我們也可以使用預訓練模型。預訓練模型是指已經在大量訓練數據上進行訓練、與我們的目標任務相似的模型,可以用于下游任務。BERT就是一種預訓練模型[4],通過微調,可以用于任何機器學習任務。在微調過程中,我們可以采用已經在通用數據集上進行過預訓練的模型。例如,BERT 是在 BookCorpus 和 English Wikipedia 上訓練的,前者是由 11K 本書籍和 25 億個單詞組成的,后者是由 8 億個單詞組成的[5]。
關于訓練數據的一些說明
訓練數據是任何模型中最重要的部分。對于預訓練的大語言模型來說,訓練數據通常來自于對互聯網的大規模爬取。為了保持競爭優勢,這些訓練數據集的組成通常不會被公開,因此需要進行相當多的逆向工程和猜測。例如,《What’s in my AI》[6]一書中介紹了GPT系列模型背后的訓練數據,發現GPT-3是在Books1和Books2的基礎上進行訓練的。Books1很可能是BookCorpus[7],而Books2很可能是LibGen[8]。GPT還包括Common Crawl、WebText2和Wikipedia等大型開源數據集。這些信息非常重要,因為在選擇預訓練模型時,我們至少需要從高層次上了解它的訓練數據,以便解釋在微調時發生了哪些變化。
在微調模型時,我們需要執行與從頭開始訓練模型相同的所有步驟。需要收集訓練數據、訓練模型和將損失函數最小化。當然也有幾個不同之處。當創建新模型時,我們會復制現有的預訓練模型,但最終輸出層除外,我們會根據新任務從頭開始初始化輸出層。在訓練模型時,我們會隨機初始化這些參數,且只繼續調整前幾層的參數,使它們專注于這項任務,而不是從頭開始訓練。通過這種方式,如果我們有一個像BERT這樣的模型,訓練完成后就可以泛化學習整個互聯網,但我們這個使用Flutter制作的應用程序其語料庫對流行話題非常敏感,因此需要每天更新,那么我們就可以重新調整模型的重點,而不必訓練一個新的模型,只需要使用 10k 個樣本,而非原來的數億個[9]。同樣,我們也可以對BERT嵌入進行微調。
還有其他一些通用語料庫可用,例如GloVE、Word2Vec 和FastText[10](也使用CBOW進行訓練)。我們需要決定是使用這些語料庫,還是從頭開始訓練一個模型,或者采用第三種方法,通過API獲取可用的嵌入[11],就像OpenAI的嵌入那樣,盡管這樣做可能相對于訓練或微調我們自己的模型來說成本更高[12]。當然,我們需要根據具體用例在項目開始時進行評估和選擇。
03 存儲和檢索嵌入
當我們訓練好模型后,需要從其中提取嵌入。一般來說,模型經過訓練后,其輸出結果是一個包含所有模型參數的數據結構,包括模型的權重、偏置、層數和學習率(weights, biases, layers and learning rate)。 在訓練模型時,嵌入被定義為一個層(layer),并與其他層一起組成了整個模型對象,在模型訓練期間,嵌入在內存中存儲。當我們將模型寫入磁盤時,會將它們作為模型對象傳播,并序列化到內存中,并在重新訓練或推斷時加載。
最簡單的嵌入存儲形式可以是numpy數組,該數組最初存在于內存中,并可以在需要時被訪問和使用。
但是,如果我們正在迭代構建一個具有嵌入的模型,我們希望能夠對它們進行多種操作:
? 在推理時批量或逐個訪問模型
? 對嵌入的質量進行離線分析
? 嵌入特征工程
? 用新模型更新嵌入
? 版本控制嵌入
? 為新文檔編碼新的嵌入
處理這些用例的最復雜和可定制的軟件是向量數據庫(vector database),而介于向量數據庫和使用內存數據庫之間的是已經存在的存儲系統或數據庫(如Postgres和SQLite)的向量搜索插件,以及緩存(如Redis等)。
我們要對嵌入進行的最重要的操作是向量搜索(vector search),它允許我們找到與給定嵌入相似的嵌入向量,以便返回相似度。如果我們想要搜索嵌入,就需要一種經過優化的機制來搜索矩陣數據結構(matrix data structures),并以與傳統關系型數據庫經過優化來搜索基于行的關系相同的方式,執行最近鄰比較。關系型數據庫使用B樹結構,通過在數據庫中的索引列上建立的節點層次結構中,按升序排序的方式來優化讀取。由于我們無法有效地對向量執行列查找(columnar lookups),因此我們需要為它們創建不同的結構。例如,許多向量存儲是基于倒排索引(inverted indices)的。
通用形式的嵌入存儲包含嵌入本身、將它們從隱空間(latent space)映射回單詞、圖片或文本的索引,以及使用各種最近鄰算法在不同類型的嵌入之間進行相似度比較的方法。我們之前談到過余弦相似度(cosine similarity)是比較隱空間表征(latent space representations)的基本方法。但是,當我們需要對數百萬個向量集進行比較時,計算成本會變得非常昂貴,因為我們需要對每一對向量進行比較。為了解決這個問題,近似最近鄰(ANN)算法被開發了出來,就像推薦系統中一樣,從向量元素中創建鄰域,并找到向量的k個最近鄰。 最常用的算法包括HNSW(hierarchical navigable small worlds)和Faiss,這兩種算法都是獨立的庫,也作為許多現有向量存儲的一部分實現。
全搜索(full search)和最近鄰搜索(nearest neighbor search)之間的權衡是,后者精確率較低,但速度更快。當我們在評估精確率(precision)和召回率(recall)之間切換時,我們需要注意權衡,并考慮我們對嵌入的準確率和推斷延遲的要求是什么。
以下是Twitter為這個用例構建的嵌入存儲系統的示例,早在向量數據庫出現之前就已經存在了。[13]
圖4 Twitter的嵌入管道[13]
如本系列上一篇文章所述,Twitter在系統多處都使用了嵌入,Twitter通過創建一個集中式平臺,將數據重新處理并將嵌入生成到下游的特征注冊表(feature registry)中,使嵌入成為“一等公民”。
04 數據漂移檢測、版本控制和可解釋性
我們完成了嵌入的訓練后,可能會認為已經大功告成。但是,與任何機器學習管道(machine learning pipeline)一樣,嵌入需要定期更新,因為我們可能會遇到概念漂移(concept drift),概念漂移是指模型底層的數據發生變化。例如,假設某個模型包含一個二元特征,即是否擁有固定電話。但是,在2023年,由于大多數人已經改用手機作為主要電話,這在世界上大多數地方都不再是一個相關的特征,因此模型的準確性會降低。
這種現象在用于分類的嵌入中更為普遍。例如,假設我們使用嵌入進行trending欄目的話題檢測。模型必須如wide and deep model那樣能夠泛化,以便能夠檢測新類別,但如果內容的類別變化很快,它可能無法實現泛化,因此我們需要經常重新訓練生成新的嵌入。或者,舉例來說,如果我們在圖(graph)中對嵌入進行建模,如Pinterest所做的那樣,而圖中節點之間的關系發生了變化,我們可能就必須更新它們[14]。我們還可能會有大量的垃圾內容或損壞的內容,這會改變嵌入中的關系,在這種情況下,我們就需要重新訓練。
我們可能很難理解嵌入(有些人甚至寫了一整篇論文來討論它們),并且更難以解釋。例如,為什么在某個嵌入空間中,國王的嵌入向量與皇后的嵌入向量非常接近,但與騎士的嵌入向量相距很遠?在某個嵌入空間中,兩個flits的嵌入向量非常接近是什么意思?
我們可以從內部評估和外部評估兩種角度來思考這個問題。對于嵌入本身(外部評估),我們可以通過UMAP(Uniform Manifold Approximation and Projection for Dimension Reduction)或t-sne(t-distributed stochastic neighbor embedding)進行可視化,這些算法允許我們將高維數據可視化為二維或三維數據,就像PCA一樣。或者,我們也可以將嵌入適配到下游任務中(例如,摘要任務或分類任務),并以離線指標(offline metrics)相同的方式進行分析。還有其他許多不同的方法[15],但總的來說,嵌入客觀上很難進行評估,我們需要將執行此評估的時間因素考慮到我們的模型構建時間中。
在重新訓練初始基準模型(initial baseline model)后,我們將面臨一個次要問題:如何比較第一組嵌入和第二組嵌入?也就是說,鑒于嵌入通常是無監督的,我們如何評估它們是否能很好地表示我們的數據,也就是說,我們如何知道"king"應該靠近"queen"?,對嵌入進行初步解釋或評估時,嵌入本身可能很難解釋,因為在多維空間中,由于向量的維度很多,有時很難理解,向量的哪個維度對應于將嵌入空間中的實體放在一起的決策[16]。與其他嵌入集進行比較時,我們可以使用最終模型任務(final model task)的離線指標(offline metrics),如精確率和召回率,或者我們可以通過比較兩個概率分布(probability distributions)之間的統計距離(statistical distance),使用一種稱為Kullback-Leibler divergence的指標來測量隱空間中嵌入分布的距離。
最后,假設我們有兩組嵌入,需要對它們進行版本控制,并保留兩組嵌入,以便在新模型效果不佳時可以回退到舊模型。這與機器學習操作中的模型版本控制問題是相輔相成的,只是在這種情況下,我們需要同時對模型和輸出數據進行版本控制。
有許多不同的模型和數據的版本控制方法,其中一種方法是建立一個系統,來跟蹤二級數據存儲系統中資產的元數據和位置。另一個需要注意的問題是,特別是對于大詞匯表,嵌入層可能會變得非常龐大,因此我們還需要考慮存儲成本。
05 推理和延遲情況
在使用嵌入時,我們不僅需要在理論環境下工作,還在實際的工程環境中。任何在生產環境中運行的機器學習系統面臨的最關鍵工程問題之一是推理時間——查詢模型資產并將結果返回給終端用戶需要多長時間。
為此,我們需要關心延遲,我們可以將其大致定義為全部的等待時間(any time spent waiting),這是所有生產系統中的關鍵性能指標[17]。一般來說,它是所有操作完成的時間——應用程序請求、數據庫查詢等等。Web服務級別的延遲通常以毫秒為單位衡量,每個人都會盡力將延遲時間減少到盡可能接近零。對于搜索和加載內容饋送的用例,必須是即時的,否則用戶體驗將會下降,我們甚至可能會失去收入。在Amazon的一項研究中,他們發現每增加100毫秒的延遲,利潤就會減少1% [18]。
因此,我們需要考慮如何減少模型的占用空間以及為其提供服務的層數,從而實現對用戶的即時響應。我們通過在整個機器學習系統中創建可觀測性(observability)來實現這一點,從運行系統的硬件開始,到CPU和GPU的利用率,模型架構的性能以及該模型與其他組件的交互方式。例如,在執行最近鄰查找時,我們執行查找的方式、我們使用的算法、我們用來編寫該算法的編程語言,所有這些都會影響延遲的大小。
在《the wide and deep》論文中,推薦排序模型每秒對超過 1000 萬個應用程序進行評分。該應用程序最初是單線程的,需要耗時31毫秒。通過實現多線程,能夠將客戶端延遲降低到14毫秒[19]。因此,需要在推理和延遲方面進行優化,以確保機器學習系統能夠在生產環境中高效地運行。
機器學習系統的運營是另一個獨立的領域,需要深入研究和探討,最好單獨寫一篇論文來討論。[20]
06 在線和離線模型評估
我們剛剛觸及模型最關鍵部分之一的表面:模型在離線和在線測試中的表現如何。當我們談論離線測試時,指的是分析模型的統計特性,以了解模型是否是一個有效的模型——即我們的損失函數是否收斂?模型是否過擬合或欠擬合?精確率和召回率是多少?我們是否遇到了任何數據漂移?對于推薦排序模型來說,我們使用像NDCG(normalized discounted cumulative gain)這樣的指標來了解新模型,是否比上一次迭代對內容的排序更好?
然后是在線評估,即模型在生產環境中實際的成功程度。通常是通過A/B測試來評估的,即一組用戶使用舊模型或系統,另一組用戶使用新系統,并查看像點擊率、提供的內容數量和在網站特定區域停留時間等指標。
07 使用嵌入的項目的成功之道
最后,當我們把所有算法和工程方面的問題都考慮清楚之后,還有最后一個問題需要考慮,那就是從業務角度來看怎樣才能使我們的項目取得成功。我們應該認識到,不一定所有機器學習問題都需要用到嵌入技術,或者說,我們可能根本不需要機器學習,如果說我們的項目完全基于一些啟發式規則,而這些規則可以由人類確定和分析[21]。
如果我們得出結論,我們是在一個數據豐富的空間中操作,在這個空間中自動推斷實體之間的語義關系是正確的,那么我們需要問自己,是否愿意花費大量的精力來制作干凈的數據集,這是任何優秀機器學習模型的基礎,即使在大語言模型的情況下也是如此。實際上,干凈的垂直領域數據非常重要,以至于本文討論的許多公司最終都訓練了屬于自己的嵌入模型,而最近像彭博社[22]和Replit[23]這樣的公司甚至正在訓練自己的大語言模型,主要是為了提高其特定業務領域的準確率。
關鍵是,要讓機器學習系統達到一個使用嵌入的階段,我們需要一個團隊,圍繞需要完成的工作進行多層次的協調。在規模較大的公司中,該團隊的規模將更大,但是最重要的是,大多數嵌入工作需要有人能夠明確定義用例,還要一個支持實際用例并將其優先考慮的人,以及一個可以完成工作的技術人員[24]。
如果滿足這些要求,我們就能構建一個基于嵌入的推薦系統。
END
參考資料
[1]David Sculley, Gary Holt, Daniel Golovin, Eugene Davydov, Todd Phillips, Dietmar Ebner, Vinay Chaudhary, and Michael Young. Machine learning: The high interest credit card of technical debt.(2014), 2014.
[2]https://amatriain.net/blog/RecsysArchitectures
[3]https://blog.replit.com/llm-training
[4]https://huggingface.co/docs/transformers/model_doc/bert
[5]https://resources.wolframcloud.com/NeuralNetRepository/resources/BERT-Trained-on-BookCorpus-and-English-Wikipedia-Data
[6]https://s10251.pcdn.co/pdf/2022-Alan-D-Thompson-Whats-in-my-AI-Rev-0.pdf
[7]https://github.com/soskek/bookcorpus/issues/27#issuecomment-716104208
[8]https://en.wikipedia.org/wiki/Library_Genesis
[9]Tianyi Zhang, Felix Wu, Arzoo Katiyar, Kilian Q Weinberger, and Yoav Artzi. Revisiting few-sample bert fine-tuning. arXiv preprint arXiv:2006.05987, 2020.
[10]https://fasttext.cc/docs/en/crawl-vectors.html
[11]https://platform.openai.com/docs/guides/embeddings/limitations-risks
[12]https://github.com/ray-project/llm-numbers#101----cost-ratio-of-openai-embedding-to-self-hosted-embedding
[13]Dan Shiebler and Abhishek Tayal. Making machine learning easy with embeddings. SysML http://www.sysml.cc/doc/115.pdf, 2010.
[14]Christopher Wewer, Florian Lemmerich, and Michael Cochez. Updating embeddings for dynamic knowledge graphs. arXiv preprint arXiv:2109.10896, 2021.
[15]Krysta M Svore and Christopher JC Burges. A machine learning approach for improved bm25 retrieval. In Proceedings of the 18th ACM conference on Information and knowledge management, pages 1811–1814, 2009.
[16]Adi Simhi and Shaul Markovitch. Interpreting embedding spaces by conceptualization. arXiv preprint arXiv:2209.00445, 2022.
[17]Brendan Gregg. Systems performance: enterprise and the cloud. Pearson Education, 2014.
[18]Tobias Flach, Nandita Dukkipati, Andreas Terzis, Barath Raghavan, Neal Cardwell, Yuchung Cheng, Ankur Jain, Shuai Hao, Ethan Katz-Bassett, and Ramesh Govindan. Reducing web latency: the virtue of gentle aggression. In Proceedings of the ACM SIGCOMM 2013 conference on SIGCOMM, pages 159–170, 2013.
[19]Heng-Tze Cheng, Levent Koc, Jeremiah Harmsen, Tal Shaked, Tushar Chandra, Hrishi Aradhye, Glen Anderson, Greg Corrado, Wei Chai, Mustafa Ispir, et al. Wide & deep learning for recommender systems. In Proceedings of the 1st workshop on deep learning for recommender systems, pages 7–10, 2016.
[20]Dominik Kreuzberger, Niklas Kühl, and Sebastian Hirschl. Machine learning operations (mlops): Overview, definition, and architecture. arXiv preprint arXiv:2205.02302, 2022.
[21]Martin Zinkevich. Rules of machine learning: Best practices for ml engineering. URL: https://developers. google. com/machine-learning/guides/rules-ofml, 2017.
[22]Shijie Wu, Ozan Irsoy, Steven Lu, Vadim Dabravolski, Mark Dredze, Sebastian Gehrmann, Prabhanjan Kambadur, David Rosenberg, and Gideon Mann. Bloomberggpt: A large language model for finance. arXiv preprint arXiv:2303.17564, 2023.
[23]Reza Shabani. How to train your own large language models, Apr 2023.
URL https://blog.replit.com/llm-training.
[24]Doug Meil. Ai in the enterprise. Communications of the ACM, 66(6):6–7, 2023.
本文經原作者授權,由Baihai IDP編譯。如需轉載譯文,請聯系獲取授權。
原文鏈接:
https://vickiboykis.com/what_are_embeddings/index.html
往期相關文章:
Embedding技術與應用(3):Embeddings技術的實踐應用
Embedding技術與應用 (2) :神經網絡的發展及現代Embedding方法簡介
Embeddig技術與應用 (1) :Embedding技術發展概述及Word2Vec