Model visualisation not coherent with mermaid graphs, wrong inputs/outputs connections
Modules
Modules used: aidge_core, aidge_onnx, aidge_quantization and aidge_model_explorer
Every module was fetche, pulled and compiled the 16/07/2025 from dev
Problem description
When using the the aidge_model_explorer.visualize() the model seen is coompletely different from what is expected. the model.save() function to save to mermaid format was used to see coherence of the graph forms and there were big differenes.
My code may have issues building the model but mermaid and model_explorer different outputs is the main issue.
Reproducible example code
The following code is used with the following original model: bug_test_model_1_conv.onnx
This model is a simple padded convolution without bias so it is possible to just recreate the model if needed.
import numpy as np
import aidge_core
import aidge_onnx
import aidge_quantization
import aidge_model_explorer
MODEL_PATH = "/path/to/my/model.onnx"
# Put path if mermaid model is desired
MERMAID_PATH = None #"/path/to/save/mermaid_graph"
def addQuantizeInput(qgraph, first_node, backend = "cpu"):
"""Add a quantizer node at the input of the graph. Forced to quantize in int8
"""
#simplified for test function
scale = 127
mul_op = aidge_core.Mul(name="in_scaling")
sacling_prod = aidge_core.Producer(aidge_core.Tensor(scale), "in_scale_factor")
min_prod = aidge_core.Producer(aidge_core.Tensor(np.array(-128, dtype=np.float32)), "in_min")
max_prod = aidge_core.Producer(aidge_core.Tensor(np.array(127, dtype=np.float32)), "in_max")
round_op = aidge_core.Round(name="in_round")
clip_op = aidge_core.Clip(name="in_clip")
cast_op = aidge_core.Cast(aidge_core.dtype.int8, name="in_cast")
x = aidge_core.Connector()
s = aidge_core.Connector(sacling_prod)
min_c = aidge_core.Connector(min_prod)
max_c = aidge_core.Connector(max_prod)
micro_graph = aidge_core.generate_graph([cast_op(clip_op(round_op(mul_op(x, s)), min_c, max_c))])
mul_op.get_operator().set_datatype(aidge_core.dtype.float32)
round_op.get_operator().set_datatype(aidge_core.dtype.float32)
clip_op.get_operator().set_datatype(aidge_core.dtype.float32)
micro_graph.set_backend(backend)
qlin_op = aidge_core.meta_operator(
"Quantizer",
micro_graph,
name="qlin_in"
)
qlin_op.get_operator().set_datatype(aidge_core.dtype.float32)
qlin_op.add_child(first_node, 0, 0)
qgraph.add(qlin_op)
model = aidge_onnx.load_onnx(MODEL_PATH)
#random data for the quantization process
arrays_list = list(np.array([[[[[0.51, 0.48, 0.33, 0.20, 0.19],
[0.60, 0.27, 0.386, 0.275, 0.321],
[0.173, 0.29, 0.22, 0.906, 0.128],
[0.113, 0.445, 0.272, 0.161, 0.347],
[0.269, 0.458, 0.400, 0.372, 0.379]]]],
[[[[0.661, 0.386, 0.241, 0.100, 0.60061],
[0.482, 0.312, 0.209, 0.906, 0.142],
[0.107, 0.373, 0.343, 0.240, 0.3531],
[0.284, 0.379, 0.413, 0.421, 0.407],
[0.551, 0.365, 0.306, 0.145, 0.398]]]],
[[[[0.538, 0.125, 0.200, 0.919, 0.152],
[0.097, 0.311, 0.370, 0.331, 0.325],
[0.293, 0.496, 0.261, 0.398, 0.376],
[0.514, 0.324, 0.391, 0.130, 0.162],
[0.242, 0.267, 0.190, 0.879, 0.164]]]],
[[[[0.115, 0.300, 0.438, 0.345, 0.326],
[0.528, 0.354, 0.416, 0.239, 0.348],
[0.678, 0.330, 0.243, 0.415, 0.103],
[0.561, 0.189, 0.180, 0.854, 0.178],
[0.110, 0.327, 0.401, 0.361, 0.343]]]]]))
#to aidge_tensors
tensors = []
for array in arrays_list:
tensor = aidge_core.Tensor(array)
tensor.set_backend("cpu")
tensor.set_datatype(aidge_core.dtype.float32)
tensors.append(tensor)
# aidge_model_explorer.visualize(model,"before_quant_graph")
# 8 bit fake quantization
aidge_quantization.quantize_network(
model,
8,
tensors,
target_type = aidge_core.dtype.float32,
clipping_mode = aidge_quantization.Clipping.MSE,
no_quant = False,
optimize_signs = False,
single_shift = False,
use_cuda = False,
verbose = True,
fold_graph = False)
# get the first node
first_node = model.get_ordered_inputs()[0][0]
print(f"first node is {first_node.name} of type {first_node.type()}")
addQuantizeInput(model, first_node)
if MERMAID_PATH is not None:
model.save(MERMAID_PATH)
aidge_model_explorer.visualize(model,"test_graph")