Skip to content

Conversation

megemini
Copy link
Contributor

@megemini megemini commented May 15, 2024

PR Category

User Experience

PR Types

New features

Description

NO.17 为 Paddle 新增 sparse.mask_as API

关联 RFC PaddlePaddle/community#901

### 20240515
  • 此 PR 暂时为 RFC 提供 review 参考,未实现 docstring 与单测

Copy link

paddle-bot bot commented May 15, 2024

你的PR提交成功,感谢你对开源项目的贡献!
请关注后续CI自动化测试结果,详情请参考Paddle-CI手册
Your PR has been submitted. Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

@luotao1
Copy link
Contributor

luotao1 commented May 23, 2024

冲突了

@megemini megemini changed the title 【WIP】【Hackathon 6th No.17】为 Paddle 新增 sparse.mask_as API 【Hackathon 6th No.17】为 Paddle 新增 sparse.mask_as API May 23, 2024
@megemini
Copy link
Contributor Author

Update 20240524

  • 增加 docstring
  • 增加 unittest

@luotao1 已解决冲突 ~

@zhwesky2010 请评审 ~

>>> csr = paddle.sparse.sparse_csr_tensor(crows, cols, values, dense_shape)
>>> np.random.seed(2024)
>>> d = np.random.rand(*dense_shape)
>>> x = paddle.to_tensor(d, dtype=csr.dtype)
Copy link
Contributor

Choose a reason for hiding this comment

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

不可以直接用paddle.rand创建吗

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK ~


def check(self, shape, dtype, place, check_grad=True):
paddle.disable_static()
data_np, mask_np = generate_data(shape, dtype)
Copy link
Contributor

Choose a reason for hiding this comment

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

这个命名可以改一下,一个是dense_np,一个是sparse_np
mask一般是0/1矩阵,这里是一个稀疏矩阵

Copy link
Contributor Author

Choose a reason for hiding this comment

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

这个命名可以改一下,一个是dense_np,一个是sparse_np
mask一般是0/1矩阵,这里是一个稀疏矩阵

这里需要澄清一下:

  • data_np 和 mask_np 此时都是 dense
  • 为了比对后面 numpy 的值,mask 此时还不是稀疏矩阵,后面会转为 paddle 的稀疏矩阵
  • 这里的 mask 可以是任何值的矩阵
In [3]: def generate_data(shape, dtype):
   ...:     """
   ...:     Generate `data` and `mask` with the same shape and dtype.
   ...:     """
   ...:     _mask = np.random.randint(0, 2, shape)
   ...:     if np.sum(_mask) == 0:
   ...:         _mask.flat[0] = 1
   ...:     mask = (np.random.randint(-100, 100, shape) * _mask).astype(dtype)
   ...:     data = np.random.randint(-100, 100, shape).astype(dtype)
   ...:     return data, mask
   ...: 

In [4]: data, mask = generate_data((3, 4), 'float32')

In [5]: data
Out[5]: 
array([[  2., -57.,  86.,   2.],
       [-77., -59., -55.,   10.],
       [-38.,  70.,   6., -63.]], dtype=float32)

In [6]: mask
Out[6]: 
array([[  0.,   0.,   0.,  91.],
       [  0.,  99.,  94., -41.],
       [  0.,  57.,  99.,  52.]], dtype=float32)

后面 mask_as 的时候,会有具体转换的操作

        if self.format == 'coo':
            mask = paddle.to_tensor(
                mask_np, dtype=dtype, place=place
            ).to_sparse_coo(len(shape))
        else:
            mask = paddle.to_tensor(
                mask_np, dtype=dtype, place=place
            ).to_sparse_csr()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

这里的命名我一起改一下吧 ~

self.assertEqual(sparse_grad.dtype, data.dtype)

# make a dense tensor to compare the grad from sparse_out
dense_tensor = paddle.to_tensor(data_np)
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.

确实 ... ... 这里各种矩阵的名称都有,我看看改一下 ~

