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

Add New OP: gumbel_softmax #35506

Merged
merged 10 commits into from
Sep 15, 2021

Conversation

YuanRisheng
Copy link
Contributor

@YuanRisheng YuanRisheng commented Sep 6, 2021

PR types

New features

PR changes

OPs

Describe

Add new op named Gumbel Softmax for paddle.
This op is used for sampling from the Gumbel-Softmax distribution and optionally discretizes.

Verify the performance of Gumbel softmax operator locally. The input is random tensor (shape = [200,30]) and repeat the test 100 times. Compare Paddle with Pytorch: the average time-consuming of Paddle is 0.0114 seconds, and the average time-consuming of Pytorch is 0.0123 seconds. The performance of Gumbel softmax operator of Paddle is about 7% better than that of Pytorch.

API:
paddle.nn.functional.gumbel_softmax()

Usage example:

import paddle
import paddle.nn.functional as F

logits = paddle.randn([4, 6])
temperature = 0.01
gumbel_softmax = F.gumbel_softmax(logits, temperature)
print(gumbel_softmax)
The result is as follows:
 [[0.00000001, 1.        , 0.00000000, 0.00000000, 0.00000006, 0.00000000],
 [0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 1.        ],
 [0.00000062, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.99999940],
 [0.00000000, 0.00000000, 0.00000000, 0.00001258, 0.99998736, 0.00000000]]

Doc
Cn Doc PR: PaddlePaddle/docs/3857

image
image

@paddle-bot-old
Copy link

paddle-bot-old bot commented Sep 6, 2021

Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

name='x_int32', shape=[2, 3], dtype='int32')
paddle.nn.functional.gumbel_softmax(x_int32)

self.assertRaises(TypeError, test_dtype)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里单测缺少了

if __name__ == '__main__':
    unittest.main()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

@chenwhql chenwhql left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在PR描述中加上英文文档预览截图,并且关联到中文文档PR,可参考 #33278

}

protected:
framework::OpKernelType GetExpectedKernelType(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetExpectedKernelType这里可以不写,只有一个输入X,默认根据X的特征确定Kernel类型

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

"hard",
"(bool, default false) "
"if True, the returned samples will be discretized as one-hot vectors, "
"but will be differentiated as if it is the soft sample in autograd")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

autograd后面需要.?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

void InferShape(framework::InferShapeContext* ctx) const override {
OP_INOUT_CHECK(ctx->HasInput("Out"), "Input", "Out", "gumbel_softmax_grad");
OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")), "Input",
"Out@grad", "gumbel_softmax_grad");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out@grad -> Out@GRAD

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

T min_, max_;
unsigned int seed_;
unsigned int offset_ = 0;
__host__ __device__ UniformGenerator(T min, T max, unsigned int seed)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__host__ __device__ -> HOSTDEVICE, 有全局的宏定义

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/framework/operator.h"
#include "paddle/fluid/memory/memcpy.h"
#include "paddle/fluid/operators/gumbel_softmax_op.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

int axis_dim = dX->dims()[axis];
// allocate memory on device.
dX->mutable_data<T>(context.GetPlace());
if (dX->numel() == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里直接return是什么场景

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的逻辑和softmax是一样的,所以也同样按照softmax算子的做法添加了对dx的边界处理

const int size_to_axis = SizeToAxis(axis, dX->dims());
const int size_from_axis = SizeFromAxis(axis, dX->dims());
Tensor dX_2d, Out_2d, dOut_2d;
dX_2d.ShareDataWith(*dX).Resize({size_to_axis, size_from_axis});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上,为什么必须使用sharedatawith

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里需要将out的数据resize到2维进行处理计算结果,使用shareDataWith可以减少copy次数

self.check_output_customized(self.verify_output)

def test_check_grad(self):
self.check_grad(["X"], "Out", max_relative_error=0.01)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里0.01的精度设置是什么根据?有特殊原因吗?默认是0.005

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

由于梯度计算逻辑和softmax算子是一样的,这里精度误差0.01取自softmax算子使用的精度误差

self.check_grad(["X"], "Out", max_relative_error=0.01)


class TestGumbelSoftmaxOpGrad(unittest.TestCase):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为什么需要单独写这个单测,理论上前面应该测了反向?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里测的hard为ture和false条件下,反向梯度是否一致,和前边测的反向内容略有不同

self.x_shape = [2, 3, 4, 5]
self.x = np.random.uniform(-1., 1., self.x_shape).astype(np.float32)
self.count_expected = 24
self.place = paddle.CUDAPlace(0) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with cuda的话应该是CPU和CUDA都测试?没有CUDA的话也应该有CPU测试

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个下边代码是有的,没有cuda的话是cpu测试

chenwhql
chenwhql previously approved these changes Sep 13, 2021
Copy link
Contributor

@chenwhql chenwhql left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

lanxianghit
lanxianghit previously approved these changes Sep 13, 2021
zhhsplendid
zhhsplendid previously approved these changes Sep 13, 2021
Copy link
Member

@zhhsplendid zhhsplendid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM on ShareDataWith

Copy link
Contributor

@lanxianghit lanxianghit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for API change

Copy link
Contributor

@Xreki Xreki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for op benchmark ci

Copy link
Member

@zhhsplendid zhhsplendid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for ShareDataWith

@chenwhql chenwhql merged commit 18eda6c into PaddlePaddle:develop Sep 15, 2021
AnnaTrainingG pushed a commit to AnnaTrainingG/Paddle that referenced this pull request Sep 29, 2021
* Add New Op: gumbel_softmax

* Add New Op: gumbel_softmax

* Add New Op: gumbel_softmax (amend)

* add __main__ function in unit test

* fix bugs when test in windows ci

* update en docs

* delete reletive error in unit test

* delete relative error in unit test

* set hard=True in unit test
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 this pull request may close these issues.

7 participants