程序如何在兩個gpu卡上并行運行_深度學習分布式訓練相關介紹 - Part 1 多GPU訓練...

e07ee1e99ba66c217cd67ab9fded4ee6.png

本篇文章主要是對深度學習中運用多GPU進行訓練的一些基本的知識點進行的一個梳理

文章中的內容都是經過認真地分析,并且盡量做到有所考證

拋磚引玉,希望可以給大家有更多的啟發,并能有所收獲

介紹

大多數時候,梯度下降算法的訓練需要較大的Batch Size才能獲得良好性能。而當我們選擇比較大型的網絡時候,由于GPU資源有限,我們往往要減少樣本數據的Batch Size。

當GPU無法存儲足夠的訓練樣本時,我們該如何在更大的batch size上進行訓練?

面對這個問題,事實上我們有幾種工具、技巧可以選擇,它們也是下文中將介紹的內容。

在這篇文章中,我們將探討:

  • 多GPU訓練和單GPU訓練有什么區別
  • 如何最充分地使用多GPU機器
  • 如何進行多機多卡訓練?

更多關于多機多卡的分布式訓練的詳細架構理解和實踐請參考我的下一篇文章:

Zhang Bin:深度學習分布式訓練相關介紹 - Part 2 詳解分布式訓練架構PS-Worker與Horovod?zhuanlan.zhihu.com
f6b2595689d275f8ee79be68e976b1bb.png

本文章介紹的內容在框架間是通用的,代碼示例為:在不借助外部框架的情況下,將單GPU訓練TensorFlow代碼改為支持多GPU的訓練代碼

單GPU訓練 vs 多GPU訓練

單GPU訓練 一般代碼比較簡單,并且能滿足我們的基本需求,通常做法是設定變量CUDA_VISIBLE_DEVICES的值為某一塊GPU來Mask我們機器上的GPU設備,雖然有時當我們忘了設定該變量時程序會自動占用所有的GPU資源,但如果沒有相應的代碼去分配掌控GPU資源的使用的話,程序還是只會利用到第一張卡的計算資源,其他的資源則僅是占用浪費狀態。

多GPU訓練 則可以從兩個方面提升我們模型訓練的上限:1. 超過單卡顯存上限的模型大小, 2. 更大的Batch Size和更快訓練速度。相應的,目前各大主流框架的多GPU訓練一般存在兩種模式:

  • 模型并行 :分布式系統中的不同GPU負責網絡模型的不同部分,進而可以 構建超過單卡顯存容量大小的模型 。比如,可以將神經網絡的不同層分配到不同的GPU設備,或者將不同的參數變量分配到不同的GPU設備。
  • 數據并行 :不同的 GPU設備有同一模型的多個副本,將數據分片并分配到每個GPU上,然后將所有GPU的計算結果按照某種方式合并,進而可以增加訓練數據的Batch Size

cc4b6e5d08f4edfa0627cd2edc2cd00f.png

此外,從主機的數量的角度來講還存在 單機多卡多機多卡(分布式)的區別:

  • 單機多卡:只需運行一份代碼,由該代碼分配該臺機器上GPU資源的使用
  • 多機多卡:每臺機器上都需要運行一份代碼,機器之間需要互相通信傳遞梯度,并且模型參數的更新也存在同步訓練模式和異步訓練模式的區別

多GPU機器的充分利用

這一節,將詳細探討一下多GPU的機器該如何利用。

對于多GPU訓練,一般我們需要用數據并行的模式比較多,通過增大 Batch Size 并輔以較高的 Learning Rate 可以加快模型的收斂速度。

由于我們模型是通過若干步梯度反向傳播來迭代收斂模型的參數,而每一步的梯度由一個Batch內樣本數據的損失情況(Loss)得到,因此當 Batch Size 比較大時, 可以減少 Batch樣本的分布和整體樣本的分布偏差太大的風險,進而使得每一步的梯度更新方向更加準確。

比如,單卡訓練 InceptionResNet 網絡最大Batch Size為100, 學習率為0.001。采用4張卡去訓練時,可以設置Batch Size為400, 學習率為 0.002。在代碼中對每一個Batch 400 切分成 4*100,然后給到不同GPU卡上的模型上去訓練。

下面主要介紹一下單機多卡訓練的細節及部分Tensorflow代碼:

  • 數據切片
  • 模型構建
  • 梯度反傳

1. 數據分片

對于多GPU訓練,我們首先要做的就是對訓練數據進行分片,對于單機多卡模型,其數據的分片可以在代碼的內部進行, 而對于多機多卡模型,多機之間沒有必要進行數據切分方面的通信,建議的做法是先在本地做好數據的分配,然后再由不同的機器讀取不同的數據。

