PFCCLab / netron

Visualizer for neural network, deep learning and machine learning models
https://netron.app
MIT License
0 stars 0 forks source link

【Hackathon 7th】Netron 原生支持 Paddle PIR 可视化 #1

Open megemini opened 1 week ago

megemini commented 1 week ago

本 ISSUE 用于跟踪 Netron 原生支持 Paddle PIR 可视化的相关问题 ~

关联:https://github.com/PaddlePaddle/community/blob/master/hackathon/hackathon_7th/%E3%80%90Hackathon%207th%E3%80%91FundableProject%E4%BB%BB%E5%8A%A1%E5%90%88%E9%9B%86.md#%E5%85%ABnetron-%E5%8E%9F%E7%94%9F%E6%94%AF%E6%8C%81-paddle-pir-%E5%8F%AF%E8%A7%86%E5%8C%96

Update 20241113

已测试如下模型:

for_net.json

image

图中的 while 子图 block_1

image

if_net.json

image

图中的 if 子图 block_1

image

if 子图 block_2

image

model.json

image

model_pylayer.json

image

图中的 pylayer 子图

image

while_net.json

image

图中的 while 子图

image

另外,tensor 边的映射如下

image


目前需要确认的问题:

  1. 子图的显示方案

    netron 显示子图的方案如上图所示,是单独开一个窗口。VisualDL 如何显示的,可以在评论区贴一下 ~

    至少需要覆盖以下几种情况:

    • 只有一个子图
    • 多个子图
    • 即有 attr 也有子图
    • 子图中还可以有子图

    不过,具体采用哪种方案,得说服 netron 作者 ... ...

  2. op 和属性的映射

    目前,save 时会压缩,有一些 op 会用简写,如 p ,相应的属性也没有名字,这里暂时以 idx 作为 name。

    可以提供一下需要映射的字段做适配 ~

  3. json 中有一些字段在 netron 中没有合适的映射位值,如 OA DA ,这里没有做适配。

  4. tensor 边在做映射时,只考虑 t_dtensor 这一种情况,与 netron 中其他框架保持一致。

  5. "ModuleOp" 是个啥?json 中找不到 ... ...

  6. 可以再贴一些需要验证的 json 模型 ~

  7. 目前只有 json 模型文件,是否还需要参数文件?

  8. 目前 netron 的子图中只能读取一个 graph,但是 json 模型还是用的 blocks 的形式,所以,目前的解决方法是只显示region 中第一个 block

请各位大佬看看还有啥遗漏或者建议?

p.s. netron 的 repo 好像只有一个 PR 被合入,这个做为潜在风险吧 ... ...

@luotao1

megemini commented 1 week ago

@luotao1 帮忙拉一下各位大佬吧 ~ 🙏🙏🙏

wanghuancoder commented 1 week ago

关于现有case的截图,我的一些观点:

  1. for_net.json中主图while的input、output在子图中没有体现。且子图sacle的input中存在-1。需要追查修复。
  2. if_net.json中,同样存在主图while的input、output在子图中没有体现。且子图sacle的input中存在1,而主图中1并不是if的input。需要追查修复。
  3. model_pylayer.json中,存在主图pylayer的output在子图总没有映射体现的情况。
  4. while_net.json中主图while的input、output在子图中没有体现。且子图sacle的input中存在-2。需要追查修复。
  5. tensor 边的映射,type中包含name和tensor,我觉得也没有问题。我们把dtype、shape、layout等meta信息直接全都展现在tensor中效果还挺好的。
  6. 但是目前tensor都是以12345命名的,能看一下参数的命名效果吗?参数命名应该类似于model.linear.w。
wanghuancoder commented 1 week ago

关于子图的显示方案: 毋庸置疑,肯定是VisualDL的显示方案更友好。我们可以如下处理:

  1. 先把别的能力支持善,主图、子图一起显示单独一个PR来支持。
  2. 给netron提的PR包含两部分解耦:1)netron能力扩展,一方面不影响其它框架的正常展示,另一方面客供其它框架调用使用。2)Paddle调用新扩展的netron能力,同时展示主图、子图。 VisualDL的效果图如下: Image

