Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

自定义外部算子如何写二次反向? #40800

Closed
miemie2013 opened this issue Mar 22, 2022 · 23 comments · Fixed by #41072
Closed

自定义外部算子如何写二次反向? #40800

miemie2013 opened this issue Mar 22, 2022 · 23 comments · Fixed by #41072
Assignees

Comments

@miemie2013
Copy link

如题,官方文档 https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/07_new_op/new_custom_op_cn.html 给出了一个relu的示例,提到了一个宏PD_BUILD_DOUBLE_GRAD_OP,但是,没有给出这个宏的使用示例。现在项目中需要使用二阶导,希望能得到官方解答。

@paddle-bot-old
Copy link

您好,我们已经收到了您的问题,会安排技术人员尽快解答您的问题,请耐心等待。请您再次检查是否提供了清晰的问题描述、复现代码、环境&版本、报错信息等。同时,您也可以通过查看官网API文档常见问题历史IssueAI社区来寻求解答。祝您生活愉快~

Hi! We've received your issue and please be patient to get responded. We will arrange technicians to answer your questions as soon as possible. Please make sure that you have posted enough message to demo your request. You may also check out the APIFAQGithub Issue and AI community to get the answer.Have a nice day!

@GT-ZhangAcer
Copy link
Member

mark

@chenwhql
Copy link
Contributor

它的用法和一阶反向注册宏PD_BUILD_GRAD_OP是类似的,重点还是二阶的计算逻辑需要自己推演一下,我今天提供一个示例哈

@miemie2013
Copy link
Author

它的用法和一阶反向注册宏PD_BUILD_GRAD_OP是类似的,重点还是二阶的计算逻辑需要自己推演一下,我今天提供一个示例哈

期待

@chenwhql
Copy link
Contributor

chenwhql commented Mar 25, 2022

提交了一个添加示例的PR,并添加相应单测在动态图测试通过了

#40963

写法基本是没问题的,但在测试时发现一处原先遗留的小问题(少了个break语句),因此顺便修复了一下。但是这导致您不能基于已发布的paddle版本上进行开发了,可能需要等下即将发布的2.3RC或者基于develop版本进行开发

给您造成不便,非常抱歉!

@miemie2013
Copy link
Author

提交了一个添加示例的PR,并添加相应单测在动态图测试通过了

#40963

写法基本是没问题的,但在测试时发现一处原先遗留的小问题(少了个break语句),因此顺便修复了一下。但是这导致您不能基于已发布的paddle版本上进行开发了,可能需要等下即将发布的2.3RC或者基于develop版本进行开发

给您造成不便,非常抱歉!

感谢大佬!那我就安装develop版本体验一下,祝飞桨越来越好!

@chenwhql
Copy link
Contributor

提交了一个添加示例的PR,并添加相应单测在动态图测试通过了
#40963
写法基本是没问题的,但在测试时发现一处原先遗留的小问题(少了个break语句),因此顺便修复了一下。但是这导致您不能基于已发布的paddle版本上进行开发了,可能需要等下即将发布的2.3RC或者基于develop版本进行开发
给您造成不便,非常抱歉!

感谢大佬!那我就安装develop版本体验一下,祝飞桨越来越好!

得等这个PR合入了哈,合入之后我通知您,感谢支持!

@GT-ZhangAcer
Copy link
Member

感谢wh老师

@chenwhql
Copy link
Contributor

PR已合入,但是paddle的develop,即nightly build版本是当天晚上编包,所以可能要到第二天才能下载的最新的,https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/develop/install/pip/linux-pip.html

@miemie2013
Copy link
Author

PR已合入,但是paddle的develop,即nightly build版本是当天晚上编包,所以可能要到第二天才能下载的最新的,https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/develop/install/pip/linux-pip.html

感谢大佬!这样不用自己编译了,呜呜呜

@miemie2013
Copy link
Author

PR已合入,但是paddle的develop,即nightly build版本是当天晚上编包,所以可能要到第二天才能下载的最新的,https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/develop/install/pip/linux-pip.html

