Skip to content

Commit 365d710

Browse files
tpu-mlir-vis-toolscharlesxzb
authored andcommitted
docs: add vis tool guidance
- put neuron vis tool in https://tpu-mlir-vis-tools.github.io/demo/#/neuron - add vis tool guidance in quick_start Change-Id: I9524a9eb69547c5cd2b271254e5880ca5a319cf5
1 parent 6344de2 commit 365d710

9 files changed

Lines changed: 176 additions & 4 deletions

File tree

67.2 KB
Loading
67.6 KB
Loading
700 KB
Loading
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
Appendix.07: Visualization Tool Guidance
2+
==================================
3+
This chapter mainly introduces the use of the visualization tool. Currently, a web-based online visualization tool is provided for LayerGroup-related visualizations (not covered here for now) and neuron space visualization. This tool supports functionalities such as inspecting peak neuron memory usage and analyzing tensor lifetimes.
4+
5+
Website: https://tpu-mlir-vis-tools.github.io/demo/#/neuron
6+
7+
This tool does not support addr_mode modes other than auto.
8+
9+
10+
Preparatory work
11+
------------------
12+
13+
**Environment configuration**
14+
15+
First you need to refer to :ref:`Environment Setup chapter <env setup>` to complete the environment configuration, enter the Docker container of TPU-MLIR, and install tpu_mlir in it.
16+
17+
If you have completed the environment configuration, you can ignore this step.
18+
19+
20+
**Generate final.mlir**
21+
22+
Before using tool, you need to generate the final.mlir file through TPU-MLIR, refer to :ref:`Compile the ONNX model chapter <onnx to bmodel>` to generate the bmodel file from the model.
23+
24+
You need to use the following two commands:
25+
26+
.. code-block:: shell
27+
28+
# Convert the ONNX model to top_mlir
29+
$ model_transform
30+
# Convert top_mlir to bmodel
31+
$ model_deploy
32+
33+
34+
Website usage
35+
------------------
36+
After opening the webpage, select your final.mlir file.
37+
38+
.. figure:: ../assets/navigator.png
39+
:align: center
40+
41+
The page will automatically parse the final.mlir file and generate two visualizations: a peak memory utilization chart and a memory allocation Gantt chart.
42+
43+
.. figure:: ../assets/neuron_vis.png
44+
:align: center
45+
46+
The first chart shows peak memory usage over time on the device. Since memory management on the device resembles an overwrite operation—only tracking allocations but not explicit deallocations—this chart primarily helps identify at which timestep the peak memory usage occurs. Hovering your mouse over the chart displays the current memory allocation details.
47+
48+
The second chart provides a more precise and granular view of memory allocation status. The horizontal axis represents timesteps, and the vertical axis represents memory addresses. It visualizes the start/end timesteps and start/end addresses of each memory block. Hover tooltips are supported, and horizontal mouse-wheel zooming is enabled.
49+
50+
During analysis, users typically identify the peak timestep from the first chart, then zoom into that region in the second chart to locate the tensors and their corresponding loc identifiers occupying memory at that timestep. These can then be cross-referenced with the final.mlir file to analyze tensor lifetimes and assess whether memory consumption is reasonable. Tensor lifetimes are determined by the model’s topology, while memory footprint is jointly determined by tensor shape and data type.
51+
52+
Below is a zoomed-in view of the Gantt chart around the peak region shown above:
53+
54+
.. figure:: ../assets/neuron_detail.png
55+
:align: center
56+
:height: 8cm
57+
58+
Below is the corresponding final.mlir snippet for the peak region shown above:
59+
60+
.. code-block:: text
61+
62+
%419 = "tpu.MatMul"(%415, %418, %0, %0, %0) {do_relu = false, dq_type = "NONE", fuse_rq = false, hdim_is_batch = false, input_zp = 0 : i64, is_lora = false, keep_dims = true, left_reuse = 1 : i64, left_transpose = false, multipliers = [1], output_transpose = false, q_group_size = 0 : i64, quant_mode = #tpu<rq_mode MultiplierShift>, relu_limit = -1.000000e+00 : f64, right_transpose = true, right_zp = 0 : i64, round_mode = #tpu<round_mode HalfAwayFromZero>, rshifts = [0]} : (tensor<1x4800x128xf32, 4788801536 : i64>, tensor<1x4800x128xf32, 4601942016 : i64>, none, none, none) -> tensor<1x4800x4800xf32, 4791259136 : i64> loc(#loc685)
63+
%420 = "tpu.MulConst"(%419) {const_val = 0.088388349161020605 : f64, do_relu = false, is_scalar = false, multiplier = 1 : si32, relu_limit = -1.000000e+00 : f64, rshift = 0 : si32} : (tensor<1x4800x4800xf32, 4791259136 : i64>) -> tensor<1x4800x4800xf32, 4601942016 : i64> loc(#loc686)
64+
%421 = "tpu.MulConst"(%411) {const_val = 0.088388349161020605 : f64, do_relu = false, is_scalar = false, multiplier = 1 : si32, relu_limit = -1.000000e+00 : f64, rshift = 0 : si32} : (tensor<1x60x80x60x80xf32, 4694102016 : i64>) -> tensor<1x60x80x60x80xf32, 4788801536 : i64> loc(#loc687)
65+
%422 = "tpu.Reshape"(%421) {flatten_start_dim = -1 : i64, shape = [1, 4800, 4800]} : (tensor<1x60x80x60x80xf32, 4788801536 : i64>) -> tensor<1x4800x4800xf32, 4788801536 : i64> loc(#loc688)
66+
%423 = "tpu.Softmax"(%422, %0, %0, %0, %0, %0) {axis = 2 : si32, beta = 1.000000e+00 : f64, log = false, round_mode = #tpu<round_mode HalfAwayFromZero>} : (tensor<1x4800x4800xf32, 4788801536 : i64>, none, none, none, none, none) -> tensor<1x4800x4800xf32, 4694102016 : i64> loc(#loc689)
67+
68+
As shown above, each line in mlir typically represents one operation (op). An op has input and output tensors, with the output tensor being defined on that line and subsequently used as an input to other operations in later lines. In addition to this information, the MLIR file includes a mapping table at the end that associates loc identifiers with original layer names(e.g., #loc686 = loc("/model/feature_flow_attn/Div_output_0_Div")). If users want to determine which part of the original model a given tensor corresponds to, they can look up the tensor's loc identifier in this table to find the corresponding layer name.
69+
70+
In the figure above, loc677 refers to a long-lived tensor defined earlier in the code and used as %411 to produce output %421 (i.e., loc687). Together, loc677, loc686, and loc687 (highlighted in blue) fully occupy memory during timesteps 301-302. Note that loc687 (the blue segment) overlaps spatially and temporally with the subsequent loc688. This occurs because reshape is an in-place operation—it reuses the same memory address for computation. Similar behaviors are also observed with operators like slice and concat.
71+
72+
In the following timesteps (303-304), memory is again fully occupied by loc688, loc689, and loc686. The extended lifetime of loc686 is due to its reuse as an input by later operations.
73+
74+
For more detailed analysis, you may examine the original ONNX model source to perform structural optimizations.
75+
76+
77+
78+
**Notes:**
79+
80+
Memory address allocation employs two strategies, and the better result from both is selected as the final allocation:
81+
82+
* firstFit: Scans forward from the starting address to find the first available space that fits.
83+
* opSizeOrder: Sorts tensors by size (largest first) and allocates larger tensors first.
84+
85+
Under firstFit, input tensors are allocated contiguously at the beginning of the address space, whereas under opSizeOrder, they may be scattered across different addresses.
86+

docs/quick_start/source_en/Appx.07_supported_ops.rst renamed to docs/quick_start/source_en/Appx.08_supported_ops.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Appendix.07: Supported Operations
1+
Appendix.08: Supported Operations
22
=================================
33

44
List of operators currently supported by TPU-MLIR

docs/quick_start/source_en/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ TPU-MLIR Quick Start
2626
Appx.04_modelzoo_test
2727
Appx.05_profile.rst
2828
Appx.06_debugger
29-
Appx.07_supported_ops
29+
Appx.07_vis_tools
30+
Appx.08_supported_ops
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
附录07:可视化工具使用指南
2+
==================================
3+
本章节主要介绍可视化工具的使用方法,目前提供了一个部署于在线网页的可视化工具,用于做LayerGroup相关可视化(暂不介绍)和neuron空间的可视化,可用于查看neuron的峰值占用和tensor的生存周期分析等功能。
4+
5+
网址:https://tpu-mlir-vis-tools.github.io/demo/#/neuron
6+
7+
此工具目前不支持,addr_mode除了auto之外的模式
8+
9+
准备工作
10+
------------------
11+
12+
**环境配置**
13+
14+
首先需要参考 :ref:`开发环境配置章节 <env setup>` 完成环境配置,进入TPU-MLIR的Docker容器,并在其中安装tpu_mlir。
15+
16+
若已完成环境配置可忽略此步骤。
17+
18+
19+
**生成final.mlir**
20+
21+
在使用可视化工具之前需要先通过TPU-MLIR生成final.mlir文件,可参考 :ref:`编译ONNX模型章节 <onnx to bmodel>` 中的命令从模型生成final.mlir文件,该文件为model_deploy过程的中间文件。
22+
23+
需要使用以下2个命令:
24+
25+
.. code-block:: shell
26+
27+
# 将ONNX模型转换为top_mlir
28+
$ model_transform
29+
# 将top_mlir转换为bmodel
30+
$ model_deploy
31+
32+
33+
页面使用方法
34+
------------------
35+
进入页面后选择final.mlir文件。
36+
37+
.. figure:: ../assets/navigator.png
38+
:align: center
39+
40+
页面会自动处理final.mlir文件并生成空间利用率峰值图和内存分配甘特图。
41+
42+
.. figure:: ../assets/neuron_vis.png
43+
:align: center
44+
45+
第一个图展示了设备上的空间峰值情况,由于设备上更贴近于是一个覆盖写的操作,仅管理内存分配,而不管理内存释放,因此该图的主要作用是关注峰值在哪个时间步产生,鼠标悬浮会展示当前的分配情况。
46+
47+
第二个图提供更准确、细致的内存分配状态,横轴为时间步,纵轴为内存地址,展示了每个内存块的起始结束时间步和起始结束地址,支持鼠标悬浮展示,同时该图支持横向的鼠标滚轮缩放。
48+
49+
使用过程中一般根据图一的峰值,到图二去缩放找到占用该时间步的tensor及其loc,对应到final.mlir中去分析tensor的生命周期以及占用大小是否合理。生命周期源自模型拓扑结构,tensor的占用大小由shape与数据类型共同决定。
50+
51+
以下为上图峰值区域甘特图缩放区域:
52+
53+
.. figure:: ../assets/neuron_detail.png
54+
:align: center
55+
:height: 8cm
56+
57+
以下为上图峰值区域对应的final.mlir片段
58+
59+
.. code-block:: text
60+
61+
%419 = "tpu.MatMul"(%415, %418, %0, %0, %0) {do_relu = false, dq_type = "NONE", fuse_rq = false, hdim_is_batch = false, input_zp = 0 : i64, is_lora = false, keep_dims = true, left_reuse = 1 : i64, left_transpose = false, multipliers = [1], output_transpose = false, q_group_size = 0 : i64, quant_mode = #tpu<rq_mode MultiplierShift>, relu_limit = -1.000000e+00 : f64, right_transpose = true, right_zp = 0 : i64, round_mode = #tpu<round_mode HalfAwayFromZero>, rshifts = [0]} : (tensor<1x4800x128xf32, 4788801536 : i64>, tensor<1x4800x128xf32, 4601942016 : i64>, none, none, none) -> tensor<1x4800x4800xf32, 4791259136 : i64> loc(#loc685)
62+
%420 = "tpu.MulConst"(%419) {const_val = 0.088388349161020605 : f64, do_relu = false, is_scalar = false, multiplier = 1 : si32, relu_limit = -1.000000e+00 : f64, rshift = 0 : si32} : (tensor<1x4800x4800xf32, 4791259136 : i64>) -> tensor<1x4800x4800xf32, 4601942016 : i64> loc(#loc686)
63+
%421 = "tpu.MulConst"(%411) {const_val = 0.088388349161020605 : f64, do_relu = false, is_scalar = false, multiplier = 1 : si32, relu_limit = -1.000000e+00 : f64, rshift = 0 : si32} : (tensor<1x60x80x60x80xf32, 4694102016 : i64>) -> tensor<1x60x80x60x80xf32, 4788801536 : i64> loc(#loc687)
64+
%422 = "tpu.Reshape"(%421) {flatten_start_dim = -1 : i64, shape = [1, 4800, 4800]} : (tensor<1x60x80x60x80xf32, 4788801536 : i64>) -> tensor<1x4800x4800xf32, 4788801536 : i64> loc(#loc688)
65+
%423 = "tpu.Softmax"(%422, %0, %0, %0, %0, %0) {axis = 2 : si32, beta = 1.000000e+00 : f64, log = false, round_mode = #tpu<round_mode HalfAwayFromZero>} : (tensor<1x4800x4800xf32, 4788801536 : i64>, none, none, none, none, none) -> tensor<1x4800x4800xf32, 4694102016 : i64> loc(#loc689)
66+
67+
如上所示,final.mlir中一行一般表示一个算子,算子有其输入输出tensor,输出tensor在该行被定义,在后续行中作为其他操作的输入。除了这些信息之外,mlir的尾部有loc和layer_name的对应表,例如#loc686 = loc("/model/feature_flow_attn/Div_output_0_Div")。用户如果想知道该tensor对应到原模型的哪一部分,可以根据tensor的loc,查找对应的layer_name。
68+
69+
在上图中,loc677为定义在代码段之前的一个长生命周期tensor,作为%411用于产生输出%421即loc687。loc677、loc686和loc687(蓝色区域)共同占满时间步301-302的内存空间。注意loc687为图中蓝色部分,与后续的loc688有时空上的重叠,这是由于是reshape是inplace算子,会在地址进行原地运算,类似的情况还有slice和concat。
70+
71+
同时后续时间步303-304被loc688、loc689和loc686也占满了内存空间,loc686的时间步较长是因为,其在后续还作为输入被其他算子所用到。
72+
73+
更具体的分析可以到onnx的源码中,做模型结构上的优化分析等。
74+
75+
76+
**注意:**
77+
78+
地址分配时有两种分配策略,取两种策略的最优作为最后的地址分配:
79+
80+
* firstFit:从起始地址往后扫描找到第一个可以放的空间
81+
* opSizeOrder:把tensor从大到小排序,优先分配大的
82+
83+
如果是firstFit输入会在起始地址统一分配,opSizeOrder则会分散到不同地址中。
84+

docs/quick_start/source_zh/Appx.07_supported_ops.rst renamed to docs/quick_start/source_zh/Appx.08_supported_ops.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
附录07:已支持的算子
1+
附录08:已支持的算子
22
====================
33

44
本章节主要提供目前TPU-MLIR支持的算子列表

docs/quick_start/source_zh/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ TPU-MLIR快速入门手册
2626
Appx.04_modelzoo_test
2727
Appx.05_profile
2828
Appx.06_debugger
29-
Appx.07_supported_ops
29+
Appx.07_vis_tools
30+
Appx.08_supported_ops

0 commit comments

Comments
 (0)