- 原文地址:MEET MICHELANGELO: UBER’S MACHINE LEARNING PLATFORM
- 原文做者:JEREMY HERMANN & MIKE DEL BALSO
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:lsvih
- 校對者:TobiasLee, xfffrank
Uber 工程師們一直致力於開發各類新技術,以讓客戶獲得有效、無縫的用戶體驗。如今,他們正在加大對人工智能、機器學習領域的投入來實現這個願景。在 Uber,工程師們開發出了一個名爲「米開朗基羅」(Michelangelo)的機器學習平臺,它是一個內部的「MLaaS」(機器學習即服務)平臺,用以下降機器學習開發的門檻,並能根據不一樣的商業需求對 AI 進行拓展與縮放,就有如客戶使用 Uber 打車同樣方便。前端
米開朗基羅平臺可讓公司內部團隊無縫構建、部署與運行 Uber 規模的機器學習解決方案。它旨在覆蓋所有的端到端機器學習工做流,包括:數據管理、訓練模型、評估模型、部署模型、進行預測、預測監控。此係統不只支持傳統的機器學習模型,還支持時間序列預測以及深度學習。react
米開朗基羅在 Uber 投產約一年時間,已經成爲了 Uber 工程師、數據科學家真正意義上的「平臺」,如今有數十個團隊在此平臺上構建、部署模型。實際上,米開朗基羅平臺如今部署於多個 Uber 數據中心並使用專用硬件,用於爲公司內最高負載的在線服務提供預測功能。android
本文將介紹米開朗基羅以及其產品用例,並簡單經過這個強大的 MLaaS 系統介紹整個機器學習工做流。ios
在米開朗基羅平臺出現前,Uber 的工程師和數據科學家們在構建、部署一些公司須要,而且能根據實際操做進行規模拓展的機器學習模型時,遇到了不少挑戰。那時他們試圖使用各類各樣的工具來建立預測模型(如 R 語言、scikit-learn、自定義算法等),此時工程團隊會構建一些一次性的系統以使用這些模型進行預測。所以,在 Uber 內可以在短期內使用各類開源工具構建出框架的數據科學家與工程師少之又少,限制了機器學習在公司內的應用。git
具體來講,那時沒有創建一個可靠、統1、pipeline 可複用的系統用於建立、管理、訓練、預測規模化數據。所以在那時,不會有人作出數據科學家的臺式機跑不了的模型,也沒有一個規範的結果存儲方式,要將幾個實驗結果進行對比也是至關困難的事情。更重要的是,那時沒有一種將模型部署到生產環境的肯定方法。所以,大多數狀況下都是相關的工程團隊不得不爲手中的項目開發定製的服務容器。這時,他們注意到了這些跡象符合由 Scully 等人記錄的機器學習的反模式一文的描述。github
米開朗基羅旨在將整個團隊的工做流程和工具標準化,經過端對端系統讓整個公司的用戶都能輕鬆構建、運行大型機器學習系統。可是工程師們的目標不只限於解決這些直觀的問題,更是要創立一個能與業務共同發展的體系。web
當工程師們於 2015 年年中開始構建米開朗基羅系統時,他們也開始解決一些規模化模型訓練以及一些將模型部署於生產環境容器的問題。接着,他們專一於構建可以更好進行管理、共享特徵 pipeline 的系統。而最近,他們的重心轉移到了開發者生產效率 — 如何加速從想法到產品模型的實現以及接下來的快速迭代。算法
下一節將經過一個樣例來介紹如何使用米開朗基羅構建、部署一個模型,用於解決 Uber 的某種特定問題。雖然下面重點講的是 UberEATS 中的具體用例,可是這個平臺也管理着公司裏其餘針對多種預測用例的相似模型。數據庫
UberEATS 在米開朗基羅中有數個模型在運行,包括送餐到達時間預測、搜索排行、搜索自動完成、餐廳排行等。送餐到達時間預測模型可以預測準備膳食、送餐以及送餐過程當中的各個階段所需的時間。apache
圖 1:UberEATS app 提供了估測外賣送達時間的功能,此功能由基於米開朗基羅構建的機器學習模型驅動。
預測外賣的送達時間(ETD)並非一件簡單的事情。當 UberEATS 用戶下單時,訂單將被送到餐廳進行處理。餐廳須要確認訂單,根據訂單的複雜度以及餐廳的繁忙程度準備餐品,這一步天然要花費一些時間。在餐品快要準備完畢的時候,Uber 外賣員出發去取餐。接着,外賣員須要開車到達餐廳、找到停車場、進餐廳取餐、回到車裏、開車前往客戶家(這個步驟耗時取決於路線、交通等因素)、找到車位、走到客戶家門口,最終完成交貨。UberEATS 的目標就是預測這個複雜的多階段過程的總時間,並在各個步驟從新計算 ETD。
在米開朗基羅平臺上,UberEATS 數據科學家們使用了 GBDT(梯度提高決策樹)迴歸模型來預測這種端到端的送達時間。此模型使用的特徵包括請求信息(例如時間、送餐地點)、歷史特徵(例如餐廳在過去 7 天中的平均餐食準備時間)、以及近似實時特徵(例如最近一小時的平均餐食準備時間)。此模型部署於 Uber 數據中心的米開朗基羅平臺提供的容器中,經過 UberEATS 微服務提供網絡調用。預測結果將在餐食準備及送達前展現給客戶。
米開朗基羅系統由一些開源系統和內置組件組成。主要使用的開源組件有 HDFS、Spark、Samza、Cassandra、MLLib、XGBoost、TensorFlow。在條件容許的前提下,開發團隊更傾向於使用一些成熟的開源系統,並會進行 fork、定製化,若是有需求的話也會對其進行貢獻。若是找不到合適的開源解決方案,他們也會本身構建一些系統。
米開朗基羅系統創建與 Uber 的數據及計算基礎設施之上,它們提供了一個「數據湖」,其中包含了 Uber 全部的事務和日誌數據。由 Kafka 對 Uber 的全部服務日誌進行採集彙總,使用 Cassandra 集羣管理的 Samza 流計算引擎以及 Uber 內部服務進行計算與部署。
在下一節中將以 UberEATS 的 ETD 模型爲例,簡單介紹系統的各個層次,說明米開朗基羅的技術細節。
在 Uber,大多數的機器學習用例(包括一些正在作的工做,例如分類、迴歸以及時間序列預測等)都有着一套一樣的工做流程。這種工做流程能夠與具體實現分離,所以很容易進行拓展以支持新的算法和框架(例如最新的深度學習框架)。它還適用於各類不一樣預測用例的部署模式(如在線部署與離線部署,在車輛中使用與在手機中使用)。
米開朗基羅專門設計提供可拓展、可靠、可重用、易用的自動化工具,用於解決下面 6 步工做流:
下面將詳細介紹米開朗基羅的架構是如何促進工做流中的各個步驟的。
找出良好的特徵常常是是機器學習最難的部分,工程師們也發現整個機器學習解決方案中最費時費力的部分就是構建及管理數據管道。
所以,平臺應提供一套標準工具以構建數據管道,生成特徵,對數據集進行標記(用於訓練及再訓練),以及提供無標記特徵數據用以預測,這些工具須要與公司的數據湖、數據中心以及公司的在線數據服務系統進行深度的整合。構建出來的數據管道必須具備可縮放性以及足夠的性能,可以監控數據流以及數據質量,爲各類在線/離線訓練與預測都提供全面的支持。這些工具還應該能經過團隊共享的方式生成特徵,以減小重複工做並提升數據質量。此外,這些工具應當提供強有力的保護措施,鼓勵用戶去採用最好的方式使用工具(例如,保證在訓練時和預測時都採用同一批次生成的數據)。
米開朗基羅的數據管理組件分爲在線管道和離線管道。目前,離線管道主要用於爲批量模型訓練以及批量預測做業提供數據;在線管道主要爲在線、低時延預測做業提供數據(以及以後會爲在線學習系統提供支持)。
此外,工程師們還爲數據管理層新加了一個特徵存儲系統,可讓各個團隊共享、發現高質量的數據特徵以解決他們的機器學習問題。工程師們發現,Uber 的許多模型都是用了相似或相同的特徵,而在不一樣組織的團隊以及團隊裏的不一樣項目中共享特徵是一件頗有價值的事情。
圖 2:數據預處理管道將數據存入特徵庫以及訓練數據倉庫中。
Uber 的事務與日誌數據會「流入」一個 HDFS 數據湖中,可使用 Spark 和 Hive SQL 的計算做業輕鬆調用這些數據。平臺提供了容器與計劃任務兩種方式運行常規做業,用於計算項目內部的私有特徵或將其發佈至特徵存儲庫(見後文)與其餘團隊共享。當計劃任務運行批量做業或經過別的方式觸發批量做業時,做業將被整合傳入數據質量監控工具,此工具可以快速回溯找出問題出在 pipeine 中的位置,判明是本地代碼的問題仍是上游代碼的問題致使的數據錯誤。
在線部署的模型將沒法訪問 HDFS 存儲的數據,所以,一些須要在 Uber 生產服務的支撐數據庫中讀取的特徵很難直接用於這種在線模型(例如,沒法直接查詢 UberEATS 的訂單服務去計算某餐廳某特定時間段平均膳食準備時間)。所以,工程師們將在線模型須要的特徵預計算並存儲在 Cassandra 中,線上模型能夠低延遲讀取這些數據。
在線部署支持兩種計算系統:批量預計算與近實時計算,詳情以下:
工程師們發現創建一個集中的特徵庫是頗有用的,這樣 Uber 的各個團隊可使用其餘團隊建立和管理的可靠的特徵,且特徵能夠被分享。從大方向上看,它作到了如下兩件事情:
目前,Uber 的特徵庫中有大約 10000 個特徵用於加速機器學習工程的構建,公司的各個團隊還在不斷向其中增長新的特徵。特徵庫中的特徵天天都會進行自動計算與更新。
將來,工程師們打算構建自動化系統,以進行特徵庫搜索並找出解決給定預測問題的最有用的特徵。
用於特徵選擇及轉換的領域特定語言(DSL)。
由數據 pipeline 生成的特徵與客戶端服務傳來的特徵常常不符合模型須要的數據格式,並且這些數據時常會缺失一些值,須要對其進行填充;有時候,模型可能只須要傳入的特徵的一個子集;還有的時候,將傳入的時間戳轉換爲 小時/天 或者 天/周 會在模型中起到更好的效果;另外,還可能須要對特徵值進行歸一化(例如減去平均值再除以標準差)。
爲了解決這些問題,工程師們爲建模人員創造了一種 DSL(領域特定語言),用於選擇、轉換、組合那些用於訓練或用於預測的特徵。這種 DSL 爲 Scala 的子集,是一種純函數式語言,包含了一套經常使用的函數集,工程師們還爲這種 DSL 增長了自定義函數的功能。這些函數可以從正確的地方取出特徵(離線模型從數據 pipeline 取特徵值,在線模型從客戶請求取特徵值,或是直接從特徵庫中取出特徵)。
此外,DSL 表達式是模型配置的一部分,在訓練時取特徵的 DSL 與在與測試時用的 DSL 須要保持一致,以確保任什麼時候候傳入模型的特徵集的一致性。
目前平臺支持離線、大規模分佈式訓練,包括決策樹、線性模型、邏輯模型、無監督模型(k-means)、時間序列模型以及深度神經網絡。工程師們將按期根據用戶的需求增長一些由 Uber AI 實驗室新開發的模型。此外,用戶也能夠本身提供模型類型,包括自定義訓練、評價以及提供服務的代碼。分佈式模型訓練系統能夠規模化處理數十億的樣本數據,也能夠處理一些小數據集進行快速迭代。
一個模型的配置包括模型類型、超參、數據源、特徵 DSL,以及計算資源需求(須要的機器數量、內存用量、是否使用 GPU 等)。這些信息將用於配置運行在 YARN 或 Mesos 集羣上的訓練做業。
在模型訓練完畢以後,系統會將其計算獲得的性能指標(例如 ROC 曲線和 PR 曲線)進行組合,獲得一個模型評價報告。在訓練結束時,系統會將原始配置、學習到的參數以及評價包括存回模型庫,用於分析與部署。
除了訓練單個模型以外,米開朗基羅系統還支持對分塊模型等各類模型進行超參搜索。以分塊模型爲例,以分塊模型爲例,系統會根據用戶配置自動對訓練數據進行分塊,對每一個分塊訓練一個模型;在有須要的時候再將各個分塊模型合併到父模型中(例如,先對每一個城市數據進行訓練,若是沒法獲得準確的市級模型時再將其合併爲國家級模型)。
訓練做業能夠經過 Web UI 或者 API 進行配置與管理(一般使用 Jupyter notebook)。大多數團隊都使用 API 以及流程管理工具來對他們的模型進行按期重訓練。
圖 3:模型訓練做業使用特徵庫與數據訓練倉庫中的數據集來訓練模型,接着將模型存入模型庫中。
訓練模型能夠當作是一種尋找最佳特徵、算法、超參以針對問題創建最佳模型的探索過程。在獲得用例的理想模型前,訓練數百種模型而一無所得也是常有的事。雖然這些失敗的模型最終不能用於生產,但它們能夠指導工程師們更好地進行模型配置,從而得到更好的性能。追蹤這些訓練過的模型(例如誰、什麼時候訓練了它們,用了什麼數據集、什麼超參等),對它們的性能進行評估、互相對比,能夠爲平臺帶來更多的價值與機會。不過要處理如此之多的模型,也是一個極大的挑戰。
米開朗基羅平臺中訓練的每一個模型都須要將如下信息做爲版本對象存儲在 Cassandra 的模型庫中:
用戶能夠經過 Web UI 或者使用 API 輕鬆獲取這些數據,用以檢查單個模型的詳細狀況或者對多個模型進行比較。
迴歸模型的準確率報告會展現標準的準確率指標與圖表;分類模型的準確率報告則會展現不一樣的分類集合,如圖 4 圖 5 所示:
圖 4:迴歸模型的報告展現了與迴歸相關的性能指標。
圖 5:二分類模型報告展現了分類相關的性能指標。
決策樹做爲一種重要的模型類型,工程師們爲其提供了可視化工具,以幫助建模者更好地理解模型的行爲原理,並在建模者須要時幫助其進行調試。例如在一個決策樹模型中,用戶能夠瀏覽每一個樹分支,看到其對於總體模型的重要程度、決策分割點、每一個特徵對於某個特定分支的權重,以及每一個分支上的數據分佈等變量。用戶能夠輸入一個特徵值,可視化組件將會遍歷整個決策樹的觸發路徑、每一個樹的預測、整個模型的預測,將數據展現成相似下圖的樣子:
圖 6:使用強大的樹可視化組件查看樹模型。
米開朗基羅提供了特徵報告,在報告中使用局部依賴圖以及混合直方圖展現了各個特徵對於模型的重要性。選中兩個特徵可讓用戶看到它們之間相互的局部依賴圖表,以下所示:
圖 7:在特徵報告中能夠看到的特徵、對模型的重要性以及不一樣特徵間的相關性。
米開朗基羅支持使用 UI 或 API 端對端管理模型的部署。一個模型能夠有下面三種部署方式:
圖 8:模型庫中的模型部署於在線及離線容器中用於提供服務。
上面全部狀況中,所須要的模型組件(包括元數據文件、模型參數文件以及編譯好的 DSL)都將被打包爲 ZIP 文件,使用 Uber 的標準代碼部署架構將其複製到 Uber 數據中心的相關數據上。預測服務容器將會從磁盤自動加載新模型,並自動開始處理預測請求。
許多團隊都本身寫了自動化腳本,使用米開朗基羅 API 進行通常模型的按期再訓練及部署。例如 UberEATS 的送餐時間預測模型就由數據科學家和工程師經過 Web UI 控制進行訓練與部署。
一旦模型部署於服務容器並加載成功,它就能夠開始用於對數據管道傳來的特徵數據或用戶端發來的數據進行預測。原始特徵將經過編譯好的 DSL 傳遞,若有須要也能夠對 DSL 進行修改以改進原始特徵,或者從特徵存儲庫中拉取一些額外的特徵。最終構造出的特徵向量會傳遞給模型進行評分。若是模型爲在線模型,預測結果將經過網絡傳回給客戶端。若是模型爲離線模型,預測結果將被寫回 Hive,以後能夠經過下游的批處理做業或者直接使用 SQL 查詢傳遞給用戶,以下所示:
圖 9:在線預測服務及離線預測服務使用一組特徵向量生成預測結果。
在米開朗基羅平臺中能夠同時向服務容器部署多個模型。這也使得從舊模型向新模型進行無痛遷移以及對模型進行 A/B 測試成爲可能。在服務中,能夠由模型的 UUID 以及一個在部署時可指定的 tag(或者別名)識別不一樣的模型。以一個在線模型爲例,客戶端服務會將特徵向量與須要使用的模型 UUID 或者 tag 同時發送給服務容器;若是使用的是 tag,服務容器會使用此 tag 對應的最新部署的模型進行預測。若是使用的是多個模型,全部對應的模型都將對各批次的數據進行預測,並將 UUID 和 tag 與預測結果一同傳回,方便客戶端進行篩選過濾。
若是在部署一個新模型替換舊模型時用了相同的事物(例如用了一些一樣的特徵),用戶能夠爲新模型設置和舊模型同樣的 tag,這樣容器就會當即開始使用新模型。這可讓用戶只須要更新模型,而不用去修改他們的客戶端代碼。用戶也能夠經過設置 UUID 來部署新模型,再將客戶端或中間件配置中舊模型的 UUID 換成新的,逐步將流量切換到新模型去。
若是須要對模型進行 A/B 測試,用戶能夠經過 UUID 或者 tag 輕鬆地部署競爭模型,再使用客戶端服務中的 Uber 實驗框架將部分流量導至各個模型,再對性能指標進行評估。
因爲機器學習模型是無狀態的,且不須要共享任何東西,所以,不管是在線模式仍是離線模式下對它們進行規模縮放都是一件垂手可得的事情。若是是在線模型,工程師能夠簡單地給預測服務集羣增長機器,使用負載均衡器分攤負載。若是是離線預測,工程師能夠給 Spark 設置更多的 executor,讓 Spark 進行並行管理。
在線服務的延遲取決於模型的類型與複雜度以及是否使用從 Cassandra 特徵庫中取出的特徵。在模型不須要從 Cassandra 取特徵的狀況下,P95 測試延遲小於 5 毫秒。在須要從 Cassandra 取特徵時,P95 測試延遲仍小於 10 毫秒。目前用量最大的模型每秒能提供超過 250000 次預測。
當模型訓練完成並完成評價以後,使用的數據都將是歷史數據。監控模型的預測狀況,是確保其在將來正常工做的重要保障。工程師須要確保數據管道傳入的是正確的數據,而且生產環境沒有發生變化,這樣模型纔可以進行準確的預測。
爲了解決這個問題,米開朗基羅系統會自動記錄並將部分預測結果加入到數據 pipeline 的標籤中去,有了這些信息,就能獲得持續的、實時的模型精確度指標。在迴歸模型中,會將 R^2/決定係數、均方根對數偏差(RMSLE)、均方根偏差(RMSE)以及平均絕對值偏差發佈至 Uber 的實時監控系統中,用戶能夠分析指標與時間關係的圖標,並設置閾值告警:
圖 10:對預測結果進行採樣,與觀測結果進行比較獲得模型準確指標。
米開朗基羅系統的最後一個重要部分就是 API 層了,它也是整個系統的大腦。API 層包含一個管理應用,提供了 Web UI 以及網絡 API 兩種訪問方式,並與 Uber 的監控、報警系統相結合。同時該層還包含了用於管理批量數據管道、訓練做業、批量預測做業、模型批量部署以及在線容器的工做流系統。
米開朗基羅的用戶能夠經過 Web UI、REST API 以及監控、管理工具直接與這些組件進行交互。
工程師們打算在接下來幾個月繼續擴展與增強現有的系統,以支持不斷增加的用戶和 Uber 的業務。隨着米開朗基羅平臺各個層次的不斷成熟,他們計劃開發更高層的工具與服務,以推進機器學習在公司內部的發展,更好地支持商業業務:
若是你對挑戰規模化機器學習有興趣,歡迎申請Uber 機器學習平臺團隊 !
做者簡介:Jeremy Hermann 是 Uber 機器學習平臺團隊的工程經理,Mike Del Balso 是 Uber 機器學習平臺團隊的產品經理。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、React、前端、後端、產品、設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。