Skip to content

修复 reshape 系列转换规则:新增 ReshapeInplaceRule 并对齐 ValidateShape - #721

Open
feixi139 wants to merge 1 commit into
PFCCLab:mainfrom
feixi139:fix-reshape-inplace-rule
Open

修复 reshape 系列转换规则:新增 ReshapeInplaceRule 并对齐 ValidateShape#721
feixi139 wants to merge 1 commit into
PFCCLab:mainfrom
feixi139:fix-reshape-inplace-rule

Conversation

@feixi139

Copy link
Copy Markdown
Collaborator

背景

reshape 系列的 Paddle→Torch 转换规则存在三个问题:

  1. paddle.reshape_paddle.Tensor.reshape_ 没有任何映射;paddle._C_ops.reshape_CopsReshapeRuleConversionKind.DIRECT 承载,其 docstring 声称通过 set_ 实现 in-place,但代码里从未调用 set_,实际不具备 in-place 语义。

  2. ReshapeRuleCopsReshapeRule 各自持有一份 shape 归一化逻辑,两份都与 Paddle 的真值 paddle/phi/infermeta/unary.cc 中的 ValidateShape 不符:

    • shape 里的 0 下标越界(i >= x.ndim)且输入非空时,Paddle 抛 (InvalidArgument) If The index of 0 in 'shape' >= the input tensor X's dimensions, It can only be Zero-Sized Tensorunary.cc:2423),而原逻辑直接索引 in_dims[i] 抛出 Python IndexError。该文本不在 tester/base.py classify_runtime_error 的白名单内,导致无效配置被误分类为 torch_error
    • zero-size 输入同时出现 0-1 时,Paddle 按非零维乘积之比推导([0,2,4] → [0,-1][0,8]),原逻辑用 in_size // capacity 恒得 0,产出静默的错误形状,表现为 paddle_accuracy 形状不匹配。
  3. tester/input_generation/generation_rules.pygenerate_reshape_inputsstate["maxvalue"] //= shape[index] 前缺少下标检查,0 越界时抛 IndexError。该异常在 --paddle_only 模式的 Input 阶段即触发,掩盖了 Paddle 侧真正的 InvalidArgument

修改内容

  • tester/paddle_to_torch/rules.py
    • 新增模块级共享常量 _RESHAPE_VALIDATE_SHAPE,逐条复刻 unary.ccValidateShape,报错文本统一带 (InvalidArgument) 前缀以便 classify_runtime_error 归类为 config_input
    • 新增 ReshapeInplaceRuleConversionKind.COMPOSITE),承载 paddle.reshape_paddle.Tensor.reshape_paddle._C_ops.reshape_。实现为:目标 shape 与原 shape 相同时短路返回 x(对齐 python/paddle/tensor/manipulation.py 的 Python 层提前返回,不触发 CheckInplace);否则拦截需要梯度的叶子 Tensor(对齐 paddle/fluid/eager/utils.ccCheckInplace)后执行 x.set_(torch.reshape(x, shape))set_ 不包裹 no_grad,与既有 CopsFlattenRule 一致;包裹后 x 会保留形状已变的旧 grad_fn,反向校验失败。
    • ReshapeRule 改为复用共享常量,删除内联的重复归一化逻辑。
    • 删除 CopsReshapeRule
  • tester/paddle_to_torch/mapping.json:新增 paddle.reshape_paddle.Tensor.reshape_ 两项指向 ReshapeInplaceRulepaddle._C_ops.reshape_CopsReshapeRule 改指 ReshapeInplaceRule
  • tester/input_generation/generation_rules.py:为 generate_reshape_inputs 补下标守卫,0 越界时不再抛 IndexError,交由 Paddle 报 InvalidArgument

验证

pre-commit(全部 hook 通过,无文件被自动修改):

pre-commit run --files tester/paddle_to_torch/rules.py tester/paddle_to_torch/mapping.json tester/input_generation/generation_rules.py

语法与格式检查:

python -m py_compile tester/paddle_to_torch/rules.py tester/input_generation/generation_rules.py
git diff --check

转换链路核对:paddle.reshape / paddle.Tensor.reshapeDIRECT,三个 reshape_ 入口为 COMPOSITE,五者共用同一份 60 行预处理;CopsReshapeRule 已不存在。

功能用例(engineV4.py --accuracy=True --bitwise_alignment=True,即 atol=rtol=0 逐位对齐,日志头已确认 --atol: 0.0 / --rtol: 0.0)共 67 条,结果为 43 pass / 24 config_input,未出现 torch_errorpaddle_errorpaddle_accuracytorch_accuracy

用例集 pass config_input
共享预处理边界(三个 API 入口 × 0 下标越界 / 多个 -1 / 负维 / zero-size 带 -1),17 条 9 8
in-place 边界,11 条 9 2
in-place 广覆盖(dtype、tuple/Tensor 形式的 shape、zero-size),20 条 19 1
非 in-place 边界,3 条 2 1
0-size 大 shape,16 条 4 12

24 条 config_input 均为配置本身无效,可逐条对应到 ValidateShape 的具体位置:多个 -1unary.cc:2400)、除 -1 外的负维(unary.cc:2432)、非空输入上 0 下标越界(unary.cc:2423)、numel 不匹配(unary.cc:2533)。修改前,其中涉及 0 下标越界的用例被误分类为 torch_error,zero-size 混合 0-1 的用例为静默的 paddle_accuracy

回归:

tools/regression/regression_runner.sh

447 条配置,436 pass / 6 skip / 2 paddle_error / 3 torch_error,与本次修改前的基线逐字节一致;残留失败为 fused_swiglu_weighted_clamp_bwdfused_linear_param_grad_add,与 reshape 无关。该回归是以 runner 默认参数执行的,未开启 --bitwise_alignment

附带影响

paddle._C_ops.reshape_ConversionKindDIRECT 变为 COMPOSITEtester/torch_gpu_performance.py:80 会将其标记为 combined。若性能报表按单 kernel 统计,此处存在口径变化。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant