-
Notifications
You must be signed in to change notification settings - Fork 6k
[API Compatibility] Align paddle.Tensor.is_sparse, paddle.Tensor.type, paddle.Tensor.size api, paddle.nn.PReLU and paddle.distributions.categorical.Categorical -part #79550
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
base: develop
Are you sure you want to change the base?
Changes from 6 commits
91b9144
3451263
d5154f3
4865ecc
8aa81ef
7f2684a
7eda286
ec4686b
cf76ec4
f668adb
111a665
b3bb47c
2f3cc36
ec1295c
f514e71
a721161
c64978f
826269a
a119dbe
5a5b7b3
219307c
fde90cf
b0217d4
82f8ebf
ce136ec
3eeb401
43c95f1
8c035b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,7 @@ | |
| from collections.abc import Sequence | ||
|
|
||
| from paddle import Tensor | ||
| from paddle._typing import DTypeLike | ||
|
|
||
| __all__ = [ | ||
| 'allclose', | ||
|
|
@@ -55,6 +56,26 @@ | |
| 'seed', | ||
| ] | ||
|
|
||
| _TENSOR_TYPE_NAMES = { | ||
| 'float16': 'HalfTensor', | ||
| 'float32': 'FloatTensor', | ||
| 'float64': 'DoubleTensor', | ||
| 'float8_e4m3fn': 'Float8_e4m3fnTensor', | ||
| 'float8_e5m2': 'Float8_e5m2Tensor', | ||
| 'bfloat16': 'BFloat16Tensor', | ||
| 'uint8': 'ByteTensor', | ||
| 'int8': 'CharTensor', | ||
| 'int16': 'ShortTensor', | ||
| 'int32': 'IntTensor', | ||
| 'int64': 'LongTensor', | ||
| 'bool': 'BoolTensor', | ||
| 'complex64': 'ComplexFloatTensor', | ||
| 'complex128': 'ComplexDoubleTensor', | ||
| } | ||
| _TENSOR_TYPE_DTYPES = { | ||
| tensor_type: dtype for dtype, tensor_type in _TENSOR_TYPE_NAMES.items() | ||
| } | ||
|
|
||
|
|
||
| def __getattr__(name): | ||
| if name == "paddle_triton": | ||
|
|
@@ -66,6 +87,74 @@ def __getattr__(name): | |
| raise AttributeError(f"module {__name__!r} has no attribute {name!r}") | ||
|
|
||
|
|
||
| def _tensor_numel(input: Tensor) -> int: | ||
| return int(input.size) | ||
|
|
||
|
|
||
| def _tensor_type( | ||
| input: Tensor, | ||
| dtype: DTypeLike | str | type | None = None, | ||
| non_blocking: bool = False, | ||
| **kwargs: Any, | ||
| ) -> str | Tensor: | ||
| if "async" in kwargs: | ||
| non_blocking = kwargs.pop("async") | ||
| if kwargs: | ||
| key = next(iter(kwargs)) | ||
| raise TypeError(f"type() got an unexpected keyword argument {key!r}") | ||
|
|
||
| if dtype is None: | ||
| dtype_name = str(input.dtype).removeprefix("paddle.") | ||
| tensor_type = _TENSOR_TYPE_NAMES[dtype_name] | ||
| prefix = "torch.cuda" if input.place.is_gpu_place() else "torch" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个返回 |
||
| if input.is_sparse_coo(): | ||
| prefix += ".sparse" | ||
| return f"{prefix}.{tensor_type}" | ||
|
|
||
| device = None | ||
| if isinstance(dtype, type) and dtype.__name__ in _TENSOR_TYPE_DTYPES: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里是否考虑了全部情况且能正确执行: |
||
| tensor_type = dtype.__name__ | ||
| dtype = _TENSOR_TYPE_DTYPES[tensor_type] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. np.float32触发这个分支吗?看起来有点问题 直接判断np.dtype、paddle.dtype吧,鲁棒些。 这个isinstance(dtype, type) 比较奇怪 |
||
| device = "cpu" | ||
| elif isinstance(dtype, str): | ||
| dtype_string = dtype | ||
| tensor_type = dtype_string.rsplit(".", 1)[-1] | ||
| if ( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里输入即可以是 |
||
| not dtype_string.startswith("torch.") | ||
| or tensor_type not in _TENSOR_TYPE_DTYPES | ||
| ): | ||
| raise ValueError(f"invalid type: {dtype_string!r}") | ||
| dtype = _TENSOR_TYPE_DTYPES[tensor_type] | ||
| device = "gpu" if dtype_string.startswith("torch.cuda.") else "cpu" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. paddle API进行兼容性设计:输入应同时支持torch.xxx和paddle.xxx,输出为paddle.xxx 这里好几个地方思路都不对 |
||
|
|
||
| dtype_name = str(input.dtype).removeprefix("paddle.") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 直接判断: dtype本身就是字符串
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| target_dtype_name = str(dtype).removeprefix("paddle.") | ||
| same_device = ( | ||
| device is None | ||
| or (device == "cpu" and input.place.is_cpu_place()) | ||
| or (device == "gpu" and input.place.is_gpu_place()) | ||
| ) | ||
| if dtype_name == target_dtype_name and same_device: | ||
| return input | ||
|
|
||
| return input.to( | ||
| device=device, | ||
| dtype=dtype, | ||
| blocking=not non_blocking, | ||
| ) | ||
|
|
||
|
|
||
| def _tensor_is_sparse(input: Tensor) -> bool: | ||
|
Manfredss marked this conversation as resolved.
Manfredss marked this conversation as resolved.
|
||
| return input.is_sparse_coo() | ||
|
|
||
|
|
||
| _TENSOR_API_OVERRIDES = { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 我建议这个是不是和上面的字典合并起来,统一成一个字典: |
||
| 'numel': (_tensor_numel, False), | ||
| 'type': (_tensor_type, False), | ||
| 'is_sparse': (_tensor_is_sparse, True), | ||
| } | ||
|
|
||
|
|
||
| def allclose( | ||
| input: Tensor, | ||
| other: Tensor, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -123,6 +123,37 @@ def __call__(cls, *args: Any, **kwargs: Any) -> Any: | |
| return proxy | ||
|
|
||
|
|
||
| class _TensorCompatDescriptor: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个与其他tensor method这里为何会有这么多特殊之处?除了名字不同。 这一块的设计比较冗余,优化下设计,与其他tensor method合并处理。尽可能代码复用并减少行数。
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 不太理解要加这个东西解决什么问题,如果只是一个property的问题,单独整一个 dispatch_property 这个函数,其他继续使用dispatch_function
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个问题点改了吗?上次沟通的意思理解了没?看起来和沟通的不是一回事 disptch_function + disptch_property |
||
| """Caller-aware adapter for Tensor method/property shape differences.""" | ||
|
|
||
| def __init__( | ||
| self, | ||
| native_attr: Any, | ||
| compat_fn: Any, | ||
| as_property: bool, | ||
| ) -> None: | ||
| self.__native_fn__ = native_attr | ||
| self.__compat_fn__ = compat_fn | ||
| self._as_property = as_property | ||
| self.__doc__ = compat_fn.__doc__ | ||
| self.__name__ = compat_fn.__name__ | ||
| self.__signature__ = inspect.signature(compat_fn) | ||
|
|
||
| def __get__(self, instance: Any, owner: type | None = None) -> Any: | ||
| if instance is None: | ||
| if _caller_is_paddle_internal(): | ||
| return self.__native_fn__ | ||
| return self if self._as_property else self.__compat_fn__ | ||
| if ( | ||
| len(_PADDLE_NAMESPACE_SAVED) > 0 | ||
| and not _caller_is_paddle_internal() | ||
| ): | ||
| if self._as_property: | ||
| return self.__compat_fn__(instance) | ||
| return self.__compat_fn__.__get__(instance, owner) | ||
| return self.__native_fn__.__get__(instance, owner) | ||
|
|
||
|
|
||
| def _patch_tensor_methods() -> None: | ||
| """Route ``paddle.Tensor.<m>`` to the compat function for the root compat APIs | ||
| that torch also exposes as Tensor methods (max/min/sort/split/unique/...), so | ||
|
|
@@ -146,6 +177,20 @@ def _patch_tensor_methods() -> None: | |
| dispatch_function(compat_fn)(native_method), | ||
| ) | ||
|
|
||
| for attr_name, ( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个 _TENSOR_API_OVERRIDES 和 __all__先合并为字典,然后再统一进行patch |
||
| compat_fn, | ||
| as_property, | ||
| ) in compat_root._TENSOR_API_OVERRIDES.items(): | ||
| native_attr = inspect.getattr_static(paddle.Tensor, attr_name, None) | ||
| if native_attr is None: | ||
| continue | ||
| _PADDLE_NAMESPACE_SAVED[(paddle.Tensor, attr_name)] = native_attr | ||
| setattr( | ||
| paddle.Tensor, | ||
| attr_name, | ||
| _TensorCompatDescriptor(native_attr, compat_fn, as_property), | ||
| ) | ||
|
|
||
|
|
||
| def _apply_paddle_namespace_aliases() -> None: | ||
| """Install caller-aware dispatchers/proxies for every public ``paddle.compat.*`` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,7 @@ | |
| __all__ = [ | ||
| 'Unfold', | ||
| 'Linear', | ||
| 'PReLU', | ||
| 'Softmax', | ||
| 'AvgPool1D', | ||
| 'AvgPool2D', | ||
|
|
@@ -662,6 +663,22 @@ def reset_parameters(self) -> None: | |
| nn.init.uniform_(self.bias, -bound, bound) | ||
|
|
||
|
|
||
| class PReLU(nn.PReLU, metaclass=_CompatClassMeta): | ||
| def __init__( | ||
| self, | ||
| num_parameters: int = 1, | ||
| init: float = 0.25, | ||
| device: PlaceLike | None = None, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个做一个重载设计吧,新增一个装饰器,判断传入的第3个位置参数是ParamAttrLike还是PlaceLike类型进行分发 非必要不添加compat函数 |
||
| dtype: DTypeLike | None = None, | ||
| ) -> None: | ||
| super().__init__( | ||
| num_parameters=num_parameters, | ||
| init=init, | ||
| device=device, | ||
| dtype=dtype, | ||
| ) | ||
|
|
||
|
|
||
| class Softmax(nn.Layer, metaclass=_CompatClassMeta): | ||
| r""" | ||
| Softmax Activation. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ | |
| from typing import TYPE_CHECKING, Any, Literal | ||
|
|
||
| from .api_dispatch import ( | ||
| _PADDLE_NAMESPACE_SAVED, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 只是加一个level,这里为啥要改动上百行,5行内能解决问题吗? |
||
| _apply_paddle_namespace_aliases, | ||
| _iter_compat_modules, | ||
| _restore_paddle_namespace_aliases, | ||
|
|
@@ -604,6 +605,7 @@ def use_compat_guard( | |
| already_has_torch_proxy = TORCH_PROXY_FINDER in sys.meta_path | ||
| original_local_enabled_scope = set(TORCH_PROXY_FINDER._local_enabled_scope) | ||
| original_globally_enabled = TORCH_PROXY_FINDER._globally_enabled | ||
| original_level = 2 if _PADDLE_NAMESPACE_SAVED else 1 | ||
| if enable == already_has_torch_proxy and ( | ||
| (original_globally_enabled and scope is None) | ||
| or (original_local_enabled_scope == (scope or set())) | ||
|
|
@@ -625,7 +627,7 @@ def use_compat_guard( | |
| try: | ||
| yield | ||
| finally: | ||
| enable_compat(scope=None, silent=True) | ||
| enable_compat(scope=None, silent=True, level=original_level) | ||
| TORCH_PROXY_FINDER._local_enabled_scope = ( | ||
| original_local_enabled_scope | ||
| ) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -586,6 +586,9 @@ def __init__( | |
| device: PlaceLike | None = None, | ||
| dtype: DTypeLike | None = None, | ||
| ) -> None: | ||
| if not isinstance(data_format, str): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 自定义装饰器 兼容两套签名,参考skill的具体要求 |
||
| device, dtype = weight_attr, data_format | ||
| weight_attr, data_format = None, "NCHW" | ||
| super().__init__() | ||
| self._num_parameters = num_parameters | ||
| self._init = init | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.