• [其他干货] CUDA编程(二)CUDA代码执行原理
    我们把 CPU,内存这块区域叫做“主机(HOST)”,把GPU,显存这块区域叫做“设备(DEVICE)”。(是不是跟昇腾有点类似?)CUDA的代码执行包含以下几步:简述一下,就是 host_to_device-》在device上并行计算-》device_to_host。cuda程序其实是一个对C的扩展程序。其后缀名为.cu,如果头文件则为.cuh。这个.cu 程序除了C程序的语法外,还有一些cuda的特有部分,比如它在函数前面加了前缀,分为 __global__, __host__,__device__ 三种。对于__global__:所谓的“执行配置”,下面会提到,比如说是 <<< >>>中间的内容。这个标识符将一个C函数声明成一个 核函数。它只能在设备(device)上执行。对于__host__:对于__device_:这几个前缀定义了这些代码运行的设备,这会让程序决定在哪个设备上运行。对于一个简单的Hello World代码而言:#include <stdio.h> void hello_from_cpu() { printf("Hello World from the CPU!\n"); } int main(void) { hello_from_cpu(); return 0;如果我们想让它在GPU上运行,仅需要做两步:(1)将被调用的函数 hello_from_cpu 改为 hello_from_gpu ,前面加上 __global__ 将其定义为核函数。(2)在main主函数调用的时候,加上执行配置<<< >>>部分,如加上<<<1,1>>>则为并行1次,如加上<<<2,4>>>则运行 2X4次。我们看看实际代码修改后的效果:#include <stdio.h> __global__ void hello_from_gpu() { printf("Hello World from the GPU!\n"); } int main(void) { hello_from_gpu<<<1,1>>>(); return 0; }cu代码必须使用nvcc编译,编译的时候要根据GPU架构的不同填不同的参数。其中,arch参数如下:code参数如下:举个简单的例子,张小白这台笔记本的显卡是Quardo P1000,是Pascal架构,那么参数是compute_61和sm_61.我们执行以下语句:/usr/local/cuda/bin/nvcc -arch=compute_61 -code=sm_61 hello_cuda.cu -o hello_cuda./hello_cuda如果将执行配置改为2,4:可以发现这个核函数被执行了8次。
  • [分布式并行] MindSpore易点通·精讲系列--模型训练之GPU分布式并行训练
    # Dive Into MindSpore -- Distributed Training With GPU For Model Train > MindSpore易点通·精讲系列--模型训练之GPU分布式并行训练 本文开发环境 - Ubuntu 20.04 - Python 3.8 - MindSpore 1.7.0 - OpenMPI 4.0.3 - RTX 1080Ti * 4 本文内容摘要 - 基础知识 - 环境搭建 - 单卡训练 - 多卡训练--OpenMPI - 多卡训练--非OpenMPI - 本文总结 - 遇到问题 - 本文参考 ## 1. 基础知识 ### 1.1 概念介绍 在深度学习中,随着模型和数据的不断增长,在很多情况下需要使用单机多卡或者多机多卡进行训练,即分布式训练。分布式训练策略按照并行方式不同,可以简单的分为数据并行和模型并行两种方式。 - 数据并行 - 数据并行是指在不同的 GPU 上都 copy 保存一份模型的副本,然后将不同的数据分配到不同的 GPU 上进行计算,最后将所有 GPU 计算的结果进行合并,从而达到加速模型训练的目的。 - 模型并行 - 与数据并行不同,分布式训练中的模型并行是指将整个神经网络模型拆解分布到不同的 GPU 中,不同的 GPU 负责计算网络模型中的不同部分。这通常是在网络模型很大很大、单个 GPU 的显存已经完全装不下整体网络的情况下才会采用。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/15/1657853676059222796.png) ### 1.2 MindSpore中的支持 `1.1`中介绍了理论中的并行方式,具体到`MIndSpore`框架中,目前支持下述的四种并行模式: - 数据并行:用户的网络参数规模在单卡上可以计算的情况下使用。这种模式会在每卡上复制相同的网络参数,训练时输入不同的训练数据,适合大部分用户使用。 - 半自动并行:用户的神经网络在单卡上无法计算,并且对切分的性能存在较大的需求。用户可以设置这种运行模式,手动指定每个算子的切分策略,达到较佳的训练性能。 - 自动并行:用户的神经网络在单卡上无法计算,但是不知道如何配置算子策略。用户启动这种模式,`MindSpore`会自动针对每个算子进行配置策略,适合想要并行训练但是不知道如何配置策略的用户。 - 混合并行:完全由用户自己设计并行训练的逻辑和实现,用户可以自己在网络中定义`AllGather`等通信算子。适合熟悉并行训练的用户。 对于大部分用户来说,其实能够用到的是数据并行模式,所以下面的案例中,会以数据并行模式来展开讲解。 ## 2. 环境搭建 ### 2.1 MindSpore安装 略。可参考笔者之前的文章[MindSpore入门--基于GPU服务器安装MindSpore 1.5.0](https://bbs.huaweicloud.com/forum/thread-179309-1-1.html),注意将文章中的`MindSpore`版本升级到`1.7.0`。 ### 2.2 OpenMPI安装 在`GPU`硬件平台上,`MindSpore`采用`OpenMPI`的`mpirun`进行分布式训练。所以我们先来安装`OpenMPI`。 本文安装的是`4.0.3`版本,安装命令如下: ```shell wget -c https://download.open-mpi.org/release/open-mpi/v4.0/openmpi-4.0.3.tar.gz tar xf openmpi-4.0.3.tar.gz cd openmpi-4.0.3/ ./configure --prefix=/usr/local/openmpi-4.0.3 make -j 16 sudo make install echo -e "export PATH=/usr/local/openmpi-4.0.3/bin:\$PATH" >> ~/.bashrc echo -e "export LD_LIBRARY_PATH=/usr/local/openmpi-4.0.3/lib:\$LD_LIBRARY_PATH" >> ~/.bashrc source ~/.bashrc ``` 使用`mpirun --version`命令验证是否安装成功,输出如下内容: ```shell mpirun (Open MPI) 4.0.3 Report bugs to http://www.open-mpi.org/community/help/ ``` ### 2.3 环境验证 上面基础环境安装完成后,我们对环境进行一个初步验证,来看看是否搭建成功。 验证代码如下: ```python # nccl_allgather.py import numpy as np import mindspore.ops as ops import mindspore.nn as nn from mindspore import context, Tensor from mindspore.communication import init, get_rank class Net(nn.Cell): def __init__(self): super(Net, self).__init__() self.allgather = ops.AllGather() def construct(self, x): return self.allgather(x) if __name__ == "__main__": context.set_context(mode=context.GRAPH_MODE, device_target="GPU") init("nccl") value = get_rank() input_x = Tensor(np.array([[value]]).astype(np.float32)) net = Net() output = net(input_x) print(output) ``` 将上面代码保存到文件`nccl_allgather.py`中,运行命令: > 命令解读: > > - `-n` 后面数字代表使用GPU的数量,这里使用了机器内全部GPU。如果读者不想使用全部,记得设置相应的环境变量。 ```shell mpirun -n 4 python3 nccl_allgather.py ``` 输出内容如下: ```shell [[0.] [1.] [2.] [3.]] [[0.] [1.] [2.] [3.]] [[0.] [1.] [2.] [3.]] [[0.] [1.] [2.] [3.]] ``` 至此,我们的环境搭建完成,且验证成功。 ## 3. 单卡训练 为了能够后续进行对比测试,这里我们先来进行单卡训练,以此做为基准。 ### 3.1 代码部分 > 代码说明: > > 1. 网络结构采用的是`ResNet-50`,读者可以在`MindSpore Models`仓库进行获取,复制粘贴过来即可,[ResNet-50代码链接](https://gitee.com/mindspore/mindspore/blob/r1.1/model_zoo/official/cv/resnet/src/resnet.py)。 > 2. 数据集采用的是`Fruit-360`数据集,有关该数据集的更详细介绍可以参看笔者之前的文章[MindSpore易点通·精讲系列--数据集加载之ImageFolderDataset](https://bbs.huaweicloud.com/forum/thread-190708-1-1.html)。[数据集下载链接](https://git.openi.org.cn/kaierlong/Fruits_360/datasets) > 3. 读者注意将代码中的`train_dataset_dir`和`test_dataset_dir`替换为自己的文件目录。 单卡训练的代码如下: ```python import numpy as np from mindspore import context from mindspore import nn from mindspore.common import dtype as mstype from mindspore.common import set_seed from mindspore.common import Tensor from mindspore.communication import init, get_rank, get_group_size from mindspore.dataset import ImageFolderDataset from mindspore.dataset.transforms.c_transforms import Compose, TypeCast from mindspore.dataset.vision.c_transforms import HWC2CHW, Normalize, RandomCrop, RandomHorizontalFlip, Resize from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits from mindspore.nn.optim import Momentum from mindspore.ops import operations as P from mindspore.ops import functional as F from mindspore.train import Model from mindspore.train.callback import CheckpointConfig, ModelCheckpoint, LossMonitor from scipy.stats import truncnorm # define reset50 def create_dataset(dataset_dir, mode="train", decode=True, batch_size=32, repeat_num=1): if mode == "train": shuffle = True else: shuffle = False dataset = ImageFolderDataset( dataset_dir=dataset_dir, shuffle=shuffle, decode=decode) mean = [127.5, 127.5, 127.5] std = [127.5, 127.5, 127.5] if mode == "train": transforms_list = Compose( [RandomCrop((32, 32), (4, 4, 4, 4)), RandomHorizontalFlip(), Resize((100, 100)), Normalize(mean, std), HWC2CHW()]) else: transforms_list = Compose( [Resize((128, 128)), Normalize(mean, std), HWC2CHW()]) cast_op = TypeCast(mstype.int32) dataset = dataset.map(operations=transforms_list, input_columns="image") dataset = dataset.map(operations=cast_op, input_columns="label") dataset = dataset.batch(batch_size=batch_size, drop_remainder=True) dataset = dataset.repeat(repeat_num) return dataset def run_train(): context.set_context(mode=context.GRAPH_MODE, device_target="GPU") set_seed(0) train_dataset_dir = "/mnt/data_0002_24t/xingchaolong/dataset/Fruits_360/fruits-360_dataset/fruits-360/Training" test_dataset_dir = "/mnt/data_0002_24t/xingchaolong/dataset/Fruits_360/fruits-360_dataset/fruits-360/Test" batch_size = 32 train_dataset = create_dataset(dataset_dir=train_dataset_dir, batch_size=batch_size) test_dataset = create_dataset(dataset_dir=test_dataset_dir, mode="test") train_batch_num = train_dataset.get_dataset_size() test_batch_num = test_dataset.get_dataset_size() print("train dataset batch num: {}".format(train_batch_num), flush=True) print("test dataset batch num: {}".format(test_batch_num), flush=True) # build model net = resnet50(class_num=131) loss = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") optim = Momentum(params=net.trainable_params(), learning_rate=0.01, momentum=0.9, loss_scale=1024.0) model = Model(net, loss_fn=loss, optimizer=optim, metrics={"accuracy"}) # CheckPoint CallBack definition config_ck = CheckpointConfig(save_checkpoint_steps=train_batch_num, keep_checkpoint_max=35) ckpoint_cb = ModelCheckpoint(prefix="fruit_360_renet50", directory="./ckpt/", config=config_ck) # LossMonitor is used to print loss value on screen loss_cb = LossMonitor() # model train model.train(10, train_dataset, callbacks=[ckpoint_cb, loss_cb], dataset_sink_mode=True) # model eval result = model.eval(test_dataset) print("eval result: {}".format(result), flush=True) def main(): run_train() if __name__ == "__main__": main() ``` ### 3.2 训练部分 保存代码到`gpu_single_train.py`,使用如下命令进行训练: ```shell export CUDA_VISIBLE_DEVICES=0 python3 gpu_single_train.py ``` 训练过程输出内容如下: ```shell train dataset batch num: 2115 test dataset batch num: 709 epoch: 1 step: 2115, loss is 4.219570636749268 epoch: 2 step: 2115, loss is 3.7109947204589844 ...... epoch: 9 step: 2115, loss is 2.66499400138855 epoch: 10 step: 2115, loss is 2.540522336959839 eval result: {'accuracy': 0.676348730606488} ``` 使用`tree ckpt`命令,查看一下模型保存目录的情况,输出内容如下: ```shell ckpt/ ├── fruit_360_renet50-10_2115.ckpt ├── fruit_360_renet50-1_2115.ckpt ...... ├── fruit_360_renet50-9_2115.ckpt └── fruit_360_renet50-graph.meta ``` ## 4. 多卡训练--OpenMPI 下面我们通过实际案例,介绍如何在GPU平台上,采用OpenMPI进行分布式训练。 ### 4.1 代码部分 > 代码说明: > > - 前三点说明请参考`3.1`部分的代码说明。 > - 多卡训练主要修改的是数据集读取和`context`设置部分。 > - 数据集读取:需要指定`num_shards`和`shard_id`,详细内容参考代码。 > - `context`设置:包含参数一致性和并行模式设定。参数一致性这里使用的是`set_seed`来设定;并行模式通过`set_auto_parallel_context`方法和`parallel_mode`参数来进行设置。 多卡训练的代码如下: ```python import numpy as np from mindspore import context from mindspore import nn from mindspore.common import dtype as mstype from mindspore.common import set_seed from mindspore.common import Tensor from mindspore.communication import init, get_rank, get_group_size from mindspore.dataset import ImageFolderDataset from mindspore.dataset.transforms.c_transforms import Compose, TypeCast from mindspore.dataset.vision.c_transforms import HWC2CHW, Normalize, RandomCrop, RandomHorizontalFlip, Resize from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits from mindspore.nn.optim import Momentum from mindspore.ops import operations as P from mindspore.ops import functional as F from mindspore.train import Model from mindspore.train.callback import CheckpointConfig, ModelCheckpoint, LossMonitor from scipy.stats import truncnorm # define reset50 def create_dataset(dataset_dir, mode="train", decode=True, batch_size=32, repeat_num=1): if mode == "train": shuffle = True rank_id = get_rank() rank_size = get_group_size() else: shuffle = False rank_id = None rank_size = None dataset = ImageFolderDataset( dataset_dir=dataset_dir, shuffle=shuffle, decode=decode, num_shards=rank_size, shard_id=rank_id) mean = [127.5, 127.5, 127.5] std = [127.5, 127.5, 127.5] if mode == "train": transforms_list = Compose( [RandomCrop((32, 32), (4, 4, 4, 4)), RandomHorizontalFlip(), Resize((100, 100)), Normalize(mean, std), HWC2CHW()]) else: transforms_list = Compose( [Resize((128, 128)), Normalize(mean, std), HWC2CHW()]) cast_op = TypeCast(mstype.int32) dataset = dataset.map(operations=transforms_list, input_columns="image") dataset = dataset.map(operations=cast_op, input_columns="label") dataset = dataset.batch(batch_size=batch_size, drop_remainder=True) dataset = dataset.repeat(repeat_num) return dataset def run_train(): context.set_context(mode=context.GRAPH_MODE, device_target="GPU") init("nccl") rank_id = get_rank() rank_size = get_group_size() print("rank size: {}, rank id: {}".format(rank_size, rank_id), flush=True) set_seed(0) context.set_auto_parallel_context( device_num=rank_size, gradients_mean=True, parallel_mode=context.ParallelMode.DATA_PARALLEL) train_dataset_dir = "/mnt/data_0002_24t/xingchaolong/dataset/Fruits_360/fruits-360_dataset/fruits-360/Training" test_dataset_dir = "/mnt/data_0002_24t/xingchaolong/dataset/Fruits_360/fruits-360_dataset/fruits-360/Test" batch_size = 32 train_dataset = create_dataset(dataset_dir=train_dataset_dir, batch_size=batch_size//rank_size) test_dataset = create_dataset(dataset_dir=test_dataset_dir, mode="test") train_batch_num = train_dataset.get_dataset_size() test_batch_num = test_dataset.get_dataset_size() print("train dataset batch num: {}".format(train_batch_num), flush=True) print("test dataset batch num: {}".format(test_batch_num), flush=True) # build model net = resnet50(class_num=131) loss = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") optim = Momentum(params=net.trainable_params(), learning_rate=0.01, momentum=0.9, loss_scale=1024.0) model = Model(net, loss_fn=loss, optimizer=optim, metrics={"accuracy"}) # CheckPoint CallBack definition config_ck = CheckpointConfig(save_checkpoint_steps=train_batch_num, keep_checkpoint_max=35) ckpoint_cb = ModelCheckpoint(prefix="fruit_360_renet50_{}".format(rank_id), directory="./ckpt/", config=config_ck) # LossMonitor is used to print loss value on screen loss_cb = LossMonitor() # model train model.train(10, train_dataset, callbacks=[ckpoint_cb, loss_cb], dataset_sink_mode=True) # model eval result = model.eval(test_dataset) print("eval result: {}".format(result), flush=True) def main(): run_train() if __name__ == "__main__": main() ``` ### 4.2 训练部分 下面来介绍如何使用多卡GPU训练。 #### 4.2.1 4卡GPU训练 使用如下命令,进行4卡GPU训练: ```shell export CUDA_VISIBLE_DEVICES=0,1,2,3 mpirun -n 4 python3 gpu_distributed_train.py ``` 训练过程中,输出内容如下: ```shell rank size: 4, rank id: 0 rank size: 4, rank id: 1 rank size: 4, rank id: 2 rank size: 4, rank id: 3 train dataset batch num: 2115 test dataset batch num: 709 train dataset batch num: 2115 test dataset batch num: 709 train dataset batch num: 2115 test dataset batch num: 709 train dataset batch num: 2115 test dataset batch num: 709 [WARNING] PRE_ACT(294248,7fa67e831740,python3):2022-07-13-17:11:24.528.381 [mindspore/ccsrc/backend/common/pass/communication_op_fusion.cc:198] GetAllReduceSplitSegment] Split threshold is 0. AllReduce nodes will take default fusion strategy. [WARNING] PRE_ACT(294245,7f57993a5740,python3):2022-07-13-17:11:26.176.114 [mindspore/ccsrc/backend/common/pass/communication_op_fusion.cc:198] GetAllReduceSplitSegment] Split threshold is 0. AllReduce nodes will take default fusion strategy. [WARNING] PRE_ACT(294247,7f36f889b740,python3):2022-07-13-17:11:30.475.177 [mindspore/ccsrc/backend/common/pass/communication_op_fusion.cc:198] GetAllReduceSplitSegment] Split threshold is 0. AllReduce nodes will take default fusion strategy. [WARNING] PRE_ACT(294246,7f5f1820c740,python3):2022-07-13-17:11:31.271.259 [mindspore/ccsrc/backend/common/pass/communication_op_fusion.cc:198] GetAllReduceSplitSegment] Split threshold is 0. AllReduce nodes will take default fusion strategy. epoch: 1 step: 2115, loss is 4.536644458770752 epoch: 1 step: 2115, loss is 4.347061634063721 epoch: 1 step: 2115, loss is 4.557111740112305 epoch: 1 step: 2115, loss is 4.467658519744873 ...... epoch: 10 step: 2115, loss is 3.263073205947876 epoch: 10 step: 2115, loss is 3.169656753540039 epoch: 10 step: 2115, loss is 3.2040905952453613 epoch: 10 step: 2115, loss is 3.812671184539795 eval result: {'accuracy': 0.48113540197461213} eval result: {'accuracy': 0.5190409026798307} eval result: {'accuracy': 0.4886283497884344} eval result: {'accuracy': 0.5010578279266573} ``` 使用`tree ckpt`命令,查看一下模型保存目录的情况,输出内容如下: ```shell ckpt/ ├── fruit_360_renet50_0-10_2115.ckpt ├── fruit_360_renet50_0-1_2115.ckpt ├── fruit_360_renet50_0-2_2115.ckpt ├── fruit_360_renet50_0-3_2115.ckpt ├── fruit_360_renet50_0-4_2115.ckpt ├── fruit_360_renet50_0-5_2115.ckpt ├── fruit_360_renet50_0-6_2115.ckpt ├── fruit_360_renet50_0-7_2115.ckpt ├── fruit_360_renet50_0-8_2115.ckpt ├── fruit_360_renet50_0-9_2115.ckpt ├── fruit_360_renet50_0-graph.meta ...... ├── fruit_360_renet50_3-10_2115.ckpt ├── fruit_360_renet50_3-1_2115.ckpt ├── fruit_360_renet50_3-2_2115.ckpt ├── fruit_360_renet50_3-3_2115.ckpt ├── fruit_360_renet50_3-4_2115.ckpt ├── fruit_360_renet50_3-5_2115.ckpt ├── fruit_360_renet50_3-6_2115.ckpt ├── fruit_360_renet50_3-7_2115.ckpt ├── fruit_360_renet50_3-8_2115.ckpt ├── fruit_360_renet50_3-9_2115.ckpt └── fruit_360_renet50_3-graph.meta ``` #### 4.2.2 2卡GPU训练 为了进行对比,再来进行2卡GPU训练,命令如下: > 这里为了验证普遍性,并非依序选择GPU。 ```shell export CUDA_VISIBLE_DEVICES=2,3 mpirun -n 2 python3 gpu_distributed_train.py ``` 训练过程中,输出内容如下: ```shell rank size: 2, rank id: 0 rank size: 2, rank id: 1 train dataset batch num: 2115 test dataset batch num: 709 train dataset batch num: 2115 test dataset batch num: 709 [WARNING] PRE_ACT(295459,7ff930118740,python3):2022-07-13-17:31:07.210.231 [mindspore/ccsrc/backend/common/pass/communication_op_fusion.cc:198] GetAllReduceSplitSegment] Split threshold is 0. AllReduce nodes will take default fusion strategy. [WARNING] PRE_ACT(295460,7f5fed564740,python3):2022-07-13-17:31:07.649.536 [mindspore/ccsrc/backend/common/pass/communication_op_fusion.cc:198] GetAllReduceSplitSegment] Split threshold is 0. AllReduce nodes will take default fusion strategy. epoch: 1 step: 2115, loss is 4.391518592834473 epoch: 1 step: 2115, loss is 4.337993621826172 ...... epoch: 10 step: 2115, loss is 2.7631659507751465 epoch: 10 step: 2115, loss is 3.0124118328094482 eval result: {'accuracy': 0.6057827926657263} eval result: {'accuracy': 0.6202397743300423} ``` 使用`tree ckpt`命令,查看一下模型保存目录的情况,输出内容如下: ```shell ckpt/ ├── fruit_360_renet50_0-10_2115.ckpt ├── fruit_360_renet50_0-1_2115.ckpt ├── fruit_360_renet50_0-2_2115.ckpt ├── fruit_360_renet50_0-3_2115.ckpt ├── fruit_360_renet50_0-4_2115.ckpt ├── fruit_360_renet50_0-5_2115.ckpt ├── fruit_360_renet50_0-6_2115.ckpt ├── fruit_360_renet50_0-7_2115.ckpt ├── fruit_360_renet50_0-8_2115.ckpt ├── fruit_360_renet50_0-9_2115.ckpt ├── fruit_360_renet50_0-graph.meta ├── fruit_360_renet50_1-10_2115.ckpt ├── fruit_360_renet50_1-1_2115.ckpt ├── fruit_360_renet50_1-2_2115.ckpt ├── fruit_360_renet50_1-3_2115.ckpt ├── fruit_360_renet50_1-4_2115.ckpt ├── fruit_360_renet50_1-5_2115.ckpt ├── fruit_360_renet50_1-6_2115.ckpt ├── fruit_360_renet50_1-7_2115.ckpt ├── fruit_360_renet50_1-8_2115.ckpt ├── fruit_360_renet50_1-9_2115.ckpt └── fruit_360_renet50_1-graph.meta ``` #### 4.2.3 多卡对比说明 - 结合`3.2`部分,进行4卡GPU训练和2卡GPU训练的对比。 - 三种情况下,分别将`batch_size`设置为了32、8、16,对应到的`batch_num`不变。也可以认为是在`GPU`显存不足于支持更大`batch_size`时,通过多卡来实现更大`batch_size`的方案。 - 从实际训练情况来看(都训练了10个epoch),单卡的效果最好,2卡次之,4卡最差。导致这种情况的原因是因为网络中使用到了`BatchNorm2d`算子,而在多卡情况下,无法跨卡计算,从而导致精度上的差别。在GPU硬件下,笔者暂时并没有找到合理的解决方案。 ## 5. 多卡训练--非OpenMPI 在`4`中我们介绍了依赖`OpenMPI`如何来进行`GPU`多卡训练,同时`MindSpore`也支持不依赖`OpenMPI`来进行`GPU`多卡训练。官方对此的说明如下: > 出于训练时的安全及可靠性要求,`MindSpore GPU`还支持**不依赖OpenMPI的分布式训练**。 > > `OpenMPI`在分布式训练的场景中,起到在`Host`侧同步数据以及进程间组网的功能;`MindSpore`通过**复用Parameter Server模式训练架构**,取代了`OpenMPI`能力。 不过`Parameter Server`相关的文档及代码示例不够充分。笔者尝试采用此种方式进行训练,参考了官方文档、`gitee`上面的测试用例,最终未能顺利完成整个`pipline`。 ## 6. 本文总结 本来重点介绍了在`GPU`硬件环境下,如何依赖`OpenMPI`进行多卡训练。对于非依赖`OpenMPI`的`Parameter Server`本文也有所涉及,但由于官方文档的缺失和相应代码不足,无法形成可行案例。 ## 7. 遇到问题 `Parameter Server`模式下的官方文档跳跃性太大,相关的测试用例缺失中间过程代码,希望能够完善这部分的文档和代码。 ## 8. 本文参考 - [深度学习中的分布式训练](https://cloud.tencent.com/developer/news/841792) - [MindSpore分布式并行总览](https://www.mindspore.cn/tutorials/experts/zh-CN/r1.7/parallel/introduction.html) - [MindSpore分布式并行训练基础样例(GPU)](https://www.mindspore.cn/tutorials/experts/zh-CN/r1.7/parallel/train_gpu.html) - [MindSpore Parameter Server模式](https://www.mindspore.cn/docs/zh-CN/r1.7/design/parameter_server_training.html) 本文为原创文章,版权归作者所有,未经授权不得转载!
  • [openEuler] openEuler 22.03LTS 安装部署nvidia open gpu driver
    环境信息:1. 禁用开源驱动nouveaurmmod nouveauecho “blacklist nouveau” >> /etc/modprobe.d/blacklist.conf 2. 下载Nvidia 驱动源码安装时构建的内核模块必须与gsp一起使用。bin固件和用户空间NVIDIA GPU驱动程序组件来自相应的515.43.04驱动程序版本。因此在安装源码前需要安装nvidia gpu驱动。wget https://cn.download.nvidia.cn/XFree86/aarch64/515.43.04/NVIDIA-Linux-aarch64-515.43.04.run安装gpu驱动:sh ./NVIDIA-Linux-[version].run --no-kernel-modules  3. 下载Nvidia 驱动源码wget https://cn.download.nvidia.cn/XFree86/aarch64/515.43.04/NVIDIA-Linux-aarch64-515.43.04.run4. 安装gpu驱动:bash ./NVIDIA-Linux-aarch64-515.43.04.run --no-kernel-modules 5. 下载开源驱动源码git clone https://github.com/NVIDIA/open-gpu-kernel-modules.git 6. 编译源码cd open-gpu-kernel-modules-mainmake modules -j`nproc`    7. 安装源码make modules_install -j`nproc` 8. 编译安装nvidia驱动cd /lib/modules/5.10.0/kernel/drivers/video/insmod nvidia.ko 9. 查看驱动信息modinfo nvidia Agenda1. 编译nvidia开源驱动报错,无法找到/lib/modules/4.19.90-2204.3.0.0146.oe1.aarch64/build 下载内核源码包,创建软链接指向当前下载的源码路径:ln -s /usr/src/kernels/4.19.90-2205.1.0.0148.oe1.aarch64  /lib/modules/4.19.90-2204.3.0.0146.oe1.aarch64/build 2. 安装nvidia驱动报错,无法找到目录/lib/modules/5.10.0在2022/7/14使用github上最新的代码进行编译安装时,提示无法找到目录/lib/modules/5.10.0,这个是因为内核检查的是5.10.0大版本,设置软链接指向该目录即可:ln -s /lib/modules/5.10.0-60.18.0.50.oe2203.aarch64 /lib/modules/5.10.0 3. 安装nvidia驱动报错,内核签名校验失败这个是内核签名校验失败,ko已经编译完成,可以进入对应目录手动安装ko文件。cd /usr/lib/modules/${编译的内核版本}/kernel/drivers/videoinsmod nvidia.ko 4. 编译失败,出现modpost undfined error如果使用515.43.04版本的开源驱动代码,并且在aarch64上编译,会产生如下错误。这个是程序代码问题,在 515.48.07版本中已被修复。 本次安装的gpu固件驱动版本和open gpu 版本不一致,所以无法使用相关命令,后续会在安装对应版本的固件驱动和开源驱动后重新使用,然后更新文档。 
  • [前沿分享] 一文带你入门虚拟遗憾最小化CFR算法
    ## 背景 2017年,Libratus和DeepStack两个算法被提出,用于解决无限制德州扑克。DeepStack 和 Libratus不约而同的使用 Counterfactual Regret Minimization (CFR) 来找到接近纳什均衡策略。 网上有很多介绍CFR算法的文章,这些文章系统的介绍了博弈论的概念,CFR算法中的公式和推导过程。本文尽量避免引入新概念和复杂公式,尝试通过示例和读者熟悉的方式介绍算法和背后的思路。由于时间紧张以及能力所限,难免存在纰漏,敬请大家指正。 ## 遗憾最小化和Regret Matching 在介绍算法之前,大家不妨花30秒使用“如果当初...,现在就不会..."来造个句。 ... ... 好了,不知道大家造了什么句子,可能是一个悲伤的故事。 CFR算法正是基于这样的思路:如果一个智能体因为采取了某个动作而带来了损失,那么智能体需要避免采取这个动作。更进一步,计算机并不理解**遗憾**,CFR算法将遗憾进行量化——**最好的行动方案**与**实际采取行动方案**之间的差距 以石头-剪刀-布游戏为例,假设赢得比赛收益为1,输掉比赛收益为-1,平局收益0。显然,最优策略是赢得比赛。当对手出石头时,我们自己出石头,剪刀,布的收益和遗憾值如下表所示: | 对手 | 自己 | 收益 | 遗憾值 = 最优策略收益 - 当前动作的收益 | |----|----|----|----| | 石头 | 剪刀 | -1 | 2 | | 石头 | 石头 | 0 | 1 | | 石头 | 布 | 1 | 0 | 在石头-剪刀-布游戏中,我们并不知道对方接下来会出什么,但是仍然通过历史对局的**累计遗憾值**来选择动作,累计遗憾值反映了对手历史的策略。 假设对手则采取以1/3概率出石头、剪刀和布,而我们自己是一个总结和善于改进的智能体——**游戏过程中记录遗憾值,并选择遗憾值最低的动作**。 ```python import numpy as np from prettytable import PrettyTable class Opponent: def __init__(self): # 对手采取石头,剪刀,布的概率 self.probs = (1/3, 1/3, 1/3) def action(self): return np.random.choice(len(self.probs), 1, p=self.probs).item(0) class Agent: def __init__(self): self.cum_regret = np.array([0.1, 0.1, 0.1]) def action(self): # regret matching return np.argmin(self.cum_regret) def update_regret(self, action, regret): self.cum_regret[action] += regret class Game: def __init__(self): self.payoff = [ #石头 剪刀 布 [0, 1, -1], # 石头 [-1, 0, 1], # 剪刀 [1, -1, 0] # 布 ] @property def best_payoff(self): return 1 def play(self, agent_action, opponent_action): return self.payoff[agent_action][opponent_action] game = Game() opponet = Opponent() agent = Agent() table = PrettyTable(['round','opponent','agent', 'current round regret', 'cum_regret']) for round in range(100): agent_action = agent.action() opponent_action = opponet.action() payoff = game.play(agent_action, opponent_action) regret = game.best_payoff - payoff agent.update_regret(agent_action, regret) table.add_row([round, opponent_action, agent_action, regret, str(agent.cum_regret)]) print(table) ``` 随着博弈次数的增加,我们也会逐渐采用1/3的概率选择石头、剪刀和布。有了解过博弈论的同学应该可以发现,CFR算法使得智能体在石头-剪刀-布游戏中达到了**纳什均衡** ```text +-------+----------+-------+----------------------+---------------+ | round | opponent | agent | current round regret | cum_regret | +-------+----------+-------+----------------------+---------------+ | 0 | 2 | 0 | 2 | [2. 0. 0.] | | 1 | 0 | 1 | 2 | [2. 2. 0.] | | 2 | 1 | 2 | 2 | [2. 2. 2.] | | 3 | 0 | 0 | 1 | [3. 2. 2.] | | 4 | 1 | 1 | 1 | [3. 3. 2.] | | 5 | 2 | 2 | 1 | [3. 3. 3.] | | 6 | 1 | 0 | 0 | [3. 3. 3.] | | 7 | 2 | 0 | 2 | [5. 3. 3.] | ... ... | 94 | 0 | 2 | 0 | [36. 35. 34.] | | 95 | 0 | 2 | 0 | [36. 35. 34.] | | 96 | 0 | 2 | 0 | [36. 35. 34.] | | 97 | 2 | 2 | 1 | [36. 35. 35.] | | 98 | 0 | 1 | 2 | [36. 37. 35.] | | 99 | 1 | 2 | 2 | [36. 37. 37.] | +-------+----------+-------+----------------------+---------------+ ``` 在实际算法中,为了**平衡探索-利用**,智能体通常通过采样的方式选择动作,这意味着即时某个动作的遗憾值很大,也有较小的概率被采样到。 ## 考虑更加复杂的情况 接下来,我们尝试将石头-剪刀-布的算法套用到扑克游戏中来,这时候会遇到一些问题 - 玩家不知道自己处于何种状态: 在一局游戏结束之前,玩家得到的信息是有限的。例如:玩家只知道自己的手牌、公牌,以及所有玩家出牌的记录,并不知道对手的手牌。 解决方案:既然没有办法准确区分那就不区分,干脆将这些可能的状态放在一个集合里,起个高大上的名字——信息集(Information Set) - 某个动作产生的收益不唯一: 玩家执行某个动作之后,并不能立刻得到反馈,需要再经历多次交互之后,才能得到最终的收益。 最终的收益不仅和当前采取的动作有关,还和自己后续的动作,对手后续的动作、以及对手底牌有关。 解决这个问题比较简单:将上述不确定性作为随机变量,计算统计学意义上的收益——期望。 - 最优的策略和收益: 和上面的情况类似,玩家不知道最优的策略(事实上这正是我们的求解目标),也不知道最优策略下的收益 解决方案:虽然我们不知道最优策略的收益,我们可以退而求其次,找到一个还不错的策略,例如计算当前信息集下各个动作收益的期望。随着智能体水平越来越高,这个替代品也越来越接近最优策略收益。 这里暂时略过难懂的证明过程和公式,整个过程类似EM(Expectation Maximization Algorithm)算法: - 利用 **当前策略的期望收益** 来改进 **智能体的策略** - 利用 **智能体的策略** 来估算 **当前策略期望收益** - 如此往复... ## 继续增加难度 双人无限制德州扑克 的决策点个数超过$10^{160}$,有人估算宇宙原子总数大致是$10^{80}$,现有的计算机还是没有能力存储这么多 信息集-行动对,也没有办法计算这些期望: - 信息集-行动对:这比较简单,和很多传统算法一样,可以通过神经网络来提取特征,降低维度,拟合出一个策略 - 计算期望:计算期望时,需要对所有的可能性进行累加。目前的解决方案是,通过采样方式降低搜索空间,即只使用部分动作计算期望;同时增加搜索的次数,近似的估算出一个期望。典型的算法有outcome sampling、external sampling等,这些算法都可以统称为MCCFR。 ## 总结 本文使用通俗方式介绍CFR算法思想和发展脉络,适用于初学者的入门指南。MindSpore Reinforcement[https://gitee.com/mindspore/reinforcement]近期会上线DeepCFR算法,有兴趣进一步了深入了解算法的读者欢迎移步围观。 最后插入一波广告:MindSpore Reinforcement是一个开源的强化学习框架,为强化学习算法提供了干净整洁的API抽象,将算法与部署和执行进行解耦,包括异构加速器、并行度和跨worker集群部署,**欢迎大家Star,fork、共同开发**。
  • [问题求助] 鲲鹏超高I/O型 | ki1.2large.4 | 8vCPUs | 32GiB 云服务有配置GPU吗
    如题,最近在帮老师做深度学习任务,老师给了个如题配置华为云服务器,说是有2张V100的卡,但是在配置环境的时候却发现没有英伟达GPU信息。系统查到的配置图如下,请各位帮忙解答一下,是这个服务器本来就没有配置显卡,还是我配环境没配好。
  • [安装经验] 【MindSpore易点通·漫游世界】在Jetson AGX Orin上源码编译安装MindSpore 1.8.0 GPU版
    上次 张小白使用 gcc 9.4.0源码编译 MindSpore 1.8.0 CUDA11的版本失败了:https://bbs.huaweicloud.com/forum/thread-193443-1-1.html于是张小白提了一个问题贴:https://bbs.huaweicloud.com/forum/thread-193443-1-1.html专家提示:用gcc 7.3.0试下呢?那就试试吧。下载mindspore r1.8分支源码:git clone  http://gitee.com/mindspore/mindspore.git -b r1.8修改 mindspore/scripts/build/build_mindspore.sh:在Xoff那一行增加 -DENABLE_GITEE=ON 强制使用gitee因为gcc7.3.0好像被破坏了,所以重新源码编译下:cd /home/zhanghuiln -s /home1/zhanghui/gcc-7.3.0cd /home1/zhanghui/gcc-7.3.0make -j12sudo make installcd /usr/binsudo rm g++sudo rm gccsudo ln -s /usr/local/bin/g++ g++sudo ln -s /usr/local/bin/gcc gcccdgcc --versiong++ --version开始正式编译:cd /home1/zhanghui/mindspore./build.sh -e gpu -j12成功完成编译。cd output可以看到生成好的whl创建conda环境:conda create -n mindspore1.8 python=3.9conda activate mindspore1.8安装已编译的whlpip install ./mindspore_gpu-1.8.0-cp39-cp39-linux_aarch64.whl -i https://pypi.tuna.tsinghua.edu.cn/simplepython -c "import mindspore;mindspore.run_check()"这个很奇怪的现象又出现了。在conda环境中,报错:ModuleNotFoundError: No module named 'packaging'退出conda环境:conda deactivate重新 python -c "import mindspore;mindspore.run_check()"说明一个很奇怪的事情,虽然在conda环境里面做pip install,但是好像还是装到了base环境。python test.py这说明gcc 7.3.0可以正常完成mindspore 1.8.0的编译和安装。。。gcc 9.4.0暂时不行。张小白不甘心,还是决定在conda环境试一试,先确认下base环境和conda环境的版本:显然是两个不同的环境。然后,在原来直接pip install的基础上,换成使用python -m pip install的方式安装:这次居然有把packaging的包装进去。看来原因是前面pip install仅仅装到了base环境。再试下两种检验方式:另一种方式:终于都没问题了。这倒是解决了  https://bbs.huaweicloud.com/forum/thread-193449-1-1.html 在安装1.7.0过程中出的问题。但是至于gcc 9.4.0为啥编译报错,这个问题还是留给mindspore团队吧!(全文完,谢谢阅读)
  • [安装经验] 【MindSpore易点通·漫游世界】在Jetson AGX Orin上安装MindSpore 1.7.0 GPU版
    张小白曾经在 Jetson AGX Orin上使用gcc 7.3.0成功源码编译安装过 MindSpore 1.6.0 CUDA11的版本:https://bbs.huaweicloud.com/forum/thread-186292-1-1.html也刚刚试图使用 gcc 9.4.0源码编译 MindSpore 1.8.0 CUDA11的版本失败:https://bbs.huaweicloud.com/forum/thread-193443-1-1.html所以不得不退而求其次,安装官方明着显示的最高版本 1.7.0具体方法如下:先将 gcc和g++的软连接都指向 /usr/bin/gcc-9和 /usr/bin/g++-9然后下载mindspore 1.7的源码包:接着修改build_mindspore.sh如上图所示,箭头处增加  -DENABLE_GITEE=ON执行 ./build.sh -e gpu -j12 开始编译。。。。编译得非常顺利,让张小白有点觉得不可思议。张小白几乎忘记了现在到底是用什么Python版本编译的:原来是Python 3.9看看编译的结果:创建一个新的conda环境:查看下版本:于是开始安装:pip install ./mindspore_gpu-1.7.0-cp39-cp39-linux_aarch64.whl -i https://pypi.tuna.tsinghua.edu.cn/simple验证:vi test.pyimport numpy as np from mindspore import Tensor import mindspore.ops as ops import mindspore.context as context context.set_context(device_target="GPU") x = Tensor(np.ones([1,3,3,4]).astype(np.float32)) y = Tensor(np.ones([1,3,3,4]).astype(np.float32)) print(ops.add(x, y))python test.py奇怪了,退回到base看看:conda deactivate python test.pypython3 test.py貌似是python和python3有多个版本的问题。貌似在base环境,怎么都可以。但是在conda的orin python 3.9环境。两个都不行。怪事。。这可能是一个头孢的未解之谜。(全文完,谢谢阅读)
  • [安装] 【MindSpore】【安装问题】linux GPU/CUDA11.1/Mindspore1.6.2 安装后 执行测试代码报错
    (mindspore_py37) opadm@cndgdlbpdu01-47-3:/work/notebook/download$ pip install mindspore_gpu-1.6.2-cp37-cp37m-linux_x86_64.whl Processing ./mindspore_gpu-1.6.2-cp37-cp37m-linux_x86_64.whlRequirement already satisfied: asttokens>=2.0.0 in /home/opadm/anaconda3/envs/mindspore_py37/lib/python3.7/site-packages (from mindspore-gpu==1.6.2) (2.0.5)Requirement already satisfied: protobuf>=3.13.0 in /home/opadm/anaconda3/envs/mindspore_py37/lib/python3.7/site-packages (from mindspore-gpu==1.6.2) (4.21.2)Requirement already satisfied: numpy>=1.17.0 in /home/opadm/anaconda3/envs/mindspore_py37/lib/python3.7/site-packages (from mindspore-gpu==1.6.2) (1.21.6)Requirement already satisfied: packaging>=20.0 in /home/opadm/anaconda3/envs/mindspore_py37/lib/python3.7/site-packages (from mindspore-gpu==1.6.2) (21.3)Requirement already satisfied: pillow>=6.2.0 in /home/opadm/anaconda3/envs/mindspore_py37/lib/python3.7/site-packages (from mindspore-gpu==1.6.2) (9.2.0)Requirement already satisfied: psutil>=5.6.1 in /home/opadm/anaconda3/envs/mindspore_py37/lib/python3.7/site-packages (from mindspore-gpu==1.6.2) (5.9.1)Requirement already satisfied: scipy>=1.5.2 in /home/opadm/anaconda3/envs/mindspore_py37/lib/python3.7/site-packages (from mindspore-gpu==1.6.2) (1.7.3)Requirement already satisfied: six in /home/opadm/anaconda3/envs/mindspore_py37/lib/python3.7/site-packages (from asttokens>=2.0.0->mindspore-gpu==1.6.2) (1.16.0)Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /home/opadm/anaconda3/envs/mindspore_py37/lib/python3.7/site-packages (from packaging>=20.0->mindspore-gpu==1.6.2) (3.0.9)Installing collected packages: mindspore-gpu  Attempting uninstall: mindspore-gpu    Found existing installation: mindspore-gpu 1.6.1    Uninstalling mindspore-gpu-1.6.1:      Successfully uninstalled mindspore-gpu-1.6.1Successfully installed mindspore-gpu-1.6.2(mindspore_py37) opadm@cndgdlbpdu01-47-3:/work/notebook/download$ python -c "import mindspore;mindspore.run_check()"MindSpore version:  1.6.2[CRITICAL] DEVICE(136615,7f8ee3b19700,python):2022-07-04-14:52:15.224.989 [mindspore/ccsrc/runtime/device/gpu/gpu_device_manager.cc:40] InitDevice] cusolver Error: Failed to create cusolver dn handle. | Error Number: 7MindSpore running check failed.mindspore/ccsrc/runtime/device/gpu/gpu_device_manager.cc:40 InitDevice] cusolver Error: Failed to create cusolver dn handle. | Error Number: 7(mindspore_py37) opadm@cndgdlbpdu01-47-3:/work/notebook/download$ 
  • [安装经验] 【MindSpore易点通·漫游世界】在WSL的Ubuntu 22.04上一键安装MindSpore GPU 1.7.0踩坑记
    (也不知道自己为啥没注意到上图的e跑到下面来了。。。懒得改了。。。作为一个技术人员,要留BUG在人间。。)近期张小白的周边发生了如下大事:(1)2022年4月,ubuntu推出22.04版本。(2)MindSpore推出自动安装脚本(3)张小白写过 【MindSpore易点通·漫游世界】在WSL的Ubuntu 20.04上一键安装MindSpore GPU 1.6.1(4)MindSpore推出 1.7.0版本。所以,张小白打算使用WSL的ubuntu 22.04自动安装MindSpore GPU 1.7.0版本。先安装WSL ubuntu 22.04版本,其实这个安装过程跟安装 WSL的ubuntu 20.04版本类似。(1)使用Microsoft Store安装 ubuntu 22.04 LTS:点击“打开”,这次的方式好像略有变化,因为多了些配置界面:输入用户名和密码:zhanghui/zhanghui点击Finish:这个执行可以先执行前面提示要运行的语句:sudo apt updatesudo apt upgrade
  • [执行问题] 【MindSpore】【GPU运行报错】CPU可以正常运行的,但是GPU下报错
    【功能模块】DEVICE 报错【操作步骤&问题现象】1、context.set_context(device_target="CPU") 正常跑2、context.set_context(device_target="GPU") 报错【截图信息】【日志信息】(可选,上传日志内容或者附件)[ERROR] DEVICE(3664,7f3ee8ff0700,python):2022-07-01-07:39:30.407.528 [mindspore/ccsrc/runtime/device/gpu/blocking_queue.cc:50] Push] Invalid Input: ptr: 0x7f3d702400a0, len: 262144 [ERROR] MD(3664,7f3ee8ff0700,python):2022-07-01-07:39:30.407.697 [mindspore/ccsrc/minddata/dataset/util/task_manager.cc:217] InterruptMaster] Task is terminated with err msg(more detail in info level log):Unexpected error. Invalid data, the types or shapes of current row is different with previous row(i.e. do batch operation but drop_reminder is False, or without resize image into the same size, these will cause shapes differs). Line of code : 529 File : /home/jenkins/agent-working-dir/workspace/Compile_GPU_X86_CentOS_Cuda10/mindspore/mindspore/ccsrc/minddata/dataset/engine/datasetops/device_queue_op.cc [CRITICAL] KERNEL(3664,7f404a7de700,python):2022-07-01-07:44:31.326.304 [mindspore/ccsrc/backend/kernel_compiler/gpu/data/dataset_iterator_kernel.cc:119] ReadDevice] For 'GetNext', get data timeout [ERROR] RUNTIME_FRAMEWORK(3664,7f4055fe9700,python):2022-07-01-07:44:31.327.103 [mindspore/ccsrc/runtime/framework/actor/abstract_actor.cc:92] EraseInput] Erase input controls failed: Default/network-TrainOneStepCell/optimizer-Adam/Mul-op6918, sequential_num: 0 Traceback (most recent call last): File "SD_net_2_train_on_mindspore_GPU.py", line 205, in <module> reduce_lr] File "/opt/conda/lib/python3.7/site-packages/mindspore/train/model.py", line 774, in train sink_size=sink_size) File "/opt/conda/lib/python3.7/site-packages/mindspore/train/model.py", line 87, in wrapper func(self, *args, **kwargs) File "/opt/conda/lib/python3.7/site-packages/mindspore/train/model.py", line 540, in _train self._train_dataset_sink_process(epoch, train_dataset, list_callback, cb_params, sink_size) File "/opt/conda/lib/python3.7/site-packages/mindspore/train/model.py", line 608, in _train_dataset_sink_process outputs = train_network(*inputs) File "/opt/conda/lib/python3.7/site-packages/mindspore/nn/cell.py", line 479, in __call__ out = self.compile_and_run(*args) File "/opt/conda/lib/python3.7/site-packages/mindspore/nn/cell.py", line 828, in compile_and_run return _cell_graph_executor(self, *new_inputs, phase=self.phase) File "/opt/conda/lib/python3.7/site-packages/mindspore/common/api.py", line 711, in __call__ return self.run(obj, *args, phase=phase) File "/opt/conda/lib/python3.7/site-packages/mindspore/common/api.py", line 735, in run return self._exec_pip(obj, *args, phase=phase_real) File "/opt/conda/lib/python3.7/site-packages/mindspore/common/api.py", line 61, in wrapper results = fn(*arg, **kwargs) File "/opt/conda/lib/python3.7/site-packages/mindspore/common/api.py", line 718, in _exec_pip return self._graph_executor(args, phase) RuntimeError: mindspore/ccsrc/backend/kernel_compiler/gpu/data/dataset_iterator_kernel.cc:119 ReadDevice] For 'GetNext', get data timeout [WARNING] MD(3664,7f40cc3bc740,python):2022-07-01-07:44:31.391.343 [mindspore/ccsrc/minddata/dataset/engine/datasetops/device_queue_op.cc:73] ~DeviceQueueOp] preprocess_batch: 3; batch_queue: 0, 0, 5, 5, 5, 4, 9, 8; push_start_time: 2022-07-01-07:39:21.366.263, 2022-07-01-07:39:21.810.354, 2022-07-01-07:39:21.810.375, 2022-07-01-07:39:29.889.068; push_end_time: 2022-07-01-07:39:21.809.469, 2022-07-01-07:39:21.810.373, 2022-07-01-07:39:29.889.040. [ERROR] DEVICE(3664,7f40cc3bc740,python):2022-07-01-07:45:31.966.256 [mindspore/ccsrc/runtime/device/gpu/gpu_buffer_mgr.cc:180] CloseNotify] time out of receiving signals [ERROR] DEVICE(3664,7f40cc3bc740,python):2022-07-01-07:45:31.966.306 [mindspore/ccsrc/runtime/hardware/gpu/gpu_device_context.cc:165] Destroy] Could not close gpu data queue.
  • [其他] 从0到1制作自定义镜像并创建训练作业(CPU/GPU)
    使用自定义镜像创建训练作业时,需要您熟悉 docker 软件的使用,并具备一定的开发经验。详细步骤如下所示:准备工作制作自定义镜像上传镜像至SWR服务创建训练作业准备工作已注册华为云账号,且在使用ModelArts前检查账号状态,账号不能处于欠费或冻结状态。当前账号已完成访问授权的配置。如未完成,请参考使用委托授权。针对之前使用访问密钥授权的用户,建议清空授权,然后使用委托进行授权。已在OBS服务中创建桶和文件夹,用于存放样例数据集以及训练代码。如下示例中,请创建命名为“test-modelarts”的桶,并创建如表1所示的文件夹。创建OBS桶和文件夹的操作指导请参见创建桶和新建文件夹。训练脚本 pytorch-verification.py 文件,请上传至对应文件夹下。pytorch-verification.py 文件内容如下import torch import torch.nn as nn x = torch.randn(5, 3) print(x) available_dev = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") y = torch.randn(5, 3).to(available_dev) print(y)制作自定义镜像目标:构建安装好如下软件的容器镜像,并使用ModelArts训练服务运行。ubuntu-18.04cuda-10.2python-3.7.13pytorch-1.8.1本示例使用Dockerfile文件定制自定义镜像。以linux x86_x64架构的主机为例,您可以购买相同规格的ECS或者应用本地已有的主机进行自定义镜像的制作。安装Docker。以linux x86_64架构的操作系统为例,获取Docker安装包。您可以使用以下指令安装Docker。curl -fsSL get.docker.com -o get-docker.sh sh get-docker.sh         如果docker images命令可以执行成功,表示Docker已安装,此步骤可跳过。2.准备名为 context 的文件夹。mkdir -p context3.准备可用的pip源文件pip.conf 。本示例使用华为开源镜像站提供的 pip 源,其 pip.conf 文件内容如下。[global] index-url = https://repo.huaweicloud.com/repository/pypi/simple trusted-host = repo.huaweicloud.com timeout = 1204.下载 torch*.whl 文件。在网站 https://download.pytorch.org/whl/torch_stable.html 搜索并下载如下 whl文件。torch-1.8.1+cu102-cp37-cp37m-linux_x86_64.whltorchaudio-0.8.1-cp37-cp37m-linux_x86_64.whltorchvision-0.9.1+cu102-cp37-cp37m-linux_x86_64.whl5.下载 Miniconda3 安装文件。使用地址https://repo.anaconda.com/miniconda/Miniconda3-py37_4.12.0-Linux-x86_64.sh, 下载 Miniconda3 py37 4.12.0 安装文件(对应 python 3.7.13)。6.将上述pip源文件、torch*.whl 文件、 Miniconda3 安装文件放置在 context 文件夹内,context 文件夹内容如下。context ├── Miniconda3-py37_4.12.0-Linux-x86_64.sh ├── pip.conf ├── torch-1.8.1+cu102-cp37-cp37m-linux_x86_64.whl ├── torchaudio-0.8.1-cp37-cp37m-linux_x86_64.whl └── torchvision-0.9.1+cu102-cp37-cp37m-linux_x86_64.whl7.编写容器镜像 Dockerfile 文件。在 context 文件夹内新建名为 Dockerfile 的空文件,并将下述内容写入其中。# 容器镜像构建主机需要连通公网 # 基础容器镜像, https://github.com/NVIDIA/nvidia-docker/wiki/CUDA # # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds # require Docker Engine >= 17.05 # # builder stage FROM nvidia/cuda:10.2-runtime-ubuntu18.04 AS builder # 基础容器镜像的默认用户已经是 root # USER root # 使用华为开源镜像站提供的 pypi 配置 RUN mkdir -p /root/.pip/ COPY pip.conf /root/.pip/pip.conf # 拷贝待安装文件到基础容器镜像中的 /tmp 目录 COPY Miniconda3-py37_4.12.0-Linux-x86_64.sh /tmp COPY torch-1.8.1+cu102-cp37-cp37m-linux_x86_64.whl /tmp COPY torchvision-0.9.1+cu102-cp37-cp37m-linux_x86_64.whl /tmp COPY torchaudio-0.8.1-cp37-cp37m-linux_x86_64.whl /tmp # https://conda.io/projects/conda/en/latest/user-guide/install/linux.html#installing-on-linux # 安装 Miniconda3 到基础容器镜像的 /home/ma-user/miniconda3 目录中 RUN bash /tmp/Miniconda3-py37_4.12.0-Linux-x86_64.sh -b -p /home/ma-user/miniconda3 # 使用 Miniconda3 默认 python 环境 (即 /home/ma-user/miniconda3/bin/pip) 安装 torch*.whl RUN cd /tmp && \ /home/ma-user/miniconda3/bin/pip install --no-cache-dir \ /tmp/torch-1.8.1+cu102-cp37-cp37m-linux_x86_64.whl \ /tmp/torchvision-0.9.1+cu102-cp37-cp37m-linux_x86_64.whl \ /tmp/torchaudio-0.8.1-cp37-cp37m-linux_x86_64.whl # 构建最终容器镜像 FROM nvidia/cuda:10.2-runtime-ubuntu18.04 # 安装 vim / curl 工具(依然使用华为开源镜像站) RUN cp -a /etc/apt/sources.list /etc/apt/sources.list.bak && \ sed -i "s@http://.*archive.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list && \ sed -i "s@http://.*security.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list && \ apt-get update && \ apt-get install -y vim curl && \ apt-get clean && \ mv /etc/apt/sources.list.bak /etc/apt/sources.list # 增加 ma-user 用户 (uid = 1000, gid = 100) # 注意到基础容器镜像已存在 gid = 100 的组,因此 ma-user 用户可直接使用 RUN useradd -m -d /home/ma-user -s /bin/bash -g 100 -u 1000 ma-user # 从上述 builder stage 中拷贝 /home/ma-user/miniconda3 目录到当前容器镜像的同名目录 COPY --chown=ma-user:100 --from=builder /home/ma-user/miniconda3 /home/ma-user/miniconda3 # 设置容器镜像预置环境变量 # 请务必设置 PYTHONUNBUFFERED=1, 以免日志丢失 ENV PATH=$PATH:/home/ma-user/miniconda3/bin \ PYTHONUNBUFFERED=1 # 设置容器镜像默认用户与工作目录 USER ma-user WORKDIR /home/ma-user确认已创建完成Dockerfile文件。此时 context 文件夹内容如下。context ├── Dockerfile ├── Miniconda3-py37_4.12.0-Linux-x86_64.sh ├── pip.conf ├── torch-1.8.1+cu102-cp37-cp37m-linux_x86_64.whl ├── torchaudio-0.8.1-cp37-cp37m-linux_x86_64.whl └── torchvision-0.9.1+cu102-cp37-cp37m-linux_x86_64.whl9.确认 Docker Engine 版本。执行如下命令。docker version | grep -A 1 Engine以 Docker Engine 18.09.0 版本为例,上述命令回显示意如下。10.构建容器镜像。在 Dockerfile 文件所在的目录执行如下命令构建容器镜像 pytorch:1.8.1-cuda10.2# 要求 Docker Engine 版本 >= 17.05 docker build . -t pytorch:1.8.1-cuda10.2上传镜像至SWR服务登录容器镜像服务控制台,选择区域。图1 容器镜像服务控制台单击右上角“创建组织”,输入组织名称完成组织创建。您可以自定义组织名称,本示例使用“deep-learning”。图2 创建组织单击右上角“登录指令”,获取登录访问指令。图3 登录指令以root用户登录本地环境,输入登录访问指令。上传镜像至容器镜像服务镜像仓库。使用docker tag命令给上传镜像打标签。sudo docker tag pytorch:1.8.1-cuda10.2 swr.cn-north-4.myhuaweicloud.com/deep-learning/pytorch:1.8.1-cuda10.2使用docker push命令上传镜像。sudo docker push swr.cn-north-4.myhuaweicloud.com/deep-learning/pytorch:1.8.1-cuda10.2完成镜像上传后,在“容器镜像服务控制台>我的镜像”页面可查看已上传的自定义镜像。“swr.cn-north-4.myhuaweicloud.com/deep-learning/pytorch:1.8.1-cuda10.2”即为此自定义镜像的“SWR_URL”。创建训练作业登录ModelArts管理控制台,在左侧导航栏中选择“训练管理 > 训练作业 New”,默认进入“训练作业”列表。在“创建训练作业”页面,填写相关参数信息,然后单击“下一步”。创建方式:选择“自定义算法”镜像来源:选择“自定义”镜像地址:“swr.cn-north-4.myhuaweicloud.com/deep-learning/pytorch:1.8.1-cuda10.2”代码目录:设置为OBS中存放启动脚本文件的目录,例如:“obs://test-modelarts/deep-learning/pytorch/code/”启动命令:“/home/ma-user/miniconda3/bin/python ${MA_JOB_DIR}/code/pytorch-verification.py”资源池:选择公共资源池类型:选择GPU或者CPU规格。永久保存日志:打开作业日志路径:设置为OBS中存放训练日志的路径。例如:“obs://test-modelarts/deep-learning/pytorch/log/”在“规格确认”页面,确认训练作业的参数信息,确认无误后单击“提交”。训练作业创建完成后,后台将自动完成容器镜像下载、代码目录下载、执行启动命令等动作。训练作业一般需要运行一段时间,根据您的训练业务逻辑和选择的资源不同,训练时间将耗时几十分钟到几小时不等。训练作业执行成功后,日志信息如下所示。图4 GPU 规格运行日志信息图5 CPU 规格运行日志信息至此,从0到1制作自定义镜像并创建训练作业(CPU/GPU)整个流程结束
  • [功能调试]  MindSpore报错 Select GPU kernel op * fail! Incompatible data type
    1 报错描述1.1 系统环境Hardware Environment(Ascend/GPU/CPU): GPUSoftware Environment:– MindSpore version (source or binary): 1.5.2– Python version (e.g., Python 3.7.5): 3.7.6– OS platform and distribution (e.g., Linux Ubuntu 16.04): Ubuntu 4.15.0-74-generic– GCC/Compiler version (if compiled from source):1.2 基本信息1.2.1 脚本训练脚本是通过构建BatchNorm单算子网络,对Tensor做归一化处理。脚本如下: 01 class Net(nn.Cell): 02 def __init__(self): 03 super(Net, self).__init__() 04 self.batch_norm = ops.BatchNorm() 05 def construct(self,input_x, scale, bias, mean, variance): 06 output = self.batch_norm(input_x, scale, bias, mean, variance) 07 return output 08 09 net = Net() 10 input_x = Tensor(np.ones([2, 2]), mindspore.float16) 11 scale = Tensor(np.ones([2]), mindspore.float16) 12 bias = Tensor(np.ones([2]), mindspore.float16) 13 bias = Tensor(np.ones([2]), mindspore.float16) 14 mean = Tensor(np.ones([2]), mindspore.float16) 15 variance = Tensor(np.ones([2]), mindspore.float16) 16 output = net(input_x, scale, bias, mean, variance) 17 print(output) 1.2.2 报错这里报错信息如下:Traceback (most recent call last): File "116945.py", line 22, in <module> output = net(input_x, scale, bias, mean, variance) File "/data2/llj/mindspores/r1.5/build/package/mindspore/nn/cell.py", line 407, in __call__ out = self.compile_and_run(*inputs) File "/data2/llj/mindspores/r1.5/build/package/mindspore/nn/cell.py", line 734, in compile_and_run self.compile(*inputs) File "/data2/llj/mindspores/r1.5/build/package/mindspore/nn/cell.py", line 721, in compile _cell_graph_executor.compile(self, *inputs, phase=self.phase, auto_parallel_mode=self._auto_parallel_mode) File "/data2/llj/mindspores/r1.5/build/package/mindspore/common/api.py", line 551, in compile result = self._graph_executor.compile(obj, args_list, phase, use_vm, self.queue_name) TypeError: mindspore/ccsrc/runtime/device/gpu/kernel_info_setter.cc:355 PrintUnsupportedTypeException] Select GPU kernel op[BatchNorm] fail! Incompatible data type! The supported data types are in[float32 float32 float32 float32 float32], out[float32 float32 float32 float32 float32]; in[float16 float32 float32 float32 float32], out[float16 float32 float32 float32 float32]; , but get in [float16 float16 float16 float16 float16 ] out [float16 float16 float16 float16 float16 ]原因分析我们看报错信息,在TypeError中,写到Select GPU kernel op[BatchNorm] fail! Incompatible data type!The supported data types are in[float32 float32 float32 float32 float32], out[float32 float32 float32 float32 float32]; in[float16 float32 float32 float32 float32], out[float16 float32 float32 float32 float32]; , but get in [float16 float16 float16 float16 float16 ] out [float16 float16 float16 float16 float16 ],大概意思是GPU环境下, 不支持当前输入的数据类型组合, 并说明了支持的数据类型组合是怎样的:全部为float32或者input_x为float16, 其余为float32。检查脚本的输入发现全部为float16类型, 因此报错。2 解决方法基于上面已知的原因,很容易做出如下修改: 01 class Net(nn.Cell): 02 def __init__(self): 03 super(Net, self).__init__() 04 self.batch_norm = ops.BatchNorm() 05 def construct(self,input_x, scale, bias, mean, variance): 06 output = self.batch_norm(input_x, scale, bias, mean, variance) 07 return output 08 09 net = Net() 10 input_x = Tensor(np.ones([2, 2]), mindspore.float16) 11 scale = Tensor(np.ones([2]), mindspore.float32) 12 bias = Tensor(np.ones([2]), mindspore.float32) 13 mean = Tensor(np.ones([2]), mindspore.float32) 14 variance = Tensor(np.ones([2]), mindspore.float32) 15 16 output = net(input_x, scale, bias, mean, variance) 17 print(output)此时执行成功,输出如下:output: (Tensor(shape=[2, 2], dtype=Float16, value= [[ 1.0000e+00, 1.0000e+00], [ 1.0000e+00, 1.0000e+00]]), Tensor(shape=[2], dtype=Float32, value= [ 0.00000000e+00, 0.00000000e+00]), Tensor(shape=[2], dtype=Float32, value= [ 0.00000000e+00, 0.00000000e+00]), Tensor(shape=[2], dtype=Float32, value= [ 0.00000000e+00, 0.00000000e+00]), Tensor(shape=[2], dtype=Float32, value= [ 0.00000000e+00, 0.00000000e+00]))3 总结定位报错问题的步骤:1、找到报错的用户代码行: 16 output = net(input_x, scale, bias, mean, variance);2、 根据日志报错信息中的关键字,缩小分析问题的范围:The supported data types are in[float32 float32 float32 float32 float32], out[float32 float32 float32 float32 float32]; in[float16 float32 float32 float32 float32], out[float16 float32 float32 float32 float32]; , but get in [float16 float16 float16 float16 float16 ] out [float16 float16 float16 float16 float16 ]3、需要重点关注变量定义、初始化的正确性。4 参考文档4.1 BatchNorm算子API接口
  • [安装] 【mindspore-gpu】【gpu训练】ubuntu终端自动退出
    【环境】Ubuntu22.04+mindspore-gpu1.7.0+cuda11.1+cudnn8.0.5【操作步骤&问题现象】1、正确配置显卡驱动和安装cuda,自己写了个一个用GPU训练的测试程序,没有问题。2、运行我自己写得网络的时候,数据处理部分没有问题,到训练那一步的时候突然终端会关闭掉。用pycharm的时候是pycharm会关闭掉。3、没有报错,终端和pycharm直接就关掉了,请问有人遇到过同类问题吗?
  • [分布式] 如何在mindspore中指定矩阵运算的gpu并且切换gpu
    举例如下,我需要在一个循环的第奇数次让两个矩阵A和B在gpu0上运算,否则在gpu1上运算。 如果是pytorch我可以这样实现: device0='cuda: 0' device1='cuda: 1' for j in range(10): if j%2==0: A=A.to(device0) B=B.to(device0) else: A=A.to(device1) B=B.to(device1) C=A+B 如果换成mxnet也可以用nd.array(ctx=gpu(0))这样的语句来实现。 因为最近有需要想用mindspore框架。 但是是mindspore中,我只找到context.set_context(divece_target='GPU', device_id=0)这样的语句来设定矩阵运算所在的GPU,当我想要人为地切换回GPU1时,我再调用context.set_context(divece_target='GPU', device_id=1)就会报错。 想请教在mindspore中,我如何实现如上面pytorch下程序对应的功能呢? (手机打字,请忽略格式问题)
  • [分布式] 在mindspore框架下,如何在指定GPU下计算矩阵运算
    如题。想请问如何在mindspore框架下,实现在指定GPU下的矩阵运算。假设有两个维度完全一样的矩阵A和B,比如进行矩阵相加。 如果在pytorch下,我有这样一个操作:device0 = 'cuda: 0' device1 = 'cuda: 1' for j in range(10): if j%2==0: A = A.to(device0) A = B.to(device0) else: A = A.to(device1) A = B.to(device1) C = A + B也就是在第奇数次循环时在GPU0上运行,否则在GPU1上运行。调研学习了一下,还没能找到办法如何在mindspore中实现这样的操作。还请各位前辈指点。手机码字,请忽略格式问题。感谢