偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

調(diào)參俠看過來!兩個提高深度學(xué)習(xí)訓(xùn)練效率的絕技

人工智能 深度學(xué)習(xí)
本文分享了通過GPU利用率和分布式訓(xùn)練Horovod框架來提升深度學(xué)習(xí)訓(xùn)練。

[[343402]]

 1. 訓(xùn)練的瓶頸在哪里

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

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

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

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

2.1 CPU vs GPU的通信

  •  CPU負責(zé)加載數(shù)據(jù)+數(shù)據(jù)預(yù)處理,并不斷的在內(nèi)存和顯存之間交互數(shù)據(jù)
  •  GPU負責(zé)模型訓(xùn)練(圖片來自網(wǎng)絡(luò))

2.2 解決方案

采用多進程并行處理,加快CPU加載數(shù)據(jù)的性能

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

3. 分布式并行訓(xùn)練

3.1 并行模式

當(dāng)訓(xùn)練的數(shù)據(jù)量很大時,可以通過多個機器多個GPU來提高訓(xùn)練的效率。不同于hadoop和spark等分布式數(shù)據(jù)處理框架,深度學(xué)習(xí)訓(xùn)練因為要涉及參數(shù)的前項傳播和反向傳播,有兩種并行方式:

  •  模型并行( model parallelism ):分布式系統(tǒng)中的不同機器(GPU/CPU等)負責(zé)網(wǎng)絡(luò)模型的不同部分,通常是神經(jīng)網(wǎng)絡(luò)模型的不同網(wǎng)絡(luò)層被分配到不同的機器,或者同一層內(nèi)部的不同參數(shù)被分配到不同機器。一般是超大的模型,一張顯卡放不下的情況,如NLP的模型。模型并行的缺點是層和層之間可能存在依賴關(guān)系,不能完全的并行。(圖片來自網(wǎng)絡(luò))  

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

3.2 數(shù)據(jù)并行

Facebook在《Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour》介紹了使用 256 塊 GPU 進行 ResNet-50 網(wǎng)絡(luò)「數(shù)據(jù)并行」訓(xùn)練的方法

  •  數(shù)據(jù)分割: 選用大的batch-size, 按照worker數(shù)量進行分割, 分發(fā)到不同worker執(zhí)行
  •  參數(shù)更新:參數(shù)的更新有兩種模式(1)參數(shù)服務(wù)器 (2) ring環(huán)狀更新(無服務(wù)器模式)

3.2.1 參數(shù)服務(wù)器模式

參數(shù)服務(wù)器模式,見下圖。在每個worker執(zhí)行完一個batch的訓(xùn)練后,反向傳播參數(shù)的時候,所有的worker都會把參數(shù)傳給參數(shù)服務(wù)器,進行匯總求均值,之后再傳給每個worker,進入第二個batch的訓(xùn)練。(圖片來自網(wǎng)絡(luò))

參數(shù)服務(wù)器有一個或者多個的結(jié)構(gòu)模式,可以看出這種數(shù)據(jù)并行的模式效率是否提升取決于參數(shù)服務(wù)器與worker之間的通信效率,也就是最慢的worker的訓(xùn)練時間和參數(shù)服務(wù)器的接收和更新參數(shù)后再回傳的時間。worker數(shù)量多的話,參數(shù)服務(wù)器可能存在瓶頸。(圖片來自網(wǎng)絡(luò))

3.2.2 ring-reduce

百度提出的ring-reduce摒棄了參數(shù)服務(wù)器,采用環(huán)狀結(jié)構(gòu)來更新參數(shù)。ring-reduce把所有的worker組成一個兩兩相鄰的環(huán)形結(jié)構(gòu)。每個worker只與相鄰的worker交換參數(shù)。經(jīng)過幾次交換之后,所有的worker都包含其他worker的參數(shù)信息,達到更新的目的。(圖片來自網(wǎng)絡(luò))

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

4. 實現(xiàn)框架:Horovod

