一键导入
modify-origin-api
负责《Paddle API 对齐 PyTorch 项目》中 Step2 代码修改,实施『修改原有 API』方案。通过修改原有 Paddle API 的实现(新增参数、扩展参数类型/功能),使 Paddle API 与 PyTorch API 行为对齐,同时保持后向兼容性。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
负责《Paddle API 对齐 PyTorch 项目》中 Step2 代码修改,实施『修改原有 API』方案。通过修改原有 Paddle API 的实现(新增参数、扩展参数类型/功能),使 Paddle API 与 PyTorch API 行为对齐,同时保持后向兼容性。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
负责《Paddle API 对齐 PyTorch 项目》中 Step2 代码修改,实施『C++下沉』方案。通过将 Python API 下沉至 C++层,可以减少 Python 装饰器带来的性能开销,提升 API 调度效率。
负责《Paddle API 对齐 PyTorch 项目》中 Step5 更新文档,在 API 代码修改完成后,同步更新中文 API 文档,确保文档准确反映 API 的最新行为
负责《Paddle API 对齐 PyTorch 项目》中 Step2 代码修改,实施『新增 API』方案。通过新增 Paddle API(新增 API 别名、新增 Python 层 API、新增 C++算子),覆盖 Pytorch API 调用路径,实现与 PyTorch API 行为对齐。
负责《Paddle API 对齐 PyTorch 项目》中 Step2 代码修改,实施『新增 compat 类型 API』方案。在 `paddle.compat` 命名空间下新增 API,实现与 PyTorch API 行为对齐。
开展《Paddle API 对齐 PyTorch 项目》,负责项目整体统筹规划,调用多个 skill,完成输入的 API 对齐
负责《Paddle API 对齐 PyTorch 项目》中 Step3 兼容测试,为已修改的 Paddle API 添加兼容性单测并执行验证,确保 API 的 Paddle 用法与 PyTorch 用法均能正常工作。
| name | modify-origin-api |
| description | 负责《Paddle API 对齐 PyTorch 项目》中 Step2 代码修改,实施『修改原有 API』方案。通过修改原有 Paddle API 的实现(新增参数、扩展参数类型/功能),使 Paddle API 与 PyTorch API 行为对齐,同时保持后向兼容性。 |
| context | fork |
| disable-model-invocation | false |
根据差异分析结果,本方案适用于以下四类场景:
| 场景 | 适用情况 | 典型示例 |
|---|---|---|
| 新增参数 | torch 比 paddle 多出某些参数(不含参数名/顺序差异) | paddle.randn 新增 out/device/requires_grad/pin_memory |
| 扩展参数类型/功能 | 参数支持的类型范围不同(torch 支持 paddle 不支持的类型) | paddle.eye 的 num_rows 从 int 扩展为 int | paddle.Tensor |
若尚未获得 PyTorch API 的相关信息,则自行获取,获取方式请参考api-compatibility/SKILL.md 中的「API 信息获取方式」内容。
然后分析 PyTorch API 的功能和行为,以及与 Paddle API 的差异。在 ${ROOT_DIR}/Paddle/python/paddle/ 目录下定位到对应的 API 实现位置,修改 Paddle API 的签名和实现代码。
修改原则:
若不满足以上两个原则,则无法适用本方案,需考虑其他方案。
修改现有 API 签名:
# 修改前
def randn(
shape: ShapeLike,
dtype: DTypeLike | None = None,
name: str | None = None,
) -> Tensor:
# 修改后:新增 out/device/requires_grad 为 keyword-only 参数
def randn(
shape: ShapeLike,
dtype: DTypeLike | None = None,
name: str | None = None,
*,
out: paddle.Tensor | None = None,
device: PlaceLike | None = None,
requires_grad: bool = False,
) -> Tensor:
以下给出了几个常用参数的实现方式:
out 参数前置检查:若 PyTorch API 有 out 参数,必须先确认其性质:
* 后):torch.api(input, *, out=None) → Paddle 实现中 out 也应为 keyword-only(*, out=None)torch.api(input, out=None) → Paddle 实现中 out 可为位置参数方式一:直接指定 out(推荐)
适用条件:
_C_ops;情况 2:API 调用了其他 API,调用的最后一个其他 API 也支持 out# 情况 1:API 最后一个逻辑是调用`_C_ops`
def less_than(x, y, name=None, *, out=None) -> Tensor:
if in_dynamic_or_pir_mode():
return _C_ops.less_than(x, y, out=out)
else:
...
# 情况 2:API 调用的最后一个其他 API 也支持 out
def fft(x, n=None, axis=-1, norm="backward", name=None, *, out=None) -> Tensor:
if is_integer(x) or is_floating_point(x):
return fft_r2c(
x, n, axis, norm, forward=True, onesided=False, name=name, out=out
)
else:
return fft_c2c(x, n, axis, norm, forward=True, name=name, out=out)
方式二:通过 assign 实现
适用条件:不符合方式一的情况
def func(x, axis=None, name=None, *, out: Tensor | None = None):
# case1: 只有 1 个 out 的情况
ret = <计算逻辑>
if out is not None:
paddle.assign(ret, out)
return out
return ret
# case2: 有多个 out 的情况
ret1, ret2 = <计算逻辑>
if out is not None:
paddle.assign(ret1, out[0])
paddle.assign(ret2, out[1])
return out
return ret1, ret2
注意事项:
out参数需与 Pytorch 用法一致,一般情况下 out 均是 keyword-only 参数(使用*,分隔),少数情况下 out 是位置参数device 参数替换原有的 _current_expected_place() 调用,根据 device 是否为 None 来决定使用哪个设备:
# 修改前
place = _current_expected_place()
# 修改后
place = (
_current_expected_place()
if device is None
else _get_paddle_place(device)
)
需确保 _get_paddle_place 已在文件中导入:
from ..framework import (
_get_paddle_place,
...
)
requires_grad 参数在返回 tensor 前设置 stop_gradient:
tensor = _C_ops.xxx(...)
if requires_grad is True:
tensor.stop_gradient = False
return tensor
pin_memory 参数pin_memory 参数已封装为 _to_pinned_place 函数,使用方式如下:
需确保 _to_pinned_place 已在文件中导入:
from paddle.framework import (
_to_pinned_place,
...
)
实现逻辑:
# 第一处:处理 device 后,在调用 _C_ops 创建 tensor 前添加
if pin_memory and in_dynamic_mode() and device is not None:
device = _to_pinned_place(device)
# ... 调用 _C_ops 创建 tensor ...
# 第二处:返回前
if requires_grad is True:
tensor.stop_gradient = False
if pin_memory and in_dynamic_mode():
tensor = tensor.pin_memory()
return tensor
若现有实现已能通过 _C_ops 接受新类型(通常情况下 C++ 底层支持 Scalar 类型可同时接受 int 和 Tensor),则无需改动实现逻辑。
若底层不支持,添加类型转换分支:
# 若底层需要 int,先将 Tensor 转换
if isinstance(num_rows, paddle.Tensor):
num_rows = int(num_rows)
if isinstance(num_columns, paddle.Tensor):
num_columns = int(num_columns)
在 docstring 的 Args 部分(或 Keyword Args 部分,取决于参数是否为 keyword-only)添加新参数说明。
文档更新模板:
"""
...
Args:
shape (ShapeLike): ...
dtype (DTypeLike|None, optional): ...
name (str|None, optional): ...
Keyword Args:
out (Tensor|None, optional): ...
device (PlaceLike|None, optional): ...
requires_grad (bool, optional): ...
Returns:
...
"""
文档规范:
Keyword Args: 下描述# 获取当前期望的 place
from paddle.framework import _current_expected_place
place = _current_expected_place()
# 将 device 字符串/对象转为 Place
from paddle.framework import _get_paddle_place
place = _get_paddle_place("cpu") # -> core.CPUPlace()
place = _get_paddle_place("gpu:0") # -> core.CUDAPlace(0)
place = _get_paddle_place("cuda:0") # -> core.CUDAPlace(0)(扩展后支持)
# 将 device 转为 pinned place(用于 pin_memory 参数)
from paddle.framework import _to_pinned_place
if pin_memory and in_dynamic_mode() and device is not None:
device = _to_pinned_place(device)
# 判断运行模式
from paddle.framework import in_dynamic_mode, in_dynamic_or_pir_mode
if in_dynamic_mode(): ...
if in_dynamic_or_pir_mode(): ...
pin_memory 参数机制pin_memory=True 将 Tensor 分配在锁页内存(pinned memory),提升 CPU->GPU 数据传输速度。
Paddle 已封装 _to_pinned_place 函数(参见 PR #78823),简化实现:
from paddle.framework import _to_pinned_place
# 使用方式
if pin_memory and in_dynamic_mode() and device is not None:
device = _to_pinned_place(device)
# 创建 tensor 后
if pin_memory and in_dynamic_mode():
tensor = tensor.pin_memory()
PlaceLike 类型导入若函数签名中需要使用 PlaceLike 类型,需在文件顶部的 TYPE_CHECKING 块中添加导入:
if TYPE_CHECKING:
from paddle import Tensor
from paddle._typing import DTypeLike, PlaceLike, ShapeLike # 添加 PlaceLike
randn -> standard_normal -> gaussian),必须在整个调用链上都添加该参数math_op_patch.py 中的 Tensor 方法必须与对应的普通函数保持参数同步,且需同时修改 dygraph 版和 pir 版两个文件layout 参数无需支持,直接忽略即可name 参数,新增参数可作为位置参数放在 name 之前,不必考虑 name 参数对顺序的影响_C_ops 调用报错 "unexpected keyword argument 'out'"错误现象:
TypeError: xxx() got an unexpected keyword argument 'out'
解决方法:
该 op 对应的 _C_ops 接口不支持 out 参数。需确认底层 op 是否有 out 支持,若没有则不能使用 C++ 侧 out 注入方式,改为手动复制结果:
tensor = _C_ops.xxx(...)
if out is not None:
paddle.assign(tensor, output=out)
return out
return tensor
pin_memory 测试时报 "Pinning memory is not supported"错误现象:
RuntimeError: Pinning memory is not supported for Place(cpu)
解决方法:
pin_memory=True 仅在 GPU/XPU 设备上有意义。确保测试逻辑中正确添加了环境判断:
if paddle.device.is_compiled_with_cuda() or paddle.device.is_compiled_with_xpu():
x = paddle.xxx([2], device="gpu", pin_memory=True)
self.assertTrue("pinned" in str(x.place))
math_op_patch.py 后静态图测试失败错误现象:
AttributeError: 'OpResult' object has no attribute 'pin_memory'
解决方法:
pin_memory 调用(tensor.pin_memory())需在 in_dynamic_mode() 保护下执行,PIR 静态图中 tensor 是 Value 对象,不支持该方法。确认实现中有正确的模式判断:
if pin_memory and in_dynamic_mode():
tensor = tensor.pin_memory()
int | Tensor)后运行报错错误现象:
TypeError: eye(): argument 'num_rows' must be int, not Tensor
解决方法:
底层 _C_ops 接口尚不支持该类型。在 Python 层添加显式转换:
if isinstance(num_rows, paddle.Tensor):
num_rows = int(num_rows)