大佬你好!我按照你给的示例写了一个tanh的自定义op,现在遇到了y的一阶梯度找不到的问题:
项目地址:https://aistudio.baidu.com/aistudio/projectdetail/3653409

首先,输入以下命令安装最新的develop分支的paddlepaddle

cd ~/work/tanh
python -m pip install paddlepaddle-gpu==0.0.0.post101 -f https://www.paddlepaddle.org.cn/whl/linux/gpu/develop.html

然后,输入以下命令编译、安装、运行自定义tanh op

rm -rf build
rm -rf custom_ops.egg-info
python setup.py install
python test2_16_elementwise_grad_paddle_custom.py

会报以下错误:
RuntimeError: (NotFound) No Input(Y@GRAD) found for Custom operator.
[Hint: Expected ctx->HasInput(in_name) == true, but received ctx->HasInput(in_name):0 != true:1.] (at /paddle/paddle/fluid/framework/custom_operator.cc:292)

系计算二阶梯度时需要Y的一阶梯度,但是找不到。

另外,我也看了paddle/phi/kernels/funcs/activation_functor.h中tanh二阶梯度的实现(TanhGradGradFunctor),需要求2个梯度,分别是ddy和dy_new,用伪代码可以这样写

    ddy = ddx * (1 - paddle.square(y))
    dy_new = ddx * dy * -2 * y

我在tanh.cpp中这样写:

PD_BUILD_DOUBLE_GRAD_OP(tanh_op)
    .Inputs({"Y", paddle::Grad("Y"), paddle::Grad(paddle::Grad("X"))})
    .Outputs({paddle::Grad(paddle::Grad("Y")), paddle::Grad("Y")})
    .SetKernelFn(PD_KERNEL(TanhDoubleBackward))
    .SetInferShapeFn(PD_INFER_SHAPE(tanh_double_backward_InferShape));

即我不知道用paddle::Grad("Y")来表示dy_new是不是正确的?所以请大佬帮我解决一下Y@GRAD找不到的问题以及dy_new如何写如何实现的问题,谢谢!

@chenwhql
Copy link
Contributor

我用您的代码在本地复现调试一下吧,看起来也是一种之前没有试过的特殊case,但这个aistudio点进去看不到代码,请问这个要怎么看到

@miemie2013
Copy link
Author

我用您的代码在本地复现调试一下吧,看起来也是一种之前没有试过的特殊case,但这个aistudio点进去看不到代码,请问这个要怎么看到

大佬您好!代码在~/work/tanh/目录下。或者这里:
代码地址:https://github.com/miemie2013/Paddle_custom_op
在tanh目录下。

大佬,现在又遇到了另一个问题,我该怎么写个自定义sum呢?(代码在上面仓库的sum目录下)sum操作对某几维求和,现在我准备只实现对1维求和,不知道_cuda_forwark_kernel怎么写并行求和,希望也能得到一个示例。

另外希望飞桨能尽快支持用paddle.autograd.PyLayer写二阶导,像 #39649 中所说的一样。

@chenwhql
Copy link
Contributor

我用您的代码在本地复现调试一下吧,看起来也是一种之前没有试过的特殊case,但这个aistudio点进去看不到代码,请问这个要怎么看到

大佬您好!代码在~/work/tanh/目录下。或者这里: 代码地址:https://github.com/miemie2013/Paddle_custom_op 在tanh目录下。

大佬,现在又遇到了另一个问题,我该怎么写个自定义sum呢?(代码在上面仓库的sum目录下)sum操作对某几维求和,现在我准备只实现对1维求和,不知道_cuda_forwark_kernel怎么写并行求和,希望也能得到一个示例。

另外希望飞桨能尽快支持用paddle.autograd.PyLayer写二阶导,像 #39649 中所说的一样。

源码中的16.npz和16.pdparams,我这里没有,我想要快速复现一下现象好进行调试,这个方便共享吗

@chenwhql
Copy link
Contributor

