Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# 《Paddle API 对齐 PyTorch 项目》完整 SKILL 体系

AI Agent 自动对齐 Paddle API 与 PyTorch API。包含 1 个总 skill 和 6 个分阶段 skill。

## 两种使用方式

### 方式一:一步到位(推荐)

使用总 skill **`/api-compatibility`**,传入待对齐的 PyTorch API 列表:

```
/api-compatibility torch.atan torch.asinh torch.abs_
```

总 skill 会自动执行完整流程(Step1→Step2→Step3→Step4→Step5),返回对齐结果统计表。

### 方式二:分步操作

针对具体任务,单独调用对应 skill:

| 阶段 | Skill | 用途 |
|------|-------|------|
| Step1 | `/api-change-decider` | 分析 API 差异,决策改动方案 |
| Step2 | `/python-decorator` | 用 Python 装饰器修改 API |
| Step2 | `/cpp-sink` | 用 C++下沉修改 API(性能更优) |
| Step3 | `/pytorch-alignment-validator` | 验证 API 对齐 |
| Step4 | `/api-docs-updater` | 更新中文文档 |
| Step5 | `/create-pr` | 提交 PR 到三个仓库 |

## 工作流程

```
输入:待对齐 API 列表
Step1:方案决策(api-change-decider)
├─ 分析 API 差异
└─ 决策改动方案(方案 1-6)
Step2:代码修改(python-decorator 或 cpp-sink)
├─ 方案 1:Python 装饰器
├─ 方案 2:C++下沉
└─ 其他方案:跳过
Step3:对齐验证(pytorch-alignment-validator)
├─ 更新 API 映射
├─ 补充测试用例
└─ 运行单元测试
Step4:文档更新(api-docs-updater)
└─ 更新中文 API 文档
Step5:代码提交(create-pr)
└─ 提交 PR 到 Paddle/PaConvert/docs
输出:对齐结果统计表
```

## 使用示例

**完整对齐一个 API**(推荐方式):
```
/api-compatibility torch.atan
```
自动完成全流程,得到对齐结果。

