-
Notifications
You must be signed in to change notification settings - Fork 5.9k
[API Compatibility No.352、377] Add torch-style arg and alias for std -part
#77006
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
[API Compatibility No.352、377] Add torch-style arg and alias for std -part
#77006
Conversation
|
你的PR提交成功,感谢你对开源项目的贡献! |
|
/re-run all-failed |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #77006 +/- ##
==========================================
Coverage ? 93.75%
==========================================
Files ? 2
Lines ? 16
Branches ? 0
==========================================
Hits ? 15
Misses ? 1
Partials ? 0 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR enhances the paddle.std function to support PyTorch-style parameter aliases and adds new functionality including the correction parameter and out parameter support. The changes aim to improve API compatibility with PyTorch.
Key Changes
- Refactored
stdfunction implementation to use*args, **kwargsforwarding to thevarfunction - Added comprehensive test coverage for parameter aliases (
inputforx,dimforaxis), the newcorrectionparameter, and theoutparameter - Fixed typos in existing tests (
expact_out→expect_out)
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
test/legacy_test/test_std_layer.py |
Added new test classes for compatibility testing (aliases) and correction parameter testing; fixed typos in variable names |
python/paddle/tensor/stat.py |
Refactored std function to forward arguments to var and handle the out parameter for sqrt operation |
python/paddle/_paddle_docs.py |
Added comprehensive documentation for std including alias notes, new parameter descriptions, and usage examples |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
python/paddle/tensor/stat.py
Outdated
| def std(*args, **kwargs) -> Tensor: | ||
| variance = var(*args, **kwargs) | ||
| if 'out' in kwargs: | ||
| return paddle.sqrt(variance, out=kwargs['out']) |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The refactored std function forwards all arguments to var using *args and **kwargs, but this approach has a problem: when the decorator is added to enable parameter aliases, the function needs a proper signature to work correctly with the decorator. The decorator needs to know which parameters to alias, but with *args, **kwargs, there's no explicit signature to decorate. The function should have an explicit signature matching the documented parameters (x, axis, unbiased, keepdim, name, correction, out) similar to the var function, and then be decorated with @ParamAliasDecorator({"x": ["input"], "axis": ["dim"]}) or @param_two_alias(["x", "input"], ["axis", "dim"]).
| def std(*args, **kwargs) -> Tensor: | |
| variance = var(*args, **kwargs) | |
| if 'out' in kwargs: | |
| return paddle.sqrt(variance, out=kwargs['out']) | |
| @ParamAliasDecorator({"x": ["input"], "axis": ["dim"]}) | |
| def std( | |
| x, | |
| axis=None, | |
| unbiased: bool = True, | |
| keepdim: bool = False, | |
| name: str | None = None, | |
| correction=None, | |
| out=None, | |
| ) -> Tensor: | |
| variance = var( | |
| x, | |
| axis=axis, | |
| unbiased=unbiased, | |
| keepdim=keepdim, | |
| name=name, | |
| correction=correction, | |
| out=out, | |
| ) | |
| if out is not None: | |
| return paddle.sqrt(variance, out=out) |
| variance = var(*args, **kwargs) | ||
| if 'out' in kwargs: | ||
| return paddle.sqrt(variance, out=kwargs['out']) |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The handling of the out parameter needs careful consideration. The current implementation extracts out from kwargs and passes it to paddle.sqrt. However, the var function is also called with all kwargs including out, which means out would first receive the variance result from var, and then be overwritten with the sqrt result. This could lead to incorrect behavior if the var function tries to assign to out. The implementation should either remove out from kwargs before calling var, or handle this more explicitly in the proper signature-based implementation.
| variance = var(*args, **kwargs) | |
| if 'out' in kwargs: | |
| return paddle.sqrt(variance, out=kwargs['out']) | |
| out = kwargs.pop('out', None) | |
| variance = var(*args, **kwargs) | |
| if out is not None: | |
| return paddle.sqrt(variance, out=out) |
python/paddle/_paddle_docs.py
Outdated
| >>> print(out4.numpy()) | ||
| [[1.721326]] | ||
| >>> out5 = paddle.std(input=x, dim=[0, 1]) # type: ignore[call-arg] |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation example on line 3361 contains a type ignore comment that indicates the signature doesn't properly support the alias parameters (input and dim). This is correct given that the implementation is missing the required decorator to enable these aliases. Once the decorator is added to the std function in stat.py, this type ignore comment should be removed as the call will be type-safe.
| >>> out5 = paddle.std(input=x, dim=[0, 1]) # type: ignore[call-arg] | |
| >>> out5 = paddle.std(input=x, dim=[0, 1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
文档位置不对
zhwesky2010
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这两个API不仅仅是参数名不同,涉及到更多的参数差异。
case有点复杂,先跑一下PaConvert,本地先验证PaConvert能通过后,再提交paddle。
| ) | ||
| out = var(**locals()) | ||
| return paddle.sqrt(out) | ||
| variance = var(*args, **kwargs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
看来std、var这两个API不是简单的别名替换。
需要一套参数分发的逻辑,参考group_norm、gather的写法,这里需要处理args/kwargs来判断overload的两种签名。
var是底层的接口,先处理好var,std只需要这么写就行:
return sqrt(var(*args, **kwargs), out=out)
out=None的默认缺省逻辑在各API底层以及下沉后都会有,不需要重复判断。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
那个if逻辑可能删不了,out需要从kwargs里面取,取不到的话会报KeyError。目前的实现也不涉及像gather一样新定义一个wrapper。
|
/re-run all-failed |
|
/re-run all-failed |
zhwesky2010
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| *, | ||
| correction: float = 1, | ||
| out: Tensor | None = None, | ||
| ) -> Tensor: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
只有一种签名?这里用 overload 的意义是什么?
| ) -> Tensor: ... | ||
|
|
||
|
|
||
| def std(*args: Any, **kwargs: Any) -> Tensor: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为使用 不过现在加了overload签名还是没有的话,我可能需要再看一下怎么补上 |
常规思路是加一层装饰器实现参数别名,但这个对性能影响比较严重,所以现在实现的是不用装饰器的方案 API 然而如果 |
既然有别名,那为什么会只有一个签名?这不对吧,参考的 |
确实不对,理论上最好应该是paddle用法一个签名,torch用法一个签名,这样可以包括所有的参数可能性 不过因为 要不给torch用法(别名用法)加个签名(? |
加,这种才是合理的写法 运行时签名需要单独考虑,可以考虑使用其第一个签名,可以加一个简单的装饰器来实现这一点 from typing import overload, Any, get_overloads, TypeVar
from typing_extensions import ParamSpec
from collections.abc import Callable
import inspect
P = ParamSpec("P")
R = TypeVar("R")
def use_first_signature(fn: Callable[P, R]) -> Callable[P, R]:
overloads = get_overloads(fn)
if not overloads:
return fn
first_overload = overloads[0]
sig = inspect.signature(first_overload)
fn.__signature__ = sig
return fn
@overload
def fn(x: int) -> int: ...
@overload
def fn(x: str) -> str: ...
@use_first_signature
def fn(*args: Any, **kwargs: Any) -> Any: ...
print(inspect.getfullargspec(fn))这个装饰器对装饰后的函数没有额外运行时开销,不必担心 目前以 Paddle 签名为主,所以 Paddle 签名写在前面 |
|
签名和重载加好了,虽说参数 |
|
/re-run all-failed |
zhwesky2010
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM



PR Category
User Experience
PR Types
Improvements
Description
inputanddimoutandcorrectionstdcorrectiontest forstdstdtestsUsed AI Studio