执行问题
Linux
Windows
Ascend
GPU
CPU
环境准备
初级
中级
Q: 使用MindSpore在模型保存后生成的.meta
文件作用是什么,可以用.meta
文件导入图结构吗?
A: 这里的.meta
文件是编译好的图结构,但是目前并不支持直接导入这种结构。如果不知道图结构的情况下想要导入网络,还是需要用MindIR格式的文件。
Q: 请问yolov4-tiny-3l.weights
模型文件可以直接转换成MindSpore模型吗?
A: 不能的,需要把其他框架训练好的参数转换成MindSpore的格式,才能转成MindSpore的模型。
Q: 使用MindSpore进行model.train
的时候进行了如下设置,为什么会报错呢?
model.train(1, dataset, callbacks=LossMonitor(1), dataset_sink_mode=True)
model.train(1, dataset, callbacks=LossMonitor(1), dataset_sink_mode=False)
A: 因为在已经设置为下沉模式的情况下,就不能再设置为非下沉了,是运行机制上的限制。
Q: 使用MindSpore训练模型在eval
阶段,需要注意什么?能够直接加载网络和参数吗?需要在Model中使用优化器吗?
A: 在eval
阶段主要看需要什么,比如图像分类任务eval
网络的输出是各个类的概率值,与对应标签计算acc
。
大多数情况是可以直接复用训练的网络和参数的,需要注意的是需要设置推理模式。
net.set_train(False)
在eval阶段不需要优化器,但是需要使用MindSpore的model.eval
接口的话需要配置一下loss function
,如:
# 定义模型
model = Model(net, loss_fn=loss, metrics={'top_1_accuracy', 'top_5_accuracy'})
# 评估模型
res = model.eval(dataset)
Q: 如何使用SGD里的param_group
来实现学习率的衰减?
A: 如果需要按照epoch
来变化,可以使用Dynamic LR,把其中的step_per_epoch
设置成step_size
,如果需要按照step
来变化,可以把其中的step_per_epoch
设置成1,也可以用LearningRateSchedule。
Q: MindSpore如何进行参数(如dropout值)修改?
A: 在构造网络的时候可以通过 if self.training: x = dropput(x)
,推理时,执行前设置network.set_train(mode_false)
,就可以不使用dropout,训练时设置为True就可以使用dropout。
Q: 如何查看模型参数量?
A: 可以直接加载CheckPoint统计,可能额外统计了动量和optimizer中的变量,需要过滤下相关变量。 您可以参考如下接口统计网络参数量:
def count_params(net):
"""Count number of parameters in the network
Args:
net (mindspore.nn.Cell): Mindspore network instance
Returns:
total_params (int): Total number of trainable params
"""
total_params = 0
for param in net.trainable_params():
total_params += np.prod(param.shape)
return total_params
具体脚本链接。
Q: 如何在训练过程中监控loss
在最低的时候并保存训练参数?
A: 可以自定义一个Callback
。参考ModelCheckpoint
的写法,此外再增加判断loss
的逻辑:
class EarlyStop(Callback):
def __init__(self):
self.loss = None
def step_end(self, run_context):
loss = ****(get current loss)
if (self.loss == None or loss < self.loss):
self.loss = loss
# do save ckpt
Q: 使用nn.Conv2d
时,怎样获取期望大小的feature map
?
A: Conv2d shape
推导方法可以参考这里,Conv2d
的pad_mode
改成same
,或者可以根据Conv2d shape
推导公式自行计算pad
,想要使得shape
不变,一般pad为(kernel_size-1)//2
。
Q: 使用MindSpore可以自定义一个可以返回多个值的loss函数?
A: 自定义loss function
后还需自定义TrainOneStepCell
,实现梯度计算时sens
的个数和network
的输出个数相同。具体可参考:
net = Net()
loss_fn = MyLoss()
loss_with_net = MyWithLossCell(net, loss_fn)
train_net = MyTrainOneStepCell(loss_with_net, optim)
model = Model(net=train_net, loss_fn=None, optimizer=None)
Q: MindSpore如何实现早停功能?
A: 可以自定义callback
方法实现早停功能。
例子: 当loss降到一定数值后,停止训练。
class EarlyStop(Callback):
def __init__(self, control_loss=1):
super(EarlyStep, self).__init__()
self._control_loss = control_loss
def step_end(self, run_context):
cb_params = run_context.original_args()
loss = cb_params.net_outputs
if loss.asnumpy() < self._control_loss:
# Stop training
run_context._stop_requested = True
stop_cb = EarlyStop(control_loss=1)
model.train(epoch_size, ds_train, callbacks=[stop_cb])
Q: 模型已经训练好,如何将模型的输出结果保存为文本或者npy
的格式?
A: 您好,我们网络的输出为Tensor
,需要使用asnumpy()
方法将Tensor
转换为numpy
,再进行下一步保存。具体可参考:
out = net(x)
np.save("output.npy", out.asnumpy())
Q: 运行时报错“Create python object `<class ‘mindspore.common.tensor.Tensor’>` failed, only support create Cell or Primitive object.”怎么办?
A: 当前在图模式下,construct
函数(或@ms_function
装饰器修饰的函数)仅支持构造Cell
和Primitive object
,不支持构造Tensor
,即不支持语法x = Tensor(args...)
。
如果是常量Tensor
,请在__init__
函数中定义。如果不是常量Tensor
,可以通过@constexpr
装饰器修饰函数,在函数里生成Tensor
。
关于@constexpr
的用法可参考: https://www.mindspore.cn/docs/api/zh-CN/r1.3/api_python/ops/mindspore.ops.constexpr.html。
对于网络中需要用到的常量Tensor
,可以作为网络的属性,在init
的时候定义,即self.x = Tensor(args...)
,然后在construct
函数(或@ms_function
装饰器修饰的函数)里使用。
如下示例,通过@constexpr
生成一个shape = (3, 4), dtype = int64
的Tensor
。
@constexpr
def generate_tensor():
return Tensor(np.ones((3, 4).astype(np.int64)))
Q: 运行时报错“’self.xx’ should be defined in the class ‘init’ function.”怎么办?
A: 如果在construct
函数里,想对类成员self.xx
赋值,那么self.xx
必须已经在__init__
函数中被定义为Parameter
类型,其他类型则不支持。局部变量xx
不受这个限制。
Q: 运行时报错“This comparator ‘AnyValue’ is not supported. For statement ‘is’, only support compare with ‘None’, ‘False’ or ‘True’”怎么办?
A: 对于语法is
或 is not
而言,当前MindSpore
仅支持与True
、False
和None
的比较。暂不支持其他类型,如字符串等。
Q: 运行时报错“MindSpore does not support comparison with operators more than one now, ops size =2”怎么办?
A: 对于比较语句,MindSpore
最多支持一个操作数。例如不支持语句1 < x < 3
,请使用1 < x and x < 3
的方式代替。
Q: 运行时报错“TypeError: The function construct need 1 positional argument and 0 default argument, but provided 2”怎么办?
A: 网络的实例被调用时,会执行construct
方法,然后会检查construct
方法需要的参数个数和实际传入的参数个数,如果不一致则会抛出以上异常。
请检查脚本中调用网络实例时传入的参数个数,和定义的网络中construct
函数需要的参数个数是否一致。
Q: 运行时报错“Type Join Failed”或“Shape Join Failed”怎么办?
A: 在前端编译的推理阶段,会对节点的抽象类型(包含type
、shape
等)进行推导,常见抽象类型包括AbstractScalar
、AbstractTensor
、AbstractFunction
、AbstractTuple
、AbstractList
等。在一些场景比如多分支场景,会对不同分支返回值的抽象类型进行join
合并,推导出返回结果的抽象类型。如果抽象类型不匹配,或者type
/shape
不一致,则会抛出以上异常。
当出现类似“Type Join Failed: dtype1 = Float32, dtype2 = Float16”的报错时,说明数据类型不一致,导致抽象类型合并失败。根据提供的数据类型和代码行信息,可以快速定位出错范围。此外,报错信息中提供了具体的抽象类型信息、节点信息,可以通过analyze_fail.dat
文件查看MindIR信息,定位解决问题。关于MindIR的具体介绍,可以参考MindSpore IR(MindIR)。代码样例如下:
import numpy as np
import mindspore as ms
import mindspore.ops as ops
from mindspore import nn, Tensor, context
context.set_context(mode=context.GRAPH_MODE)
class Net(nn.Cell):
def __init__(self):
super().__init__()
self.relu = ops.ReLU()
self.cast = ops.Cast()
def construct(self, x, a, b):
if a > b:
return self.relu(x)
else:
return self.cast(self.relu(x), ms.float16)
input_x = Tensor(np.random.rand(2, 3, 4, 5).astype(np.float32))
input_a = Tensor(2, ms.float32)
input_b = Tensor(6, ms.float32)
net = Net()
out_me = net(input_x, input_a, input_b)
执行结果如下:
TypeError: The return values of different branches do not match. Type Join Failed: dtype1 = Float32, dtype2 = Float16. The abstract type of the return value of the current branch is AbstractTensor(shape: (2, 3, 4, 5), element: AbstractScalar(Type: Float16, Value: AnyValue, Shape: NoShape), value_ptr: 0x32ed00e0, value: AnyValue), and that of the previous branch is AbstractTensor(shape: (2, 3, 4, 5), element: AbstractScalar(Type: Float32, Value: AnyValue, Shape: NoShape), value_ptr: 0x32ed00e0, value: AnyValue). Please check the node construct.4:[CNode]5{[0]: [CNode]6}, true branch: ✓construct.2, false branch: ✗construct.3. trace:
In file test_type_join_failed.py(14)/ if a > b:/
The function call stack (See file 'analyze_fail.dat' for more details):
# 0 In file test_type_join_failed.py(14)
if a > b:
当出现类似“Shape Join Failed: shape1 = (2, 3, 4, 5), shape2 = ()”的报错时,说明shape
不一致,导致抽象类型合并失败。代码样例如下:
import numpy as np
import mindspore as ms
import mindspore.ops as ops
from mindspore import nn, Tensor, context
context.set_context(mode=context.GRAPH_MODE)
class Net(nn.Cell):
def __init__(self):
super().__init__()
self.relu = ops.ReLU()
self.reducesum = ops.ReduceSum()
def construct(self, x, a, b):
if a > b:
return self.relu(x)
else:
return self.reducesum(x)
input_x = Tensor(np.random.rand(2, 3, 4, 5).astype(np.float32))
input_a = Tensor(2, ms.float32)
input_b = Tensor(6, ms.float32)
net = Net()
out = net(input_x, input_a, input_b)
执行结果如下:
ValueError: The return values of different branches do not match. Shape Join Failed: shape1 = (2, 3, 4, 5), shape2 = (). The abstract type of the return value of the current branch is AbstractTensor(shape: (), element: AbstractScalar(Type: Float32, Value: AnyValue, Shape: NoShape), value_ptr: 0x239b5120, value: AnyValue), and that of the previous branch is AbstractTensor(shape: (2, 3, 4, 5), element: AbstractScalar(Type: Float32, Value: AnyValue, Shape: NoShape), value_ptr: 0x239b5120, value: AnyValue). Please check the node construct.4:[CNode]5{[0]: [CNode]6}, true branch: ✓construct.2, false branch: ✗construct.3. trace:
In file test_shape_join_failed.py(14)/ if a > b:/
The function call stack (See file 'analyze_fail.dat' for more details):
# 0 In file test_shape_join_failed.py(14)
if a > b:
当出现如“Type Join Failed: abstract type AbstractTensor can not join with AbstractTuple”的报错时,说明这两种抽象类型无法匹配,需要根据提供的代码行等报错信息,重新检视代码并修改。
Q: 缓存服务器异常关闭如何处理?
A: 缓存服务器使用过程中,会进行IPC共享内存和socket文件等系统资源的分配。若允许溢出,在磁盘空间还会存在溢出的数据文件。一般情况下,如果通过cache_admin --stop
命令正常关闭服务器,这些资源将会被自动清理。
但如果缓存服务器被异常关闭,例如缓存服务进程被杀等,用户需要首先尝试重新启动服务器,若启动失败,则应该依照以下步骤手动清理系统资源:
删除IPC资源。
检查是否有IPC共享内存残留。
一般情况下,系统会为缓存服务分配4GB的共享内存。通过以下命令可以查看系统中的共享内存块使用情况。
$ ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x61020024 15532037 root 666 4294967296 1
其中,
shmid
为共享内存块id,bytes
为共享内存块的大小,nattch
为链接到该共享内存块的进程数量。nattch
不为0表示仍有进程使用该共享内存块。在删除共享内存前,需要停止使用该内存块的所有进程。删除IPC共享内存。
找到对应的共享内存id,并通过以下命令删除。
ipcrm -m {shmid}
删除socket文件。
一般情况下,socket文件位于
/tmp/mindspore/cache
。进入文件夹,执行以下命令删除socket文件。rm cache_server_p{port_number}
其中
port_number
为用户创建缓存服务器时指定的端口号,默认为50052。删除溢出到磁盘空间的数据文件。
进入启用缓存服务器时指定的溢出数据路径。通常,默认溢出路径为
/tmp/mindspore/cache
。找到路径下对应的数据文件夹并逐一删除。
Q: 通过Hub可以使用GPU加载vgg16
模型以及是否可以做迁移模型吗?
A: 请手动修改如下两处参数即可:
# 增加**kwargs参数: 如下
def vgg16(num_classes=1000, args=None, phase="train", **kwargs):
# 增加**kwargs参数: 如下
net = Vgg(cfg['16'], num_classes=num_classes, args=args, batch_norm=args.batch_norm, phase=phase, **kwargs)
Q: 如何得到VGG模型中间层特征?
A: 你好,获取网络中间层的特征,其实跟具体框架没有太大关系了。torchvison
里定义的vgg
模型,可以通过features
字段获取”中间层特征”,torchvison
的vgg
源码如下:
class VGG(nn.Module):
def __init__(self, features, num_classes=1000, init_weights=True):
super(VGG, self).__init__()
self.features = features
self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
在MindSpore的ModelZoo里定义的vgg16
,可以通过layers
字段获取,如下:
network = vgg16()
print(network.layers)
Q: 使用MindSpore进行模型训练时,CTCLoss
的输入参数有四个: inputs
, labels_indices
, labels_values
, sequence_length
,如何使用CTCLoss
进行训练?
A: 定义的model.train
接口里接收的dataset
可以是多个数据组成,形如(data1
, data2
, data3
, …),所以dataset
是可以包含inputs
,labels_indices
,labels_values
,sequence_length
的信息的。只需要定义好相应形式的dataset
,传入model.train
里就可以。具体的可以了解下相应的数据处理接口
Q: 模型转移时如何把PyTorch的权重加载到MindSpore中?
A: 首先输入PyTorch的pth
文件,以ResNet-18
为例,MindSpore的网络结构和PyTorch保持一致,转完之后可直接加载进网络,这边参数只用到BN
和Conv2D
,若有其他层ms
和PyTorch名称不一致,需要同样的修改名称。
Q: MindSpore有哪些现成的推荐类或生成类网络或模型可用?
A: 目前正在开发Wide & Deep、DeepFM、NCF等推荐类模型,NLP领域已经支持Bert_NEZHA,正在开发MASS等模型,用户可根据场景需要改造为生成类网络,可以关注MindSpore Model Zoo。
Q: 如何使用MindSpore拟合\(f(x)=a \times sin(x)+b\)这类函数?
A: 以下拟合案例是基于MindSpore线性拟合官方案例改编而成。
# The fitting function is: f(x)=2*sin(x)+3.
import numpy as np
from mindspore import dataset as ds
from mindspore.common.initializer import Normal
from mindspore import nn, Model, context
from mindspore.train.callback import LossMonitor
context.set_context(mode=context.GRAPH_MODE, device_target="CPU")
def get_data(num, w=2.0, b=3.0):
# f(x)=w * sin(x) + b
# f(x)=2 * sin(x) +3
for i in range(num):
x = np.random.uniform(-np.pi, np.pi)
noise = np.random.normal(0, 1)
y = w * np.sin(x) + b + noise
yield np.array([np.sin(x)]).astype(np.float32), np.array([y]).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=['data','label'])
input_data = input_data.batch(batch_size)
input_data = input_data.repeat(repeat_size)
return input_data
class LinearNet(nn.Cell):
def __init__(self):
super(LinearNet, self).__init__()
self.fc = nn.Dense(1, 1, Normal(0.02), Normal(0.02))
def construct(self, x):
x = self.fc(x)
return x
if __name__ == "__main__":
num_data = 1600
batch_size = 16
repeat_size = 1
lr = 0.005
momentum = 0.9
net = LinearNet()
net_loss = nn.loss.MSELoss()
opt = nn.Momentum(net.trainable_params(), lr, momentum)
model = Model(net, net_loss, opt)
ds_train = create_dataset(num_data, batch_size=batch_size, repeat_size=repeat_size)
model.train(1, ds_train, callbacks=LossMonitor(), dataset_sink_mode=False)
print(net.trainable_params()[0], "\n%s" % net.trainable_params()[1])
Q: 如何使用MindSpore拟合\(f(x)=ax^2+bx+c\)这类的二次函数?
A: 以下代码引用自MindSpore的官方教程的代码仓
在以下几处修改即可很好的拟合\(f(x)=ax^2+bx+c\):
数据集生成。
拟合网络。
优化器。
修改的详细信息如下,附带解释。
# Since the selected optimizer does not support CPU, so the training computing platform is changed to GPU, which requires readers to install the corresponding GPU version of MindSpore.
context.set_context(mode=context.GRAPH_MODE, device_target="GPU")
# Assuming that the function to be fitted this time is f(x)=2x^2+3x+4, the data generation function is modified as follows:
def get_data(num, a=2.0, b=3.0 ,c = 4):
for i in range(num):
x = np.random.uniform(-10.0, 10.0)
noise = np.random.normal(0, 1)
# The y value is generated by the fitting target function ax^2+bx+c.
y = x * x * a + x * b + c + noise
# When a*x^2+b*x+c is fitted, a and b are weight parameters and c is offset parameter bias. The training data corresponding to the two weights are x^2 and x respectively, so the data set generation mode is changed as follows:
yield np.array([x*x, x]).astype(np.float32), np.array([y]).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=['data','label'])
input_data = input_data.batch(batch_size)
input_data = input_data.repeat(repeat_size)
return input_data
class LinearNet(nn.Cell):
def __init__(self):
super(LinearNet, self).__init__()
# Because the full join function inputs two training parameters, the input value is changed to 2, the first Nomral(0.02) will automatically assign random weights to the input two parameters, and the second Normal is the random bias.
self.fc = nn.Dense(2, 1, Normal(0.02), Normal(0.02))
def construct(self, x):
x = self.fc(x)
return x
if __name__ == "__main__":
num_data = 1600
batch_size = 16
repeat_size = 1
lr = 0.005
momentum = 0.9
net = LinearNet()
net_loss = nn.loss.MSELoss()
# RMSProp optimalizer with better effect is selected for quadratic function fitting, Currently, Ascend and GPU computing platforms are supported.
opt = nn.RMSProp(net.trainable_params(), learning_rate=0.1)
model = Model(net, net_loss, opt)
ds_train = create_dataset(num_data, batch_size=batch_size, repeat_size=repeat_size)
model.train(1, ds_train, callbacks=LossMonitor(), dataset_sink_mode=False)
print(net.trainable_params()[0], "\n%s" % net.trainable_params()[1])
Q: mindspore/tests
下怎样执行单个ut
用例?
A: ut
用例通常需要基于debug版本的MindSpore包,官网并没有提供。可以基于源码使用sh build.sh
编译,然后通过pytest
指令执行,debug模式编包不依赖后端。编译选项sh build.sh -t on
,用例执行可以参考tests/runtest.sh
脚本。
Q: 在Ascend平台上,执行用例有时候会报错run task error
,如何获取更详细的日志帮助问题定位?
A: 使用msnpureport工具设置device侧日志级别,工具位置在: /usr/local/Ascend/driver/tools/msnpureport
。
全局级别:
/usr/local/Ascend/driver/tools/msnpureport -g info
模块级别:
/usr/local/Ascend/driver/tools/msnpureport -m SLOG:error
Event级别:
/usr/local/Ascend/driver/tools/msnpureport -e disable/enable
多device id级别:
/usr/local/Ascend/driver/tools/msnpureport -d 1 -g warning
假设deviceID的取值范围是[0-7],device0
-device3
和device4
-device7
分别在一个os上。其中device0
-device3
共用一个日志配置文件;device4
-device7
共用一个配置文件。如果修改了device0
-device3
中的任意一个日志级别,其他device
的日志级别也会被修改。如果修改了device4
-device7
中的任意一个日志级别,其他device的日志级别也会被修改。
Driver
包安装以后(假设安装路径为/usr/local/HiAI,在Windows环境下,msnpureport.exe
执行文件在C:\ProgramFiles\Huawei\Ascend\Driver\tools\目录下),假设用户在/home/shihangbo/目录下直接执行命令行,则Device侧日志被导出到当前目录下,并以时间戳命名文件夹进行存放。
Q: 使用Ascend平台执行训练过程,出现报错: Out of Memory!!! total[3212254720] (dynamic[0] memory poll[524288000]) malloc[32611480064] failed!
如何解决?
A: 此问题属于内存占用过多导致的内存不够问题,可能原因有两种:
batch_size
的值设置过大。解决办法: 将batch_size
的值设置减小。引入了异常大的
Parameter
,例如单个数据shape为[640,1024,80,81],数据类型为float32,单个数据大小超过15G,这样差不多大小的两个数据相加时,占用内存超过3*15G,容易造成Out of Memory
。解决办法: 检查参数的shape
,如果异常过大,减少shape。如果以上操作还是未能解决,可以上官方论坛发帖提出问题,将会有专门的技术人员帮助解决。
Q: 如何在训练神经网络过程中对计算损失的超参数进行改变?
A: 您好,很抱歉暂时还未有这样的功能。目前只能通过训练–>重新定义优化器–>训练,这样的过程寻找较优的超参数。
Q: 运行应用时报错error while loading shared libraries: libge_compiler.so: cannot open shared object file: No such file or directory
怎么办?
A: 安装MindSpore所依赖的Ascend 310 AI处理器配套软件包时,CANN
包不能安装nnrt
版本,而是需要安装功能完整的toolkit
版本。
Q: MindSpore代码里面的model_zoo/official/cv/resnet/train.py中context.set_ps_context(enable_ps=True)为什么一定要在init之前设置
A: MindSpore Ascend模式下,如果先调用init,那么会为所有的进程都分配卡,但是parameter server训练模式下server是不需要分配卡的,那么worker和server就会去使用同一块卡,导致会报错: Hccl dependent tsd is not open。