Horovod 是 Uber 開源的又一個深度學(xué)習(xí)工具,它的發(fā)展吸取了 Facebook「一小時訓(xùn)練 ImageNet 論文」與百度 Ring Allreduce 的優(yōu)點,可為用戶實現(xiàn)分布式訓(xùn)練提供幫助。https://github.com/horovod/horovod

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

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

  •  horovod安裝 建議安裝docker的horovod,省去安裝環(huán)境的麻煩。horovod依賴NCCL 2 open MPI 
  1. $ mkdir horovod-docker-gpu  
  2. $ wget -O horovod-docker-gpu/Dockerfile https://raw.githubusercontent.com/horovod/horovod/master/Dockerfile.gpu  
  3. $ docker build -t horovod:latest horovod-docker-gpu 
  •  機器worker機器之間ssh打通
  •  修改訓(xùn)練代碼 horovod支持tf,keras,pytorch和mxnet等不同的深度學(xué)習(xí)框架。以keras為例,修改主要6個步驟 (1) 初始化:hvd.init() (2)分配GPU計算資源:config.gpu_options.visible_device_list = str(hvd.local_rank())(3)分布式的優(yōu)化器來實現(xiàn)參數(shù)的分布式更新:opt = hvd.DistributedOptimizer(opt)(4)定義所有worker模型初始化一致性 hvd.callbacks.BroadcastGlobalVariablesCallback(0)(5)模型保存在某一個worker   
  1. from __future__ import print_function  
  2.    import keras 
  3.    from keras.datasets import mnist  
  4.    from keras.models import Sequential  
  5.    from keras.layers import Dense, Dropout, Flatten  
  6.    from keras.layers import Conv2D, MaxPooling2D  
  7.    from keras import backend as K  
  8.    import math  
  9.    import tensorflow as tf 
  10.    import horovod.keras as hvd  
  11.    # Horovod: initialize Horovod.  
  12.    hvd.init()  
  13.    # Horovod: pin GPU to be used to process local rank (one GPU per process)  
  14.    config = tf.ConfigProto()  
  15.    config.gpu_options.allow_growth = True  
  16.    config.gpu_options.visible_device_list = str(hvd.local_rank())  
  17.    K.set_session(tf.Session(configconfig=config))  
  18.    batch_size = 128  
  19.    num_classes = 10  
  20.    # Horovod: adjust number of epochs based on number of GPUs.  
  21.    epochs = int(math.ceil(12.0 / hvd.size()))  
  22.    # Input image dimensions 
  23.    img_rows, img_cols = 28, 28   
  24.    # The data, shuffled and split between train and test sets  
  25.    (x_train, y_train), (x_test, y_test) = mnist.load_data()   
  26.    if K.image_data_format() == 'channels_first':  
  27.        x_trainx_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)  
  28.        x_testx_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)  
  29.        input_shape = (1, img_rows, img_cols)  
  30.    else:  
  31.        x_trainx_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)  
  32.        x_testx_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)  
  33.        input_shape = (img_rows, img_cols, 1)  
  34.    x_trainx_train = x_train.astype('float32')  
  35.    x_testx_test = x_test.astype('float32')  
  36.    x_train /= 255  
  37.    x_test /= 255  
  38.    print('x_train shape:', x_train.shape)  
  39.    print(x_train.shape[0], 'train samples')  
  40.    print(x_test.shape[0], 'test samples')  
  41.    # Convert class vectors to binary class matrices  
  42.    y_train = keras.utils.to_categorical(y_train, num_classes)  
  43.    y_test = keras.utils.to_categorical(y_test, num_classes)  
  44.    model = Sequential()  
  45.    model.add(Conv2D(32, kernel_size=(3, 3),  
  46.                    activation='relu' 
  47.                    input_shapeinput_shape=input_shape))  
  48.    model.add(Conv2D(64, (3, 3), activation='relu'))  
  49.    model.add(MaxPooling2D(pool_size=(2, 2)))  
  50.    model.add(Dropout(0.25))  
  51.    model.add(Flatten())  
  52.    model.add(Dense(128, activation='relu'))  
  53.    model.add(Dropout(0.5))  
  54.    model.add(Dense(num_classes, activation='softmax'))  
  55.    # Horovod: adjust learning rate based on number of GPUs.  
  56.    opt = keras.optimizers.Adadelta(1.0 * hvd.size())  
  57.    # Horovod: add Horovod Distributed Optimizer.  
  58.    opt = hvd.DistributedOptimizer(opt)  
  59.    model.compile(loss=keras.losses.categorical_crossentropy,  
  60.                optoptimizer=opt,  
  61.                metrics=['accuracy'])  
  62.    callbacks = [ 
  63.         # Horovod: broadcast initial variable states from rank 0 to all other processes.  
  64.        # This is necessary to ensure consistent initialization of all workers when  
  65.        # training is started with random weights or restored from a checkpoint.  
  66.        hvd.callbacks.BroadcastGlobalVariablesCallback(0),  
  67.    ]  
  68.    # Horovod: save checkpoints only on worker 0 to prevent other workers from corrupting them.  
  69.    if hvd.rank() == 0:  
  70.        callbacks.append(keras.callbacks.ModelCheckpoint('./checkpoint-{epoch}.h5'))  
  71.    model.fit(x_train, y_train, 
  72.             batch_sizebatch_size=batch_size,  
  73.            callbackscallbacks=callbacks,  
  74.            epochsepochs=epochs,  
  75.            verbose=1 
  76.            validation_data=(x_test, y_test))  
  77.    score = model.evaluate(x_test, y_test, verbose=0 
  78.    print('Test loss:', score[0])  
  79.    print('Test accuracy:', score[1]) 
  •  利用horovodrun 執(zhí)行分布式訓(xùn)練

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

5. 總結(jié)

本文分享了通過GPU利用率和分布式訓(xùn)練Horovod框架來提升深度學(xué)習(xí)訓(xùn)練。

  •  并行CPU加載數(shù)據(jù)和預(yù)處理,讓GPU不再等待CPU
  •  采用Horovod讓數(shù)據(jù)并行來提高大數(shù)據(jù)量的訓(xùn)練的迭代時間 

 

責(zé)任編輯:龐桂玉 來源: Python中文社區(qū)
相關(guān)推薦

2013-10-14 14:15:21

程序員讀書

2020-11-05 10:57:47

云計算多云公有云

2018-09-29 15:59:18

APPiOS優(yōu)化

2009-10-20 14:10:00

CCIE考試

2024-11-18 08:08:21

2009-08-05 09:37:11

云計算CIO

2015-11-30 14:10:49

大無線eLTE華為

2018-05-14 12:18:47

AI開發(fā)深度學(xué)習(xí)框架

2023-11-29 13:58:00

模型數(shù)據(jù)

2015-09-15 09:12:04

程序媛Google特殊獎勵

2019-01-24 10:18:25

機器學(xué)習(xí)深度學(xué)習(xí)圖像處理

2015-02-09 13:48:12

2022-05-11 07:17:29

MySQLAnsible運維

2020-05-26 15:16:44

5G兩會全息

2013-11-08 17:33:52

2011-03-01 13:07:36

MySQLOrder by查詢

2019-08-08 17:14:31

5G手機華為三星

2020-07-04 11:01:36

Kotlin開發(fā)Android

2020-03-28 15:48:13

iOS 13.4蘋果體驗

2011-05-27 11:21:58

打印機技巧
點贊
收藏

51CTO技術(shù)棧公眾號