技術分享caffe2分布式平臺安裝部署文檔

      網友投稿 806 2022-05-29

      本文旨在搭建部署Caffe2的分布式環境,支持多機多GPU的神經網絡訓練,最后以resnet50為例進行分布式訓練。

      1??????環境準備

      1.1??????系統準備

      1.1.1????????物理服務器環境

      三臺服務器,硬件配置如下:

      服務器名稱

      CPU

      內存

      GPU

      顯存

      server1

      Xeon E5-2680 v4

      440 GB

      Tesla P100

      16 GB

      server2

      Xeon E5-2680 v4

      440 GB

      Tesla P100

      16 GB

      server3

      Xeon E5-2680 v4

      440 GB

      Tesla P4

      8 GB

      系統環境如下:

      服務器名稱

      系統

      IP

      CUDA版本

      server1

      Ubuntu 16.04

      192.168.133.10

      8.0

      server2

      Ubuntu 16.04

      192.168.133.11

      8.0

      server3

      Ubuntu 16.04

      192.168.133.12

      8.0

      在每個服務器上安裝docker,隨后安裝nvidia-docker插件這里不再給出步驟,參考https://docs.docker.com/install/linux/docker-ce/ubuntu/

      https://github.com/NVIDIA/nvidia-docker/wiki/Frequently-Asked-Questions#setting-up

      1.1.2????????容器環境準備

      選擇某個物理主機,創建一個鏡像,并且編譯caffe2,隨后將鏡像保存后push到私有倉庫,其他物理主機直接拉取鏡像即可完成包含caffe2的容器創建,這里選擇server1。

      在server1物理服務器上拉取NVIDIA包含cuda的官方鏡像,地址https://hub.docker.com/r/nvidia/cuda/(這里沒有直接拉取caffe2的官方鏡像,是為了能夠方便自行編譯,并且caffe2官方鏡像中的版本時間較早,不一定能滿足需求)這里選擇了包含CUDA 8.0的devel版本,方便編譯caffe2(base和runtime版本不支持cuda應用的源碼編譯,只支持編譯好的應用)。

      docker pull nvidia/cuda:8.0-devel-ubuntu16.04

      使用nvidia-docker啟動容器,支持GPU。

      nvidia-docker run -it --name caffe2 --net=host --hostname caffe2 --dns 8.8.8.8 –v /mnt:/mnt nvidia/cuda:8.0-devel-ubuntu16.04 bash

      容器操作系統:Ubuntu 16.04,64位版本,用戶:root

      1.2??????網絡配置

      容器內的操作系統需要proxy代理方能連接yum源安裝軟件包。

      本文使用的代理是http://192.168.5.18:3128,編輯根目錄下的.bashrc?或者/etc/profile文件,在最后增加如下幾行:

      export http_proxy="http://192.168.5.18:3128"

      export https_proxy="http://192.168.5.18:3128"

      export ip_range=$(echo 192.168.79.{1..255} | sed 's/ /,/g')

      export no_proxy="localhost,127.0.0.1,$ip_range,.huawei.com"

      之后source .bashrc?或者?source /etc/profile即可。

      使用curl baidu.com驗證,如果有內容輸出說明網絡已連通。

      2??????部署caffe2

      首先在單個節點的容器中完成caffe2的編譯安裝,隨后拓展到其他節點。

      2.1??????安裝依賴包

      2.1.1????????配置軟件源

      由于鏡像中沒有編輯器,先安裝vim

      apt-get update && apt-get install vim

      更換軟件源(速度更快一點),首先備份已有源

      cd /etc/apt && mv sources.list sources.list.bk

      下載或者通過vim將163或者阿里源寫入sources.list中。

      deb http://mirrors.163.com/ubuntu/ trusty main restricted universe multiverse

      deb http://mirrors.163.com/ubuntu/ trusty-security main restricted universe multiverse

      deb http://mirrors.163.com/ubuntu/ trusty-updates main restricted universe multiverse

      deb http://mirrors.163.com/ubuntu/ trusty-proposed main restricted universe multiverse

      deb http://mirrors.163.com/ubuntu/ trusty-backports main restricted universe multiverse

      deb-src http://mirrors.163.com/ubuntu/ trusty main restricted universe multiverse

      deb-src http://mirrors.163.com/ubuntu/ trusty-security main restricted universe multiverse

      deb-src http://mirrors.163.com/ubuntu/ trusty-updates main restricted universe multiverse

      deb-src http://mirrors.163.com/ubuntu/ trusty-proposed main restricted universe multiverse

      deb-src http://mirrors.163.com/ubuntu/ trusty-backports main restricted universe multiverse

      更新列表

      apt-get update

      2.1.2????????安裝依賴包

      apt-get install openssh-server

      apt-get install -y --no-install-recommends build-essential cmake git libgoogle-glog-dev libgtest-dev libiomp-dev libleveldb-dev liblmdb-dev libopencv-dev libopenmpi-dev libsnappy-dev libprotobuf-dev openmpi-bin openmpi-doc protobuf-compiler protobuf-c-compiler libgflags-dev python-dev python-pip python-setuptools graphviz

      與官方推薦的依賴包相比增加了一些必要的依賴包。

      2.1.3????????安裝python依賴庫

      sudo pip install flask future hypothesis numpy protobuf pydot python-nvd3 pyyaml requests scikit-image scipy setuptools six tornado jupyter matplotlib pydot

      與官方推薦的庫相比增加了一些必要的庫。

      2.1.4????????安裝cuDNN

      由于鏡像中包含了CUDA,所以這里只需要安裝cuDNN加速庫即可,兩種方法:

      安裝cuDNN方法1:

      添加源

      echo "deb http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64 /" > /etc/apt/sources.list.d/nvidia-ml.list

      更新列表并安裝

      apt-get update

      apt-get install -y --no-install-recommends libcudnn7=7.1.2.21-1+cuda8.0 libcudnn7-dev=7.1.2.21-1+cuda8.0

      rm -rf /var/lib/apt/lists/*

      安裝cuDNN方法2:

      下載源碼包并解壓,在https://developer.nvidia.com/rdp/cudnn-download下載cuDNN支持8.0的版本

      tar -xzvf cudnn-8.0-linux-x64-v7.1.tgz

      cd cuda/include/cudnn.h /usr/local/cuda/include/

      cp cuda/lib64/libcudnn* /usr/local/cuda/lib64/

      rm cudnn-8.0-linux-x64-v7.1.tgz && sudo ldconfig

      配置環境變量

      export PATH=/usr/local/cuda-8.0/bin:$PATH

      export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64:/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH

      2.2??????編譯Caffe2

      2.2.1????????下載caffe2源代碼

      下載方法1:

      cd /opt && git clone --recursive https://github.com/caffe2/caffe2.git

      下載方法2:

      如果公司內部服務器無法直接下載,可以在windows上安裝git進行下載。注意要設置proxy?,參考http://3ms.huawei.com/km/blogs/details/5098499。(另外直接在瀏覽器下載源代碼zip的方式最終在編譯時會出錯,原因在于此類方式會少下載third-party那部分源代碼,因此必須使用git加--recursive的方式來下載這些submodule,否則它們不會直接下載)

      2.2.2????????編譯安裝caffe2

      cd /opt/caffe2 && mkdir build && cd build

      cmake ..

      make install

      編譯時可能遇到cmake版本過低的問題,解決方法參考Troubleshooting。

      環境變量設置

      在/etc/profile中添加

      export PYTHONPATH=/usr/local:$PYTHONPATH

      export PYTHONPATH=/opt/caffe2/build:$PYTHONPATH

      export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

      2.2.3????????測試caffe2

      cd ~ && python -c 'from caffe2.python import core' 2>/dev/null && echo "Success" || echo "Failure"

      輸出Success則表示成功

      檢測GPU是否生效(GPU支持并且cuda安裝正常時可使用)。

      python caffe2/python/operator_test/relu_op_test.py

      python2 -c 'from caffe2.python import workspace; print(workspace.NumCudaDevices())'

      輸出結果大于0說明GPU正常被使用,否則會報錯。

      2.3??????NFS共享目錄部署

      由于Caffe2在進行分布式訓練時,需要共享目錄完成參數的rendezvous,可以使用NFS或者Redis,這里選擇NFS快速搭建一個可用的分布式環境。由于容器不能直接掛載NFS共享目錄,或者這里通過物理主機映射的方式來實現共享。

      2.3.1????????NFS共享服務器搭建

      首先選擇一個物理主機搭建NFS server,這里選擇192.168.133.10,將/export共享出去

      apt-get install nfs-kernel-server

      mkdir /export

      chmod 777 /export

      方便重啟后NFS共享仍然生效,將其寫入/etc/exports

      /export 127.0.0.1(ro,fsid=0,insecure,no_subtree_check,async)

      掛載目錄

      exportfs –a

      2.3.2????????掛載NFS客戶端

      在三個物理主機中都安裝nfs-kernel

      apt-get install nfs-kernel-server

      然后掛載共享目錄

      mount –t nfs?192.168.133.10:/export /mnt

      對于容器訪問NFS共享目錄,則在容器啟動的時候將/mnt映射上去即可。

      將容器打上tag,push到私有倉庫之中,方便在其它主機上啟動。

      docker push 192.168.133.11:5000/caffe2:latest

      這樣該鏡像就有編譯好的caffe2和nfs-kernel

      將剛才的容器關閉,以新的鏡像重新啟動一個容器

      nvidia-docker run -it --name caffe2-dis --net=host --hostname caffe2 --dns 8.8.8.8 -v /mnt:/mnt? 192.168.133.11:5000/caffe2:latest? bash

      在其他兩個節點上則通過拉取來獲取剛才創建的鏡像

      docker pull 192.168.133.11:5000/caffe2:latest

      nvidia-docker run -it --name caffe2-dis --net=host --hostname caffe2 --dns 8.8.8.8 -v /mnt:/mnt? 192.168.133.11:5000/caffe2:latest? bash

      至此包含caffe2并且能訪問NFS共享目錄的分布式環境搭建完畢

      2.4??????Troubleshooting

      (1)編譯時遇到cmake版本過低的問題。

      解決方法:通過源碼重新安裝最新版本的cmake

      在http://www.cmake.org/download/中下載最新源碼包,如cmake-3.10.3.tar,然后執行解壓安裝

      tar –xzvf cmake-3.10.3.tar.gz

      cd cmake-3.10.3

      ./boostrap

      make

      make install

      (2)linux環境下,git caffe2源碼可能遇到證書錯誤。

      解決方法:將github加入到信任列表

      export GIT_SSL_NO_VERIFY=1

      sudo update-ca-certificates

      echo -n | openssl s_client -showcerts -connect github.com:443 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

      (3)make install caffe2的源碼出錯

      [third_party/onnx/onnx/onnx_onnx_c2.pb.cc] Error 1

      解決方法:

      重新下載編譯安裝最新版本的Protobuf,地址https://github.com/google/protobuf/releases/,隨后解壓編譯安裝即可。

      首先刪除原有的低版本軟件包

      apt-get remove protobuf

      然后解壓編譯安裝3.5.1版本

      tar –xzvf protobuf-all-3.5.1.tar.gz

      cd protobuf-3.5.1

      ./autogen.sh

      ./configure

      make

      make check

      make install

      如果protoc不在/usr/bin/下,可以添加連接

      ln -s /usr/local/bin/protoc /usr/bin/protoc

      ln -s /usr/local/lib/libprotobuf.so /usr/lib64/libprotobuf.so

      不然仍然無法通過編譯。

      (5)ImportError: cannot import name caffe2_pb2

      環境變量設置問題,參考官網正確設置PATH,PYTHONPATH,LD_LIBRARY_PATH等變量,使用env查看是否有多余冒號等情況出現。

      (6)cmake時提示無法找到cudnn庫

      這是因為cuDNN的庫解壓后,沒有正確地被添加到/usr/local/cuda/下的原因,可以使用find / -name cudnn.h進行搜索,看是否存在了cudnn.h的頭文件,以確實cudnn是否被正確安裝。不能使用官網中提供的直接解壓到目錄的方法,該方法會導致沒有該庫文件存在,參考文中的方法,拷貝過去即可。

      (7)ImportError: No module named _tkinter, please install the python-tk package

      解決方法:sudo apt-get install python-tk

      (8)如果安裝了anaconda2,可能會遇到python的依賴找不到的情況,導致cmake的時候,numpy等python都找不到。

      解決方法:在PYTHONPATH中添加對應的python路徑,如/root/anaconda2/lib/python2.7/site-packages。并且在此種情況下用conda去管理安裝需要的依賴包。

      (9)WARNING:root:Debug message: /root/anaconda2/bin/../lib/libstdc++.so.6: version `CXXABI_1.3.8' not found?。

      解決方法:

      libstdc++.so.6在系統中的位置為

      /usr/lib/x86_64-linux-gnu/libstdc++.so.6

      這里出錯的原因是該文件在別的位置也存在,如Anaconda中,并且Anaconda中的版本低于系統版本(可以使用strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6查看),解決辦法是將系統中的位置都拷貝過去.

      mv /root/anaconda2/lib/libstdc++.so.6 /root/anaconda2/lib/libstdc++.so.6.bk

      cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21 /root/anaconda2/lib/

      3??????ResNet50訓練實踐

      ResNet50模型是caffe2官網上給出的多GPU訓練的指導的例子,該網絡被用于圖像識別任務,常作為神經網絡訓練性能的基準測試網絡。數據集為ImageNet 1K,但是該數據集過大(約300G空間),GPU太少時訓練時間過長(兩張GPU卡要耗一周),所以這里采用它的一個子集,訓練集包含了640種車和640種船,一共1280張圖片;測試集包含了48種車和48種船,一共96張圖片,數據集總體130MB。

      3.1??????單機訓練測試

      單機上測試ResNet50的構建和訓練,下載數據方便進行分布式地訓練。(地址:https://github.com/caffe2/caffe2/blob/master/caffe2/python/tutorials/Multi-GPU_Training.ipynb)(單機也可以參考官網進行MNIST手寫字符識別任務的學習,地址:https://github.com/caffe2/tutorials/blob/master/MNIST.ipynb)

      3.1.1????????導入數據

      首先,通過代碼下載并且解壓數據(也可以手動進行),代碼:

      from __future__ import absolute_import

      from __future__ import division

      from __future__ import print_function

      from __future__ import unicode_literals

      from caffe2.python import core, workspace, model_helper, net_drawer, memonger, brew

      from caffe2.python import data_parallel_model as dpm

      from caffe2.python.models import resnet

      from caffe2.proto import caffe2_pb2

      import numpy as np

      import time

      import os

      from IPython import display

      workspace.GlobalInit(['caffe2', '--caffe2_log_level=2'])

      # This section checks if you have the training and testing databases

      current_folder = os.path.join(os.path.expanduser('~'), 'caffe2_notebooks')

      data_folder = os.path.join(current_folder, 'tutorial_data', 'resnet_trainer')

      # Train/test data

      train_data_db = os.path.join(data_folder, "imagenet_cars_boats_train")

      train_data_db_type = "lmdb"

      # actually 640 cars and 640 boats = 1280

      train_data_count = 1280

      test_data_db = os.path.join(data_folder, "imagenet_cars_boats_val")

      test_data_db_type = "lmdb"

      # actually 48 cars and 48 boats = 96

      test_data_count = 96

      # Get the dataset if it is missing

      def DownloadDataset(url, path):

      import requests, zipfile, StringIO

      print("Downloading {} ... ".format(url))

      r = requests.get(url, stream=True)

      z = zipfile.ZipFile(StringIO.StringIO(r.content))

      z.extractall(path)

      print("Done downloading to {}!".format(path))

      # Make the data folder if it doesn't exist

      if not os.path.exists(data_folder):

      os.makedirs(data_folder)

      else:

      print("Data folder found at {}".format(data_folder))

      # See if you already have to db, and if not, download it

      if not os.path.exists(train_data_db):

      DownloadDataset("http://download.caffe2.ai/databases/resnet_trainer.zip", data_folder)

      代碼通過官網下載imagenet數據集,隨后將其解壓到文件夾:~/caffe2_notebooks/tutorial_data/resnet_trainer

      完成后我們可以看到該文件夾下包含了imagenet_cars_boats_train和imagenet_cars_boats_val兩個文件夾,分別存儲了訓練數據集和測試數據集。這里記錄了訓練數據集和測試集的位置和數據庫類型、數據大小等信息。

      3.1.2????????配置訓練參數

      配置網絡訓練時采用的參數,代碼如下:

      # Configure how you want to train the model and with how many GPUs

      # This is set to use two GPUs in a single machine, but if you have more GPUs, extend the array [0, 1, 2, n]

      gpus = [0]

      # Batch size of 32 sums up to roughly 5GB of memory per device

      batch_per_device = 32

      total_batch_size = batch_per_device * len(gpus)

      # This model discriminates between two labels: car or boat

      num_labels = 2

      # Initial learning rate (scale with total batch size)

      base_learning_rate = 0.0004 * total_batch_size

      # only intends to influence the learning rate after 10 epochs

      stepsize = int(10 * train_data_count / total_batch_size)

      # Weight decay (L2 regularization)

      weight_decay = 1e-4

      這里指定了使用的GPU、batch size、總batch size(這里單GPU就等于batch size)、標簽數量(兩類船和車)、學習速率、step size、權重衰減值。

      3.1.3????????構建網絡并訓練

      創建網絡并清空工作區,防止上次訓練數據產生的干擾(如果你是第二次運行的話會有影響)

      train_model = model_helper.ModelHelper(name="resnet_test")

      workspace.ResetWorkspace()

      3.1.4????????數據讀取

      創建數據讀取,從之前指定的位置讀取數據作為訓練數據。

      reader = train_model.CreateDB("train_reader", db=train_data_db, db_type=train_data_db_type)

      3.1.5????????圖片輸入

      定義原始圖片輸入的處理方法

      def add_image_input_ops(model):

      # utilize the ImageInput operator to prep the images

      data, label = brew.image_input(model,

      reader,

      ["data", "label"],

      batch_size=batch_per_device,

      # mean: to remove color values that are common

      mean=128.,

      # std is going to be modified randomly to influence the mean subtraction

      std=128.,

      # scale to rescale each image to a common size

      scale=256,

      # crop to the square each image to exact dimensions

      crop=224,

      # not running in test mode

      is_test=False,

      # mirroring of the images will occur randomly

      mirror=1

      )

      # prevent back-propagation: optional performance improvement; may not be observable at small scale

      data = model.net.StopGradient(data, data)

      3.1.6????????定義ResNet50網絡模型創建方法

      def create_resnet50_model_ops(model, loss_scale=1.0):

      # Creates a residual network

      [softmax, loss] = resnet.create_resnet50(

      model,

      "data",

      num_input_channels=3,

      num_labels=num_labels,

      label="label",

      )

      prefix = model.net.Proto().name

      loss = model.net.Scale(loss, prefix + "_loss", scale=loss_scale)

      brew.accuracy(model, [softmax, "label"], prefix + "_accuracy")

      return [loss]

      這里調用了resnet的create_resnet50方法創建網絡,該方法為caffe2官方實現,可以查看源碼深入理解。

      3.1.7????????定義參數更新方法

      def add_parameter_update_ops(model):

      brew.add_weight_decay(model, weight_decay)

      iter = brew.iter(model, "iter")

      lr = model.net.LearningRate(

      [iter],

      "lr",

      base_lr=base_learning_rate,

      policy="step",

      stepsize=stepsize,

      gamma=0.1,

      )

      # Momentum SGD update

      for param in model.GetParams():

      param_grad = model.param_to_grad[param]

      param_momentum = model.param_init_net.ConstantFill(

      [param], param + '_momentum', value=0.0

      )

      # Update param_grad and param_momentum in place

      model.net.MomentumSGDUpdate(

      [param_grad, param_momentum, lr, param],

      [param_grad, param_momentum, param],

      momentum=0.9,

      # Nesterov Momentum works slightly better than standard momentum

      nesterov=1,

      )

      3.1.8????????梯度優化

      def optimize_gradient_memory(model, loss):

      model.net._net = memonger.share_grad_blobs(

      model.net,

      loss,

      set(model.param_to_grad.values()),

      # Due to memonger internals, we need a namescope here. Let's make one up; we'll need it later!

      namescope="imonaboat",

      share_activations=False)

      3.1.9????????創建網絡并且訓練

      強制指定網絡訓練使用的GPU(本機的第一個),隨后調用之前定義的方法創建網絡,并開始訓練。

      # We need to give the network context and force it to run on the first GPU even if there are more.

      device_opt = core.DeviceOption(caffe2_pb2.CUDA, gpus[0])

      # Here's where that NameScope comes into play

      with core.NameScope("imonaboat"):

      # Picking that one GPU

      with core.DeviceScope(device_opt):

      # Run our reader, and create the layers that transform the images

      add_image_input_ops(train_model)

      # Generate our residual network and return the losses

      losses = create_resnet50_model_ops(train_model)

      # Create gradients for each loss

      blobs_to_gradients = train_model.AddGradientOperators(losses)

      # Kick off the learning and managing of the weights

      add_parameter_update_ops(train_model)

      # Optimize memory usage by consolidating where we can

      optimize_gradient_memory(train_model, [blobs_to_gradients[losses[0]]])

      # Startup the network

      workspace.RunNetOnce(train_model.param_init_net)

      # Load all of the initial weights; overwrite lets you run this multiple times

      workspace.CreateNet(train_model.net, overwrite=True)

      num_epochs = 1

      for epoch in range(num_epochs):

      # Split up the images evenly: total images / batch size

      num_iters = int(train_data_count / total_batch_size)

      for iter in range(num_iters):

      # Stopwatch start!

      t1 = time.time()

      # Run this iteration!

      workspace.RunNet(train_model.net.Proto().name)

      t2 = time.time()

      dt = t2 - t1

      # Stopwatch stopped! How'd we do?

      print((

      "Finished iteration {:>" + str(len(str(num_iters))) + "}/{}" +

      " (epoch {:>" + str(len(str(num_epochs))) + "}/{})" +

      " ({:.2f} images/sec)").

      format(iter+1, num_iters, epoch+1, num_epochs, total_batch_size/dt))

      將以上代碼合并或者在python的交互端口依次輸入上述代碼即可開始訓練。

      提示:這部分代碼與官網代碼有部分方法調用上的不同,可能是caffe2接口更新,但是官方文檔到目前為止還未更新的原因。建議在代碼中,將model.xxx創建算子的方法更改為使用brew.xxx的幫手函數方法,增加第一個參數為定義的model即可。

      3.2??????分布式訓練測試

      3.2.1????????下載resnet50代碼

      在每個節點上完成單機測試之后,即可開始分布式的測試。訓練數據即是剛才我們下載的數據,代碼為官方在github上給出的代碼,下載下來后命名為resnet50_trainer.py。

      (地址:https://github.com/caffe2/caffe2/blob/master/caffe2/python/examples/resnet50_trainer.py)

      3.2.2????????重要提示

      容器內進行分布式訓練,需要修改/etc/hosts,將該容器的域名解析設置為自己物理主機的IP,如

      192.168.133.10? caffe2

      如果不修改,會發生Gloo在通信時無法發現對方主機,無法建立socket連接(因此推測Gloo是根據IP進行通信的)。

      3.2.3????????分布式訓練

      訓練時需要在每個節點上依次輸入命令,在這里具體的命令為(節點更多時可以通過腳本來完成):

      第一個節點:

      time python resnet50_trainer.py --train_data ~/caffe2_notebooks/tutorial_data/resnet_trainer/imagenet_cars_boats_train/ --test_data ~/caffe2_notebooks/tutorial_data/resnet_trainer/imagenet_cars_boats_val/ --gpus 0 --num_labels 2 --base_learning_rate 0.0384? --batch_size 32 --epoch_size 1280 --num_epochs 10 --num_shards 3 --shard_id 0 --run_id 1234 --file_store_path=/mnt/

      第二個節點:

      time python resnet50_trainer.py --train_data ~/caffe2_notebooks/tutorial_data/resnet_trainer/imagenet_cars_boats_train/ --test_data ~/caffe2_notebooks/tutorial_data/resnet_trainer/imagenet_cars_boats_val/ --gpus 0 --num_labels 2 --base_learning_rate 0.0384? --batch_size 32 --epoch_size 1280 --num_epochs 10 --num_shards 3 --shard_id 1--run_id 1234 --file_store_path=/mnt/

      第三個節點:

      time python resnet50_trainer.py --train_data ~/caffe2_notebooks/tutorial_data/resnet_trainer/imagenet_cars_boats_train/ --test_data ~/caffe2_notebooks/tutorial_data/resnet_trainer/imagenet_cars_boats_val/ --gpus 0 --num_labels 2 --base_learning_rate 0.0384? --batch_size 32 --epoch_size 1280 --num_epochs 10 --num_shards 3 --shard_id 2 --run_id 1234 --file_store_path=/mnt/

      可以看到三個節點上的命令基本相同,唯一不同的是shard-ids參數,它作為了每個節點的唯一標識,其他的參數解釋參考下一節。

      3.2.4????????參數解釋

      參數的解釋可以參考官網,個人的理解如下:

      參數

      個人理解

      train_data

      必備,訓練數據集的位置,文件夾即可

      test_data

      可選,測試數據集的位置,文件夾即可

      db_type

      可選,數據庫類型,默認lmdb

      gpus

      可選,指定當前節點上使用的gpu的ID列表,從0開始,用“,”隔開

      num_gpus

      可選,指定當前節點上的gpu個數,可用于替代gpu數目

      num_channels

      可選,圖片的顏色通道數目,默認為3

      image_size

      輸入圖片的像素尺寸,高或寬,假設圖片是正方形,默認227,可能不能應對小尺寸

      num_labels

      數據中的標簽數量,默認是1000類,可以根據輸入數據集而變化,這里的命令設置為2類

      batch_size

      batch的大小,這里指的是該節點上所有GPU的batch size,而不是所有節點的,單個GPU默認是32,根據該節點上的GPU數量增加

      epoch_size

      每個epoch輸入的數量,默認未1500000,可以自定義,如caffe2官網提供的小數據集有1280張

      num_epochs

      epoch數量

      base_learning_rate

      學習速率,官方建議設置為所有節點batch_size之和*0.0004,默認值為0.1,假設所有節點的batch size之和為256的學習速率值,根據自己設定的總batch size而改變(不是該節點上的batch size)

      weight_decay

      權重衰減

      num_shards

      分布式訓練時的機器節點數量,默認為1,單節點,

      shard_id

      該節點的shard ID,默認為0,將第一個節點設置為0,后續節點依次設置為1,2,3……即可

      run_id

      運行ID標識,用于分布式運行時,所有節點相互標識,參與該次訓練的所有節點保持一致即可

      redis_host

      Redis服務器的端口,用作rendezvous

      redis_port

      Redis服務器的IP

      file_store_path

      共享目錄位置,用于不同節點參數同步的臨時文件夾,作為redis的替代,兩者二選一即可,這里使用之前掛載的NFS目錄。

      3.3??????簡單的性能測試

      使用resnet50_trainer.py,我們在配置好的物理環境中測試分布式測試的性能,結果如下(單機命令去掉num_shards等分布式所需的命令,修改batch size即可):

      服務器數目

      GPU/服務器

      總GPU數目

      單節點Batch?size

      時間(s)

      1

      1(p100)

      1

      32

      415.5

      1

      1(p100)

      1

      64

      585

      1

      1(p4)

      1

      32

      671

      2

      1

      2(p4+p100)

      32

      516

      2

      1

      2(p100*2)

      32

      【技術分享】caffe2分布式平臺安裝部署文檔

      283

      3

      1

      3(p100*2+p4)

      32

      410

      該測試為單次測試結果,沒有多次重復進行,數據不嚴謹,僅作為分布式訓練能力的探測,并且部分GPU加速、網絡分發未優化。

      可以看到P100和P4在性能上差距還是蠻大的,在測試過程中P4卡上batch size設置為64時便出現了out of memory的錯誤提示。因為P4卡的存在,多機分布式訓練時反而降低了訓練速度,看來使用同步的隨機梯度優化還是使用同構的硬件比較好,不然會嚴重影響效率。

      3.4??????Troubleshooting

      分布式過程中遇到的大部分問題,如connection error、Aborted (core dumped)都是由多節點的網絡通信異常引起的,首先是保證各個節點自己能夠解析自己的主機名(如本文中的caffe2),隨后會使用解析出來的IP進行通信,然后保證節點之間能夠順利完成通信便可以解決大部分的訓練問題。

      4??????參考資料

      https://caffe2.ai/docs/getting-started.html?platform=ubuntu&configuration=compile

      https://caffe2.ai/docs/getting-started.html?platform=centos&configuration=cloud

      https://github.com/caffe2/tutorials/blob/master/MNIST.ipynb

      https://github.com/caffe2/caffe2/blob/master/caffe2/python/tutorials/Multi-GPU_Training.ipynb

      https://github.com/caffe2/caffe2/blob/master/caffe2/python/examples/resnet50_trainer.py

      https://blog.csdn.net/zziahgf/article/details/79022490

      https://hub.docker.com/r/nvidia/cuda/

      人工智能

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:接口工具使用對比 (apipost、jmeter、postman、swagger )
      下一篇:[跟著官方文檔學JUnit5][七][WritingTests][學習筆記]
      相關文章
      亚洲youwu永久无码精品| 亚洲成人福利网站| 亚洲AV无码乱码在线观看代蜜桃 | 亚洲成熟丰满熟妇高潮XXXXX| 亚洲伦理中文字幕| 亚洲国产日韩在线人成下载| 337p日本欧洲亚洲大胆艺术| 久久亚洲国产成人亚| 亚洲AV无一区二区三区久久| 亚洲精品乱码久久久久66| 国产亚洲精品精品国产亚洲综合| 亚洲国产成人乱码精品女人久久久不卡| 亚洲AV无码专区在线电影成人| 亚洲乱妇老熟女爽到高潮的片| 亚洲欧洲无码一区二区三区| 亚洲精品色播一区二区| 亚洲av最新在线观看网址| 亚洲a∨无码精品色午夜| 怡红院亚洲红怡院在线观看| 亚洲A丁香五香天堂网| 亚洲午夜爱爱香蕉片| 中文字幕精品亚洲无线码一区| 亚洲精品你懂的在线观看| 亚洲国产成人片在线观看无码| 午夜亚洲AV日韩AV无码大全| 亚洲美女中文字幕| 亚洲国产成人91精品| 中文字幕无码亚洲欧洲日韩| 亚洲精品美女久久久久久久| 色五月五月丁香亚洲综合网| 亚洲精品和日本精品| 亚洲日产无码中文字幕| 亚洲伦另类中文字幕| 亚洲影视一区二区| 亚洲人成电影网站色www| 亚洲AV伊人久久青青草原 | 国产精品亚洲四区在线观看| 亚洲а∨精品天堂在线| 久久久久亚洲av成人无码电影 | 久久亚洲精品11p| 亚洲国产综合久久天堂|