add-new-api

star 281

负责《Paddle API 对齐 PyTorch 项目》中 Step2:API 代码修改,实施『新增 API』方案。通过新增 Paddle API(新增 API 别名、新增 Python 层 API、新增 C++算子),覆盖 Pytorch API 调用路径,实现与 PyTorch API 行为对齐。

PaddlePaddle By PaddlePaddle schedule Updated 6/4/2026

name: add-new-api description: 负责《Paddle API 对齐 PyTorch 项目》中 Step2:API 代码修改,实施『新增 API』方案。通过新增 Paddle API(新增 API 别名、新增 Python 层 API、新增 C++算子),覆盖 Pytorch API 调用路径,实现与 PyTorch API 行为对齐。 context: fork disable-model-invocation: false

一、适用场景

根据 API 的性质,将新增场景分为三种模式:

场景一:新增 API 别名

  • 适用:目标 API 已有对应 Paddle 实现,仅名称/路径不同
  • 是否需要编译:不需要
  • 修改文件数:1~5 个 .py
  • 实现难度:简单
  • 典型示例:ne、cat、paddle.optim、paddle.distributions

场景二:新增 Python 层 API

  • 适用:需要新 API 逻辑,可纯 Python 实现(不需要开发新的 C++ 算子,可用其他 Python API 组合实现)
  • 是否需要编译:不需要
  • 修改文件数:3~6 个 .py
  • 实现难度:中等
  • 典型示例:argwhere、from_numpy

场景三:新增 C++ 算子

  • 适用:需要新的底层计算逻辑,涉及 C++/CUDA(需要开发新的 C++ 算子,用 C++ 开发算子实现代码,再封装 Python API)
  • 是否需要编译:必须重新编译
  • 修改文件数:10~18 个(.py/.h/.cc/.cu/.yaml)
  • 实现难度:复杂
  • 典型示例:aminmax、addcmul

二、标准工作流程

根据实际需求,选择场景一、场景二或场景三执行。所有场景完成后,统一执行新增 API 英文文档和编译运行测试。

场景一:新增 API 别名

新增的 API 别名应统一在 __init__.py 中定义,便于统一管理,避免分散在各个实现文件中,与现有别名管理保持一致(位于 Paddle/python/paddle/init.py、Paddle/python/paddle/tensor/init.py、Paddle/python/paddle/nn/functional/init.py、Paddle/python/paddle/nn/init.py 等文件中)。

类型一:函数/类别名

适用条件:目标 PyTorch API 与某个已有 Paddle API 功能完全一致,仅名称不同。

典型示例:paddle.ne(对齐 torch.ne)、paddle.cat(对齐 torch.cat)、paddle.nn.SiLU(对齐 torch.nn.SiLU)

请严格按以下步骤依次执行:

Step 1:在模块文件中添加别名赋值

找到原始 API 的实现位置(如 python/paddle/tensor/math.py),在文件末尾添加别名赋值:

# python/paddle/tensor/math.py 末尾
ne = not_equal
lt = less_than
less = less_than
le = less_equal
greater = gt
ge = greater_equal

若属于 paddle.nn 命名空间(如 SiLU = Silu),则在对应的 nn/init.py 中添加:

# python/paddle/nn/__init__.py
SiLU = Silu

Step 2:在 init.py 中导出别名

在顶层 python/paddle/init.py 的对应 from paddle.tensor import (...) 块内,按字母序插入新别名:

# python/paddle/__init__.py
from paddle.tensor import (
    ...
    ge,
    greater,
    le,
    less,
    lt,
    ne,
    ...
)

Step 3(如需):添加 Tensor 方法别名

若需要以 paddle.Tensor.xxx 形式调用(对齐 torch.Tensor.xxx),在 python/paddle/tensor/init.py 中同步处理:

# python/paddle/tensor/__init__.py
# 1. 在 tensor_method_func 列表中按字母序添加方法名
tensor_method_func = [
    ...
    'ne',
    'lt',
    'less',
    ...
]

# 2. 在文件末尾与模块导出一起声明别名(作为 Tensor 方法注入来源)
ne = not_equal
lt = less_than

Paddle 通过 patch 机制将 paddle.tensor 模块中的函数动态 setattr 到 paddle.Tensor,因此只需在此处声明即可自动注入为 Tensor 方法,无需修改 class Tensor 定义。

类型二:类成员方法/属性别名

适用条件:需要对齐类的方法或属性,根据已有实现与目标形式的性质差异,分为三种情况处理。

情况一:方法 → 方法 或 属性 → 属性(性质相同)

当已有实现与目标形式性质相同时(都是方法或都是属性),直接使用别名赋值即可。

Layer 类示例(方法 → 方法):

# python/paddle/nn/layer/layers.py

class Layer:
    def get_sublayer(self, target: str) -> Layer:
        # original implementation
        ...

    def set_sublayer(self, target: str, layer: Layer) -> None:
        # original implementation
        ...

    # 在类末尾添加别名(对齐 PyTorch 的 get_submodule/set_submodule)
    get_submodule = get_sublayer
    set_submodule = set_sublayer

Tensor 方法示例(以 bar 对齐 torch.Tensor.bar 为例):