Tensorflow 單機多卡的數據切片代碼如下,其中 training_iterator 為采用tf.data.Dataset 構建的訓練數據pipeline, num_tower 為當前機器上可見的(CUDA_VISIBLE_DEVICES)GPU數量。

tower 指模型的副本。

mnist_input, mnist_label = training_iterator.get_next()
tower_inputs = tf.split(mnist_input, num_towers)
tower_labels = tf.split(mnist_label, num_towers)

通過 tf.split 函數,將輸入的數據按照GPU的數量平分。

2. 構建模型

有了分好的數據,下一步驟則是需要將模型放置在我們所有的GPU上,并將切片好的數據傳入。

Tensorflow可以指定將不同的任務分配到不同的設備上, GPU支持大量并行計算, 因此可以將模型的運算、梯度的計算分配到GPU上來,而變量的存儲、梯度的更新則可以由CPU來執行,如下圖所示

be2dacd93e51384ad738aac591bf61ee.png

下面我們來看一下TensorFlow的相關代碼

最外層的 for i in range(num_towers): 使我們需要構建模型 num_towers次。

下一層的 with tf.device(device_string % i): 代表著每次我們構建模型時,模型放置的設備名稱, 如果為GPU機器device_string = '/gpu:%d' ,如果為CPU機器 device_string = '/cpu:%d'

再下一層 with (tf.variable_scope(("tower"), reuse=True if i > 0 else None)): 通過 scope 的reuse 使得我們再后續放置模型的時候,不同GPU之間的模型參數共享。

最后一層 with (slim.arg_scope([slim.model_variable, slim.variable], device="/cpu:0" if num_gpus != 1 else "/gpu:0")): 使得我們將構建模型中的變量放到CPU上來, 而運算則仍保留在該GPU上。

tower_gradients = []
tower_predictions = []
tower_label_losses = []
optimizer = tf.train.AdamOptimizer(learning_rate=1E-3)for i in range(num_towers):with tf.device(device_string % i):with (tf.variable_scope(("tower"), reuse=True if i > 0 else None)):with (slim.arg_scope([slim.model_variable, slim.variable],device="/cpu:0" if num_gpus != 1 else "/gpu:0")):x = tf.placeholder_with_default(tower_inputs[i], [None, 224,224,3], name="input")y_ = tf.placeholder_with_default(tower_labels[i], [None, 1001], name="label")# logits = tf.layers.dense(x, 10)logits = build_model(x)predictions = tf.nn.softmax(logits, name="predictions")loss = tf.losses.softmax_cross_entropy(onehot_labels=y_, logits=logits)grads = optimizer.compute_gradients(loss)tower_gradients.append(grads)tower_predictions.append(predictions)tower_label_losses.append(loss)

3. 梯度反傳

上一步已經得到了各個tower上的梯度,下面則需要將這些梯度結合起來并進行反向傳播以更新模型的參數。

梯度結合的代碼可以參考下面的函數

def combine_gradients(tower_grads):"""Calculate the combined gradient for each shared variable across all towers.Note that this function provides a synchronization point across all towers.Args:tower_grads: List of lists of (gradient, variable) tuples. The outer listis over individual gradients. The inner list is over the gradientcalculation for each tower.Returns:List of pairs of (gradient, variable) where the gradient has been summedacross all towers."""filtered_grads = [[x for x in grad_list if x[0] is not None] for grad_list in tower_grads]final_grads = []for i in range(len(filtered_grads[0])):grads = [filtered_grads[t][i] for t in range(len(filtered_grads))]grad = tf.stack([x[0] for x in grads], 0)grad = tf.reduce_sum(grad, 0)final_grads.append((grad, filtered_grads[0][i][1],))return final_grads

通過 combine_gradients 來計算合并梯度,再通過 optimizer.apply_gradients 對得到的梯度進行反向傳播

merged_gradients = combine_gradients(tower_gradients)
train_op = optimizer.apply_gradients(merged_gradients, global_step=global_step)

最后再通過 sess.run(train_op) 對執行。

多機多卡 分布式訓練

多機多卡相比較于單機多卡,其使得模型訓練的上限進一步突破。一般我們一臺服務器只支持8張GPU卡,而采用分布式的多機多卡訓練方式,可以將幾十甚至幾百臺服務器調度起來一起訓練一個模型。

但相比于單機多卡,多機多卡分布式訓練方式的配置更復雜一些,不僅要保證多臺機器之間是可以互相通信的,還需要配置不同機器之間的角色以及不同機器之間梯度傳遞。

