tensorflow nccl_op && 單機多卡 allreduce training


Tensorflow1.13.1中關於nccl的源碼位於:tensorflow\core\kernels\nccl_ops.cc;tensorflow\core\nccl\nccl_manager.cc其中核心代碼位於nccl_manager.cc文件,入口API為:AddToAllReduce

想要看懂這部分的代碼要首先理解nccl的原理和基本用法,建議參考NCCL官方文檔:https://docs.nvidia.com/deeplearning/sdk/nccl-developer-guide/docs/,文檔中有一些基本的使用examples,安裝nccl后可以寫簡單的例子進行實踐(安裝教程:https://github.com/NVIDIA/nccl),其中主要有兩種用法(除了結合MPI的例子):單線程多設備和多線程多設備.

其中多線程多設備的用法必須由應用程序控制好同步:

具體可能導致的問題參見:https://docs.nvidia.com/deeplearning/sdk/nccl-developer-guide/docs/troubleshooting.html#concurrency-between-nccl-and-cuda-calls-nccl-up-to-2-0-5-or-cuda-8https://github.com/NVIDIA/nccl/issues/217,而單進程的用法要加 ncclGroupStart() 和 ncclGroupEnd()標識一組collective操作.為什么要標識為一組?看過AllReduce等原理的應該不難理解~.

 

1.Tensorflow單機多卡AllReduce訓練:https://github.com/tensorflow/tensorflow/issues/22692

首先需要了解這個op的特點:

      tensorflow提供了調用nccl庫的python API,位於python\ops\nccl_ops.py文件下,函數名為:all_sum(allreduce操作中的一種),函數返回一個list tensor,與輸入list tensor分布在相同設備.比如輸入list=[gpu0_var0_grad, gpu1_var0_grad],那么輸出返回兩個tensor,一個位於gpu0,一個位於gpu1,二者值相同,為輸入所有tensor的和.所以利用這個op單機多卡訓練的時候,要將不同設備對應的相同var的grad作為這個op的輸入.這樣就能求得梯度和,再除以設備個數就得到了均值,然后就可以更新參數了.

與PS架構不同的是,每個設備(節點)都持有一份參數,自己更新自己的參數,因為算出來的梯度相同,所以參數能保持一致,導出模型的時候,只導出單張卡的參數和前向計算圖就OK了.

所以與PS架構的單機多卡訓練相比,要改動的地方如下:1.每個設備有自己的參數.2.計算梯度均值的時候改用nccl的all_sum算子.3.導出模型的時候,只導出單張卡的參數.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM