ワンクリックで
pytorch-alignment-validator
// 负责《Paddle API 对齐 PyTorch 项目》中 Step3:Pytorch 对齐验证,基于 PaConvert 工具验证 Paddle API 与 PyTorch API 是否用法完全对齐一致
// 负责《Paddle API 对齐 PyTorch 项目》中 Step3:Pytorch 对齐验证,基于 PaConvert 工具验证 Paddle API 与 PyTorch 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 的向后兼容性。
| name | pytorch-alignment-validator |
| description | 负责《Paddle API 对齐 PyTorch 项目》中 Step3:Pytorch 对齐验证,基于 PaConvert 工具验证 Paddle API 与 PyTorch API 是否用法完全对齐一致 |
| disable-model-invocation | false |
请严格按以下 Step 依次执行,不要自行修改或跳过 Step:
${ROOT_DIR}/PaConvert/paconvert/api_mapping.jsonChangePrefixMatcher,其他字段全部删除掉注意 torch.abs、torch.abs_、torch.Tensor.abs、torch.Tensor.abs_是四个不同的 API
目的: 判断是否满足如下测试规范,如不满足,则需增加测试用例使之符合规范
修改位置:
${ROOT_DIR}/PaConvert/tests/test_<API 名称>.py. 替换为 _,Tensor 类保留大写 T,最终加上 test_ 前缀和 .py 后缀
torch.argmax → test_argmax.py(顶层函数)torch.Tensor.argmax → test_Tensor_argmax.py(类方法)torch.linalg.inv → test_linalg_inv.py(子模块)测试规范:
参数覆盖要全面 测试所有可能的 Pytorch 参数用法:
func(a, b, c)func(x=a, y=b, z=c)func(a, y=b, z=c)func(z=c, x=a, y=b)func(a, dim=0,offset=1)func(a)args=(a,b); func(*args)func(input=a, other=b)输入数据要有效
测试数量要充分
测试用例模板:
import textwrap
import pytest
from apibase import APIBase
obj = APIBase("torch.target_api")
def test_case_1():
"""Basic usage"""
pytorch_code = textwrap.dedent("""
import torch
result = torch.target_api(torch.tensor([1, 2, 3]))
""")
obj.run(pytorch_code, ["result"])
def test_case_2():
"""Positional arguments test"""
pytorch_code = textwrap.dedent("""
import torch
x = torch.tensor([1.0, 2.0])
result = torch.target_api(x, 2, 1)
""")
obj.run(pytorch_code, ["result"])
def test_case_3():
"""Keyword arguments test"""
pytorch_code = textwrap.dedent("""
import torch
x = torch.tensor([1.0, 2.0])
result = torch.target_api(input=x, dim=1, dtype=torch.float32)
""")
obj.run(pytorch_code, ["result"])
def test_case_4():
"""Keyword arguments out of order test"""
pytorch_code = textwrap.dedent("""
import torch
x = torch.tensor([1.0, 2.0])
result = torch.target_api(dtype=torch.float32, dim=1, input=x)
""")
obj.run(pytorch_code, ["result"])
def test_case_5():
"""Gradient computation test"""
pytorch_code = textwrap.dedent("""
import torch
x = torch.tensor([1., 2.], requires_grad=True)
y = torch.target_api(x)
y.sum().backward()
x_grad = x.grad
""")
# Skip gradient attribute check because Paddle's stop_gradient mechanism differs from PyTorch's requires_grad mechanism at the framework level.
obj.run(pytorch_code, ["y", "x_grad"], check_stop_gradient=False)
def test_case_6():
"""Edge case test"""
pytorch_code = textwrap.dedent("""
import torch
result = torch.target_api(torch.empty(0))
""")
obj.run(pytorch_code, ["result"])
def test_case_7():
"""Expression argument test"""
pytorch_code = textwrap.dedent("""
import torch
result = torch.target_api(torch.tensor([1, 2, 3]), 1 + 1)
""")
obj.run(pytorch_code, ["result"])
特殊场景处理:
import paddle
import pytest
should_skip = not paddle.device.is_compiled_with_cuda()
skip_reason = "Test requires CUDA"
@pytest.mark.skipif(condition=should_skip, reason=skip_reason)
def test_case_with_cuda():
...
@pytest.mark.skip(reason="Not supported")
def test_unsupported_case():
...
class CustomAPIBase(APIBase):
def compare(self, name, pytorch_result, paddle_result, ...):
# 自定义比较逻辑
pytorch_str = str(pytorch_result).removeprefix("torch.")
assert pytorch_str == paddle_result
在补充完测试用例后,确保能通过所有用例,请按以下命令验证执行(不可修改):
本地执行以下命令:
cd ${ROOT_DIR}/PaConvert/
python -m pytest tests/test_<API 名称>.py
根据报错信息,修改代码或测试用例(禁止通过修改 api_mapping.json 来使单测通过),确保所有测试用例通过。注意每次修改 Paddle 源码后,必须重新编译方可生效:
cd /workspace/Paddle/build
cmake ..
make -j$(nproc)
编译注意事项:
${ROOT_DIR} 变量表示根目录,需自行替换为实际路径错误标识:Failed to execute pytorch code
根本原因:PyTorch 单元测试代码存在问题,无法正常执行
处理策略:修改 PyTorch 单元测试代码,确保能正确执行 Pytorch 代码
验证标准:测试代码应该能够在标准的 PyTorch 环境中正常运行
错误标识:Failed to execute paddle code
根本原因:Pytorch 单测正确,但修改后的 Paddle API 实现存在问题,导致代码无法执行
处理策略:需要返回到前序 Step 修改,因此结束本 Step,将报错信息返回给主控智能体分析
关联任务:Paddle API 需要进一步修改以兼容 PyTorch 接口
错误标识:Unable to align results
根本原因:Pytorch 单测正确,但 Paddle API 与 PyTorch API 计算结果存在差异
处理策略:需要返回到前序 Step 修改,因此结束本 Step,将报错信息返回给主控智能体分析
验证要求:Paddle API 需要进一步修改以兼容 PyTorch 接口,确保数值精度、数据类型、形状等完全一致
禁止通过配置 api_mapping.json 为非 ChangePrefixMatcher 来使单测通过,本步骤的通过标准为:Matcher 配置为 ChangePrefixMatcher + 单测运行通过。
错误现象: Paddle 因为暂不支持某些功能(如类型提升、标量输入等)而报错
解决方法:
# 将 def test_case_x(): 改为 def _test_case_x():
# 并添加注释说明原因
def _test_case_2(): # Paddle does not support scalar input
...
注意:仅允许禁用因已知 Paddle 限制导致的失败用例,其他情况不允许禁用