Paddle [CustomDevice] test_elementwise_div Net 测例 fallback SGD优化器报错

kuarbcqp  于 4个月前  发布在  其他
关注(0)|答案(8)|浏览(60)

请提出你的问题 Please ask your question

问题:新执行器是否支持CustomDevice下小网络(如下举例)优化器fallback CPU执行?npu插件是否能复现此现象
如果不能复现,大概原因是什么?

版本:PaddlePaddle2.5.0 + 插件;PaddlePaddle-develop + 插件;
场景:小网络中优化器(如SGD)fallback cpu
现象:看上去都计算完成了,但是最后会报同步的错误

npu是否可复现:test_elementwise_div_op_npu 仅保留此测例,使用此命令执行:
CUSTOM_DEVICE_BLACK_LIST=momentum ctest -R test_elementwise_div -V

class TestElementwiseDivNet(unittest.TestCase):
    def _test(self, run_npu=True):
        main_prog = paddle.static.Program()
        startup_prog = paddle.static.Program()
        main_prog.random_seed = SEED
        startup_prog.random_seed = SEED
        np.random.seed(SEED)

        a_np = np.random.uniform(1, 2, [32, 32]).astype("float32")
        b_np = np.random.uniform(1, 2, [32, 32]).astype("float32")
        c_np = np.random.uniform(1, 2, [32, 32]).astype("float32")
        d_np = np.random.uniform(1, 2, [32, 32]).astype("float32")
        label_np = np.random.randint(2, size=(32, 1)).astype("int64")

        with paddle.static.program_guard(main_prog, startup_prog):
            a = paddle.static.data(name="a", shape=[32, 32], dtype="float32")
            b = paddle.static.data(name="b", shape=[32, 32], dtype="float32")
            c = paddle.static.data(name="c", shape=[32, 32], dtype="float32")
            d = paddle.static.data(name="d", shape=[32, 32], dtype="float32")
            label = paddle.static.data(name="label", shape=[32, 1], dtype="int64")

            e = paddle.multiply(a, b)
            f = paddle.multiply(c, d)
            f.stop_gradient = True
            g = paddle.divide(e, f)

            fc_1 = paddle.static.nn.fc(x=g, size=128)
            prediction = paddle.static.nn.fc(x=fc_1, size=2, activation="softmax")

            cost = paddle.nn.functional.cross_entropy(input=prediction, label=label)
            loss = paddle.mean(cost)
            sgd = paddle.optimizer.Momentum(learning_rate=0.01)
            sgd.minimize(loss)

        if run_npu:
            place = paddle.CustomPlace("npu", 0)
        else:
            place = paddle.CPUPlace()

        exe = paddle.static.Executor(place)
        exe.run(startup_prog)

        print("Start run on {}".format(place))
        for epoch in range(2):

            pred_res, loss_res = exe.run(
                main_prog,
                feed={"a": a_np, "b": b_np, "c": c_np, "d": d_np, "label": label_np},
                fetch_list=[prediction, loss],
            )
            if epoch % 1 == 0:
                print(
                    "Epoch {} | Prediction[0]: {}, Loss: {}".format(
                        epoch, pred_res[0], loss_res
                    )
                )

        return pred_res, loss_res

    def test_npu(self):
        #cpu_pred, cpu_loss = self._test(False)
        npu_pred, npu_loss = self._test(True)

        #self.assertTrue(np.allclose(npu_pred, cpu_pred))
        #self.assertTrue(np.allclose(npu_loss, cpu_loss))
gab6jxml

gab6jxml1#

补充一下:
我fallback了非优化器kernel发现前后会插入d2h 和 h2d 但优化器仅有前面的d2h,是否新执行器不支持优化器的fallback?

wlzqhblo

wlzqhblo2#

优化器kernel函数和普通kernel函数不同,这里的输出看上去官方想做成inplace,新执行器处理逻辑是怎样的?

动态图下,sgd外面是被包裹了sgd_的,这里面做了fallback逻辑处理;计算结果会拷回backend
0 sgd__ad_func(paddle::Tensor&, paddle::Tensor const&, paddle::Tensor const&, paddle::optionalpaddle::Tensor&, bool)
1 paddle::experimental::sgd_(paddle::Tensor&, paddle::Tensor const&, paddle::Tensor const&, paddle::optionalpaddle::Tensor&, bool)
2 void phi::SGDDenseKernel<float, phi::CPUContext>(phi::CPUContext const&, phi::DenseTensor const&, phi::DenseTensor const&, phi::DenseTensor const&, paddle::optionalphi::DenseTensor const&, bool, phi::DenseTensor*, phi::DenseTensor*)

