Embedding技術與應用(4): Embedding應用工程探析

Baihai_IDP發表於2023-11-20

編者按:隨著網際網路內容數量的急劇增長,個性化推薦已成為各大科技公司的核心競爭力之一。那麼,如何構建一個可靠、高效的基於嵌入技術的推薦系統,使其能夠在實際生產環境中正常執行呢?這是所有從業者都關心的問題。

本文是Embedding技術與應用的最後一篇,探析 Embedding 應用工程的文章。作者認為,要讓一個推薦系統專案取得成功,不能僅僅停留在演算法層面,更需要從工程實現的角度進行全面的考量和設計。

文章詳細闡述了一個推薦系統從零到一的完整流程,包括:生成嵌入、儲存嵌入、處理與迭代嵌入、檢索嵌入、更新與版本控制嵌入、推理與延遲最佳化、線上與離線評估等多個方面。這些都是構建一個可靠、高效推薦系統必須解決的關鍵問題。作者還指出,從業務角度來看,要讓一個基於機器學習的專案成功實施,需要資料、技術和產品相互配合,不能單純依靠演算法本身。

這篇文章為我們深入剖析了工程實現對推薦系統的重要性,讓我們更全面地認識到機器學習專案不僅需要出色的演算法,還需要考量資料、技術構建、產品匹配等多方面因素,方能取得成功。本文為從業者提供了很好的工程思路與指導,具有重要的參考價值。

以下是譯文,enjoy!

作者 |  Vicki Boykis

編譯 | 嶽揚

???歡迎小夥伴們加入 AI技術軟體及技術交流群 ,追蹤前沿熱點,共探技術難題~

01 將嵌入的應用視為工程問題

通常情況下,機器學習工作流程(machine learning workflows)會給整個應用工程系統增加巨大的複雜度和開銷,原因有很多[1]。首先,這個工作流程會將資料混合,而這些資料需要在下游進行監測,以防產生漂移。其次,它們的輸出是不確定的,這意味著需要非常小心地跟蹤這個工作流,因為我們通常不會對資料進行版本控制。第三,它們會導致處理管道(processing pipeline)出現混亂。

處理管道(processing pipeline)的混亂是膠水程式碼(glue code)的一種特殊情況,通常出現在資料準備流程中。隨著新的訊號被識別和新的資訊源被新增,這些管道可以有機地演變。如果不加註意,為了以機器學習友好的格式準備資料所構建的系統,這個系統通常由多個資料處理步驟組成,包括資料抓取、資料清洗、資料轉換、資料合併等,而且這些步驟之間可能存在多個依賴關係和中間檔案輸出。如果不加註意,這個系統可能會變得非常複雜和難以維護

從PinnerSage和Wide and Deep等模型的系統架構圖中可看出,生產環境中使用嵌入的推薦系統[2],都有許多可活動元件。

Embedding技術與應用(4): Embedding應用工程探析

圖1 PinnerSage和Wide and Deep模型的系統架構圖

您可能還記得我們在這張圖中討論了推薦系統的基礎階段。

Embedding技術與應用(4): Embedding應用工程探析

圖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)

如果要考慮到我們上面關注的這些問題,任何生產環境中的推薦系統的系統架構圖都會看起來像下面這樣:

Embedding技術與應用(4): Embedding應用工程探析

圖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]

Embedding技術與應用(4): Embedding應用工程探析

圖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

Embedding技術與應用(3):Embeddings技術的實踐應用

Embedding技術與應用 (2) :神經網路的發展及現代Embedding方法簡介

Embeddig技術與應用 (1) :Embedding技術發展概述及Word2Vec


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70018536/viewspace-2996121/,如需轉載,請註明出處,否則將追究法律責任。

相關文章