Describe the bug
PIR 格式下三个基础算子 linear_v2 / group_norm / layer_norm 无法正常导出 ONNX。
Bug A: nn.Linear → linear_v2 无 mapper
PIR 3.x 格式将 nn.Linear 融合为单一算子 pd_op.linear_v2,但 paddle2onnx 源码中没有任何 linear* 的 mapper 文件(旧格式下 Linear 被分解为 mul + elementwise_add 两个旧算子,因此不需要独立 mapper)。
使用 paddle2onnx 2.1.0(PyPI)或源码 commit 1877292 均无法导出含 nn.Linear 的模型。
Bug B: nn.GroupNorm → PIR 模式不兼容
已有 REGISTER_PIR_MAPPER(group_norm, GroupNormMapper),但两个问题:
GetInput("X") / GetInput("Scale") / GetInput("Bias") 在 PIR 模式下无 OpNameNormalizer 映射,返回空
- PIR 格式输入为 3D
[N, C, L],ONNX InstanceNormalization 要求 4D [N, C, H, W]
Bug C: nn.LayerNorm → PIR 模式下 Scale/Bias 被忽略
HasInput("Scale") 和 HasInput("Bias") 在 PIR 模式下返回 false(同样因为无命名映射),导致 LayerNorm 实际的 weight/bias 参数被忽略,使用全 1/全 0 常量替代,推理结果完全错误。
Root Cause
所有三个 bug 的共同根因:PIR 格式算子的输入是位置索引(I[0], I[1], I[2]),而非命名映射("X", "Weight", "Scale")。GetInput("X") 内部调用 GetOpInputOutputName2Idx 通过 OpYamlInfoInterface 解析算子参数名,但这三个算子在 OpNameNormalizer 中没有对应的 PIR 参数名映射,返回 -1 导致空结果。
Reproduction
import paddle
import paddle.nn as nn
from paddle.static import InputSpec
# Bug A: nn.Linear
model = nn.Linear(64, 128).eval()
sm = paddle.jit.to_static(model,
input_spec=[InputSpec([1, 64], 'float32', 'x')],
full_graph=True)
paddle.jit.save(sm, '/tmp/linear_model')
然后用 paddle2onnx 导出:
paddle2onnx --model_dir /tmp/linear_model ...
→ SIGABRT / unsupported operators
# Bug B: nn.GroupNorm
model = nn.GroupNorm(4, 64).eval()
→ "There are unsupported features"
# Bug C: nn.LayerNorm
class M(nn.Layer):
def __init__(self):
super().__init__()
self.w = self.create_parameter([64, 128])
self.b = self.create_parameter([128])
self.ln = nn.LayerNorm(128)
def forward(self, x):
return self.ln(paddle.matmul(x, self.w) + self.b)
→ ONNX output is all-zero because Scale/Bias are ignored
Fix (PR prepared)
- 新增
paddle2onnx/mapper/nn/linear_v2.h 和 linear_v2.cc:将 linear_v2 分解为 MatMul + Add,PIR 模式下使用位置索引 GetInput(0)/GetInput(1)/GetInput(2)
- 修改
paddle2onnx/mapper/nn/group_norm.cc:PIR 位置索引 + 3D→4D Unsqueeze→InstanceNormalization→Squeeze
- 修改
paddle2onnx/mapper/nn/layer_norm.cc:PIR 位置索引读取 Scale/Bias
- 修改
paddle2onnx/mappers_registry.h.in:注册 linear_v2
Informations (please complete the following information):
- Inference engine for deployment: ONNX Runtime (CPU/CUDA)
- Why convert to onnx: Model deployment
- Paddle2ONNX Version: 2.1.0 (PyPI) & source commit 1877292
- PaddlePaddle Version: 3.5.0.dev20260614
- OS: Ubuntu 22.04
Screenshots
N/A
Additional context
N/A
Describe the bug
PIR 格式下三个基础算子
linear_v2/group_norm/layer_norm无法正常导出 ONNX。Bug A:
nn.Linear→linear_v2无 mapperPIR 3.x 格式将
nn.Linear融合为单一算子pd_op.linear_v2,但 paddle2onnx 源码中没有任何linear*的 mapper 文件(旧格式下 Linear 被分解为mul + elementwise_add两个旧算子,因此不需要独立 mapper)。使用 paddle2onnx 2.1.0(PyPI)或源码 commit 1877292 均无法导出含
nn.Linear的模型。Bug B:
nn.GroupNorm→ PIR 模式不兼容已有
REGISTER_PIR_MAPPER(group_norm, GroupNormMapper),但两个问题:GetInput("X")/GetInput("Scale")/GetInput("Bias")在 PIR 模式下无 OpNameNormalizer 映射,返回空[N, C, L],ONNX InstanceNormalization 要求 4D[N, C, H, W]Bug C:
nn.LayerNorm→ PIR 模式下 Scale/Bias 被忽略HasInput("Scale")和HasInput("Bias")在 PIR 模式下返回 false(同样因为无命名映射),导致 LayerNorm 实际的 weight/bias 参数被忽略,使用全 1/全 0 常量替代,推理结果完全错误。Root Cause
所有三个 bug 的共同根因:PIR 格式算子的输入是位置索引(
I[0],I[1],I[2]),而非命名映射("X","Weight","Scale")。GetInput("X")内部调用GetOpInputOutputName2Idx通过 OpYamlInfoInterface 解析算子参数名,但这三个算子在 OpNameNormalizer 中没有对应的 PIR 参数名映射,返回 -1 导致空结果。Reproduction
然后用 paddle2onnx 导出:
→ SIGABRT / unsupported operators
→ "There are unsupported features"
→ ONNX output is all-zero because Scale/Bias are ignored
Fix (PR prepared)
paddle2onnx/mapper/nn/linear_v2.h和linear_v2.cc:将linear_v2分解为 MatMul + Add,PIR 模式下使用位置索引GetInput(0)/GetInput(1)/GetInput(2)paddle2onnx/mapper/nn/group_norm.cc:PIR 位置索引 + 3D→4D Unsqueeze→InstanceNormalization→Squeezepaddle2onnx/mapper/nn/layer_norm.cc:PIR 位置索引读取 Scale/Biaspaddle2onnx/mappers_registry.h.in:注册linear_v2Informations (please complete the following information):
Screenshots
N/A
Additional context
N/A