初窺Ray框架

隨著各行各業數字化的不斷推進,AI需要處理的資料越來越多,單一伺服器已經難以滿足當前產業的發展需求,伺服器叢集成為企業用AI處理資料的標配硬體,而分散式計算成為人工智慧應用的標配軟體。

從圖1可以看出,現今有很多開源的分散式計算框架,從模型的訓練、調參到部署;從NLP、CV到RS;這些框架覆蓋到了AI產業生命週期的各個方面。本文就選取其中的Ray框架進行簡單的介紹。

初窺Ray框架

圖1。 各種分散式計算框架

Ray 是伯克利大學在2017年開源的

分散式計算框架

,對應的論文是《Ray: A Distributed Framework for Emerging AI Applications》。強化學習任務需要與環境進行大量的互動(毫秒級),且在時間上支援異構性。該框架專門為機器學習與強化學習設計,相較於其他框架,ray具有以下優勢:

輕量級

可快速構建

通用性強

效能優異

下面就這四個優點為大家進行詳細介紹。

1。 Ray框架的優勢

1。1 輕量級

相較於傳統的分散式框架(尤其是hadoop、spark等),Ray可以直接透過pip進行安裝,且對系統版本無要求。

pip install -U ray

Ray是一個簡單的分散式策略,而非完整的生態,因而不需要複雜的構建。

另一方面,輕量而優秀的框架往往可以作為企業資料處理的基礎框架,企業不斷在該框架的基礎上增加生態,從而形成企業獨有的應用生態。

1。2 可快速構建

如hadoop等傳統框架,要對原有的單機程式進行分散式化,需要修改整個程式碼邏輯,以MapReduce的程式設計方案重構各個計算模組,這使得hadoop等傳統框架有著良好的可編輯性,演算法工程師可以根據業務需求進行詳細的修改。強大的可編輯性也帶來了學習成本高,程式碼重構困難等諸多問題。人工智慧日新月異,模型在不斷更迭,敏捷開發成為了很多AI企業的開發模式,AI應用的複雜構建會大大影響整個專案的推進。

如下程式碼,將一個簡單的單機程式函式,轉換為Ray分散式的函式,只是在原有函式的基礎上加入了ray。remote的裝飾器,便完成了分散式化的工作。

### 原始單機程式碼def f(x):    return x * xfutures = [f。remote(i) for i in range(4)]print(ray。get(futures))### Ray分散式程式碼import rayray。init()@ray。remotedef f(x):    return x * xfutures = [f。remote(i) for i in range(4)]print(ray。get(futures))

1。3 通用性強

近年tensorflow、torch等深度學習框架成為人工智慧應用的模型框架,考慮到產業應用場景,這些框架都給出了各自分散式訓練和部署的方案,且這些方案的計算資源利用率較高。大型的專案往往由數個演算法模型組成,為了快速開發,演算法工程師往往採用開源的程式碼構建,而這些開源的程式碼採用的深度學習框架很可能互不相同,針對單一框架的分散式方案難以適用。

除此之外,ONNIX等為代表的框架,傾向於將所有框架的模型統一到單一的解決方案上,由於很多前沿的深度學習模型對神經元進行了複雜的修改,無法適配到通用的運算元上,需要演算法工程師手寫運算元,從而拖慢了開發速度。Ray將機器學習模型、numpy資料計算、單一的函式抽象成通用的計算,實現了對各種深度學習框架、機器學習框架的適配。

另外,Ray對強化學習的應用進行了專門的生態構建。

1。4 效能優異

圖2為Ray、Horovod以及tensorflow原生的分散式方案訓練ResNet-101模型的比較,縱軸為每秒平均迭代的圖片數,可以看出Ray略微優於Horovod框架。

初窺Ray框架

圖2。 分散式訓練速度比較

圖3為Clipper和Ray在模型呼叫上吞吐量的比較,兩者均用同一網路模型,可以看出Ray優於Clipper。

初窺Ray框架

圖3。 分散式部署吞吐量比較

Ray並沒有做到每個分散式場景都優於其他框架,但Ray集合訓練、調參以及部署為一體,仍能保持不錯的效能,因而值得學習和使用。

得益於Ray框架良好的效能,Ray廣泛用於工業界(如螞蟻金服),要先學會使用Ray必先了解Ray的構成,下一小節就Ray的構成進行介紹。