d556517de8b3e9eb41d6cac3aaa80917.png
  • TensorFlow 原生 PS架構
    在Parameter server架構(PS架構)中,集群中的節點被分為兩類:parameter server和worker。其中parameter server存放模型的參數,而worker負責計算參數的梯度。在每個迭代過程,worker從parameter sever中獲得參數,然后將計算的梯度返回給parameter server,parameter server聚合從worker傳回的梯度,然后更新參數,并將新的參數廣播給worker。
  • Uber 開發的Horovod架構 - 支持 TensorFlow, Keras, PyTorch, and Apache MXNet
    Horovod 是一套面向 TensorFlow 的分布式訓練框架,由 Uber 構建并開源,目前已經運行于 Uber 的 Michelangelo 機器學習即服務平臺上。Horovod 能夠簡化并加速分布式深度學習項目的啟動與運行。
    Horovod架構采用全新的梯度同步和權值同步算法,叫做 ring-allreduce。此種算法各個節點之間只與相鄰的兩個節點通信,并不需要參數服務器。因此,所有節點都參與計算也參與存儲。

關于分布式訓練的更多介紹,請參考我的下一篇文章

Zhang Bin:深度學習分布式訓練相關介紹 - Part 2 詳解分布式訓練架構PS-Worker與Horovod?zhuanlan.zhihu.com
f6b2595689d275f8ee79be68e976b1bb.png

相關參考鏈接

TensorFlow - Multi GPU Computation

分布式tensorflow(一)

TensorFlow分布式全套(原理,部署,實例)

distributeTensorflowExample

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372933.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372933.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372933.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

集成Spring和JavaServer Faces:改進的模板

隨著2.0版的發布&#xff0c;Facelet模板成為JSF規范的核心部分。 使用<ui&#xff1a;composition>和<ui&#xff1a;decorate>標記&#xff0c;可以輕松構建復雜的頁面&#xff0c;同時仍保持標記清晰。 模板在創建HTML表單時特別有用&#xff0c;但是不幸的是&a…

whmcs模板路徑

whmcs網站根目錄 比如你的域名是server.nongbin.vip&#xff0c;你需要cd /home/wwwroot/server.nongbin.vip&#xff0c;該目錄下然后&#xff0c;cd template/ 給文件夾下就是你上傳的模板文件夾轉載于:https://www.cnblogs.com/nongbin/p/6412108.html

系統英偉達gpu驅動卸載_繞過CPU,英偉達讓GPU直連存儲設備

英偉達最近發布了一個新的GPUDirect Storage&#xff0c;暫且叫做GPU直連存儲&#xff0c;讓GPU直接連到NVMe存儲設備上。這一方案用到了RDMA設備來把數據從閃存存儲轉移到GPU本地的內存里&#xff0c;無需經過CPU還有系統內存。如果這一舉措順利的話&#xff0c;英偉達就能擺脫…

37、EnumSet詳解

EnumSet類也是有順序的&#xff0c;EnumSet按照枚舉值在Enum類內定義的順序決定集合元素的順序 EnumSet在內部已位向量的形式存儲&#xff0c;這種存儲方式非常緊湊、搞笑&#xff0c;因此EnumSet占用內存很小&#xff0c;而且運行效率很好。 EnumSet集合不允許加入null元素 En…

嘲弄和存根–了解Mockito的測試雙打

介紹 我遇到的一件事是使用模擬框架的團隊假設他們在模擬。 他們并不知道Mocks只是Gerard Meszaros在xunitpatterns.com上歸類的“測試雙打”之一。 重要的是要意識到每種類型的測試雙精度在測試中都扮演著不同的角色。 用與您需要學習不同模式或重構的方式相同&#xff0c;您…

numpy 辨異(三)—— hstack/column_stack,linalg.eig/linalg.eigh

1. np.hstack np.column_stack >>> np.hstack([np.array([1, 2, 3]), np.array([4, 5, 6])]) array([1, 2, 3, 4, 5, 6])>>> np.column_stack([np.array([1, 2, 3]), np.array([4, 5, 6])]) array([[1, 4],[2, 5],[3, 6]]) 當然對等地&#xff0c;也存在&…

【代碼筆記】iOS-首頁3張圖片變化

一&#xff0c;效果圖。 二&#xff0c;工程圖。 三&#xff0c;代碼。 RootViewController.h #import <UIKit/UIKit.h>interface RootViewController : UIViewController {NSTimer *timer;UIImageView *imageView1;UIImageView *imageView2;UIImageView *imageView3;UIV…

acwing算法提高之動態規劃--數位DP

目錄 1 基礎知識2 模板3 訓練 1 基礎知識 暫無。。。 2 模板 暫無。。。 3 訓練 題目1&#xff1a;度的數量。 解題思路&#xff1a;分類討論。 C代碼如下&#xff0c; #include <iostream> #include <vector>using namespace std;const int N 35; int K,…

python 輸入數字變成密碼_如何在python中檢查數字的“密碼”