**调试单个 API**(需要逐步修改):
```
/api-change-decider torch.atan # 确定方案
/cpp-sink torch.atan # 指定方案修改
/python-decorator torch.atan # 指定方案修改
/pytorch-alignment-validator torch.atan # 验证
/api-docs-updater torch.atan # 更新文档
/create-pr torch.atan # 提交 PR
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
---
name: api-change-decider
description: 仅用于《Paddle API 对齐 PyTorch 项目》,负责 Step1:方案决策,分析 PyTorch API 与 Paddle API 之间的差异,制定合适的 API 改动方案
allowed-tools: Read Grep‌ Glob‌ WebSearch
disable-model-invocation: false
---

# 一、输入输出规范

## 1.1 输入
需要对齐的 PyTorch API 列表(如 `torch.atan`、`torch.asinh`)

## 1.2 输出
方案类型、对应 Paddle API、差异分类、决策依据(以表格形式展示)

## 1.3 输出内容
输出应包含如下内容,以表格式形式展示:
1. **方案类型**:从方案 1~6 中选择合适的方案(可组合多种方案,例如方案 3+方案 1)
2. **对应 Paddle API**:需改动的 Paddle API 完整路径(如 `paddle.nn.functional.dropout`)
3. **差异分类**:差异分类是什么
4. **决策依据**:总结差异分析过程和选择理由
- API 相对引用路径是否一致
- 为什么选择该方案
- 为什么不选择其他方案
- 该方案是否会影响后向兼容

## 1.4 输出格式示例
```markdown
# 决策结果
|Pytorch API|方案类型|Paddle API|差异分类|决策依据|
|-|-|-|-|-|
|torch.atan|方案 2|paddle.atan|torch 参数更多|仅参数名不同(input→x)+仅多 out 参数,Python 实现仅有一次`_C_ops.atan(x)`调用,满足 C++下沉条件,性能最优|
|torch.frexp|方案 3+方案 1|paddle.frexp|torch 参数更多|API 相对引用路径一致,差异为:1)仅参数名不同(input→x);2)仅多 out 参数。当前 Python 实现包含多个 paddle 操作调用(abs、floor、log2 等),逻辑较复杂,不满足 C++下沉条件。选择方案 3 修改 API,在末尾添加 out 参数(带默认值 None),保持后向兼容。同时方案 1 支持参数名不同的重载情况。|
```

# 二、候选方案

## 方案 1:Python 装饰器
**适用场景**:
- 在 Python 层添加装饰器实现对齐
- 可对输入 `(*args, **kwargs)` 进行操作
- 支持多种重载情况:参数名不同、参数顺序不同、参数个数不同、参数类型不同
- 同时支持 torch 和 paddle 两套参数签名

**工作原理**:
- 根据输入参数的名称、类型、个数的不同来判断是 torch 签名还是 paddle 签名
- 分别针对两套签名进行不同的功能适配,从而既保留了原本的 paddle 功能,也新增了 torch 功能
- 这是方案 3(修改 API)的升级版,在保持后向兼容性的前提下实现对齐

**核心要求**:
- **必须能够区分**:能够根据输入的参数类型、名称的不同来区分 torch 签名还是 paddle 签名
- **无法区分则不适用**:如果无法通过输入参数特征区分两套签名,则方案 1 不适用

**优点**:灵活性强,兼容性好
**缺点**:性能低于 C++下沉实现

## 方案 2:C++下沉
**适用场景**:
- 将 API 直接下沉到 C++层
- Paddle 机制支持在 C++层配置参数映射
- **支持仅参数名不同的重载情况**(不涉及参数顺序或个数差异)
- **支持仅多 out 参数的情况**
- 方案 2 需要判断 API 的 Python 实现,需满足以下两个条件:
- 只有一次 `_C_ops.xxx` 调用
- `_C_ops.xxx` 前面没有**前处理逻辑**,或虽有**前处理逻辑**但逻辑简单且不涉及其他 API 调用(如 x.flatten 等),容易改写为 C++
- 注:分析时忽略静态图部分(LayerHelper 分支代码),该分支不再维护

**方案 2 不适用场景(满足其一则不适用)**:
- ❌ API 差异涉及参数顺序或个数差异
- ❌ Python 实现里调用了其他**Paddle API**,如 x.flatten、paddle.flatten(x)等
- ❌ 包含多个 `_C_ops.xxx` 调用
- ❌ `_C_ops.xxx` 前面的**前处理逻辑**较为复杂,不容易被改写为 C++

**优点**:性能最优
**缺点**:仅支持参数名不同的情况

## 方案 3:修改 API
**适用场景**:
- 直接修改现有 API 实现对齐
- 新增参数或功能
- 修改原有参数或功能

**以下修改不会导致后向兼容问题,可开展**:
- ✅ 在 API 参数末尾添加参数,且参数具有默认值
- ✅ 对已有 API 参数扩展新功能,保留原有功能

**以下修改会导致后向兼容问题,需禁止**:
- ❌ 改变已有参数顺序
- ❌ 改变已有参数名称
- ❌ 修改返回值类型

**优点**:直接对齐,实现简单
**缺点**:可能导致后向不兼容

## 方案 4:新增 API
**适用场景**:
- API 相对引用路径不一致
- 新增的 API 需要与 Pytorch 完全一致,包括 API 相对引用路径、输入参数与返回值(名称、个数、功能均一致)

**优点**:完全对齐,无后向兼容问题

## 方案 5:新增 compat 类型 API
**适用场景**:
- 在 `paddle/compat/__init__.py` 下新增 API
- 既无法原地修改(后向兼容性问题严重)
- 也无法新增 API(API 相对引用路径已被占用)

**优点**:无后向兼容问题
**缺点**:多一级 compat 路径,无法真正实现与 Pytorch 完全一致,实现之后差异分类将成为『仅 API 调用方式不一致』,在无其他方案时可以退而求其次选择

## 方案 6:无需改动
**适用场景**:
- API 完全一致

# 三、标准工作流程

## Step 1: 分析差异文档

### 1.1 获取差异文档
务必查阅每个 PyTorch API 对应的 API 差异文档(`torch.{api_name}.md`,位于 docs/docs/guides/model_convert/convert_from_pytorch/api_difference/目录下),如果实在无法找到差异文档,则说明该 API 已经实现了对齐一致,差异分类直接视作『API 完全一致』,无需再查询其他内容。

### 1.2 差异分类定义
差异分类共 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 暂无等效实现 |

### 1.3 提取差异信息

提取相关差异信息,提供给 Step2 进行方案决策:

| 项目 | 内容 |
|------|------|
| API 映射 | PyTorch API vs 对应的 Paddle API(可能为空)|
| 参数映射 | 参数对应关系和差异说明 |
| 转写示例 | 代码转换示例 |

注意以下参数直接忽略,不视作差异信息:
1. 忽略第 1 列的 generator、memory_format、layout 参数
1. 忽略第 2 列的 name 参数

## Step 2: 方案决策

### 2.1 关键概念

**API 相对引用路径**:API 完整路径在去掉框架导入模块(torch/paddle)后剩余的部分
- 示例:`torch.nn.functional.dropout` 的 API 相对引用路径是 `nn.functional.dropout`
- 示例:`paddle.nn.functional.dropout` 的 API 相对引用路径是 `nn.functional.dropout`
- 示例:`torch.Tensor.tile` 的 API 相对引用路径是 `Tensor.tile`

### 2.2 关键原则

> **⚠️ 严格遵循**:决策时必须严格遵守以下原则,不得主观臆断:
>
> 1. **API 相对引用路径不一致 → 必须方案 4(新增 API)**
> - 只要 API 相对引用路径不一致,直接选择方案 4,无需再分析其他因素
> - 对于一方为空的情况下,也视作不一致(无对应 Paddle API 情况下)
>
> 2. **严格按流程图和规则判断**
> - 必须按照决策流程图的路径执行
> - 严格按照各方案的适用条件判断
> - 不得因"可以"、"应该"等主观判断偏离规则定义

### 2.3 决策流程图

```
开始
├───→ API 相对引用路径是否一致? ──────┐
│ │
│是 │否
↓ ↓
具体有哪些差异? 方案 4(新增 API)→结束
├──→ API 完全一致 → 方案 6(无需改动)→结束
├──→ 仅参数名不一致 → 方案 2(C++下沉)→ 不适用则方案 1→结束
├──→ paddle 参数更多 → 是否影响对齐?─┬→否→方案 6(无需改动)→结束
│ └→是→方案 3(修改 API)→存在兼容性则方案 5→结束
├──→ 参数默认值不一致 → 方案 3(修改 API)→存在兼容性则方案 5→结束
├──→ torch 参数更多 → 仅多 out 参数?─┬→是→方案 2(C++下沉)→不适用则方案 3→存在兼容性则方案 1→无法区分则方案 5→结束
│ └→否→方案 3(修改 API)→存在兼容性则方案 1→无法区分则方案 5→结束
├──→ 输入参数用法/类型不一致 → 方案 3(修改 API)→存在兼容性则方案 1→无法区分则方案 5→结束
└──→ 返回参数类型不一致 → 方案 5(新增 compat 类型 API)→结束
```

### 2.4 详细决策规则

**前置判断**:以下规则均基于**API 相对引用路径一致**的前提。只要 API 相对引用路径不一致,直接选择**方案 4(新增 API)**,无需进入后续判断。

#### 1. API 完全一致
- **决策**:方案 6(无需改动)

#### 2. 仅参数名不一致
- **优先级 1**:方案 2(C++下沉)
- **适用条件**:满足方案 2 适用条件(见第三部分定义)
- **优势**:性能最优
- **优先级 2**:方案 1(Python 装饰器)
- **适用条件**:不满足方案 2 适用条件

#### 3. paddle 参数更多
- **判断**:额外参数是否影响对齐
- **否**(如默认参数,Paddle 保持默认即可)→ 方案 6(无需改动)
- **是** → 方案 3(修改 API)
- **存在兼容性** → 方案 5(新增 compat 类型 API)

#### 4. 参数默认值不一致
- **优先级 1**:方案 3(修改 API)
- **回退**:存在兼容性 → 方案 5(新增 compat 类型 API)

#### 5. torch 参数更多
- **子判断**:是否仅多 out 参数
- **是** → 方案 2(C++下沉)
- **不适用** → 方案 3(修改 API)→ 存在兼容性则方案 1→ 无法区分则方案 5
- **否** → 方案 3(修改 API)→ 存在兼容性则方案 1→ 无法区分则方案 5

#### 6. 输入参数用法/类型不一致
- **优先级 1**:方案 3(修改 API)
- **存在兼容性** → 方案 1(Python 装饰器)
- **无法区分两套签名** → 方案 5(新增 compat 类型 API)

#### 7. 返回参数类型不一致
- **唯一决策**:方案 5(新增 compat 类型 API)
- **原因**:
- ❌ 方案 3:修改返回值必然不兼容
- ❌ 方案 1:装饰器只能根据输入区分,无法区分返回值差异
- ✅ 方案 5:在 compat 路径下新增,不影响原 API

### 2.5 方案组合说明

> **重要提醒**:一个 API 可能涉及多种差异分类,需要综合分析所有差异点,可以组合多种方案来消除所有差异点。

**示例**:`torch.frexp` 存在"仅参数名不同"和"仅多 out 参数"两个差异点
- **组合方案**:方案 3 + 方案 1
- 方案 3:在末尾添加 out 参数(带默认值 None),消除"仅多 out 参数"差异
- 方案 1:支持参数名不同的重载,消除"仅参数名不同"差异
Loading