調參俠看過來!兩個提高深度學習訓練效率的絕技

2021-01-16 TechWeb

1. 訓練的瓶頸在哪裡

 GPU利用率低:模型訓練時GPU顯存沾滿了,但是GPU的利用率比較不穩定,有時候0%,有時候90%,忽高忽低。   

 訓練的數據量大:訓練數據大,在百萬/千萬的量級,訓練一個Epoch需要很長時間,模型迭代周期過長。

2. 提高GPU利用率:CPU vs GPU

GPU利用率低, 主要原因是CPU處理的效率跟不上GPU

2.1 CPU vs GPU的通信

 CPU負責加載數據+數據預處理,並不斷的在內存和顯存之間交互數據  GPU負責模型訓練(圖片來自網絡)

2.2 解決方案

採用多進程並行處理,加快CPU加載數據的性能

 keras keras 中提供了workers use_multiprocessing來採用多進程方式,並行處理數據,並push到隊列中,共GPU模型訓練。因為進程之間可能相互影響資源,並不是越大越好,workers可以設置2,4,8。  run_model.fit_generator(                generator=training_generator,                class_weight={0: config.weights, 1: 1},                epochsepochs=epochs,                verbose=1,                steps_per_epochsteps_per_epoch=steps_per_epoch,                callbacks=callbacks_list,                validation_data=valid_generator,               validation_stepsvalidation_steps=validation_steps,                shuffle=True,                workers=8,                use_multiprocessing=True,                max_queue_size=20   pytorch torch在加載數據中提供類似參數num_workers。pin_memory=True可以直接加載到顯存中,而不需要內存  torch.utils.data.DataLoader(image_datasets[x],                               batch_sizebatch_size=batch_size,                                shuffle=True,                               num_workers=8,                               pin_memory=True) 

3. 分布式並行訓練

3.1 並行模式

當訓練的數據量很大時,可以通過多個機器多個GPU來提高訓練的效率。不同於hadoop和spark等分布式數據處理框架,深度學習訓練因為要涉及參數的前項傳播和反向傳播,有兩種並行方式:

 模型並行( model parallelism ):分布式系統中的不同機器(GPU/CPU等)負責網絡模型的不同部分,通常是神經網絡模型的不同網絡層被分配到不同的機器,或者同一層內部的不同參數被分配到不同機器。一般是超大的模型,一張顯卡放不下的情況,如NLP的模型。模型並行的缺點是層和層之間可能存在依賴關係,不能完全的並行。(圖片來自網絡)  

 數據並行( data parallelism ):不同的機器有同一個模型的多個副本,每個機器分配到不同的數據,然後將所有機器的計算結果按照某種方式合併。這種就比較適合大數據的情況。數據並行要解決的問題是數據的分割和傳輸,以及參數的更新。

3.2 數據並行

Facebook在《Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour》介紹了使用 256 塊 GPU 進行 ResNet-50 網絡「數據並行」訓練的方法

 數據分割: 選用大的batch-size, 按照worker數量進行分割, 分發到不同worker執行  參數更新:參數的更新有兩種模式(1)參數伺服器 (2) ring環狀更新(無伺服器模式)

3.2.1 參數伺服器模式

參數伺服器模式,見下圖。在每個worker執行完一個batch的訓練後,反向傳播參數的時候,所有的worker都會把參數傳給參數伺服器,進行匯總求均值,之後再傳給每個worker,進入第二個batch的訓練。(圖片來自網絡)

參數伺服器有一個或者多個的結構模式,可以看出這種數據並行的模式效率是否提升取決於參數伺服器與worker之間的通信效率,也就是最慢的worker的訓練時間和參數伺服器的接收和更新參數後再回傳的時間。worker數量多的話,參數伺服器可能存在瓶頸。(圖片來自網絡)

3.2.2 ring-reduce

百度提出的ring-reduce摒棄了參數伺服器,採用環狀結構來更新參數。ring-reduce把所有的worker組成一個兩兩相鄰的環形結構。每個worker只與相鄰的worker交換參數。經過幾次交換之後,所有的worker都包含其他worker的參數信息,達到更新的目的。(圖片來自網絡)

下面幾張圖,可以看到其中的幾個步驟;ring-reduce為了加快速度,並不是一次性交換所有的參數;而是先把參數進行分割,不斷交換分割後參數。

4. 實現框架:Horovod

Horovod 是 Uber 開源的又一個深度學習工具,它的發展吸取了 Facebook「一小時訓練 ImageNet 論文」與百度 Ring Allreduce 的優點,可為用戶實現分布式訓練提供幫助。https://github.com/horovod/horovod

採用NCCL 替換百度的 ring-allreduce 實現。NCCL 是英偉達的集合通信庫,提供高度優化的 ring-allreduce 版本。NCCL 2 允許在多個機器之間運行 ring-allreduc。

如果要把單機的訓練代碼修改成分布式的代碼,只要幾個步驟就可以了 改造分布式訓練:

 horovod安裝 建議安裝docker的horovod,省去安裝環境的麻煩。horovod依賴NCCL 2 open MPI  $ mkdir horovod-docker-gpu  $ wget -O horovod-docker-gpu/Dockerfile https://raw.githubusercontent.com/horovod/horovod/master/Dockerfile.gpu  $ docker build -t horovod:latest horovod-docker-gpu   機器worker機器之間ssh打通  修改訓練代碼 horovod支持tf,keras,pytorch和mxnet等不同的深度學習框架。以keras為例,修改主要6個步驟 (1) 初始化:hvd.init() (2)分配GPU計算資源:config.gpu_options.visible_device_list = str(hvd.local_rank())(3)分布式的優化器來實現參數的分布式更新:opt = hvd.DistributedOptimizer(opt)(4)定義所有worker模型初始化一致性 hvd.callbacks.BroadcastGlobalVariablesCallback(0)(5)模型保存在某一個worker    from __future__ import print_function     import keras    from keras.datasets import mnist     from keras.models import Sequential     from keras.layers import Dense, Dropout, Flatten     from keras.layers import Conv2D, MaxPooling2D     from keras import backend as K     import math     import tensorflow as tf    import horovod.keras as hvd     # Horovod: initialize Horovod.     hvd.init()     # Horovod: pin GPU to be used to process local rank (one GPU per process)     config = tf.ConfigProto()     config.gpu_options.allow_growth = True     config.gpu_options.visible_device_list = str(hvd.local_rank())     K.set_session(tf.Session(configconfig=config))     batch_size = 128     num_classes = 10     # Horovod: adjust number of epochs based on number of GPUs.     epochs = int(math.ceil(12.0 / hvd.size()))     # Input image dimensions    img_rows, img_cols = 28, 28      # The data, shuffled and split between train and test sets     (x_train, y_train), (x_test, y_test) = mnist.load_data()      if K.image_data_format() == 'channels_first':         x_trainx_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)         x_testx_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)         input_shape = (1, img_rows, img_cols)     else:         x_trainx_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)         x_testx_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)         input_shape = (img_rows, img_cols, 1)     x_trainx_train = x_train.astype('float32')     x_testx_test = x_test.astype('float32')     x_train /= 255     x_test /= 255     print('x_train shape:', x_train.shape)     print(x_train.shape[0], 'train samples')     print(x_test.shape[0], 'test samples')     # Convert class vectors to binary class matrices     y_train = keras.utils.to_categorical(y_train, num_classes)     y_test = keras.utils.to_categorical(y_test, num_classes)     model = Sequential()     model.add(Conv2D(32, kernel_size=(3, 3),                     activation='relu',                     input_shapeinput_shape=input_shape))     model.add(Conv2D(64, (3, 3), activation='relu'))     model.add(MaxPooling2D(pool_size=(2, 2)))     model.add(Dropout(0.25))     model.add(Flatten())     model.add(Dense(128, activation='relu'))     model.add(Dropout(0.5))     model.add(Dense(num_classes, activation='softmax'))     # Horovod: adjust learning rate based on number of GPUs.     opt = keras.optimizers.Adadelta(1.0 * hvd.size())     # Horovod: add Horovod Distributed Optimizer.     opt = hvd.DistributedOptimizer(opt)     model.compile(loss=keras.losses.categorical_crossentropy,                 optoptimizer=opt,                 metrics=['accuracy'])     callbacks = [         # Horovod: broadcast initial variable states from rank 0 to all other processes.         # This is necessary to ensure consistent initialization of all workers when         # training is started with random weights or restored from a checkpoint.         hvd.callbacks.BroadcastGlobalVariablesCallback(0),     ]     # Horovod: save checkpoints only on worker 0 to prevent other workers from corrupting them.     if hvd.rank() == 0:         callbacks.append(keras.callbacks.ModelCheckpoint('./checkpoint-{epoch}.h5'))     model.fit(x_train, y_train,             batch_sizebatch_size=batch_size,             callbackscallbacks=callbacks,             epochsepochs=epochs,             verbose=1,             validation_data=(x_test, y_test))     score = model.evaluate(x_test, y_test, verbose=0)     print('Test loss:', score[0])     print('Test accuracy:', score[1])   利用horovodrun 執行分布式訓練

horovodrun -np 16 -H server1:4,server2:4,server3:4,server4:4 python train.py

5. 總結

本文分享了通過GPU利用率和分布式訓練Horovod框架來提升深度學習訓練。

 並行CPU加載數據和預處理,讓GPU不再等待CPU  採用Horovod讓數據並行來提高大數據量的訓練的迭代時間 

 

相關焦點

  • 深度學習——深度學習調參有哪些技巧?
    深度學習調參有哪些技巧?深度學習的效果很大程度上取決於參數調節的好壞,那麼怎麼才能最快最好的調到合適的參數呢?作者:京東白條https://www.zhihu.com/question/25097993/answer/651617880相信很多剛開始接觸深度學習朋友,會感覺深度學習調參就像玄學一般,有時候參數調的好,模型會快速收斂,參數沒調好,可能迭代幾次loss值就直接變成Nan了。
  • 一份來自賈揚清的AI青年修煉指南:不存在算法工程師、調參俠沒有市場
    在討論中,賈揚清認為:沒有算法工程師這個角色,只有兩個角色,一個是算法的研究人員,一個是應用的工程師,而「調參俠」沒有市場。另外,作為Caffe、PyTorch和Tensorflow曾經的核心開發者,他還提到,深度學習框架並不會出現大一統的局面,因為現實中需求很多,並沒有一家機器學習框架能夠囊括所有的需求。
  • 一份來自賈揚清的AI青年修煉指南:不存在算法工程師、調參俠沒有市場
    在討論中,賈揚清認為:沒有算法工程師這個角色,只有兩個角色,一個是算法的研究人員,一個是應用的工程師,而「調參俠」沒有市場。另外,作為Caffe、PyTorch和Tensorflow曾經的核心開發者,他還提到,深度學習框架並不會出現大一統的局面,因為現實中需求很多,並沒有一家機器學習框架能夠囊括所有的需求。
  • 教學一體機如何調亮度 提高課堂學習效率
    1、提高課堂學習效率老師上課不用手做筆記,節省時間,讓孩子在學習會議一體機的過程中,鞏固課堂的知識,提高課堂學習效率,在多方面提高孩子學習的興趣。教學一體機,是新時代下科技引領教育發展的主要載體,是發展智慧教育的核心。
  • GAITC專題論壇丨楊易:訓練機器自主學習提高檢測效率
    如何利用無標註的海量網絡視頻協助視頻特徵學習,並提升模型性能是視頻分析領域重要的研究問題。他提到,以前訓練一個模型做一件事,現在更多的是讓機器自主學習,培養機器的自我學習能力。不僅讓機器學會做事,更要教會它怎麼去學習,這是元學習的基本想法。比如,讓機器學會怎麼去做事,新的任務就很容易做自適應。
  • 《如何閱讀》:讀書也是一種技能,需要學習和訓練才能提升效率
    拿起書沒看幾眼又放下了,幾天看一頁,沒有連貫性和整體性,怎麼能理解作者想要表達的意思呢?那麼,我們是否可以通過一種方法讓自己的閱讀速度得到提升呢?《如何閱讀》這本書,就是用一種全新的方法來教授人們如何快速閱讀,同時還告訴人們如何做到深度理解書中內容。
  • 大規模分布式強化學習基礎架構Menger, 大幅提高真實任務的學習效率
    簡單來講,強化學習算法的開發過程可以視為數據收集和模型訓練的循環過程,其中主體會在環境中探索並收集樣本,而後這些數據被送入到學習器中進行訓練並更新模型。目前先進的強化學習模型大多需要在數百萬個從環境中獲取的樣本上進行多次迭代訓練循環才能夠解決特定的目標任務 (例如Dota2的訓練過程每兩秒就能對200萬幀進行學習)。
  • 如何提高英語單詞學習的短期記憶效率
    今天我們專門談一談第二項:每一次學習時,如何讓大腦在短時間內產生足夠的神經刺激,換句話說就是背單詞的短期效率問題。我們日常所說的「提高背單詞的效率」,實際上有兩種涵義。效率是結果產出與所耗費時間的比率。這裡面有兩個關鍵因子:第一是如何定義背單詞的結果,第二是如何計算背單詞的時間。
  • 疫情下如何幫助在家學習的學生提高學習效率?
    二、學生在家學習效率不高,該怎麼辦? 疫情期間,高中生小明在家學習時,學習意願很強烈,但始終感到學習效率不高,看起來一天在書桌前坐了8個小時,但事實上真正投入到學習之中的時間不超過3小時,學習效率極低。於是他給老師打電話訴說自己的苦惱,並諮詢老師:我該如何提高學習效率?
  • NVIDIA 遷移學習工具包 :用於特定領域深度學習模型快速訓練的高級...
    遷移學習工具包對於深度學習應用開發人員和數據科學家來說是理想的工具,這些開發人員和數據科學家正在為各種行業垂直領域(如智能視頻分析(IVA)和醫學成像)尋求更快、更高效的深度學習訓練工作流程。遷移學習工具包通過允許開發人員微調 NVIDIA 提供的特定領域的預訓練模型來抽象和加速深度學習訓練,而不是從頭開始花大量時間來從零開始(說明一下,「從零開始」這個詞很重要,它是遷移學習最關鍵的特點)構建深層神經網絡。預訓練模型加速了開發人員的深度學習訓練過程,並且減少了大規模數據收集、標記和從零開始訓練模型相關的成本。
  • 深度學習在改變智慧型手機!百度飛槳加速OPPO個性化推薦效率
    隨著技術的完善與門檻的降低,深度學習正在加大往各行業滲透落地的力度。5月20日,由深度學習技術及應用國家工程實驗室與百度聯合主辦的「WAVE SUMMIT」2020深度學習開發者峰會召開。
  • 深度強化學習訓練AI,像人類一樣玩DOOM
    這一競賽是在深度學習,強化學習興起的背景下產生的一項頗有挑戰的AI競賽。這項競賽吸引了不少全球頂尖的AI實驗室前來一展身手。去年,Facebook的FAIR拿了Track1的冠軍,Intel拿了Track2的冠軍,CMU的機器人Arnold拿了兩個Track的亞軍。
  • AI開發者看過來,主流移動端深度學習框架大盤點
    近年來,隨著行動裝置的廣泛普及與應用,在行動裝置上使用深度學習技術的需求開始湧現。簡書作者 dangbo 在《移動端深度學習展望》一文中對現階段的移動端深度學習做了相關展望。作者認為,現階段的移動端 APP 主要通過以下兩種模式來使用深度學習:online 方式:移動端做初步預處理,把數據傳到伺服器執行深度學習模型,優點是這個方式部署相對簡單,將現成的框架(Caffe,Theano,MXNet,Torch) 做下封裝就可以直接拿來用,伺服器性能大, 能夠處理比較大的模型,缺點是必須聯網。
  • 改善深度學習訓練的trick總結|CSDN博文精選
    作者 | ZesenChen來源 | CSDN博客精選在深度學習中,同樣一個模型用不同的初始化,數據處理,batch size,學習率,優化器都能得到不同性能的參數。我根據自己參與過的比賽中經常用到的一些trick進行大致的總結,有代碼的會順便附上,方便自己以後使用。
  • 深度學習訓練tricks總結(均有實驗支撐)
    本文轉載自【微信公眾號:機器學習算法與Python精研 ,ID:AITop100】,經微信公眾號授權轉載,如需轉載原文作者聯繫極市導讀本文作者模擬復現了自己在深度學習訓練過程中可能遇到的多種情況,並嘗試解決這些問題,文章圍繞學習率、動量、學習率調整策略、L2正則、優化器展開。
  • 最新最全深度學習訓練/GPU伺服器硬體配置推薦2020
    >深度學習兩個主要過程:訓練(Training)和推理(Inference)。其中:訓練(Training)是將大量數據加載到機器中並分析數據以建立用於分類,識別,預測等的模式的過程(已建立的模式稱為訓練後的模型),訓練需要高速密集並行計算---「高性能計算」推理(Inference)是將未知數據輸入到通過學習過程創建的訓練模型中,然後根據已建立的模式對數據進行實際分類
  • 提高複雜網絡分析效率!中國科學家研發強化學習新框架
    智東西(公眾號:zhidxcom)編 | 董溫淑智東西6月29日消息,近日,中國國防科技大學、美國加州大學洛杉磯分校和哈佛醫學院的研究人員研發了一個深度強化學習框架FINDER。相比於現有的解決方案,FINDER能夠更快速、更高效地找到複雜網絡中一組最關鍵的節點,進而使複雜網絡以較高的效率運行。這項研究發表在國際期刊《自然》旗下的《自然–機器智能》上,論文標題為《用深度強化學習找到複雜網絡的關鍵參與者(Finding key players in complex networks through deep reinforcement learning)》。
  • 如何安排力量訓練,一周訓練幾次,才能提高健身效率?
    健身訓練的時候,我們不僅需要進行有氧運動,更不能忽略力量訓練。力量訓練可以鍛鍊自身肌肉,提高身材線條,提升自身的曲線魅力。但是,很多人不知道如何科學的安排力量訓練,才能提高健身效果。
  • 微軟開源深度學習優化庫 DeepSpeed,可訓練 1000 億參數的模型
    微軟日前開源了一個深度學習優化庫 DeepSpeed,通過提高規模、速度、可用性並降低成本,可以在當前一代的 GPU 集群上訓練具有超過 1000 億個參數的深度學習模型,極大促進大型模型的訓練。同時,與最新技術相比,其系統性能可以提高 5 倍以上。
  • 潮科技行業入門指南 | 深度學習理論與實戰:提高篇(5)——深度學習...
    編者按:本文節選自《深度學習理論與實戰:提高篇 》一書,原文連結http://fancyerii.github.io/2019/03/14/dl-book/。提起深度學習的再次興起,大家首先可能會想到2012年AlexNet在圖像分類上的突破,但是最早深度學習的大規模應用發生在語音識別領域。自從2006年Geoffrey Hinton提出逐層的Pretraining之後,神經網絡再次進入大家的視野。