天天看點

分布式計算引擎—Ray SGD 設計原理及核心實作

點選 

分布式計算引擎—Ray SGD 設計原理及核心實作

現如今,随着深度模型的增大,隻在單節點上進行模型訓練,将會花費數天甚至數周的時間,基于此,Ray 社群提出基于 Ray 實作一個分布式訓練包裝器,也就是 Ray SGD,Ray SGD具備如下特點:

分布式計算引擎—Ray SGD 設計原理及核心實作
分布式計算引擎—Ray SGD 設計原理及核心實作

上面介紹到,Ray SGD是一個分布式訓練包裝器,主要對深度學習架構Tensorflow、Pytorch進行包裝,通過num_workers參數 來控制Ray節點的副本,每個副本由Ray Actor進行管理。通過下面這張圖可以看出Ray SGD的架構。

分布式計算引擎—Ray SGD 設計原理及核心實作

由于是對Tensorflow 和Pytorch 進行包裝,下面我們來看一下具體的使用規則:

分布式計算引擎—Ray SGD 設計原理及核心實作

如上圖所示:RaySGD對Tensoflow 或者Pytorch進行分布式訓練時,包含以下幾個步驟:

1、導入依賴子產品;

2、由于Ray SGD子產品依賴于Ray Core子產品,是以在訓練時,必須啟動Ray,執行圖上步驟1.

3、以Pytorch為例,RaySGD在訓練時,主要包裝了一個TorchTrainer類,在這個包裝類裡面執行了圖上步驟2, 導入資料,建立模型,對模型配置損失函數等,注冊模型,加載資料等步驟,然後将其封裝成一個類,傳給TorchTrainer類。

4、執行圖上步驟3,通過num_works 指定副本數量,是否使用GPU,每個batch_size的大小

5、執行trainer.train()方法進行訓練。

RaySGD對Tensorflow和Pytorch分布式訓練時就如上述步驟一樣 ,特别簡單!

分布式計算引擎—Ray SGD 設計原理及核心實作

下面我們通過分布式tensorflow案例來分析源碼是如何設計的,案例如下:

(1)導入依賴子產品

分布式計算引擎—Ray SGD 設計原理及核心實作

       (2)指定batch_size大小

分布式計算引擎—Ray SGD 設計原理及核心實作

(3)加載資料,注冊訓練集和測試集

分布式計算引擎—Ray SGD 設計原理及核心實作

(4)定義模型,配置損失函數

分布式計算引擎—Ray SGD 設計原理及核心實作

(5)使用raySGD 對tensorflow的包裝類 TFTrainer,進行訓練

分布式計算引擎—Ray SGD 設計原理及核心實作
分布式計算引擎—Ray SGD 設計原理及核心實作

通過上述案例,我們可以看出,包裝類是TFTrainer,将模型,資料、batch_size大小,以及副本數傳進去,調用train()方法進行訓練即可。是以現在通過源碼,我們分析一下,RaySGD是如何封裝Tensorflow的。

通過github連結通路Ray-master源碼:https://github.com/ray-project/ray,通過定位,分布式RaySGD-Tensorflow源碼位置如下:

分布式計算引擎—Ray SGD 設計原理及核心實作

關系圖如下:

分布式計算引擎—Ray SGD 設計原理及核心實作
分布式計算引擎—Ray SGD 設計原理及核心實作
分布式計算引擎—Ray SGD 設計原理及核心實作

從源碼中可以看出TFTrainer是一個Tensorflow 訓練類,其中定義了許多參數:

(1)model_creater: 接受一個字典類型的配置,傳回一個TF 模型;

(2)data_creator: 使用配置建立訓練集和驗證集;

(3)config:用來定義batch_size的大小,将其傳入data_creator,model_creater;

(4)num_replicas: 用于分布式訓練 worker的數量;

(5)num_cpus_per_worker: 每個worker請求的cpu個數。

并且根據num_replicas的設定進行許多方法的定義。

(1)worker 數的啟動邏輯判斷

分布式計算引擎—Ray SGD 設計原理及核心實作

從上圖中我們可以看到,TFTrainer源碼對num_replicas進行了邏輯判斷,當等于1時,ray遠端調用remote,啟動1個worker,當不等于1時,根據實際的數量啟動相應的worker數,進行分布式計算。

(2)train方法

TFTrainer類中,定義了多個方法,包含train()、validate()、get_model()、save()、restore()、shutdown()、get_model_from_state()等方法,這裡以train()進行分析,其他大緻相同。

分布式計算引擎—Ray SGD 設計原理及核心實作

從代碼中可以看出,w.step.remote() for w in self.workers 這句是通過設定的worker數量擷取到所有的ObjectRef,如不懂objectRef, 可觀看之前釋出的博文進行了解ObjectRef,然後通過ray.get擷取到所有的Object對象,将第一個Object對象進行複制進行傳回。得到stats.  其中w.step中的step在TFRunner中講解。

分布式計算引擎—Ray SGD 設計原理及核心實作
分布式計算引擎—Ray SGD 設計原理及核心實作

通過上述源碼可以看出,TFRunner用于管理訓練的Tensorflow模型,其中傳入的參數全部是 上述TFTrainer定義好的變量,并且也定義了許多方法,講解一下step方法,因為上文用到了。

分布式計算引擎—Ray SGD 設計原理及核心實作
分布式計算引擎—Ray SGD 設計原理及核心實作

其中verbose表示輸出的訓練資料,重點在于self.model.fit, 從這句代碼就可以知道,我們在Tensorflow案例中定義的model_create方法最終會調用tensorflow的fit方法對模型進行訓練。

分布式計算引擎—Ray SGD 設計原理及核心實作

(1)TFMLDataset類介紹

分布式計算引擎—Ray SGD 設計原理及核心實作

通過這個類可以得到許多資訊,首先Ray SGD進行訓練的資料結構為MLdataset,而TensorFlow 訓練的資料結構為TFMLdataset,是以在使用TFTrainer進行訓練時,需要将MLdataset轉為TFMLdataset。其次,在轉換過程中,需要指定特征列和目标列,最後傳回一個ds。

(2)擷取分片,傳回所有的Tensorflow 分片資料

分布式計算引擎—Ray SGD 設計原理及核心實作
分布式計算引擎—Ray SGD 設計原理及核心實作

set_num_shards()方法:

在轉換成ds後,需要判斷ds的分片數量是否和指定的分片數量相同,若不同,重新分區,傳回一個指定數量的dataset,如圖1。

get_shard()方法

圖2中it 表示 所有的分片dataset。

make_generator()方法 在 get_shard()方法裡面

圖3表示對所有的分片dataset進行周遊,拿到一個分片資料,圖4表示 拿到一個分片資料的所有特征列,圖5表示拿到一個分片資料的特征列,通過圖6進行遞歸調用make_generator 來傳回一個被給的tensorflow 分片資料來供tensorflow進行訓練。

上述已将所有的源碼進行分析,現在将整個流程進行串通起來:

(1)當執行Tensorflow案例的Trainer.train()方法後,

(2)train()會根據 設定的worker數量去擷取所有的stats對象,在擷取時,會調用TFRunner類中的step方法;

(3)在step 方法中會調用model.fit方法進行模型訓練,傳入的參數為train_dataset

(4)由于train_dataset為tensorflow的資料結構,而RaySGD的資料結構為MLDataset,是以需要調用TFMLDataset類将MLDataset轉為TFMLDataset,即最後get_shard傳回的df。

繼續閱讀