diff --git a/readme.md b/readme.md index 4ccb0d7..b44f2e3 100644 --- a/readme.md +++ b/readme.md @@ -14,13 +14,13 @@ Then `onnx-modifier` comes. With it, we can focus on editing the model graph in Currently, the following editing operations are supported: -- Delete/recover nodes +- [x] Delete/recover nodes - Delete a single node. - Delete a node and all the nodes rooted on it. - Recover a deleted node. -- Rename the name of node inputs/outputs -- Edit the attribute of nodes -- Add new nodes (experimental) +- [x] Rename the name of node inputs/outputs +- [x] Edit the attribute of nodes +- [x] Add new nodes (experimental) Hope it helps! @@ -48,7 +48,7 @@ Click the url in the output info generated by flask (`http://127.0.0.1:5000/` fo Click `Open Model...` to upload the ONNX model to edit. The model will be parsed and shown on the page. # Usage -Graph-level-operation elements are placed on the left-top of the page. Currently, there are four buttons: `Preview`, `Reset`, `Download` and `Add node`. They can do: +Graph-level-operation elements are placed on the left-top of the page. Currently, there are four buttons: `Refresh`, `Reset`, `Download` and `Add node`. They can do: - `Refresh`: Refresh the model graph to preview editing effects. > In this version, the model graph is refreshed automatically as soon as an editing operation is invoked. So this button can be used much fewer than earlier versions. @@ -83,7 +83,7 @@ For example, Now we want remove the preprocess operators (`Sub->Mul->Sub->Trans 2. The model graph is updated automatically and we can see the input node links to the 1st `Conv`directly. In addition, the preprocess operators have been split from the main routine. Delete them. 3. We are done! (click `Download`, then we can get the modified ONNX model). -> Note: To link node $A$ (`data_0` in the above example) to node $B$ (the 1st `Conv` in the above example), **it is suggested to edit the input of node $B$ to the output of node `A`, rather than edit the output of node $A$ to the input of node `B`.** Because the input of $B$ can also be other node's output and unexpected result will happen. +> Note: To link node $A$ (`data_0` in the above example) to node $B$ (the 1st `Conv` in the above example), **it is suggested to edit the input of node $B$ to the output of node `A`, rather than edit the output of node $A$ to the input of node `B`.** Because the input of $B$ can also be other node's output (`Transpose` in the above example ) and unexpected result will happen. The process is shown in the following figure: @@ -93,15 +93,21 @@ The process is shown in the following figure: Change the original attribute to a new value, then we are done. +> By clicking the `+` in the right side of placeholder, we can get some helpful reference. + ## Add new node -Sometimes we want to add new nodes into the exsited model. `onnx-modifier` supports this feature experimentally now. +Sometimes we want to add new nodes into the existed model. `onnx-modifier` supports this feature experimentally now. Note there is an `Add node` button, following with a selector elements on the top-left of the index page. To do this, what we need to do is as easy as 3 steps: 1. Choose a node type in the selector, and click `Add node` button. Then an empty node of the chosen type will emerge on the graph. + + > The selector contains all the supported operator types in domains of `ai.onnx`(171), `ai.onnx.preview.training`(4), `ai.onnx.ml`(18) and `com.microsoft`(1). + 2. Click the new node and edit it in the invoked siderbar. What we need to fill are the node Attributes (`undefined` by default) and its Inputs/Outputs (which decide where the node will be inserted in the graph). + 3. We are done. @@ -120,7 +126,7 @@ The following are some notes for this feature: 6. For the `Inputs/Outputs` with type `list`, it is forced to be at most 8 elements in the current version. If the actual inputs/outputs number is less than 8, we can leave the unused items with the name starting with `list_custom`, and they will be automatically omitted. -7. This feature is experimentally supported now and may be not very rebust. So any issues are warmly welcomed if some unexpected result is encountered. +7. This feature is experimentally supported now and may be not very robust. So any issues are warmly welcomed if some unexpected result is encountered. # Sample models diff --git a/readme_zh-CN.md b/readme_zh-CN.md index 4846eb3..7139e4b 100644 --- a/readme_zh-CN.md +++ b/readme_zh-CN.md @@ -4,13 +4,24 @@ `ONNX`(Open Neural Network Exchange) 是一种针对机器学习所设计的开放式的文件格式,经常作为不同框架模型转化的中间文件。有时我们拿到ONNX文件,想将它进行一些修改,比如: -- **删除部分节点**。 比如,`ONNX`文件中一些前后处理的算子节点。 -- **增加节点**。 -- **修改节点属性**。 比如修改某一节点的输入输出名称。 +- **删除部分节点**。 比如,`ONNX`文件中一些前后处理的算子节点,以方便后续部署。 +- **修改节点输入输出名**。 比如修改某一节点的输入输出名称,更改模型拓扑结构。 +- **编辑节点属性值**。 +- **增加新节点**。 -目前常用的方法是,先可视化模型图结构,然后基于`ONNX`的Python API编写脚本,对模型图结构进行编辑。但这可能需要我们在可视化-脚本-可视化-...之间反复横跳。而且在一张庞大的图上搜集想要修改的节点,也比较花时间。 +目前常用的方法是,先可视化模型图结构,然后基于`ONNX`的Python API编写脚本,对模型图结构进行编辑。但这可能需要我们在可视化-脚本-可视化-...之间反复横跳。而且在一张庞大的图上搜集想要修改的节点,也比较繁琐耗时。👋 -能不能有一个工具,可以**实时预览编辑后的可视化效果,从而更方便,快捷,直观地实现`ONNX`模型的编辑**呢?:rocket: 这便是`onnx-modifier` ([github]())开发的动机。所有的编辑信息将最终汇总,统一送由ONNX Python处理,得到编辑后的ONNX模型文件。 +能不能有一个工具,可以**实时预览编辑后的可视化效果,从而更方便,快捷,直观地实现`ONNX`模型的编辑**呢?:rocket: 这便是`onnx-modifier` ([github]())开发的动机。所有的编辑信息将最终汇总,统一送由ONNX Python API处理,得到编辑后的ONNX模型文件。 + +目前已支持下列操作: + +- [x] 删除/恢复节点 + - 删除单个节点 + - 删除一个节点及所有以该节点为根节点的子节点 + - 恢复误删的节点 +- [x] 修改节点输入输出名 +- [x] 编辑节点属性值 +- [x] 增加新节点(beta) `onnx-modifier`基于流行的模型可视化工具 [Netron](https://github.com/lutzroeder/netron) 和轻量级Web应用框架 [flask](https://github.com/pallets/flask) 开发。希望它能给社区带来一些贡献~ @@ -34,54 +45,91 @@ 点击输出中的url(如`http://127.0.0.1:5000/`),即可在浏览器中进入onnx-modifier界面。点击`Open Model...`,上传所需要编辑的模型文件,上传完毕后,网络可视化结构会自动显示。 -# 编辑 +# 用法 + - - - - - -
图结构层级操作
(界面左上角)
节点层级操作(节点属性栏)
+图结构层级的操作按钮放置在可视化页面的左上角,目前有四个:`Refresh`,`Reset`,`Download`和`Add node`. 它们的功能分别为: +- `Refresh`:刷新界面,预览当前编辑得到的模型图结构; + > 在当前版本里,模型图结构会在每次编辑操作后即时自动更新,无需手动刷新。所以该按钮用到的次数会比之前的版本里少上不少(解放双手:raised_hands:) -图结构层级的操作按钮放置在可视化页面的左上角,有三个:`Preview`,`Reset`和`Download`. 它们的功能分别为: +- `Reset`:重置模型图结构为导入时的初始状态; -- `Preview`:预览当前编辑得到的模型图结构; -- `Reset`:重置模型图结构为初始状态; - `Download`:保存编辑后的模型文件到本地。 -节点层级的操作都在节点属性栏里,点击某一节点后即可弹出,一起来康康。 +- `Add node`:向当前模型中,添加新节点。 + +节点层级的操作都在节点侧边栏里,点击某一节点后即可弹出。 + +一起来详细康康。 ## 删除节点 -删除节点有两种模式:`Delete With Children` 和 `Delete Single Node`. 后者只删除当前单个节点;而前者还会自动删除以这个节点为根节点的所有节点,就不用一个一个删除啦。 +删除节点有两种模式:`Delete With Children` 和 `Delete Single Node`. 后者只删除当前单个节点;而前者还会自动删除以这个节点为根节点的所有子节点,当我们需要删除一长串节点时,这个功能会比较有用。 + +> `Delete With Children`基于回溯算法实现。 + +执行删除操作后,被删除的节点首先会变灰显示,以供预览。如果某一个节点被误删了,在该节点的侧边栏点击`Recover Node`即可以将其恢复到图中。预览确认删除操作无误后,点击`Enter`,图结构会刷新,显示节点删除后的状态。 + +一个典型的删除操作如下图所示: + + + +## 修改节点输入输出名 + +通过修改节点的输出输出名,我们可以对模型拓扑结构进行修改(如删除一些预处理/后处理节点)。该功能同样可以用在更改模型的输出的名称(即修改模型叶子节点的输出名)。 + +那在`onnx-modifer`中要怎么做呢?很简单,找到节点侧边栏的输入输出对应的输入框,键入新的名称就可以啦。图结构会根据键入的名称即时自动刷新。 + +举个栗子,在下图所示的模型中,我们想要删除预处理对应的节点(`Sub->Mul->Sub->Transpose`),可以这样做: + +1. 点击第一个`Conv`节点,在弹出的属性栏中,将输入名称改为*serving_default_input:0* (`data_0`节点的输出名); +2. 图结构自动刷新,可以发现,输入节点已经和第一个`Conv`节点直接相连,几个预处理节点也已经从前向图中分离出来,将它们删除; +3. 完工(点击`Download`就可以获得编辑后的ONNX模型啦)。 + +> 如果我们希望通过修改,让节点$A$(比如上例中的`data_0`节点)连向节点$B$(比如上例中的第一个`Conv`节点),建议的方式是:将节点$B$的输入名称修改为节点$A$的输出名称,而不是把$A$的输出名称修改为节点$B$的输入名称。 因为节点$B$的输入名称可能同时为其他节点(比如上例中的`Transpose`节点)的输出名称,会导致一些预料外的结果。 + +上例的修改过程如下图所示: + + + +## 编辑节点属性值 + +在节点侧边栏对应的属性值输入框中,键入新的属性值即可。 -> `Delete With Children`方法基于回溯算法实现。 +> 点击属性值输入框右侧的`+`,可显示该属性的参考信息。 -被删除的节点会变灰显示。删除节点的效果如下: + - +## 增加新节点(beta) +有时候我们希望向模型中添加新节点。`onnx-modifier`已开始支持该功能。 +在主页面的左上方,有一个`Add node`按钮和一个selector选择器,我们可以通过这二者的配合,完成节点的添加,只需3步: -## 重置节点 +1. 在selector中选择要添加的节点类型,在点击`Add node`按钮后,一个对应类型的新节点将自动出现在图上。 -在节点对应的属性栏点击`Recover Node`按钮,可将被删除的节点重新恢复到图中。 + > selector中包含来自`ai.onnx`(171), `ai.onnx.preview.training`(4), `ai.onnx.ml`(18) 和 `com.microsoft`(1)的所有节点类型。 -## 修改节点输入输出名称 +2. 点击这个新节点,在弹出的侧边栏中进行节点的编辑: + - 节点属性:初始化为`null` (显示为`undefined`)。同上节,在对应的属性框中输入新值即可。 + - 修改节点输入输出名。输入输出名决定了节点将插入在图结构中的位置。 +3. 完工(点击`Download`即可获得编辑后的ONNX模型)。 -通过修改节点的输出输出名,我们可以对模型推理图进行修改(如删除一些预处理/后处理节点)。该功能同样可以用在更改模型的输出的名称(即修改模型叶子节点的输出名)。 + -那在`onnx-modifer`中要怎么做呢?在节点属性栏中有一个`RENAME HELPER`小节。当前节点的全部输入/输出名都会列在这里(不包含模型权重),每个输入/输出名后面跟着一个输入框,直接在对应的输入框中,键入新的名称就可以啦。 +以下是该功能的一些提醒和小tip: -比如,在下图所示的模型中,我们想要删除预处理对应的节点(`Sub->Mul->Sub->Transpose`),可以这样做: +1. 在当前版本中,是不支持添加含有参数的节点的(比如`Conv`, `BatchNormalization`)。其他大多数节点,在我的测试中,可正确添加(比如`Flatten`, `ArgMax`, `Concat`)。 +2. 点击selector,输入要添加的节点的首字母(比如`Flatten`的`f`),可帮我们定位到以该字母开头的节点列表区域,加快检索速度。 +3. 点击节点侧边栏的`NODE PROPERTIES`的`type`框右侧的`?`,和节点属性框右侧的`+`,可以显示关于当前节点类型/属性值的参考信息。 +4. 为确保正确性,节点的各属性值建议全部填写(而不是留着`undefined`)。默认值在当前版本可能支持得还不够好。 +5. 如果一个属性值是列表类型,则各元素之间使用‘`,`’分隔。 +6. 在当前版本中,如果一个节点的输入/输出是一个列表类型(如`Concat`),限制最多显示8个。如果一个节点实际输入/输出小于8个,则填写对应数目的输入输出即可,多出来的应以`list_custom`开头,它们会在后续处理中自动被忽略。 +7. 这个功能还处在开发中,可能会不够鲁棒。所以如果大家在实际使用时碰到问题,非常欢迎提issue! -1. 点击第一个`Conv`节点,在弹出的属性栏中,将输入名称改为*serving_default_input:0*; -2. 预览一下,发现输入已经和第一个`Conv`直接相连,几个预处理节点也已经从前向图中分离出来,将它们删除; -3. 完工,预览check一下(点击`Download`就可以获得编辑后的ONNX模型啦)。 -rename_node_io `onnx-modifer`正在活跃地更新中:hammer_and_wrench:。 欢迎使用,提issue,如果有帮助的话,感谢给个:star:~ @@ -100,6 +148,7 @@ - [Netron](https://github.com/lutzroeder/netron) - [flask](https://github.com/pallets/flask) +- ONNX IR [Official doc](https://github.com/onnx/onnx/blob/main/docs/IR.md) - ONNX Python API [Official doc](https://github.com/onnx/onnx/blob/main/docs/PythonAPIOverview.md), [Leimao's Blog](https://leimao.github.io/blog/ONNX-Python-API/) - ONNX IO Stream [Leimao's Blog](https://leimao.github.io/blog/ONNX-IO-Stream/) - [onnx-utils](https://github.com/saurabh-shandilya/onnx-utils)