假设已有方法 original_bar,需在注入列表中直接注册别名:

# python/paddle/base/dygraph/math_op_patch.py

# 在注入列表中直接注册(方法→方法,无需额外实现)
(
    'bar',  # 新 API 名称
    original_bar,  # 指向已有方法
),

情况二:方法 → 属性

当已有实现是方法(需调用),目标形式是属性(直接访问)时,需使用 @property 装饰器包装原有方法。

简单示例:

class PyLayerContext:
    def saved_tensor(self):
        ...

    @property
    def saved_tensors(self):
        return self.saved_tensor()

Tensor 属性示例:

假设已有方法 rank() 需调用,现改为属性 ndims 直接访问:

# python/paddle/base/dygraph/math_op_patch.py

@property
def ndims(var: Tensor) -> int:
    return var.rank()

然后在注入列表中注册为元组形式(属性用元组):

(
    'ndims',
    ndims,
),

这样 tensor.ndims 可直接访问,无需括号调用。

情况三:属性 → 方法

当已有实现是属性(直接访问),目标形式是方法(需调用)时,需定义新方法返回属性值。

简单示例:

class Layer:
    @property
    def parameters(self):
        ...

    def get_parameters(self):  # 新增方法形式
        return list(self.parameters)

Tensor 方法示例:

假设已有属性 dims 直接访问,现添加方法 get_dims 需调用:

# python/paddle/base/dygraph/math_op_patch.py

# dims 是已有属性,get_dims 是其方法形式
def get_dims(var: Tensor) -> list:
    return list(var.dims)

然后在注入列表中注册:

(
    'get_dims',
    get_dims,
),

这样就可以通过 tensor.get_dims() 方法调用来获取 dims。

类型三:命名空间别名

适用条件:PyTorch 拥有某个 Paddle 没有的命名空间,需创建新包将已有 API 重新组织暴露。

典型示例:paddle.optim(对齐 torch.optim)、paddle.utils.data(对齐 torch.utils.data)、paddle.distributions(对齐 torch.distributions)

(详细步骤待补充)

场景二:新增 Python 层 API

适用条件:PyTorch 有某个 API,Paddle 没有,但可以基于已有 Paddle API 组合实现,无需新增 C++ 算子。

典型示例:paddle.argwhere(= paddle.nonzero(input, as_tuple=False))、paddle.from_numpy、paddle.asarray

详细开发流程请参考:开发 API Python 端(references/new_python_api.md)

场景三:新增 C++ 算子

适用条件:PyTorch 有某个计算 OP,Paddle 完全没有对应实现,需要从底层开始完整新增算子。

典型示例:paddle.aminmax(对齐 torch.aminmax)、paddle.addcmul(对齐 torch.addcmul)

详细开发流程请参考:开发 C++ 算子(references/new_cpp_op.md)

三、背景知识

代码文件存放位置应尽可能与已有 API 的目录保持一致。下方介绍了 python/paddle/tensor/ 目录的组织结构,供开发者参考。

大部分常用的数组运算 API(在 NumPy 中有功能相似的 numpy.xxx API)都放在 python/paddle/tensor 目录下:

  • array.py:TensorArray 相关操作
  • attribute.py:Tensor 元数据操作:is_complex, is_integer, shape, rank 等
  • creation.py:Tensor 创建:to_tensor, ones, full_like 等
  • einsum.py:einsum 运算
  • linalg.py:线性代数:matmul, norm, det
  • logic.py:逻辑运算:logical_and, allclose, greater_than
  • manipulation.py:数组元素操作:concat, stack, transpose 等
  • math.py:算术运算:加减乘除、三角函数、sum、cumsum 等
  • random.py:随机数:randn, uniform
  • search.py:搜索排序:argsort, argmin
  • stat.py:统计:mean, var, std
  • to_string.py:Tensor 打印功能

python/paddle/nn/functional 目录中包含用于神经网络的函数,如 batch_norm、conv2d,这些在 NumPy 中通常没有直接对应的函数。

四、注意事项

  1. 严格按标准工作流程执行,杜绝自行臆断和跳过步骤
  2. 代码中不允许提交中文,代码注释与 docstring 均使用英文
  3. 别名添加需注意顺序:在 init.py 中按字母序插入,保持代码风格一致
  4. Inplace 别名注意:mul_ 等 inplace 方法需确保原方法支持对应调用形式;inplace API 无需测试静态图
  5. 新命名空间不要遗漏注册:创建新包后,务必在 setup.py.in 和 setup.py 中同步注册

五、常见问题处理

Q1:Tensor 方法别名未生效(AttributeError)

错误现象:

x = paddle.to_tensor([1, 2, 3])
x.ne(y)  # AttributeError: 'Tensor' object has no attribute 'ne'

解决方法:

  1. 检查 python/paddle/tensor/init.py 中 tensor_method_func 列表是否包含 'ne'
  2. 检查 python/paddle/tensor/math.py 末尾是否有 ne = not_equal
Install via CLI
npx skills add https://github.com/PaddlePaddle/docs --skill add-new-api
Repository Details
star Stars 281
call_split Forks 907
navigation Branch main
article Path SKILL.md
More from Creator
PaddlePaddle
PaddlePaddle Explore all skills →