现在又遇到了另一个问题,我该怎么写个自定义sum呢?(代码在上面仓库的sum目录下)sum操作对某几维求和,现在我准备只实现对1维求和,不知道_cuda_forwark_kernel怎么写并行求和,希望也能得到一个示例

cuda kernel编写我这边不是很擅长,建议您新创建一个issue,专门问cuda kernel编写的问题,值班同学会为您找到合适的同学进行支持,这个issue我重点为您解决自定义算子二阶反向的问题

@miemie2013
Copy link
Author

我用您的代码在本地复现调试一下吧,看起来也是一种之前没有试过的特殊case,但这个aistudio点进去看不到代码,请问这个要怎么看到

大佬您好!代码在~/work/tanh/目录下。或者这里: 代码地址:https://github.com/miemie2013/Paddle_custom_op 在tanh目录下。
大佬,现在又遇到了另一个问题,我该怎么写个自定义sum呢?(代码在上面仓库的sum目录下)sum操作对某几维求和,现在我准备只实现对1维求和,不知道_cuda_forwark_kernel怎么写并行求和,希望也能得到一个示例。
另外希望飞桨能尽快支持用paddle.autograd.PyLayer写二阶导,像 #39649 中所说的一样。

源码中的16.npz和16.pdparams,我这里没有,我想要快速复现一下现象好进行调试,这个方便共享吗

先跑test2_16_elementwise_grad.py,再跑test2_16_elementwise_grad_2paddle.py就有了,需要安装pytorch。或者那个aistudio项目,~/work/tanh下有16.npz和16.pdparams。

@chenwhql
Copy link
Contributor

chenwhql commented Mar 29, 2022

这里有两个问题:

  1. 之前框架中处理二阶反向自定义算子时,对paddle::Grad("Y")的判别逻辑有点问题,我修复了一下,[CustomOp] Fix double grad var judging #41072
  2. 因为二阶反向有两个输出,所infershape时也要反回两个,改动如下:

image

以上两次改完之后,我本地可以正常执行了
image

@miemie2013
Copy link
Author

这里有两个问题:

  1. 之前框架中处理二阶反向自定义算子时,对paddle::Grad("Y")的判别逻辑有点问题,我修复了一下,[CustomOp] Fix double grad var judging #41072
  2. 因为二阶反向有两个输出,所infershape时也要反回两个,改动如下:
image

以上两次改完之后,我本地可以正常执行了 image

感谢大佬了!顺便问一下dy_new有没有实现呢?如果正确实现的话ddd的值会一直是0的,谢谢!

@chenwhql
Copy link
Contributor

chenwhql commented Mar 30, 2022

这还不支持标记,看来还需要继续扩展下,我继续看下,顺便加个单测测试一下,因为有别的事也在忙,这次可能会需要个一两天,请见谅

@miemie2013
Copy link
Author

这还不支持标记,看来还需要继续扩展下,我继续看下,顺便加个单测测试一下,因为有别的事也在忙,这次可能会需要个一两天,请见谅

辛苦了,看来自定义算子,任重而道远

@miemie2013
Copy link
Author

这还不支持标记,看来还需要继续扩展下,我继续看下,顺便加个单测测试一下,因为有别的事也在忙,这次可能会需要个一两天,请见谅

感谢大佬,已经看到自定义tanh的示例了,很赞!

@chenwhql
Copy link
Contributor

这还不支持标记,看来还需要继续扩展下,我继续看下,顺便加个单测测试一下,因为有别的事也在忙,这次可能会需要个一两天,请见谅

感谢大佬,已经看到自定义tanh的示例了,很赞!

嗯嗯,PR刚刚合入了,您可以用明天的night-build版本试一下,我加了tanh的CPU单测,和paddle api的结果一致

@paddle-bot
Copy link

paddle-bot bot commented Apr 18, 2023

Since you haven't replied for more than a year, we have closed this issue/pr.
If the problem is not solved or there is a follow-up one, please reopen it at any time and we will continue to follow up.
由于您超过一年未回复,我们将关闭这个issue/pr。
若问题未解决或有后续问题,请随时重新打开,我们会继续跟进。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants