MindSpore模型转换报错RuntimeError: Can not find key SiLU in convert nap. Exporting SiLU operator is not yet supported.

1 系统环境

硬件环境(Ascend/GPU/CPU): Ascend/GPU/CPU
MindSpore版本: mindspore=2.2.10
执行模式(PyNative/ Graph):不限
Python版本: Python=3.8
操作系统平台: linux

2 报错信息

2.1 问题描述

在用mindspore的如下脚本加载模型保存文件的时候,出现了如下报错。

2.2 脚本信息

ckpt_file = 'C:/Users/24305/PycharmProjects/yolov5_6/train/runs/2024.09.03-10.11.55/weights/yolov5s-6_8.ckpt'
param_dict = load_checkpoint(ckpt_file)
load_param_into_net(model, param_dict)

input_tensor = Tensor(np.ones([1, 3, 256, 256]).astype(np.float32))
ms.export(model, input_tensor, file_name='lenet', file_format='ONNX')
print("ONNX model exported successfully.")

2.3 报错信息

Traceback (most recent call last):
    File "C: \Users\24305\PycharmProjec1tslyolov5_6ltrainlonnx.py" , line 86, in <module>
        ms.export(model, input_tensor, file_name='lenet', f ile_format='ONNX')
    File "C:\Users\24305\.anacondalenvs\mindspore_py39_2.2.10\lib\site-packages\mindspore\trainlserialization.py", line 1659, in export
        Lexport(net, file_name, file_format, *inputs, ★*kwargs)
    File "C: \Users124305\.anacondalenvs\mindspore py39_2.2.10\lib\site-packages\mindsporeltra.inlserialization.py", line 1713, in _export
        _save_onnx(net, file_name, ★inputs, **kwargs)
    File "c: \users\24305\.anacondalenvslmindspore_py39_2.2.10\lib\site-packagesImindsporeltrainlserialization.py", line 1770, in _save_onnx
        onnx_stream = _executor.-get_func_graph_proto(net, graph_id)
    File "C: \Users\24305\.anaconda\envsAmindspore_py39_2.2.10\liblsite-packages\mindsporelcommonlapi.py", line 1667, in _get_func_graph_proto
        return self._graph_executor.get_func_graph_proto(exec_id, ir_type, incremental)
RuntimeError: Can not find key SiLU in convert nap. Exporting SiLU operator is not yet supported.

3 根因分析

上面报错是转换过程中无法转换SiLU算子
查看相关文档部署 - MindYOLO Docs

  1. 导出ONNX需要调整nn.SiLU算子,采用sigmoid算子底层实现
    例如:添加如下自定义层并替换mindyolo中所有的nn.SiLU
class EdgeSiLU(nn.Cell):  
    """  
    SiLU activation function: x * sigmoid(x). To support for onnx export with nn.SiLU.  
    """  
    
    def __init__(self):  
        super().__init__()  
    
    def construct(self, x):  
        return x * ops.sigmoid(x)

4 解决方案

此处需要修改mindyolo的代码实现
mindyolo/models/layers/conv.py
里面的nn.SiLU()
替换如下的实现

class EdgeSiLU(nn.Cell):  
    """  
    SiLU activation function: x * sigmoid(x). To support for onnx export with nn.SiLU.  
    """  
    
    def __init__(self):  
        super().__init__()  
    
    def construct(self, x):  
        return x * ops.sigmoid(x)