我建議使用sets和stdlib中的string包作為可接受字符的列表。在我還建議進行一點重構&#xff0c;以刪除大量帶有if / else分支的嵌套。在import stringupper set(list(string.uppercase))lower set(list(string.lowercase))numbers set(list(string.digits))while True:npw …

使用Eclipse在Amazon Ec2中部署Java Web應用程序的完整指南

嗨&#xff0c;讀者們&#xff0c; 今天&#xff0c;我將向您展示如何使用Eclipse IDE在Amazon EC2中部署簡單的Java Web應用程序。 在我們開始之前&#xff0c;我們需要一些必需的東西&#xff0c; Eclipse Java EE IDE –您可以從http://www.eclipse.org/downloads/下載&…

jquery的load方法

load方法指定一個界面會顯示在目標的標簽內部 比如MVC的一個分部視圖頁面想要顯示在某個標簽里面&#xff0c;可以寫成 $(標簽ID).load&#xff08;分部視圖名稱,data&#xff09; 其中第二個參數可選&#xff0c;主要是一些需要傳遞到該頁面的數據JSON格式組成&#xff0c;發送…

android 錄音原始文件_音頻采集:Android基于AudioRecord的實現

前言這篇文章簡單介紹下移動端Android系統下利用AudioRecord進行音頻采集方法。按照慣例開始前先提供一份源碼 AudioRecordLib 。AudioRecord采集的核心實現在于 AudioRecordCore.java 這個文件。權限申請想要使用AudioRecord這個API&#xff0c;需要在AndroidManifest.xml的配…

Spring 3和Java EE 6 –不公平和不完整的比較

這篇小文章的初稿標題為“ Spring&#xff06;Java EE –比較蘋果和橙子”。 在撰寫本文時&#xff0c;我了解到可以比較Spring Framework和Java EE&#xff0c;但這始終是不公平且不完整的工作。 Java for Enterprise和Spring Framework的發展緊密地聯系在一起。 兩者相互依存…

xml配置文件推薦方式

1.XML幫助類 /// <summary>/// Xml幫助類/// </summary>public class XmlHelper{/// <summary>/// 保存xml/// </summary>/// <typeparam name"T"></typeparam>/// <param name"path"></param>/// <p…

AFNetWorking https SSL認證

一般來講如果app用了web service , 我們需要防止數據嗅探來保證數據安全.通常的做法是用ssl來連接以防止數據抓包和嗅探 其實這么做的話還是不夠的 。 我們還需要防止中間人攻擊&#xff08;不明白的自己去百度&#xff09;。攻擊者通過偽造的ssl證書使app連接到了偽裝的假冒的…

查看環境列表_Xfce 4.14桌面環境正式發布,想要圖形界面又想節省內存?就它了...

1. Xfce 4.14桌面環境正式發布&#xff0c;它有什么新特性&#xff1f;本文主要講解Xfce 4.14桌面環境正式發布&#xff0c;它有什么新特性。Xfce已經開發了4年多&#xff0c;但是這個周末終于看到了期待已久的Xfce 4.14的發布。Xfce 4.14是這個輕量級桌面環境的最新穩定版本&a…

使用Log4jdbc記錄JDBC操作

當我們開發任何應用程序&#xff0c;完成它或結束其任何模塊時&#xff0c;我們都會開始優化過程。 大多數應用程序都包含數據庫訪問權限&#xff0c;并且如果您使用的是ORM &#xff0c;則可能會使用hibernate 。 優化休眠持久層&#xff0c;要求準備閱讀&#xff0c;理解和評…

android BluetoothAdapter藍牙BLE掃描總結

做室內定位的程序員應該都知道&#xff0c;在Android 5.0之后&#xff0c;google推出了藍牙掃描新接口&#xff0c;我們在實測中發現出一些問題&#xff0c;現在給大家列出&#xff0c;以供參考&#xff1a; 1.android 4.3.1(Build.VERSION_CODES.JELLY_BEAN_MR2)增加的startLe…

卷積神經網絡語音識別_用于物體識別的3D卷積神經網絡

本文提出了一種基于CNN的3D物體識別方法&#xff0c;能夠從3D圖像表示中識別3D物體&#xff0c;并在比較了不同的體素時的準確性。已有文獻中&#xff0c;3D CNN使用3D點云數據集或者RGBD圖像來構建3D CNNs&#xff0c;但是CNN也可以用于直接識別物體體積表示的體素。本文中&am…

段落排版--對齊(text-aliagn)

想為塊狀元素中的文本、圖片設置居中樣式嗎&#xff1f;可以使用text-align樣式代碼&#xff0c;如下代碼可實現文本居中顯示。(那么什么是塊狀元素呢&#xff1f;后面會講到呢~) h1{text-align:center; } <h1>了不起的蓋茨比</h1> 同樣可以設置居左&#xff1a; h…