error log
error_log.md
context | 编译/运行环境 |
- PNNX 版本:20260526(pip install pnnx)
- 系统:Ubuntu 22.04
- PyTorch:2.13.0
how to reproduce | 复现步骤
单个 GELU 算子导出 ONNX,float16 精度即可复现:
import torch, torch.nn as nn
m = nn.GELU().to(torch.float16).eval()
x = torch.randn(1, 16, 16, 16, dtype=torch.float16)
torch.onnx.export(m, x, 'gelu_f16.onnx',
input_names=['a'], output_names=['b'],
opset_version=18, dynamo=True)
pnnx gelu_f16.onnx optlevel=2
而 float32 的同样模型正常:
# 把上面脚本里 float16 改成 float32,重新导出
pnnx gelu_f32.onnx optlevel=2 # ✅ 正常通过
根因定位
第 1 步:加载 ONNX 标量常量时,pass_onnx.cpp 约第 1010–1026 行:
// INT32、INT64、FLOAT、BOOL 都有对应的分支,会设置 params["value"]
else if (tensor.data_type() == onnx::TensorProto::BOOL)
{
op_const->params["value"] = ...; // ✅
}
else
{
// FLOAT16 落到了这里
fprintf(stderr, "unknown constant scalar type %d\n", ...);
// 只打了个 warning,params["value"] 没有被设置!
}
此时 prim::Constant 节点已经创建,但缺少 "value" 参数。GELU 公式中的 0.5、1.0、√2 等标量全部变成了这种「空壳」Constant。
第 2 步:pass_level3/eliminate_noop_math.cpp 第 15 行:
static bool constant_is_all_constant(const Operator* op_constant, ...)
{
const Parameter& param = op_constant->params.at("value"); // ← 崩溃!
// "value" 这个 key 不存在 → std::map::at 抛 std::out_of_range
error log
error_log.md
context | 编译/运行环境 |
how to reproduce | 复现步骤
单个 GELU 算子导出 ONNX,float16 精度即可复现:
而 float32 的同样模型正常:
根因定位
第 1 步:加载 ONNX 标量常量时,
pass_onnx.cpp约第 1010–1026 行:此时
prim::Constant节点已经创建,但缺少"value"参数。GELU 公式中的 0.5、1.0、√2 等标量全部变成了这种「空壳」Constant。第 2 步:
pass_level3/eliminate_noop_math.cpp第 15 行: