OpenVINO匹配器用Or匹配最后层Add/Relu始终返回Add问题求助
OpenVINO模式匹配中Or节点优先匹配Add的问题解决
你遇到的问题是因为原模式中Or包含的两个模式存在重叠依赖:relu模式的输入是add节点,而add本身又是Or中的一个独立模式。当模型最后是Relu时,add节点依然存在,OpenVINO的匹配器会优先匹配更简单、无依赖的add模式,而非包含它的relu模式。
修复方案
需要将两种情况定义为独立的完整模式,避免重叠:
// 模式1:最后一层是Add(直接匹配Add节点及其输入) auto add_pattern = pattern::wrap_type<opset6::Add>({ mulLeft, sub }); // 模式2:最后一层是Relu,且Relu的输入是Add(完整的链式模式) auto relu_pattern = pattern::wrap_type<opset6::Relu>( { pattern::wrap_type<opset6::Add>({ mulLeft, sub }) } ); // 用Or组合两个独立的完整模式 auto relu_or_add = std::make_shared<pattern::op::Or>(OutputVector{ relu_pattern, add_pattern });
替换逻辑调整
在匹配回调函数中,需要根据匹配到的根节点类型区分处理:
bool replace_callback(pattern::Matcher& matcher) { auto root_node = matcher.get_match_root(); // 处理Relu结尾的情况 if (auto relu_node = ov::as_type<opset6::Relu>(root_node)) { auto add_node = ov::as_type<opset6::Add>(relu_node->input_value(0).get_node_shared_ptr()); // 执行你的替换逻辑,例如创建新节点并替换Relu auto new_op = ...; // 根据需求构造替换后的节点 ov::replace_node(relu_node, new_op); } // 处理Add结尾的情况 else if (auto add_node = ov::as_type<opset6::Add>(root_node)) { auto new_op = ...; // 根据需求构造替换后的节点 ov::replace_node(add_node, new_op); } return true; }
关键说明
- 独立模式确保匹配器不会优先匹配子节点:两种模式是完全互斥的,不存在包含关系,匹配器会根据模型结构匹配对应的完整路径。
- 根节点判断:通过
ov::as_type判断匹配到的根节点是Relu还是Add,再执行对应的替换逻辑。
内容的提问来源于stack exchange,提问作者CMouse
相关产品推荐
相关产品推荐

