前文已經給出1.3.0gpu版本的編譯及安裝,本文在此基礎上進行分布式組件的安裝,前文信息參看:
國產計算框架mindspore在gpu環境下編譯分支r1.3,使用suod權限成功編譯並安裝,成功運行——(修復部分bug,給出具體編譯和安裝過程)—— 第一部分:依賴環境的安裝
國產計算框架mindspore在gpu環境下編譯分支r1.3,使用suod權限成功編譯並安裝,成功運行——(修復部分bug,給出具體編譯和安裝過程)—— 第二部分:源碼編譯及編譯后文件安裝、運行
===============================================================
准備工作:
(因為mindspore對應的nccl2.7.6對應的cuda版本為10.1,因此我們這里需要安裝cuda10.1,需要注意的是我們前面兩個文章介紹的是在cuda11.1環境下編譯源代碼,但是如果要使用分布式功能的話必須使用cuda10.1版本,因此前面的兩個介紹mindspore源碼編譯的文章中對應的cuda版本和cudnn版本也需要進行替換)
cuda10.1的安裝:
下載地址:
https://developer.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.105_418.39_linux.run
安裝:
sudo sh ./cuda_10.1.105_418.39_linux.run --toolkit --silent
cudnn 的安裝:
下載地址:
解壓文件:
tar -zxvf cudnn-10.1-linux-x64-v7.6.5.32.tgz
拷貝解壓后的文件到cuda安裝目錄內:
sudo cp cuda/include/* /usr/local/cuda/include
sudo cp cuda/lib64/* /usr/local/cuda/lib64
配置環境變量:
修改 .bashrc 文件
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
重新載入 .bashrc 文件:
source ~/.bashrc
===============================================================
OpenMPI 的安裝:
OpenMPI-4.0.3
:MindSpore采用的多進程通信庫。
OpenMPI-4.0.3源碼下載地址:
https://download.open-mpi.org/release/open-mpi/v4.0/openmpi-4.0.3.tar.gz
參考OpenMPI官網教程安裝:https://www.open-mpi.org/faq/?category=building#easy-build。
先安裝依賴環境:
sudo apt-get install libibverbs1
解壓:
tar -zxvf openmpi-4.0.3.tar.gz
配置:
./configure --prefix=/usr/local --enable-mpi-threads --enable-progress-threads --enable-shared --with-threads=poxis --enable-mpi-thread-multiple --with-cuda=/usr/local/cuda
(注意:這里我們假設cuda的安裝目錄為: /usr/local/cuda , 該地址可以按照具體情況進行修改)
編譯並安裝:
make&&sudo make install
測試openmpi是否安裝成功:
進入到examples文件夾中,執行make
命令
,
編譯一下測試代碼,如果編譯沒有報錯執行下面的測試語句:
mpirun -np 4 hello_c
驗證已經成功安裝openmpi 。
NCCL 的安裝:
下載地址:
(具體版本需要根據mindspore的版本來決定,這里對應的mindspore版本為1.3.0)
1. 根據nccl官網進行系統配置:
In the following commands, please replace<architecture>with your CPU architecture:x86_64,ppc64le, orsbsa, and replace<distro>with the Ubuntu version, for exampleubuntu1604,ubuntu1804, orubuntu2004.
本機環境:<architecture> 為 x86_64 , <distro> 為ubuntu1804 。
於是需執行命令:
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
2. 安裝剛才下載的 deb 文件:
sudo dpkg -i nccl-repo-ubuntu1804-2.7.6-ga-cuda10.1_1-1_amd64.deb
3. 更新 apt
sudo apt update
4. Install thelibnccl2package with APT. Additionally, if you need to compile applications with NCCL, you can install thelibnccl-devpackage as well
安裝 libnccl2 、 libnccl-dev
從剛才的官方nccl下載頁面可以知道,對應的 libnccl2 、 libnccl-dev 版本。
sudo apt install libnccl2=2.7.6-1+cuda10.1 libnccl-dev=2.7.6-1+cuda10.1
5. 使用 nccl-test 來測試是否安裝成功
本機為8核心CPU:I7-9700K, 單卡GPU:2060SUPER
因此測試命令:
./build/all_reduce_perf -b 8 -e 128M -f 2 -g 1
mpirun -np 8 ./build/all_reduce_perf -b 8 -e 128M -f 2 -g 1
nccl的測試方法具體參看:https://www.cnblogs.com/devilmaycry812839668/p/15023221.html
測試安裝號openmpi及nccl組件后的mindspore是否可以成功運行分布式代碼:
(參看:https://www.cnblogs.com/devilmaycry812839668/p/15022320.html)
(mindspore的安裝這里不進行介紹,具體可以參看前文)
============================================================================
安裝好openmpi 和 nccl 后需要配置主機的免登錄:
免密登陸配置:
主機間免密登陸(涉及多機訓練時需要)。若訓練涉及多機,則需要配置多機間免密登陸,可參考以下步驟進行配置:
- 每台主機確定同一個用戶作為登陸用戶(不推薦root);
- 執行ssh-keygen -t rsa -P ""生成密鑰;
- 執行ssh-copy-id DEVICE-IP設置需要免密登陸的機器IP;
- 執行ssh DEVICE-IP,若不需要輸入密碼即可登錄,則說明以上配置成功;
- 在所有機器上執行以上命令,確保兩兩互通。
如果只設置本機,操作如下:
ssh-keygen -t rsa -P "" ssh-copy-id 127.0.0.1
以上為配置的全部步驟,下面進行測試環境是否可以成功運行:
運行代碼:( test_nonlinear.py )
from mindspore import context from mindspore.communication.management import init context.set_context(mode=context.GRAPH_MODE, device_target="GPU") init() import numpy as np from mindspore import dataset as ds from mindspore import nn, Tensor, Model import time from mindspore.train.callback import Callback, LossMonitor, ModelCheckpoint, CheckpointConfig from mindspore.context import ParallelMode import mindspore as ms ms.common.set_seed(0) start_time = time.time() def get_data(num, a=2.0, b=3.0, c=5.0): for _ in range(num): x = np.random.uniform(-1.0, 1.0) y = np.random.uniform(-1.0, 1.0) noise = np.random.normal(0, 0.03) z = a * x ** 2 + b * y ** 3 + c + noise yield np.array([[x**2], [y**3]],dtype=np.float32).reshape(1,2), np.array([z]).astype(np.float32) def create_dataset(num_data, batch_size=16, repeat_size=1): input_data = ds.GeneratorDataset(list(get_data(num_data)), column_names=['xy','z']) input_data = input_data.batch(batch_size) input_data = input_data.repeat(repeat_size) return input_data data_number = 1600 batch_number = 64 repeat_number = 20 context.set_auto_parallel_context(parallel_mode=ParallelMode.DATA_PARALLEL) ds_train = create_dataset(data_number, batch_size=batch_number, repeat_size=repeat_number) dict_datasets = next(ds_train.create_dict_iterator()) class LinearNet(nn.Cell): def __init__(self): super(LinearNet, self).__init__() self.fc = nn.Dense(2, 1, 0.02, 0.02) def construct(self, x): x = self.fc(x) return x net = LinearNet() model_params = net.trainable_params() print ('Param Shape is: {}'.format(len(model_params))) for net_param in net.trainable_params(): print(net_param, net_param.asnumpy()) net_loss = nn.loss.MSELoss() optim = nn.Momentum(net.trainable_params(), learning_rate=0.01, momentum=0.6) ckpt_config = CheckpointConfig() ckpt_callback = ModelCheckpoint(prefix='data_parallel', config=ckpt_config) model = Model(net, net_loss, optim) epoch = 1000 #model.train(epoch, ds_train, dataset_sink_mode=True) #model.train(epoch, ds_train, callbacks=[ckpt_callback], dataset_sink_mode=True) model.train(epoch, ds_train, callbacks=[LossMonitor(500)], dataset_sink_mode=True) for net_param in net.trainable_params(): print(net_param, net_param.asnumpy()) print ('The total time cost is: {}s'.format(time.time() - start_time))
代碼原地址:
https://www.cnblogs.com/dechinphy/p/dms.html
由於運行的服務器是有1卡,因此我們的運行命令如下:
mpirun -n 1 python ./test_nonlinear.py
-------------------------------------------------
神奇的一點是我們安裝的是gpu版本的mindspore, 執行mpirun的時候-n 后的數值為gpu的卡數,如果只有一個卡的話則-n 1, 兩個卡就是-n 2,以此類推,-n 4則是分別在4張卡上並行運行。其中,-n 后的數值一點要小於本機的GPU卡數,否則報錯。
如在一張卡的機器上運行命令:
mpirun -n 2 python ./test_nonlinear.py
報錯信息:
RuntimeError: mindspore/ccsrc/runtime/device/gpu/gpu_device_manager.cc:27 InitDevice] Op Error: Failed to set current device id | Error Number: 0
參考:
https://blog.csdn.net/adsjlnmj66029/article/details/101567978
https://www.cnblogs.com/devilmaycry812839668/p/15023229.html
https://www.cnblogs.com/devilmaycry812839668/p/15023221.html
https://www.cnblogs.com/devilmaycry812839668/p/15022320.html