实现原理请 @changeyoung98 志扬介绍一下?

wanghuancoder commented 1 week ago
  1. tensor 边在做映射时,只考虑 t_dtensor 这一种情况,与 netron 中其他框架保持一致。

我觉得可以把咱们Tensor的所有meta信息集中放在t_dtensor中展示。我回答的与你提问的是一个事情吧?

wanghuancoder commented 1 week ago
  1. 目前只有 json 模型文件,是否还需要参数文件? 不需要参数文件,参数文件的内容都是参数的具体数值。数值不需要再netron中展示。我们只要将graph的节点、边的关系细心展示充分,展示友好即可。
wanghuancoder commented 1 week ago

6.可以再贴一些需要验证的 json 模型 ~

这个PR下的单测,辛苦顺师傅自己来操作一下,保存成模型文件,验证一下。同时,单测是可以在VisualDL中展示的。可以将两面的截图发出来,咱们看看。 https://github.com/PaddlePaddle/VisualDL/pull/1279/files

同时,原来提供的5个模型文件,也可以用VisualDL展示。这样可以两面对比,取优点。

changeyoung98 commented 1 week ago

https://github.com/PaddlePaddle/community/blob/538bdc4ae021f4536c4abb6a485b3bdd77279c9c/pfcc/paddle-code-reading/IR_Dialect/pir_save_load.md#L4 这里是PIR save/load的说明文档,一些缩略符对照以及json解析在文档中有说明。

changeyoung98 commented 1 week ago

关于子图的显示方案: 毋庸置疑,肯定是VisualDL的显示方案更友好。我们可以如下处理:

  1. 先把别的能力支持善,主图、子图一起显示单独一个PR来支持。
  2. 给netron提的PR包含两部分解耦:1)netron能力扩展,一方面不影响其它框架的正常展示,另一方面客供其它框架调用使用。2)Paddle调用新扩展的netron能力,同时展示主图、子图。 VisualDL的效果图如下: Image

实现原理请 @changeyoung98 志扬介绍一下?

这里实现的核心在于绘制子图时保留下子图与父block的关系。可以参考visualdl适配同学的PR和设计文档:https://github.com/PaddlePaddle/VisualDL/pull/1279

wanghuancoder commented 1 week ago

顺师傅,这是老的pdmodel的Netron的展示截图,有两点咱们需要跟他保持一致:

  1. 参数需要在节点的白色框框中展示出来
  2. 边展示的是Tensor的shape。如果可以咱们可以做成name+shape。因为我刚才看模型,第一关心的还真不是名字,而是shape

Image

megemini commented 1 week ago
  1. for_net.json中主图while的input、output在子图中没有体现。且子图sacle的input中存在-1。需要追查修复。

原因是:while中的regions里面没有使用while的input、output,所以没有体现。可以搜一下在netron附上的那个for_net.json文件 ~

如果手动给子图里面加上主图中的输入,netron会把他写在sidebar的信息中,如:

Image

这里的输入 16 是通过手动修改json文件得到的。

子图sacle的input中存在-1

因为json中就是 -1 。请核对json文件 ~

  1. if_net.json中,同样存在主图while的input、output在子图中没有体现。且子图sacle的input中存在1,而主图中1并不是if的input。需要追查修复。

同上 ~

  1. model_pylayer.json中,存在主图pylayer的output在子图总没有映射体现的情况。

同上 ~

  1. while_net.json中主图while的input、output在子图中没有体现。且子图sacle的input中存在-2。需要追查修复。

同上 ~

  1. tensor 边的映射,type中包含name和tensor,我觉得也没有问题。我们把dtype、shape、layout等meta信息直接全都展现在tensor中效果还挺好的。

👍️

  1. 但是目前tensor都是以12345命名的,能看一下参数的命名效果吗?参数命名应该类似于model.linear.w。

json中没有的信息,这里没办法处理 ... .....

megemini commented 1 week ago