const DenseTensor& x,
const SparseCooTensor& mask,
SparseCooTensor* out) {
MaskCooKernel<T, Context>(dev_ctx, x, mask, out);
Copy link
Contributor

Choose a reason for hiding this comment

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

看起来是一模一样的,直接将当前的MaskCooKernel改名吧:MaskCooKernel->MaskAsCooKernel,这样也减少以后的调用与理解成本

const DenseTensor& x,
const SparseCooTensor& mask,
SparseCooTensor* out) {
MaskCooKernel<T, Context>(dev_ctx, x, mask, out);
Copy link
Contributor

Choose a reason for hiding this comment

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

建议直接改名

@@ -329,3 +582,39 @@ PD_REGISTER_KERNEL(mask_helper_coo,
phi::dtype::complex<double>) {
kernel->InputAt(0).SetDataLayout(phi::DataLayout::SPARSE_COO);
}

PD_REGISTER_KERNEL(mask_as_coo,
Copy link
Contributor

Choose a reason for hiding this comment

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

目前的mask_coo kernel注册是否有用在某些地方,如果没有的话,建议直接全部改名为mask_as_coo,比免维护多套完全一样的内容

)
self.assertEqual(dense_data_grad.dtype, dense_data_pd.dtype)

# make a dense tensor to compare the grad from sparse_out_pd
Copy link
Contributor

Choose a reason for hiding this comment

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

不用这么麻烦,直接把expect_grad模拟写出来就行吧,就是np.ones再乘以mask的相应位置:np.ones(shape)* (dense_mask_np != 0)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

是的,这样做也可以 ~

这相当于已知先验知识,即梯度为 1

我这里相当于未知此先验,从 paddle 自身梯度回传的角度来测试 ~

两者都可以 ~

要改成 np.ones(shape)* (dense_mask_np != 0) 这种形式吗?

Copy link
Contributor

Choose a reason for hiding this comment

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

是的,这样做也可以 ~

这相当于已知先验知识,即梯度为 1

我这里相当于未知此先验,从 paddle 自身梯度回传的角度来测试 ~

两者都可以 ~

要改成 np.ones(shape)* (dense_mask_np != 0) 这种形式吗?

改一下吧,写法越简单越好

zhwesky2010
zhwesky2010 previously approved these changes May 28, 2024
Copy link
Contributor

@zhwesky2010 zhwesky2010 left a comment

Choose a reason for hiding this comment

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

LGTM

@zhwesky2010
Copy link
Contributor

@megemini 补充一下API中文文档与API映射文档,这个对应到Pytorch是torch.Tensor.sparse_mask

@luotao1
Copy link
Contributor

luotao1 commented May 29, 2024

1792 - test_sparse_mask_as_op (Timeout)
@megemini 需要加一点时间

@megemini
Copy link
Contributor Author

1792 - test_sparse_mask_as_op (Timeout) @megemini 需要加一点时间

OK ~ coverage 好像时间都比较长 ~~~

@megemini
Copy link
Contributor Author

文档:PaddlePaddle/docs#6663

@megemini
Copy link
Contributor Author

另外,这个接口是否需要 patch 到 Tensor 上?类似 torch 的调用方式?

@zhwesky2010
Copy link
Contributor

另外,这个接口是否需要 patch 到 Tensor 上?类似 torch 的调用方式?

由于其他稀疏系列的API都没有patch,这个也就不用patch吧

zhwesky2010
zhwesky2010 previously approved these changes May 31, 2024
Copy link
Contributor

@jeff41404 jeff41404 left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@sunzhongkai588 sunzhongkai588 left a comment

Choose a reason for hiding this comment

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

LGTM

@luotao1 luotao1 changed the title 【Hackathon 6th No.17】为 Paddle 新增 sparse.mask_as API 【Hackathon 6th No.17】为 Paddle 新增 sparse.mask_as API -part Jun 7, 2024
@luotao1 luotao1 merged commit 60fe41b into PaddlePaddle:develop Jun 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants