问题描述:
【功能模块】
GPU -GRAPH_MODE 与 GPU-PYNATIVE/ CPU-GRAPH_MODE 输出不一致
【操作步骤&问题现象】
1、CPU 的 GRAPH_MODE 能够正常运行, 并且每轮 step 都可以调用 CallBack
2、GPU 的PYNATIVE_MODE 下能够正常运行
3、GPU的GRAPH_MODE 存在三个问题
1. input 0 of cnode is not a value node (这在cpu 的 graph_mode 下 并没有出现这一警告)
2. step 间隔数不为1
3. loss 为 nan
想请教一下,在不同的设备与 mode下如何才能保证结果的一致性, dataset的sink mode 会不会在不同设备上有不同的效果
【截图信息】
1. CPU GRAPH_MODE
2. GPU GRAPH MODE
3. GPU PYNATIVE
我的input 0 of cnode is not a value node 的问题找到了,是由于我定义了一个独立的节点,该节点的值为0, 主要是用于当loss除以0的时候直接输出该节点。nan的问题目前不再出现了。但是,每次callback不能正常输出的问题仍然存在,即我每个step都会输出loss方便监控,但是如上图所示,只会在特定的step中才会有输出,同样的saveckpt callback也有这个问题。监控模型训练进度与保存模型很不方便,请问有什么解决措施么?目前是以graph_mode 在 gpu模式下运行的。
解答:
1,在网络参数初始化和训练数据相同的情况下,CPU和GPU的graph_mode计算出来的loss应该是相同的,出现不同的原因可能是网络参数随机初始化不同,也可能是每个step选择的训练数据集不同。
2,目前只有GPU和Ascend有下沉模式,CPU模式下不会跑真正的数据下沉;
您的问题应该主要是input 0 of cnode is not a value node 和出现nan。 方便看一下你的网络上怎么构建的吗?
因为model.train()的一个参数dataset_sink_mode的默认值为True。 根据文档(https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.5/on_device.html?highlight=dataset_sink)描述:如果dataset_sink_mode设置为False,Host侧和Device侧之间每个step交互一次,所以会每个step返回一个结果,如果dataset_sink_mode为True,因为数据在Device上通过通道传输, Host侧和Device侧之间每个epoch进行一次数据交互,所以每个epoch只返回一次结果。 所以,如果你把dataset_sink_mode设置成False的话,应该就能每个step都能看到打印了。