Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

TestNode.test_exports fails on macOS following "Implement ONNX export for gluon LSTM" #18596

Closed
leezu opened this issue Jun 20, 2020 · 1 comment · Fixed by #18601
Closed
Labels

Comments

@leezu
Copy link
Contributor

leezu commented Jun 20, 2020

2020-06-19T19:50:34.0061500Z =================================== FAILURES ===================================
2020-06-19T19:50:34.0062030Z ____________________________ TestNode.test_exports _____________________________
2020-06-19T19:50:34.0064350Z [gw3] darwin -- Python 3.6.10 /Users/runner/hostedtoolcache/Python/3.6.10/x64/bin/python3
2020-06-19T19:50:34.0064480Z 
2020-06-19T19:50:34.0064630Z self = <test_node.TestNode testMethod=test_exports>
2020-06-19T19:50:34.0064700Z 
2020-06-19T19:50:34.0064820Z     def test_exports(self):
2020-06-19T19:50:34.0064950Z         for test in export_test_cases:
2020-06-19T19:50:34.0065460Z             test_name, onnx_name, mx_op, input_shape, attrs = test
2020-06-19T19:50:34.0066030Z             input_sym = mx.sym.var('data')
2020-06-19T19:50:34.0066250Z             if isinstance(mx_op, type) and issubclass(mx_op, (mx.gluon.HybridBlock, mx.gluon.SymbolBlock)):
2020-06-19T19:50:34.0066520Z                 mx_op = mx_op(**attrs)
2020-06-19T19:50:34.0066850Z                 mx_op.initialize()
2020-06-19T19:50:34.0067320Z                 mx_op(mx.nd.zeros(input_shape))
2020-06-19T19:50:34.0068010Z                 params = {k: v.data() for k, v in mx_op.collect_params().items()}
2020-06-19T19:50:34.0068180Z                 outsym = mx_op(input_sym)
2020-06-19T19:50:34.0068290Z             else:
2020-06-19T19:50:34.0068530Z                 params = {}
2020-06-19T19:50:34.0068990Z                 outsym = mx_op(input_sym, **attrs)
2020-06-19T19:50:34.0069900Z             converted_model = onnx_mxnet.export_model(outsym, params, [input_shape], np.float32,
2020-06-19T19:50:34.0070070Z >                                                     onnx_file_path=outsym.name + ".onnx")
2020-06-19T19:50:34.0070150Z 
2020-06-19T19:50:34.0071070Z tests/python/unittest/onnx/test_node.py:132: 
2020-06-19T19:50:34.0071440Z _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
2020-06-19T19:50:34.0072310Z python/mxnet/contrib/onnx/mx2onnx/export_model.py:83: in export_model
2020-06-19T19:50:34.0072470Z     verbose=verbose)
2020-06-19T19:50:34.0073360Z _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
2020-06-19T19:50:34.0073490Z 
2020-06-19T19:50:34.0074400Z self = <mxnet.contrib.onnx.mx2onnx.export_onnx.MXNetGraph object at 0x1485d5240>
2020-06-19T19:50:34.0074560Z sym = <Symbol lstm12_rnn0>
2020-06-19T19:50:34.0075830Z params = {'l0_h2h_bias': 
2020-06-19T19:50:34.0076400Z [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
2020-06-19T19:50:34.0076980Z <NDArray 12 @cpu(0)>, 'l0_h2h_weight': 
2020-06-19T19:50:34.0077470Z [[-0.02334689 -0.006454...  0.03353088]
2020-06-19T19:50:34.0077600Z  [ 0.02073693  0.05509142]
2020-06-19T19:50:34.0078090Z  [-0.05902549 -0.02687716]
2020-06-19T19:50:34.0078570Z  [-0.00526763 -0.02571405]]
2020-06-19T19:50:34.0078750Z <NDArray 12x2 @cpu(0)>}
2020-06-19T19:50:34.0078880Z in_shape = [(3, 1, 2)], in_type = 1, verbose = False
2020-06-19T19:50:34.0078980Z 
2020-06-19T19:50:34.0079110Z     def create_onnx_graph_proto(self, sym, params, in_shape, in_type, verbose=False):
2020-06-19T19:50:34.0079240Z         """Convert MXNet graph to ONNX graph
2020-06-19T19:50:34.0079410Z     
2020-06-19T19:50:34.0079520Z         Parameters
2020-06-19T19:50:34.0079990Z         ----------
2020-06-19T19:50:34.0080120Z         sym : :class:`~mxnet.symbol.Symbol`
2020-06-19T19:50:34.0080240Z             MXNet symbol object
2020-06-19T19:50:34.0080430Z         params : dict of ``str`` to :class:`~mxnet.ndarray.NDArray`
2020-06-19T19:50:34.0080650Z             Dict of converted parameters stored in ``mxnet.ndarray.NDArray`` format
2020-06-19T19:50:34.0081200Z         in_shape : List of tuple
2020-06-19T19:50:34.0081380Z             Input shape of the model e.g [(1,3,224,224)]
2020-06-19T19:50:34.0081500Z         in_type : data type
2020-06-19T19:50:34.0081650Z             Input data type e.g. np.float32
2020-06-19T19:50:34.0081940Z         verbose : Boolean
2020-06-19T19:50:34.0082160Z             If true will print logs of the model conversion
2020-06-19T19:50:34.0082320Z     
2020-06-19T19:50:34.0082440Z         Returns
2020-06-19T19:50:34.0083120Z         -------
2020-06-19T19:50:34.0083270Z         graph : GraphProto
2020-06-19T19:50:34.0083390Z             ONNX graph
2020-06-19T19:50:34.0083550Z         """
2020-06-19T19:50:34.0083940Z         try:
2020-06-19T19:50:34.0084870Z             from onnx import (checker, helper, NodeProto, ValueInfoProto, TensorProto)
2020-06-19T19:50:34.0085040Z             from onnx.helper import make_tensor_value_info
2020-06-19T19:50:34.0085180Z         except ImportError:
2020-06-19T19:50:34.0085770Z             raise ImportError("Onnx and protobuf need to be installed. "
2020-06-19T19:50:34.0086660Z                               + "Instructions to install - https://github.com/onnx/onnx")
2020-06-19T19:50:34.0086850Z     
2020-06-19T19:50:34.0086980Z         # When MXNet model is saved to json file , MXNet adds a node for label.
2020-06-19T19:50:34.0087480Z         # The name of this node is, name of the last node + "_label" ( i.e if last node
2020-06-19T19:50:34.0088230Z         # name is "Softmax", this node will have a name "Softmax_label". Also, the new node
2020-06-19T19:50:34.0088780Z         # will always be second last node in the json graph.
2020-06-19T19:50:34.0089230Z         # Deriving the output_label name.
2020-06-19T19:50:34.0090540Z         output_label = sym.get_internals()[len(sym.get_internals()) - 1].name + "_label"
2020-06-19T19:50:34.0090720Z     
2020-06-19T19:50:34.0090840Z         weights = MXNetGraph.convert_weights_to_numpy(params)
2020-06-19T19:50:34.0091040Z     
2020-06-19T19:50:34.0091210Z         mx_graph = json.loads(sym.tojson())["nodes"]
2020-06-19T19:50:34.0091340Z     
2020-06-19T19:50:34.0091700Z         initializer = []
2020-06-19T19:50:34.0091960Z         all_processed_nodes = []
2020-06-19T19:50:34.0092290Z         onnx_processed_nodes = []
2020-06-19T19:50:34.0092630Z         onnx_processed_inputs = []
2020-06-19T19:50:34.0093510Z         onnx_processed_outputs = []
2020-06-19T19:50:34.0093660Z         index_lookup = []
2020-06-19T19:50:34.0093780Z     
2020-06-19T19:50:34.0093900Z         # Determine output and internal shapes
2020-06-19T19:50:34.0094790Z         graph_outputs = MXNetGraph.get_outputs(sym, params, in_shape, output_label)
2020-06-19T19:50:34.0094980Z         graph_shapes = MXNetGraph.get_outputs(sym.get_internals(), params, in_shape, output_label, verbose=False)
2020-06-19T19:50:34.0095330Z     
2020-06-19T19:50:34.0095540Z         graph_input_idx = 0
2020-06-19T19:50:34.0095840Z         for idx, node in enumerate(mx_graph):
2020-06-19T19:50:34.0096120Z             op = node["op"]
2020-06-19T19:50:34.0096510Z             name = node["name"]
2020-06-19T19:50:34.0096770Z             if verbose:
2020-06-19T19:50:34.0097640Z                 logging.info("Converting idx: %d, op: %s, name: %s", idx, op, name)
2020-06-19T19:50:34.0097790Z     
2020-06-19T19:50:34.0097950Z             # A node is an input node if its op_name is "null" and is not
2020-06-19T19:50:34.0098340Z             # in params dict
2020-06-19T19:50:34.0098690Z             if op == "null" and name not in params:
2020-06-19T19:50:34.0099030Z                 # Handling graph input
2020-06-19T19:50:34.0099530Z     
2020-06-19T19:50:34.0099860Z                 # Skipping output_label node, as this node is not part of graph
2020-06-19T19:50:34.0100580Z                 # Refer "output_label" assignment above for more details.
2020-06-19T19:50:34.0101330Z                 if name == output_label:
2020-06-19T19:50:34.0101470Z                     continue
2020-06-19T19:50:34.0101830Z                 converted = MXNetGraph.convert_layer(
2020-06-19T19:50:34.0101960Z                     node,
2020-06-19T19:50:34.0102100Z                     is_input=True,
2020-06-19T19:50:34.0102230Z                     mx_graph=mx_graph,
2020-06-19T19:50:34.0102970Z                     weights=weights,
2020-06-19T19:50:34.0103150Z >                   in_shape=in_shape[graph_input_idx],
2020-06-19T19:50:34.0103370Z                     in_type=in_type,
2020-06-19T19:50:34.0103660Z                     proc_nodes=all_processed_nodes,
2020-06-19T19:50:34.0104080Z                     graph_shapes=graph_shapes,
2020-06-19T19:50:34.0104580Z                     initializer=initializer,
2020-06-19T19:50:34.0104880Z                     index_lookup=index_lookup)
2020-06-19T19:50:34.0105270Z E               IndexError: list index out of range
2020-06-19T19:50:34.0105430Z 
2020-06-19T19:50:34.0106450Z python/mxnet/contrib/onnx/mx2onnx/export_onnx.py:233: IndexError

#17734

cc @RuRo

@eric-haibin-lin
Copy link
Member

Also happened in #18579

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants