繼上次用 Horovod 做為 TensorFlow 分散式深度學習框架後,我這次如願改寫 PyTorch 了,雖然是另外一個案子…。
Horovod 使用
一樣直接拿著文件直接上了,大致可以分成 5 個步驟,這跟 TensorFlow Keras 倒是滿像的:
初始化
1 |
|
為每個節點設置一個 GPU
1 |
|
但,我記得官方不推薦用 set_device?
torch.cuda.set_device(device: Union[torch.device, str, int]) → None
Sets the current device. Usage of this function is discouraged in favor of device. In most cases it’s better to use CUDA_VISIBLE_DEVICES environmental variable.
另外在看 Horovod 所提供的兩隻範例程式碼(resnet50 與 mnist)的時候,發現在 set_device
之後後都會接著:
1 |
|
推測是因為每個節點在起網路的時候,初始值不盡相同,因此為了使初始值相同所以啟用了該值。
不過, 我想了一下,我只有在做分散式訓練的會希望所有網路擁有相同的初始值,所以我改了下程式,多點判斷式:
- 進行分散式訓練的時候。
- 由 master 統一設定。
1 |
|
依照分散的個數縮放 lr
文件範例這部分好像沒做,但上方的動作分解有。所以我按照之前做 TensorFlow Keras 的經驗直接用 lr 乘上節點個數。
1 |
|
後來在 resnet50 中有看到它們實做的學習率調整,看起來是做 warmup ,不過這部分我沒跟著調整了。
1 |
|
將 optimizer 包裝到 hvd.DistributedOptimizer 中
1 |
|
在這邊我遇到的問題是,我有是使用 scheduler 去 reduced learning rate 的部分。我有找到一條 issue,是在討論這個:
雖然它的狀態是 open,但是程式碼的部分有合併回去了,所以我參考他們測試用的程式碼,把 master 目前的 learning rate 取出後傳到其他節點,其他節點接收到後設定到自己的 optimizer 中。
1 |
|
5. Broadcast
最後廣播給其他節點。
1 |
|
資料集切分
最後是資料集切分,這邊我直接仿照上次的作法採用分 epochs 數的作法。
參考資料
- Horovod with PyTorch 。檢自 Horovod documentation (2020-09-14)。
- pytorch_imagenet_resnet50.py 。檢自 horovod/horovod | github (2020-09-14)。
- pytorch_mnist.py。檢自 horovod/horovod | github (2020-09-14)。
- lbin (2018-09-06)。Horovod, 分布式进阶。檢自 知乎 (2020-09-14)。
- 王晗 (2018-08-04)。torch.manual_seed(1)是干嘛用的? - 王晗的回答。檢自 知乎 (2020-09-14)。
- tgaddair (2019-08-07)。Add support for broadcasting learning rate scheduler in PyTorch · Issue #1281。檢自 horovod/horovod | github (2020-09-14)。
- Added PyTorch support for restoring optimizer state on model load and broadcast by tgaddair · Pull Request #371。檢自 horovod/horovod | github (2020-09-14)。
- test_torch.py。檢自 horovod/horovod | github (2020-09-14)。
更新紀錄
最後更新日期:2020-12-21
- 2020-12-21 發布
- 2020-09-14 完稿
- 2020-09-10 起稿