顺师傅,这是老的pdmodel的Netron的展示截图,有两点咱们需要跟他保持一致:

  1. 参数需要在节点的白色框框中展示出来
  2. 边展示的是Tensor的shape。如果可以咱们可以做成name+shape。因为我刚才看模型,第一关心的还真不是名字,而是shape

同样的,json中没有的信息,没办法处理 ... ... 请确认json中是否有这些信息?哪些字段表示这些信息?

另外,图中 显示的是 name 而不是 shape ~ 请确认一下你那边这样显示的时候,netron是什么版本?

megemini commented 1 week ago

https://github.com/PaddlePaddle/community/blob/538bdc4ae021f4536c4abb6a485b3bdd77279c9c/pfcc/paddle-code-reading/IR_Dialect/pir_save_load.md#L4 这里是PIR save/load的说明文档,一些缩略符对照以及json解析在文档中有说明。

嗯嗯,一直参考的这个文档 ~ 其实呢,有些猜一下也是能猜出来,不过,最好能给出一个 映射表 的东西,如何?

目前能想到需要映射的:

megemini commented 1 week ago

今天翻了一下 netron 和 visualdl 的代码,基本定位到了 子图 的显示问题,结论:

可以参考 https://github.com/lutzroeder/netron/issues/1118

其中提到的 dagre cluster 可以参考 https://dagrejs.github.io/project/dagre-d3/latest/demo/clusters.html

netron 在 4c28783fd00b6de32bb6b08280028d21232c8e2d 这个 commit 已经把 var dagre = dagre || require('dagre');view.js 中删掉了 ~ 日期是 2021年4月29日 ~

visualdl 中的 netron 好像是 2.2.1 版本的(netron 现在是 8.0.0 版本),参考 VisualDL/frontend/packages/netron2/package.json ~ 即便不是,其中的 netron 版本也很老了,具体实现逻辑的参考性已经不大了 ~

另外,子图这个东西,不只是 if 等逻辑中有,有些框架的 function 也可以嵌套,visualdl 主要关注 paddle 就可以,而 netron 兼容的框架就多了 ... ...

目前,其他框架的子图在 netron 中都是以单独窗口的方式展示,比如

Image

Image

有的框架中,function 也可以进入子图,如

Image

而 visualdl 进入子图的入口,即右上角这个地方,有可能,就是复用 netron 之前在这里设置的入口 ~

综上,子图的显示方式哪个更好 这个问题,我觉得,咱们在这里讨论的意义不大,可以跟 netron 作者再确认一下 ~ 但是,让他再改回去,感觉短时间内不太可能 ... ...

