作者:秦江傑
去年 11 月的 Flink Forward Asia 2019(以下簡稱 FFA) 上 Flink 社群提出了未來發展的幾個主要方向,其中之一就是擁抱 AI [1]。實際上,近年來 AI 持續火熱,各種計算架構、模型和算法層出不窮,從某種角度上來說,這個賽道已經有些擁擠了。在這種情況下, Flink 将怎樣擁抱 AI,又會為使用者帶來什麼新的價值?Flink AI 的優劣勢分别在哪裡?本文将通過對這些問題的讨論來分析 Flink AI 的發展方向。
Lambda 架構,流批統一和 AI 實時化
Flink 在 AI 中的價值其實和大資料中 Lambda 架構[2]和流批統一這兩個概念有關系,Flink 為大資料實時化帶來的價值也将同樣使 AI 受益。
不妨讓我們簡單回顧一下大資料的發展過程。從 Google 奠基性的“三架馬車” 3[5] 論文發表後的很長一段時間内,大資料的發展主線上都隻有批計算的身影。後來随着大家認識到資料時效性的重要作用,Twitter 開源的流計算引擎 Storm [6] 紅極一時,各種流計算引擎也紛紛登場,其中也包括了 Flink。由于成本、計算準确性和容錯性等方面的考慮,各家企業紛紛使用起了被稱為 Lambda 架構的解決方案,在同一個架構下融合批計算和流計算,以便在成本,容錯和資料時效性之間達到一個平衡。
Lambda 架構在解決資料時效性的同時也存在一些問題,其中最受诟病的就是其系統複雜度和可維護性。使用者需要為 Batch Layer 和 Speed Layer 各維護一套引擎和代碼,還需要保證二者之間的計算邏輯完全一緻(圖1)。
圖1
為了解決這個問題,各個計算引擎不約而同的開始了流批統一的嘗試,試圖使用同一套引擎來執行流和批的任務(圖2)。經過若幹年的大浪淘沙,Spark [7] 和 Flink 成為了目前處于第一梯隊的兩款主流計算引擎。Flink 是從流計算逐漸進入到批計算,一個非常典型的成功案例就是使用同一套标準的 SQL 語句對流和批進行查詢,并保證最終結果一緻性[8]。而 Spark 則是采用微批 (Micro Batch) 的方式從批計算進入到流計算提出了 Spark Streaming,但是在時延的表現上始終遜色一些。
圖2
可以看到,在大資料的發展過程中,Lambda 架構和流批一體背後的原始驅動力是資料實時化。同樣是向資料要價值,AI 對資料時效性的要求同大資料是一緻的。是以AI實時化也将會是一個重要的發展方向。在觀察目前主流的 AI 場景和技術架構時,我們也會發現它們與大資料平台有很多聯系和相似之處。
目前的 AI 大緻可以分為資料預處理(也稱資料準備/特征工程等),模型訓練和推理預測三個主要階段。下面我們逐一來看一看在每個階段中 AI 實時化需求有哪些,又有什麼樣的問題待解決。為了便于與大資料的架構做類比,我們姑且認為流計算和批計算作為一種計算類型的劃分次元已經将所有基于資料的計算一分為二,沒有遺漏了。AI 的各個階段根據場景不同,也可以歸為二者之一。
資料預處理(資料準備/特征工程)
資料預處理階段是模型訓練和推理預測的前置環節,很多時候它更多的是一個大資料問題。根據資料預處理後的下遊不同,資料預處理可能是批計算也可能是流計算,計算類型和下遊一緻。在一個典型的離線訓練(批計算)和線上預測(流計算)場景下,訓練和預測時要求産生輸入資料的預處理邏輯是一緻的(比如相同的樣本拼接邏輯),這裡的需求和 Lambda 架構中的需求一樣,是以一個流批統一的引擎會格外有優勢。這樣可以避免批作業和流作業使用兩個不同的引擎,省去了維護邏輯一緻的兩套代碼的麻煩。
模型訓練
目前而言 AI 訓練階段基本上是批計算(離線訓練)産生靜态模型(Static Model)的過程。這是因為目前絕大多數的模型是基于獨立同分布(IID)的統計規律實作的,也就是從大量的訓練樣本中找到特征和标簽之間的統計相關性(Correlation),這些統計相關性通常不會突然變化,是以在一批樣本上訓練出的資料在另一批具有相同的特征分布的樣本上依然适用。然而這樣的離線模型訓練産生的靜态模型依然可能存在一些問題。
首先樣本資料可能随着時間推移會發生分布變化,這種情況下,線上預測的樣本分布和訓練樣本的分布會産生偏移,進而使模型預測的效果變差。是以靜态模型通常需要重新訓練,這可以是一個定期過程或者通過對樣本和模型的預測效果進行監控來實作(注意這裡的監控本身其實是一個典型的流計算需求)。
另外,在有些場景下,預測階段的樣本分布可能無法在訓練階段就知曉。舉例來說,在阿裡雙十一,微網誌熱搜,高頻交易等這類樣本分布可能發生無法預測的分布改變的場景下,如何迅速更新模型來得到更好的預測結果是十分有價值的。
是以一個理想的 AI 計算架構中,應該把如何及時更新模型納入考慮。在這方面流計算也有着一些獨特的優勢。事實上,阿裡巴巴在搜尋推薦系統中已經在使用線上機器學習,并且在雙十一這樣的場景下取得了良好的效果。
推理預測
推理預測環節的環境和計算類型比較豐富,既有批處理(離線預測)又有流處理。流式預測又大緻可以分為線上 (Online) 預測和近線 (Nearline) 預測。線上預測通常處于使用者通路的關鍵鍊路(Critical Path 中),是以對 latency 的要求極高,比如毫秒級。而近線預測要求略低一些,通常在亞秒級到秒級。目前大多數純流式分布式計算(Native Stream Processing)引擎可以滿足近線資料預處理和預測的需求,而線上資料預處理和預測則通常需要将預測代碼寫進應用程式内部來滿足極緻的低延遲要求。是以線上預測的場景也比較少看到大資料引擎的身影。在這方面 Flink 的 Stateful Function [9] 是一個獨特的創新,Stateful Function 的設計初衷是在 Flink 上通過若幹有狀态的函數來建構一個線上應用,通過它可以做到超低延遲的線上預測服務,這樣使用者可以在離線,近線和線上三種場景下使用同一套代碼同一個引擎來進行資料預處理和預測。
綜上所述,可以看到在機器學習的每個主要階段中對 AI 實時化都有重要的需求,那什麼樣的系統架構能夠有效滿足這樣的需求呢?
Flink 和 AI 實時化的架構
目前最典型的 AI 架構示例是離線訓練配合線上推理預測(圖3)。
圖3
正如之前提到的,這個架構存在兩個問題:
- 模型更新的周期通常比較長。
- 離線和線上的預處理可能需要維護兩套代碼。
為了解決第一個問題,我們需要引入一個實時訓練的鍊路(圖4)。
圖4
在這個鍊路中,線上的資料在用于推理預測之外還會實時生成樣本并用于線上模型訓練。在這個過程中,模型是動态更新的,是以可以更好的契合樣本發生的變化。
不論是純線上還是純離線的鍊路,都并非适合所有的 AI 場景。和 Lambda 的思想類似,我們可以把兩者結合(圖5)。
圖5
同樣的,為了解決系統複雜度和可運維性的問題(也就是上面提到的第二個問題),我們希望在資料預處理的部分用一個流批統一的引擎來避免維護兩套代碼(圖6)。不僅如此,我們還需要資料預處理和推理預測能夠支援離線,近線和線上的各種 Latency 要求,是以使用 Flink 是一個非常合适的選擇。尤其是對于資料預處理環節而言,Flink 在流和批上全面完整的 SQL 支援可以大大提高的開發效率。
圖6
除此之外,為了進一步降低系統的複雜度,Flink 也在模型訓練環節進行了一系列努力(圖7)。
- 流批一體算法庫 Alink
在去年的 FFA 2019 上,阿裡巴巴宣布開源了基于 Flink 的機器學習算法庫 Alink [10],并計劃将其逐漸貢獻回 Apache Flink,作為 Flink ML Lib 随 Apache Flink 釋出。除了離線學習的算法外,Alink 的一大特色就是為使用者提供了線上學習算法,助推 Flink 在 AI 實時化上發揮更大的作用。
- Deep Learning on Flink (flink-ai-extended [11])
幫助使用者把目前流行的深度學習架構(TensorFlow、PyTorch)整合到 Flink 中。使除了深度學習算法開發者之外的使用者可以基于 Flink 實作整套 AI 架構。
- 流批統一的疊代語義和高性能實作
AI 訓練中疊代收斂是一個最核心的計算過程。Flink 從一開始就使用了原生疊代的方式來保證疊代計算的效率。為了幫助使用者更好的開發算法,簡化代碼,進一步提高運作效率。Flink 社群也正在統一流和批上疊代的語義,同時對疊代性能進行更進一步的優化,新的優化将盡可能避免疊代輪次之間的同步開銷,允許不同批次的資料、不同輪次的疊代同時進行。
圖7
當然,在一個完整的 AI 架構中,除了以上提到的三個主要階段,還有很多其他工作需要完成,包括對各種資料源的對接,已有 AI 生态的對接,線上的模型和樣本監控和各類周邊配套支援系統等。阿裡巴巴實時計算負責人王峰(花名莫問)在 2019 年 FFA 的主題演講中的一張圖(圖8)很好的總結了其中許多工作。
圖8
Flink 社群也正在為此做出努力。大緻上來說,這些 AI 相關的工作可以分成補足,提高和創新三類。下面羅列了其中一部分進行中的工作,有些工作也許與 AI 不直接相關,但是卻會對 Flink 更好的服務于 AI 實時化産生影響。
補足:人有我無
- Flink ML Pipeline [12]:幫助使用者友善的存儲和複用一個機器學習的完整計算邏輯。
- Flink Python API(PyFlink [13]):Python 是 AI 的母語,PyFlink 為使用者提供 AI 中最重要的程式設計接口。
- Notebook Integration [14](Zeppelin):為使用者的 AI 實驗提供友好的 API。
- 原生 Kubernetes 支援 [15]:和 Kubernetes 內建來支援基于雲原生的的開發、部署和運維。
提高:人有我強
- Connector 的重新設計和優化 [16]:簡化 Connector 實作,擴大 Connector 生态。
創新:人無我有
- AI Flow:兼顧流計算的大資料 + AI 頂層工作流抽象和配套服務(即将開源)。
- Stateful Function[9]:提供堪比線上應用的超低延遲資料預處理和推理預測。
其中有些是 Flink 作為流行的大資料引擎的自有功能,比如豐富 Connector 生态來對接各種外部資料源。另一些則要依靠 Flink 之外的生态項目來完成,其中比較重要的是 AI Flow。它雖然起源于支援 AI 實時化架構,但是在引擎層并不綁定 Flink,而聚焦于頂層的流批統一工作流抽象,旨在為不同平台,不同引擎和不同系統共同服務于 AI 實時化的架構提供環境支援。由于篇幅關系在此不多贅述,将另文向大家介紹。
寫在最後
Apache Flink 從一個簡單的流計算想法開始,直到今天成長為一個業界流行的實時計算開源項目,使所有人受益,這個過程中離不開 Flink 社群中數以百計的代碼貢獻者和數以萬計的使用者。我們相信 Flink 在 AI 上也能夠有所作為,也歡迎更多的人能夠加入到 Flink 社群,同我們一起共創并共享 AI 實時化的價值。
Flink AI,未來可期。
參考資料:
[1]
https://ververica.cn/developers/the-number-of-github-stars-doubled-in-only-one-year/[MOU1][2]
https://en.wikipedia.org/wiki/Lambda_architecture[3]
https://static.googleusercontent.com/media/research.google.com/en//archive/gfs-sosp2003.pdf[4]
https://static.googleusercontent.com/media/research.google.com/en//archive/mapreduce-osdi04.pdf[5]
https://static.googleusercontent.com/media/research.google.com/en//archive/bigtable-osdi06.pdf[6]
https://storm.apache.org/[7]
https://spark.apache.org/[8]
https://ci.apache.org/projects/flink/flink-docs-release-1.10//dev/table/sql/index.html[9]
https://statefun.io/[10]
https://github.com/alibaba/alink[11]
https://github.com/alibaba/flink-ai-extended[12]
https://cwiki.apache.org/confluence/display/FLINK/FLIP-39+Flink+ML+pipeline+and+ML+libs[13]
https://ci.apache.org/projects/flink/flink-docs-release-1.10/tutorials/python_table_api.html[14]
https://mp.weixin.qq.com/s/a6Zau9c1ZWTSotl_dMg0Xg[15]
https://ci.apache.org/projects/flink/flink-docs-stable/ops/deployment/kubernetes.html[16]
https://cwiki.apache.org/confluence/display/FLINK/FLIP-27%3A+Refactor+Source+Interface