Alink漫談(一) : 從KMeans演算法實現不同看Alink設計思想
阿新 • • 發佈:2020-05-05
# Alink漫談(一) : 從KMeans演算法實現不同看Alink設計思想
[TOC]
## 0x00 摘要
Alink 是阿里巴巴基於實時計算引擎 Flink 研發的新一代機器學習演算法平臺,是業界首個同時支援批式演算法、流式演算法的機器學習平臺。本文將帶領大家從多重角度出發來分析推測Alink的設計思路。
因為Alink的公開資料太少,所以以下均為自行揣測,肯定會有疏漏錯誤,希望大家指出,我會隨時更新。
## 0x01 Flink 是什麼
**Apache Flink**是由Apache軟體基金會開發的開源流處理框架,它通過實現了 Google Dataflow 流式計算模型實現了高吞吐、低延遲、高效能兼具實時流式計算框架。
其核心是用Java和Scala編寫的分散式流資料流引擎。Flink以資料並行和流水線方式執行任意流資料程式,Flink的流水線執行時系統可以執行批處理和流處理程式。此外,Flink的執行時本身也支援迭代演算法的執行。
## 0x02 Alink 是什麼
Alink 是阿里巴巴計算平臺事業部PAI團隊從2017年開始基於實時計算引擎 Flink 研發的新一代機器學習演算法平臺,提供豐富的演算法元件庫和便捷的操作框架,開發者可以一鍵搭建覆蓋資料處理、特徵工程、模型訓練、模型預測的演算法模型開發全流程。專案之所以定為Alink,是取自相關名稱(Alibaba, Algorithm, AI, Flink, Blink)的公共部分。
藉助Flink在批流一體化方面的優勢,Alink能夠為批流任務提供一致性的操作。在2017年初,阿里團隊通過調研團隊看到了Flink在批流一體化方面的優勢及底層引擎的優秀效能,於是基於Flink重新設計研發了機器學習演算法庫,即Alink平臺。該平臺於2018年在阿里集團內部上線,隨後不斷改進完善,在阿里內部錯綜複雜的業務場景中鍛鍊成長。
## 0x03 Alink設計思路
因為目前關於Alink設計的公開資料比較少,我們手頭只有其原始碼,看起來只能從程式碼反推。但是世界上的事物都不是孤立的,我們還有其他角度來幫助我們判斷推理。所以下面就讓我們來進行推斷。
### 1. 白手起家
FlinkML 是 Flink 社群現存的一套機器學習演算法庫,這一套演算法庫已經存在很久而且更新比較緩慢。
Alink團隊起初面臨的抉擇是:是否要基於 Flink ML 進行開發,或者對 Flink ML進行更新。
經過研究,Alink團隊發現,Flink ML 其僅支援10餘種演算法,支援的資料結構也不夠通用,在演算法效能方面做的優化也比較少,而且其程式碼也很久沒有更新。所以,他們放棄了基於舊版FlinkML進行改進、升級的想法,決定基於Flink重新設計研發機器學習演算法庫。
所以我們要分析的就是如何從無到有設計出一個新的機器學習平臺/框架 。
### 2. 替代品如何造成威脅
因為Alink是市場的新進入者,所以Alink的最大問題就是如何替代市場上的現有產品。
邁克爾·波特用 “*替代品威脅*” 來解釋使用者的整個替代邏輯,當新產品能牢牢掌握住這一點,就有可能在市場上獲得非常好的表現,打敗競爭對手。
假如現在想從0到1構建一個機器學習庫或者機器學習框架,那麼我們需要從商業意識和商業邏輯出發,來思考這個產品的價值所在,就能對這個產品做個比較精確的定義,從而能夠確定產品路線。
產品需要解決應用環境下的綜合性問題,產品的價值體現,可以分拆了三個維度。
- **使用者的角度**:價值體現在使用者使用,獲取產品的意願。這個就是換用成本的問題,一旦換用成本過高,這個產品就很難成功。
- **競爭對手的角度**: 產品的競爭力,最終都體現為使用者為了獲取該產品願意支付的最高成本上限,當一個替代品進入市場,必須有能給使用者足夠的洞理驅使使用者換用替代品。
- **企業的角度**:站在企業的角度,實際就是成本結構和收益的規模性問題 。
下面就讓我們逐一分析。
### 3. 使用者角度看設計
這個就是換用成本的問題 ,一旦換用成本過高,這個產品就很難成功。
Alink大略有兩種使用者:演算法工程師,應用工程師。
Alink演算法工程師特指實現機器學習演算法的工程師。Alink應用工程師就是應用Alink AI演算法做業務的工程師。這兩類使用者的換用成本都是Alink需要考慮的。
新產品對於使用者來說,有兩個大的問題:產品底層邏輯和開發工具。一個優秀的新產品絕對不能在這兩個問題上增加使用者的換用成本。
#### 底層邏輯Flink
Flink這個平臺博大精深,無論是熟悉其API還是深入理解系統架構都不是容易的事情。如果Alink使用者還需要熟悉Flink,那勢必造成ALink使用者的換用成本,所以這點應該儘量避免。
- 對於演算法工程師,他們應該主要把思路集中在演算法上,而儘量不用關心Flink內部的細節,如果一定要熟悉Flink,那麼越少越好;
- 對於應用工程師,他們主要的需求就是API介面越簡單越好,他們最理想的狀態應該是:完全感覺不到Flink的存在。
綜上所述,**Alink的原則之一應該是 :演算法的歸演算法,Flink的歸Flink,儘量遮蔽AI演算法和Flink之間的聯絡** 。
#### 開發工具
開發工具就是究竟用什麼語言開發。Flink的開發語言主要是JAVA,SCALA,Python。而機器學習世界中主要還是Python。
- 首先要排除SCALA。因為Scala 是一門很難掌握的語言,它的規則是基於數學型別理論的,學習曲線相當陡峭。一個能夠領會規則和語言特性的優秀程式設計師,使用 Scala 會比使用 Java 更高效,但是一個普通程式設計師的生產力,從功能實現上來看,效率則會相反。
讓我們看看基於Flink的原生KMeans SCALA程式碼,很多人看了之後恐怕都會懵圈。
```scala
val finalCentroids = centroids.iterate(params.getInt("iterations", 10)) { currentCentroids => val newCentroids = points
.map(new SelectNearestCenter).withBroadcastSet(currentCentroids, "centroids")
.map { x => (x._1, x._2, 1L) }.withForwardedFields("_1; _2")
.groupBy(0)
.reduce { (p1, p2) => (p1._1, p1._2.add(p2._2), p1._3 + p2._3) }.withForwardedFields("_1")
.map { x => new Centroid(x._1, x._2.div(x._3)) }.withForwardedFields("_1->id")
newCentroids
}
```
- 其次是選擇JAVA還是Python開發具體演算法。Alink內部肯定進行了很多權宜和抉擇。因為這個不單單是哪個語言本身更合適,也涉及到Alink團隊內部有哪些資源,比如是JAVA工程師更多還是Python更多。最終Alink選擇了JAVA來開發演算法。
- 最後是API。這個就沒有什麼疑問了,Alink提供了Python和JAVA兩種語言的API,直接可參見GitHub的介紹。
> 在 PyAlink 中,演算法元件提供的介面基本與 Java API 一致,即通過預設構造方法建立一個演算法元件,然後通過 `setXXX` 設定引數,通過 `link/linkTo/linkFrom` 與其他元件相連。 這裡利用 Jupyter 的自動補全機制可以提供書寫便利。
另外,如果採用JAVA或者Python,肯定有大量現有程式碼可以修改複用。如果採用SCALA,就難以複用之前的積累。
綜上所述,**Alink的原則之一應該是 :採用最簡單,最常見的開發語言和設計思維**。
### 4. 競爭對手角度看設計
Alink的競爭對手大略可以認為是Spark ML, Flink ML, *Scikit*-learn。
他們是市場上的現有力量,擁有大量的使用者。使用者已經熟悉了這些競爭對手的設計思路,開發策略,基本概念和API。除非Alink能夠提供一種神奇簡便的API,否則Alink應該在設計上最大程度借鑑這些競爭對手。
比如機器學習開發中有如下常見概念:Transformer,Estimator,PipeLine,Parameter。這些概念 Alink 應該儘量提供。
綜上所述,**Alink的原則之一應該是 :儘量借鑑市面上通用的設計思路和開發模式,讓開發者無縫切換 **。
從 Alink的目錄結構中 ,我們可以看出,Alink確實提供了這些常見概念。
比如 Pipeline,Trainer,Model,Estimator。我們會在後續文章中再詳細介紹這些概念。
```java
./java/com/alibaba/alink:
common operator params pipeline
./java/com/alibaba/alink/params:
associationrule evaluation nlp regression statistics
classification feature onlinelearning shared tuning
clustering io outlier similarity udf
dataproc mapper recommendation sql validators
./java/com/alibaba/alink/pipeline:
EstimatorBase.java ModelBase.java Trainer.java feature
LocalPredictable.java ModelExporterUtils.java TransformerBase.java nlp
LocalPredictor.java Pipeline.java classification recommendation
MapModel.java PipelineModel.java clustering regression
MapTransformer.java PipelineStageBase.java dataproc tuning
```
### 5. 企業角度看設計
這是成本結構和收益的規模性問題。從而決定了Alink在開發時候,必須儘量提高開發工程師的效率,提高生產力。前面提到的棄用SCALA,部分也出於這個考慮。
**挑戰集中在:**
- 如何在對開發者最大程度遮蔽Flink的情況下,依然利用好Flink的各種能力。
- 如何構建一套相應打法和戰術體系,即middleware或者adapter,讓使用者基於此可以快速開發演算法
舉個例子:
- 肯定有個別開發者,其對Flink特別熟悉,他們可以運用各種Flink API和函式程式設計思維開發出高效率的演算法。這種開發者,我們可以稱為是武松武都頭。他們類似特種兵,能上戰場衝鋒陷陣,也能吊打白額大蟲。
- 但是絕大多數開發者對Flink不熟悉,他們更熟悉AI演算法和指令式程式設計思路。這種開發者我們可以認為他們屬於八十萬禁軍或者是玄甲軍,北府兵,魏武卒,背嵬軍。這種才是實際開發中的主力部隊和常規套路。
我們需要針對八十萬禁軍,讓林沖林教頭設計出一套適合正規作戰的槍棒打法。或者針對背嵬軍,讓岳飛嶽元帥設計一套馬軍衝陣機制。
因此,**Alink的原則之一應該是 :構建一套戰術打法(middleware或者adapter),即遮蔽了Flink,又可以利用好Flink,還可以讓使用者基於此可以快速開發演算法 **。
我們想想看大概有哪些基礎工作需要做:
- 如何初始化
- 如果通訊
- 如何分割程式碼,如何廣播程式碼
- 如果分割資料,如何廣播資料
- 如何迭代演算法
- ......
讓我們看看Alink做了哪些努力,這點從其目錄結構可以看出有queue,operator,mapper等等構建架構所必須的資料結構:
```java
./java/com/alibaba/alink/common:
MLEnvironment.java linalg MLEnvironmentFactory.java mapper
VectorTypes.java model comqueue utils io
./java/com/alibaba/alink/operator:
AlgoOperator.java common batch stream
```
其中最重要的概念是BaseComQueue,這是把通訊或者計算抽象成ComQueueItem,然後把ComQueueItem串聯起來形成佇列。這樣就形成了面向迭代計算場景的一套迭代通訊計算框架。其他資料結構大多是圍繞著BaseComQueue來具體運作。
```java
/**
* Base class for the com(Computation && Communicate) queue.
*/
public class BaseComQueue
> implements Serializable { /** * All computation or communication functions. */ private final