这里叠个甲:最终的解释权,归 netron 作者所有 ~~~ 🤣🤣🤣 (毕竟我接触 netron 代码也就不到一周的时间,不可能把他的整个历史扒出来 🫣🫣🫣

megemini commented 1 week ago

VisualDL 今天安装了一天,装不了

lerna ERR! yarn run build exited 1 in '@visualdl/netron2'
lerna WARN complete Waiting for 3 child processes to exit. CTRL-C to exit immediately.
Traceback (most recent call last):
  File "setup.py", line 66, in <module>
    setup(
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/__init__.py", line 117, in setup
    return distutils.core.setup(**attrs)
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 183, in setup
    return run_commands(dist)
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 199, in run_commands
    dist.run_commands()
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 954, in run_commands
    self.run_command(cmd)
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/dist.py", line 999, in run_command
    super().run_command(command)
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 973, in run_command
    cmd_obj.run()
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/command/bdist_wheel.py", line 410, in run
    self.run_command("build")
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/cmd.py", line 316, in run_command
    self.distribution.run_command(command)
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/dist.py", line 999, in run_command
    super().run_command(command)
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 973, in run_command
    cmd_obj.run()
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/command/build.py", line 135, in run
    self.run_command(cmd_name)
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/cmd.py", line 316, in run_command
    self.distribution.run_command(command)
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/dist.py", line 999, in run_command
    super().run_command(command)
  File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 973, in run_command
    cmd_obj.run()
  File "setup.py", line 58, in run
    subprocess.check_call(cmd, env=env)
  File "/usr/lib/python3.8/subprocess.py", line 364, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['bash', 'scripts/build.sh']' returned non-zero exit status 1.

AIStudio 中也装不了 ~

因此,无法验证比对~

megemini commented 1 week ago

Update 20241114

总结一下今天的问题:

感谢各位 ~~~ 🫡🫡🫡

changeyoung98 commented 1 week ago

https://github.com/PaddlePaddle/community/blob/538bdc4ae021f4536c4abb6a485b3bdd77279c9c/pfcc/paddle-code-reading/IR_Dialect/pir_save_load.md#L4 这里是PIR save/load的说明文档,一些缩略符对照以及json解析在文档中有说明。

嗯嗯,一直参考的这个文档 ~ 其实呢,有些猜一下也是能猜出来,不过,最好能给出一个 映射表 的东西,如何?

目前能想到需要映射的:

  • op 名称,如 p
  • 参数名称,目前是用的 idx
op name除parameterOp做了特殊压缩外,其余均只压缩了dialect_name,即: pbuiltin.parameter i.xxxdialect_name.xxx 其中dialect_name压缩映射表在文档中有,这里加上具体的值再贴一下: code key value
pir::BuiltinDialect::name() builtin “0”
paddle::dialect::OperatorDialect::name() pd_op “1”
pir::ControlFlowDialect::name() cf “2”
paddle::dialect::CustomOpDialect::name() custom_op “3”
paddle::dialect::DistDialect::name() pd_dist “4”

其余一些压缩符号的定义都在schema.h中,另外参数名称在parameterOp(id为"p"的op)的Attribute("A")中有体现,attribute列表中第四个位置为参数名。

p.s. 序列化和反序列化的代码在paddle/fluid/pir/serialize_deserialize 目录下,建议同学可以参照代码和文档一起阅读。

changeyoung98 commented 1 week ago

VisualDL 今天安装了一天,装不了

lerna ERR! yarn run build exited 1 in '@visualdl/netron2' lerna WARN complete Waiting for 3 child processes to exit. CTRL-C to exit immediately. Traceback (most recent call last): File "setup.py", line 66, in setup( File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/init.py", line 117, in setup return distutils.core.setup(**attrs) File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 183, in setup return run_commands(dist) File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 199, in run_commands dist.run_commands() File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 954, in run_commands self.run_command(cmd) File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/dist.py", line 999, in run_command super().run_command(command) File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 973, in run_command cmd_obj.run() File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/command/bdist_wheel.py", line 410, in run self.run_command("build") File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/cmd.py", line 316, in run_command self.distribution.run_command(command) File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/dist.py", line 999, in run_command super().run_command(command) File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 973, in run_command cmd_obj.run() File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/command/build.py", line 135, in run self.run_command(cmd_name) File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/cmd.py", line 316, in run_command self.distribution.run_command(command) File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/dist.py", line 999, in run_command super().run_command(command) File "/home/shun/venv38dev/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 973, in run_command cmd_obj.run() File "setup.py", line 58, in run subprocess.check_call(cmd, env=env) File "/usr/lib/python3.8/subprocess.py", line 364, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['bash', 'scripts/build.sh']' returned non-zero exit status 1. AIStudio 中也装不了 ~

因此,无法验证比对~

源码编译安装可以试一下python3.9以上的版本,或者直接用pip install visualdl==3.0.0b0安装

changeyoung98 commented 1 week ago

顺师傅,这是老的pdmodel的Netron的展示截图,有两点咱们需要跟他保持一致:

  1. 参数需要在节点的白色框框中展示出来
  2. 边展示的是Tensor的shape。如果可以咱们可以做成name+shape。因为我刚才看模型,第一关心的还真不是名字,而是shape

同样的,json中没有的信息,没办法处理 ... ... 请确认json中是否有这些信息?哪些字段表示这些信息?

另外,图中 显示的是 name 而不是 shape ~ 请确认一下你那边这样显示的时候,netron是什么版本?

ParameterOp和DataOp创建的value都是有name的,在属性中都有存储,这类“输入信息”建议标识name+shape,其余在网络中的value没有name,只需标识shape即可。目前json中每个op存储的输入输出value是用数值进行标识的,其中输入”I“只有数值标识,只是为了对应value的来源,而输出”O“ 有tensor的属性信息。

megemini commented 1 week ago

ParameterOp和DataOp创建的value都是有name的,在属性中都有存储,这类“输入信息”建议标识name+shape,其余在网络中的value没有name,只需标识shape即可。目前json中每个op存储的输入输出value是用数值进行标识的,其中输入”I“只有数值标识,只是为了对应value的来源,而输出”O“ 有tensor的属性信息。

举个例子哈:

{
                    "#": "p",
                    "A": [0, 1, 1, "linear_0.b_0"],
                    "DA": [],
                    "O": {
                        "%": 1,
                        "TT": {
                            "#": "0.t_dtensor",
                            "D": [{
                                    "#": "0.t_f32"
                                },
                                [20], "NCHW", [], 0
                            ]
                        }
                    },
                    "OA": [1, 0, 1],
                    "QA": []
                }

这里的:

O 是输出,已经做了处理 ~ OA 貌似没有比较好的地方放置 ... ...

其他的 opi.xxx 则只保留后面 xxx 的地方,与之前 paddle 的算子保持一致 ~

如何?

另外,这类“输入信息”建议标识name+shape,其余在网络中的value没有name,只需标识shape即可 是指在哪里标识?

megemini commented 1 week ago

Update 20241117

目前我这里还有一个问题:输入输出中 -1 -2 是什么?是不是 json 模型有问题?

以下为最新的截图

Image Image Image Image Image Image Image

wanghuancoder commented 1 week ago

另外,图中 显示的是 name 而不是 shape ~ 请确认一下你那边这样显示的时候,netron是什么版本?

我直接在官网https://netron.app/,打开老静态图的模型文件就是这样。

wanghuancoder commented 1 week ago
  1. 子图显示遵循Netron现有规则,分开展示即可
  2. 子图与主图的对应关系存在两个问题: 2.1 主图给子图的input,不能在子图内显示边,只能在某个节点的input中看到。不够友好。能否加一个边的显示展示? 2.2 有些负数名字是如何产生的? 2.3 子图给主图的output,需要显示展示边 2.4 这里有些Json缺失的信息,应该是可以“推断”补充的。麻烦 @changeyoung98 介绍介绍。
  3. 参数(边)名称的展示:参数在PIR中以DataOp、ParameterOp“喂”进来。因此DataOp、ParameterOp有参数的name、shape信息,这些信息存储在Op的attr中。需要“传递”给output。DataOp、ParameterOp的output(边)以name+shape展示,及参数以name+shape展示
  4. 临时变量(边)名称的展示:除了DataOp、ParameterOp的其它OP的output可以认为是临时变量。临时变量已shape展示
  5. model.json中,place有些地方展示为0,0,“”,这个与期望的place好像不太一样。 @changeyoung98 咱们Json里怎么表达Place的?有翻译方法吗?
  6. model.json中,data的output: 6.1 name应该为generated_tensor_0 6.2 tensor:float32[20,20],应该拆解为:dtype:float32 shape:[20,20] 6.3 应该将op的place信息,“传递给”output
  7. model.json中,边2: 7.1 name应该为linear_0.w_0 7.2 tensor:float32[20,20],应该拆解为:dtype:float32 shape:[20,20] 7.3 边上的展示信息应该为linear_0.w_0,[20,20]
megemini commented 6 days ago

另外,图中 显示的是 name 而不是 shape ~ 请确认一下你那边这样显示的时候,netron是什么版本?

我直接在官网https://netron.app/,打开老静态图的模型文件就是这样。

闹乌龙了 ~ 原来 netron 在界面上可以选择显示 name 还是 shape ~~~ 我把实现方式改回去吧,改成 netron 原来的这种方式

Image Image