已合并
【fix】: support empty onnx domain #4093
tang-haojie创建于 7月21日
【fix】: support empty onnx domain #4093
已合并
tang-haojie创建于 7月21日
2 个文件变更+15-32
Mparser/parser/onnx/onnx_parser.cc+10-29
@@ -417,34 +417,14 @@ Status OnnxModelParser::ConstructOriType(const ge::onnx::NodeProto *node_proto,
417 return SUCCESS;417 return SUCCESS;
418 }418 }
419 419 
420- std::string domain = node_proto->domain();420+ std::string domain = node_proto->domain().empty() ? "ai.onnx" : node_proto->domain();
421- int64_t version = 0;421+ std::map<std::string, int64_t>::const_iterator it = domain_verseion_.find(domain);
422- if (!domain.empty()) {422+ if (it == domain_verseion_.end()) {
423- std::map<std::string, int64_t>::const_iterator it = domain_verseion_.find(domain);423+ REPORT_INNER_ERR_MSG("E19999", "The opset of domain[%s] has no responding version.", domain.c_str());
424- if (it != domain_verseion_.end()) {424+ GELOGE(PARAM_INVALID, "[Check][Param]The opset of domain[%s] has no responding version.", domain.c_str());
425- version = it->second;425+ return PARAM_INVALID;
426- } else {
427- REPORT_INNER_ERR_MSG("E19999", "The opset of domain[%s] has no responding version.", domain.c_str());
428- GELOGE(PARAM_INVALID, "[Check][Param]The opset of domain[%s] has no responding version.", domain.c_str());
429- return PARAM_INVALID;
430- }
431- } else {
432- size_t domain_version_size = domain_verseion_.size();
433- if (domain_version_size == 1) {
434- domain = domain_verseion_.begin()->first;
435- version = domain_verseion_.begin()->second;
436- } else {
437- GELOGE(PARAM_INVALID, "[Check][Param]The size of domain_version[%zu] should be equal to one.",
438- domain_version_size);
439- REPORT_PREDEFINED_ERR_MSG("E16005", std::vector<const char *>({"domain_version_size"}),
440- std::vector<const char *>({to_string(domain_version_size).c_str()}));
441- return PARAM_INVALID;
442- }
443- }
444- 
445- if (domain.empty()) {
446- domain = "ai.onnx";
447 }426 }
427+ int64_t version = it->second;
atomgit-bot
atomgit-botatomgit-bot7月21日

🟡 Medium Priority

变更行onnx_parser.cc 第 420–427 行(ConstructOriType 函数的新逻辑)。

旧行为:当节点 domain 为空且 domain_verseion_ 中恰好只有 1 个条目时,旧代码会将该条目的 domain 和 version 回退用于该节点(无论该条目是 "ai.onnx" 还是自定义 domain 如 "com.microsoft")。这意味着仅导入单个自定义 opset、不含标准 "ai.onnx" opset 的模型,其空 domain 节点仍能成功解析。

新行为:空 domain 始终默认映射为 "ai.onnx",直接在 domain_verseion_ 中查找。若 "ai.onnx" 不在 map 中,返回 PARAM_INVALID

触发条件:模型仅导入一个自定义 domain 的 opset(如 opset_import { domain: "custom.domain", version: 1 }),不含 domain=""domain="ai.onnx" 的 opset 条目,且包含 domain="" 的节点。

失败模式:此类模型在旧代码下可成功解析,新代码下 ConstructOriType 返回 PARAM_INVALID,导致整个模型解析失败。

  1. 若需保持兼容,可在 "ai.onnx" 查找失败后增加回退:若 domain_verseion_.size() == 1,使用该唯一条目。

建议:若需保持向后兼容,在 domain_verseion_.find("ai.onnx") 返回 end()domain_verseion_.size() == 1 时,回退使用该唯一条目的 domain 和 version;否则按当前逻辑返回错误。若确认移除回退为有意行为,需在变更说明中记录此破坏性变更。

likedislike
tang-haojie
7月22日 评论:
448 428 
449 ori_type = domain + "::" + to_string(version) + "::" + ori_type;429 ori_type = domain + "::" + to_string(version) + "::" + ori_type;
450 return SUCCESS;430 return SUCCESS;
@@ -927,8 +907,9 @@ Status OnnxModelParser::ModelParseToGraph(const ge::onnx::ModelProto &onnx_model
927 907 
928 auto opset_import = onnx_model.opset_import();908 auto opset_import = onnx_model.opset_import();
929 for (auto it : opset_import) {909 for (auto it : opset_import) {
930- domain_verseion_[it.domain()] = it.version();910+ std::string domain = it.domain().empty() ? "ai.onnx" : it.domain();
931- GELOGI("Domain:[%s], Version:[%ld].", it.domain().c_str(), it.version());911+ domain_verseion_[domain] = it.version();
912+ GELOGI("Domain:[%s], Version:[%ld].", domain.c_str(), it.version());
932 }913 }
933 std::string root_graph_name =914 std::string root_graph_name =
934 ParserUtils::GetGraphName(root_graph).empty() ? "default_graph" : ParserUtils::GetGraphName(root_graph);915 ParserUtils::GetGraphName(root_graph).empty() ? "default_graph" : ParserUtils::GetGraphName(root_graph);
Mtests/parser/ut/parser/testcase/onnx_parser_testcase/onnx_parser_unittest.cc+5-3
@@ -774,7 +774,8 @@ TEST_F(UtestOnnxParser, ConstructOriType_empty_domain_multiple_versions) {
774 774 
775 std::string ori_type;775 std::string ori_type;
776 auto ret = parser.ConstructOriType(&node, ori_type);776 auto ret = parser.ConstructOriType(&node, ori_type);
777- EXPECT_EQ(ret, PARAM_INVALID);777+ EXPECT_EQ(ret, SUCCESS);
778+ EXPECT_EQ(ori_type, "ai.onnx::11::CustomOp");
778}779}
779 780 
780TEST_F(UtestOnnxParser, ConstructOriType_empty_domain_single_version) {781TEST_F(UtestOnnxParser, ConstructOriType_empty_domain_single_version) {
@@ -1100,7 +1101,7 @@ TEST_F(UtestOnnxParser, ConstructInputOutputContext_basic) {
1100 1101 
1101// ======================== Prechecker tests ========================1102// ======================== Prechecker tests ========================
1102 1103 
1103-TEST_F(UtestOnnxParser, Prechecker_construct_ori_type_failure) {1104+TEST_F(UtestOnnxParser, Prechecker_unregistered_op_type_failure) {
1104 OnnxModelParser parser;1105 OnnxModelParser parser;
1105 parser.domain_verseion_["ai.onnx"] = 11;1106 parser.domain_verseion_["ai.onnx"] = 11;
1106 parser.domain_verseion_["other.domain"] = 1;1107 parser.domain_verseion_["other.domain"] = 1;
@@ -1112,7 +1113,8 @@ TEST_F(UtestOnnxParser, Prechecker_construct_ori_type_failure) {
1112 node->set_domain("");1113 node->set_domain("");
1113 1114 
1114 auto ret = parser.Prechecker(graph);1115 auto ret = parser.Prechecker(graph);
1115- EXPECT_NE(ret, SUCCESS);1116+ EXPECT_EQ(ret, SUCCESS);
1117+ EXPECT_TRUE(parser.HasError());
1116}1118}
1117 1119 
1118// ======================== AdapterOpType tests ========================1120// ======================== AdapterOpType tests ========================