2。 Ray的使用

2。1 Ray的構成

Ray大致由四部分組成:

Tune: 超引數調整模組

RLlib: 強化學習模組

RaySGD: 分散式訓練模組

Ray Serve: 應用服務部署模組

Ray涉及了AI應用的整個生命週期:訓練、調參、部署,並對強化學習場景進行了專門的最佳化。由於個人使用經驗有限,這裡只介紹Ray的Serve模組。

2。2 Ray的啟動

如圖4,Ray由一個

頭節點

(Head node)和一組

工作節點

(Worker node)組成。啟動Ray需要首先啟動頭節點,併為工作節點提供頭節點的地址以形成叢集。頭節點負責管理和分配工作節點的任務,工作節點負責執行任務並返回結果。經過測試,頭節點和工作節點可以為同一臺計算機。

Ray的啟動由兩個步驟組成:啟動頭節點、註冊工作節點到頭節點。

初窺Ray框架

圖4。 Ray節點示意圖

以下是頭節點的啟動程式碼和關閉程式碼。

import rayray。init()  # 啟動assert ray。is_initialized() == Trueray。shutdown()  # 關閉assert ray。is_initialized() == False

注:啟動指令碼應當加入關閉程式碼,如果沒有,ray程式可能一直在程序中執行。

Ray框架採用Actor模型,相較於傳統的共享記憶體模型,Ray不存在狀態競爭、可以方便的組建叢集、能更好的控制狀態。每個Actor即每個工作節點的註冊方式如下。

import rayray。init(address=頭節點地址)  # 啟動assert ray。is_initialized() == Trueray。shutdown()  # 關閉assert ray。is_initialized() == False

2。3 Ray Serve

Ray Serve可以類比clipper,主要用於模型的部署服務,並支援多種深度學習框架,官方給出的示例有:

Keras and Tensorflow Tutorial

PyTorch Tutorial

Scikit-Learn Tutorial

這裡以tensorflow2為例,來說一下如何用ray來部署模型服務。

步驟一:定義一個模型服務類

如下是模型服務類的簡易程式碼,和Flask等框架部署AI服務類似。由於Ray使用gRPC作為通訊協議,速度更快,Ray還在gRPC基礎上進行了最佳化,有些場景快於原生的gRPC通訊。

class TFMnistModel:    def __init__(self, model_path):        import tensorflow as tf        self。model_path = model_path        # 載入模型        self。model = tf。keras。models。load_model(model_path)    async def __call__(self, starlette_request):  # 非同步呼叫        # transform HTTP request -> tensorflow input        input_array = np。array((await starlette_request。json())[“array”])        reshaped_array = input_array。reshape((1, 28, 28))        #  tensorflow input -> tensorflow output        prediction = self。model(reshaped_array)        # 返回結果        #  tensorflow output -> web output          return {            “prediction”: prediction。numpy()。tolist(),            “file”: self。model_path        }

步驟二:模型部署到Ray Serve

如下程式碼中,start函式用於啟動服務,create_backend函式用於啟動模型,create_endpoint函式啟動服務。在Ray中,模型和服務是分離的,可以多個服務呼叫同一個模型,以支援複雜的呼叫邏輯。

“tf:v1”為模型的名稱,“tf_classifier”為服務的名稱,route引數為路由,這些引數都可自由定義。

client = serve。start()client。create_backend(“tf:v1”, TFMnistModel, TRAINED_MODEL_PATH)client。create_endpoint(“tf_classifier”, backend=“tf:v1”, route=“/mnist”)

步驟三:請求測試

resp = requests。get(    “http://localhost:8000/mnist”,    json={“array”: np。random。randn(28 * 28)。tolist()})print(resp。json())

3。 結語

一個優秀的框架往往包含了眾多先進的設計理念。Ray框架在構建時,參考了許多先進的設計理念,如混合排程策略、GCS 管理等等,這些設計理念使得框架本身完善而又先進。Ray廣泛用於AI企業的分散式計算場景,從眾多框架中脫穎而出,值得學習。

我們是行者AI,我們在“AI+遊戲”中不斷前行。

快來【公眾號 | xingzhe_ai】,和我們討論更多技術問題吧!