静态图下,调到了KernelImpl 应该是VARIADIC func,应该不会处理,需要外部做处理,调用栈:
30: 0 paddle::framework::StandaloneExecutor::Run(paddle::framework::Scope*, std::vector<std::string, std::allocator<std::string > > const&, std::vector<std::string, std::allocator<std::string > > const&)
30: 1 paddle::framework::InterpreterCore::Run(std::vector<std::string, std::allocator<std::string > > const&, bool)
30: 2 paddle::framework::interpreter::BuildOpFuncList(phi::Place const&, paddle::framework::BlockDesc const&, std::set<std::string, std::less<std::string >, std::allocator<std::string > > const&, std::vector<paddle::framework::OpFuncNode, std::allocatorpaddle::framework::OpFuncNode >, paddle::framework::VariableScope, paddle::framework::interpreter::ExecutionConfig const&, bool, bool)
30: 3 void phi::KernelImpl<void (*)(phi::CPUContext const&, phi::DenseTensor const&, phi::DenseTensor const&, phi::DenseTensor const&, paddle::optionalphi::DenseTensor const&, bool, phi::DenseTensor*, phi::DenseTensor*), &(void phi::SGDDenseKernel<float, phi::CPUContext>(phi::CPUContext const&, phi::DenseTensor const&, phi::DenseTensor const&, phi::DenseTensor const&, paddle::optionalphi::DenseTensor const&, bool, phi::DenseTensor*, phi::DenseTensor*))>::KernelCallHelper<paddle::optionalphi::DenseTensor const&, bool, phi::DenseTensor*, phi::DenseTensor*, phi::TypeTag >::Compute<1, 3, 0, 0, phi::CPUContext const, phi::DenseTensor const, phi::DenseTensor const, phi::DenseTensor const>(phi::KernelContext*, phi::CPUContext const&, phi::DenseTensor const&, phi::DenseTensor const&, phi::DenseTensor const&)
30: 4 void phi::SGDDenseKernel<float, phi::CPUContext>(phi::CPUContext const&, phi::DenseTensor const&, phi::DenseTensor const&, phi::DenseTensor const&, paddle::optionalphi::DenseTensor const&, bool, phi::DenseTensor*, phi::DenseTensor*)

gdx19jrr

gdx19jrr3#

@JunnYu 请问可以帮看下吗?

p5cysglq

p5cysglq4#

@tiandou-tangdou 目前正安排同学帮你看

qzwqbdag

qzwqbdag5#

你好,NPU也会复现同步错误,但不知是否与你的错误相同,推测应该是优化器fallback之后没有h2d导致

bvn4nwqk

bvn4nwqk6#

你好,NPU也会复现同步错误,但不知是否与你的错误相同,推测应该是优化器fallback之后没有h2d导致

@ronny1996 应该是一致的,NPU之前也是通过环境变量控制使用老执行器,看上去 2.5默认使用的新执行器行为 与 老的执行器不同。
可以联系执行器相关同学帮看下吗?@junyu

dgenwo3n

dgenwo3n7#

@tiandou-tangdou 你好,这个问题已经定位到了,执行器会分析一个step的图决定fallback的kernel后是否插入memcpy_h2d(如果后续用到就会插入),优化器参数被inplace的改成了cpu,但是是在下一个step使用到,所以输入一个cpu参数就错了,目前还是不要fallback优化器,这个问题我们也会修复

k5ifujac

k5ifujac8#

@tiandou-tangdou 你好,这个问题已经定位到了,执行器会分析一个step的图决定fallback的kernel后是否插入memcpy_h2d(如果后续用到就会插入),优化器参数被inplace的改成了cpu,但是是在下一个step使用到,所以输入一个cpu参数就错了,目前还是不要fallback优化器,这个问题我们也会修复

@ronny1996 多谢,我们暂不fallback优化器使用。如果修复请帮忙关联此issue告知。

相关问题