en un clic
api-change-decider
// 负责《Paddle API 对齐 PyTorch 项目》中 Step1:方案决策,分析 PyTorch API 与 Paddle API 之间的差异,制定合适的 API 改动方案
// 负责《Paddle API 对齐 PyTorch 项目》中 Step1:方案决策,分析 PyTorch API 与 Paddle API 之间的差异,制定合适的 API 改动方案
开展《Paddle API 对齐 PyTorch 项目》,负责项目整体统筹规划,调用多个 skill,完成输入的 API 对齐
负责《Paddle API 对齐 PyTorch 项目》中 Step4:API 文档修改,在 API 代码修改完成后,同步更新中文 API 文档,确保文档准确反映 API 的最新行为
负责《Paddle API 对齐 PyTorch 项目》中 Step2:API 代码修改,实施 C++下沉的代码开发。通过将 Python API 下沉至 C++层,可以减少 Python 装饰器带来的性能开销,提升 API 调度效率。
负责《Paddle API 对齐 PyTorch 项目》中 Step5:代码提交,分别对 Paddle、PaConvert、Docs 三个仓库创建或更新 Pull Request
负责《Paddle API 对齐 PyTorch 项目》中 Step2:API 代码修改,实施 Python 装饰器的代码开发。通过 Python 装饰器,在 Python 层为 Paddle API 提供参数别名、参数顺序、参数类型和参数用法的兼容转换,实现 PyTorch 风格的 API 调用,并保持 Paddle API 的向后兼容性。
负责《Paddle API 对齐 PyTorch 项目》中 Step3:Pytorch 对齐验证,基于 PaConvert 工具验证 Paddle API 与 PyTorch API 是否用法完全对齐一致
| name | api-change-decider |
| description | 负责《Paddle API 对齐 PyTorch 项目》中 Step1:方案决策,分析 PyTorch API 与 Paddle API 之间的差异,制定合适的 API 改动方案 |
| disable-model-invocation | false |
需要对齐的 PyTorch API 列表(如 torch.atan、torch.asinh)
以表格形式展示,列说明如下:
| Pytorch API | 方案类型 | Paddle API | 差异分类 | 决策依据 |
|---|---|---|---|---|
| 需对齐的 PyTorch API | 从方案 1~6 中选择 | 需改动的 Paddle API 完整路径 | 差异分类 | 总结差异分析过程和选择理由 |
以下为示例表格:
| Pytorch API | 方案类型 | Paddle API | 差异分类 | 决策依据 |
|---|---|---|---|---|
| torch.atan | 方案 2 | paddle.atan | torch 参数更多 | 仅参数名不同(input→x)+仅多 out 参数,Python 实现仅有一次_C_ops.atan(x)调用,满足 C++下沉条件,性能最优 |
| torch.select_scatter | 方案 1 | paddle.select_scatter | 仅参数名不一致 | input→x, src→values, dim→axis 参数名不同。底层调用 _C_ops.set_value_with_tensor(非 _C_ops.select_scatter),不满足方案 2 条件 1,降级为方案 1(Python 装饰器) |
| torch.Tensor.select_scatter | 方案 1 | paddle.Tensor.select_scatter | 仅参数名不一致 | 与 paddle.select_scatter 共享实现(patch 机制),随主 API 一并修改 |
| torch.logspace | 方案 3 + 方案 1 | paddle.logspace | 参数名不一致 + torch 参数更多 | 全文有两类差异:①end→stop/steps→num 参数名不同;②torch 多 out/device/requires_grad 参数。方案 3 末尾新增 out=None/device=None/requires_grad=False(后向兼容);方案 1 装饰器添加 end/stop、steps/num 别名 |
适用场景:
工作原理: 根据输入参数的名称、类型、个数判断是 PyTorch 签名还是 Paddle 签名,针对两套签名分别适配功能,既保留原有 Paddle 功能也实现了 PyTorch 对齐
核心限制:
优点:灵活性强,兼容性好 缺点:性能低于 C++ 下沉实现
适用场景:
适用条件(必须全部满足):
_C_ops.xxx 的 OP 名称一致paddle.atan 调用 _C_ops.atanpaddle.select_scatter 调用 _C_ops.set_value_with_tensor(名称不一致)_C_ops.xxx 调用paddle.where、paddle.abs、paddle.flatten 等)x.flatten()、x.reshape()、x.unsqueeze() 等,这些等同于调用 paddle API)paddle.full_like、paddle.zeros_like、paddle.cast 等len()、isinstance()、list()、range() 等)x.shape、x.dtype、x.ndim 等)index + 1、axis < 0 等)_C_ops.xxx 前面无复杂前处理逻辑,前处理逻辑(如存在)容易改写为 C++fill_constant、paddle.where、paddle.cast 等)reshape、transpose、flatten 等)isinstance()、类型检查、范围检查)convert_np_dtype_to_dtype_)x.shape、x.dtype)注意:
优点:性能最优 缺点:限制条件很多,需严格满足
适用场景:
适用条件(必须全部满足)**:
不适用条件(❌ 禁止)**:
适用场景:
适用场景:
注意:
paddle.compat.* 路径下),不影响原 Paddle API⚠️ 短路逻辑(必须严格遵守):
- 按优先级 1 → 2 → 3 的顺序依次尝试
- 一旦从某个来源获取到完整差异信息,立即停止,不再查找其他来源
- 这是"三选一"而非"三者都要",严禁同时查找多个来源
torch.{api_name}.md,位于 ${ROOT_DIR}/docs/docs/guides/model_convert/convert_from_pytorch/api_difference/ 目录下)⚠️ 注意:差异文档标题仅反映主要分类,须阅读全文
- 差异文档的标题头(如
[ torch 参数更多 ]、[ 仅参数名不一致 ])只选取了最显著的一类差异作为标题- 一个 API 往往同时涉及多种差异,例如既有参数名不同,又有 torch 多出 out 参数
- 必须通读差异文档的完整参数映射表,提取所有差异点,不能仅以文件标题作为差异分类的唯一依据
${ROOT_DIR}/PaConvert/paconvert/api_mapping.json 或 ${ROOT_DIR}/PaConvert/paconvert/attribute_mapping.json)| 字段 | 说明 | 对应差异分类 |
|---|---|---|
Matcher: "ChangePrefixMatcher" | API 完全一致,仅框架前缀不同(torch→paddle),无需任何参数转换 | API 完全一致 |
Matcher: "ChangeAPIMatcher" | API 调用方式不同,但功能一致,无需参数转换 | 仅 API 调用方式不一致 |
Matcher: "NumelMatcher" | 特定 API(如 torch.numel)的专用转换器 | 仅 API 调用方式不一致 |
Matcher: "TensorFunc2PaddleFunc" | Tensor 类方法转为 Paddle 函数,如 x.func() → paddle.func(x) | 仅 API 调用方式不一致(无其他差异时) |
Matcher: "Func2Attribute" | 函数调用转为属性访问,如 x.func() → x.attr | 仅 API 调用方式不一致(无其他差异时) |
Matcher: "Attribute2Func" | 属性访问转为函数调用,如 x.attr → x.func() | 仅 API 调用方式不一致(无其他差异时) |
Matcher: "GenericMatcher" | 通用转换器,适用于可直接映射的 API | 仅参数名不一致 / 仅 paddle 参数更多 / 仅参数默认值不一致 / torch 参数更多 |
paddle_api | 对应的 Paddle API 完整路径,如 "paddle.transpose" | 表示 API 映射关系 |
kwargs_change | 参数名映射关系,如 {"input": "x", "dims": "perm"} | 仅参数名不一致 |
unsupport_args | 不支持的参数列表,如 ["stride"] | torch 参数更多(部分不支持) |
paddle_default_kwargs | Paddle 需要设置的默认参数,如 {"axis": -1} | 参数默认值不一致 / paddle 参数更多 |
其他自定义 Matcher | 除上述 Matcher 外的其他自定义 Matcher 名称 | 参数用法/类型不一致 / 组合替代实现等复杂情况 |
TensorFunc2PaddleFunc、Func2Attribute、Attribute2Func 同时包含 unsupport_args、kwargs_change 或 paddle_default_kwargs 字段时,说明除了调用方式差异外,还存在其他差异,不能归类为"仅 API 调用方式不一致"${ROOT_DIR}/PaConvert/paconvert/api_matcher.py 中对应 Matcher 的实现逻辑进行差异分类差异分类共 13 类,具体如下:
| 序号 | 差异分类 | 说明 |
|---|---|---|
| 1 | API 完全一致 | 无差异,无需改动 |
| 2 | 仅 API 调用方式不一致 | API 相对引用路径不一致,但参数完全相同 |
| 3 | 仅参数名不一致 | 参数功能相同但参数名称不同 |
| 4 | paddle 参数更多 | Paddle 提供更多可选参数 |
| 5 | 参数默认值不一致 | 参数默认值不同 |
| 6 | torch 参数更多 | PyTorch 提供更多参数 |
| 7 | 输入参数用法不一致 | 参数处理方式不同 |
| 8 | 输入参数类型不一致 | 参数类型要求不同 |
| 9 | 返回参数类型不一致 | 返回值类型或结构不同 |
| 10 | 组合替代实现 | PyTorch API 需多个 Paddle API 组合实现 |
| 11 | 可删除 | PyTorch API 在 Paddle 中可直接删除 |
| 12 | API 别名 | PyTorch API 是其他 API 的别名 |
| 13 | 功能缺失 | Paddle 暂无等效实现 |
总结相关差异信息,提供给 Step2 进行方案决策:
| 项目 | 内容 |
|---|---|
| 差异分类 | 具体差异分类 |
| API 映射 | PyTorch API vs 对应的 Paddle API(可能为空) |
| 参数映射 | 参数对应关系和差异说明 |
| 转写示例 | 代码转换示例 |
注意以下参数直接忽略,不视作差异信息:
只能忽略上述明确列出的参数,其他参数不可忽略。例如 device、out、requires_grad、dtype 等不可忽略,必须处理。
API 相对引用路径:API 完整路径在去掉框架导入模块(torch/paddle)后剩余的部分
torch.nn.functional.dropout 的 API 相对引用路径是 nn.functional.dropoutpaddle.nn.functional.dropout 的 API 相对引用路径是 nn.functional.dropouttorch.Tensor.tile 的 API 相对引用路径是 Tensor.tile仅多 out 参数:torch 比 paddle 恰好只多一个参数,且该参数名为 out,其余所有参数完全一致
out 一个参数,其余参数完全一致out,如同时多了 out 和 requires_grad)out(如仅多 dtype)⚠️ 严格遵循:决策时必须严格遵守以下原则,不得主观臆断:
- API 相对引用路径不一致 → 必须方案 4(新增 API)
- 只要 API 相对引用路径不一致,直接选择方案 4,无需再分析其他因素
- 对于一方为空的情况下,也视作不一致(无对应 Paddle API 情况下)
- 严格按流程图和规则判断
- 必须按照决策流程图的路径执行
- 严格按照各方案的适用条件判断
- 不得因"可以"、"应该"等主观判断偏离规则定义
开始
│
├───→ API 相对引用路径是否一致? ──────┐
│ │
│是 │否
↓ ↓
具体有哪些差异? 方案 4(新增 API)→结束
│
├──→ 1. API 完全一致 → 方案 6(无需改动)→结束
│
├──→ 2. 仅 API 调用方式不一致 → 方案 4(新增 API)→结束
│
├──→ 3. 仅参数名不一致 → 方案 2(C++下沉)→ 不适用则方案 1→结束
│
├──→ 4. paddle 参数更多 → 是否影响对齐?─┬→否→方案 6(无需改动)→结束
│ └→是→方案 3(修改 API)→导致后向不兼容则方案 5→结束
│
├──→ 5. 参数默认值不一致 → 是否影响对齐?─┬→否→方案 6(无需改动)→结束
│ └→是→方案 3(修改 API)→导致后向不兼容则方案 5→结束
│
├──→ 6. torch 参数更多 → 仅多 out 参数(见 2.1 定义)?─┬→是→方案 2(C++下沉)→不适用则方案 1→结束
│ └→否→方案 3(修改 API)→导致后向不兼容则方案 1→无法重载则方案 5→结束
│
├──→ 7. 输入参数用法不一致 → 方案 3(修改 API)→导致后向不兼容则方案 1→无法重载则方案 5→结束
│
├──→ 8. 输入参数类型不一致 → 方案 3(修改 API)→导致后向不兼容则方案 1→无法重载则方案 5→结束
│
├──→ 9. 返回参数类型不一致 → 方案 5(新增 compat 类型 API)→结束
│
├──→ 10. 组合替代实现 → 方案 4(新增 API)→结束
│
├──→ 11. 可删除 → 方案 6(无需改动)→结束
│
├──→ 12. API 别名 → 方案 4(新增 API)→结束
│
└──→ 13. 功能缺失 → 方案 4(新增 API)→结束
前置判断:分类 3~10 判定规则均基于API 相对引用路径一致的前提。只要 API 相对引用路径不一致,直接选择方案 4(新增 API),无需进行如下判断。
重要提醒:一个 API 可能涉及多种差异分类,需要综合分析所有差异点,可以组合多种方案来消除所有差异点。
示例 1:torch.logspace 差异文档标题为 [ torch 参数更多 ],但全文实际涉及两类差异:
end→stop、steps→numout、device、requires_grad 参数paddle.logspace 末尾新增 out=None、device=None、requires_grad=False 参数(后向兼容),处理"torch 参数更多"差异end/stop、steps/num,处理"参数名不一致"差异示例 2:torch.slice_scatter 差异文档标题为 [ 输入参数用法不一致 ],但全文实际涉及两类差异:
input→x、src→value、dim→axes、start→starts、end→ends、step→stridesint,Paddle 对应参数为 list of intpaddle.slice_scatter 的 axes/starts/ends/strides 参数,使其同时支持 int 和 list of int(后向兼容),处理"输入参数类型不一致"差异input/x、src/value、dim/axes、start/starts、end/ends、step/strides,处理"参数名不一致"差异此问题仅适用于流程图中标注"导致后向不兼容则方案 1/5"的分支(如差异分类 6/7/8)。
判断方法:严格按照方案 3 的"不适用条件"判断:
示例:
torch.tril_indices 多 device 参数 → 在末尾添加 device=None → 不违反上述条件 → 后向兼容 → 方案 3torch.slice_scatter 扩展参数类型(int → int|list)→ 不违反上述条件 → 后向兼容 → 方案 3${ROOT_DIR} 变量表示根目录,需自行替换为实际路径