NNVM uses JSON for graph serialization. This allows NNVM graph to be exported to any backend either natively supported or by third-party without any dependency such as protobuf.
A serialized NNVM graph in JSON format can be deserialized by any JSON parser.
# python
import json
with open('model.json', 'r') as f:
graph = json.loads(f.read())
print(graph.keys())
['nodes', 'arg_nodes', 'heads', 'node_row_ptr']
Actually, the following keys are valid in JSON graph.
Keys | Required | Description |
---|---|---|
nodes | Yes | The nodes in graph. |
arg_nodes | Yes | Indices of input nodes. |
heads | Yes | Indices of output nodes. |
node_row_ptr | Optional | Depth first search row indices. |
attr | Optional | Additional information. |
Explained by the name itself, nodes
are either placeholders or
computational nodes in NNVM graph. The nodes
are stored in list.
nodes = graph['nodes']
print(len(nodes))
print(nodes[0])
print(nodes[3])
53 {'inputs': [], 'name': 'data', 'op': 'null'} {'inputs': [[0, 0, 0], [1, 0, 0], [2, 0, 0]], 'attrs': {'channels': '64', 'padding': '(1, 1)', 'layout': 'NCHW', 'kernel_size': '[3, 3]', 'groups': '1', 'strides': '(1, 1)', 'use_bias': 'True', 'dilation': '(1, 1)'}, 'name': 'conv1_1', 'op': 'conv2d'}
The following keys are valid in each node:
Keys | Required | Descript ion |
---|---|---|
op | Yes | The operator type name, 'null' is used if it's a placehol der/vari able/inp ut. |
name | Yes | The given name of the node, defined by user composin g the network. |
inputs | Yes | List of Entry of the input nodes, can be empty list []. Entry is a list of [nose_i d, index, version] |
attrs | Optional | Extra attribut es for the specific operator . |
control_deps | Optional | Control dependen cies, left blank unless specific ally used. |
attrs
for operators is a dictionary. Key-value pair examples:
Keys | Value | Operator | Descript ion |
---|---|---|---|
'channels' | '64' | conv2d | Output channels for 2d convolut ion. |
'kernel_size' | '[3, 3]' | conv2d | Convolut ion filter kernel size in (h, w), list and tuple both works. |
'use_bias' | '1' | conv2d | Whether use bias such that y = w * x + b . |
Note
Tips for parsing key-value pair:
- Both key and value are stored as strings.
- Boolean values need extra attention, convert to int is recommended since bool('0') == True in python.
- For a full list of operator attributes, please refer to the core operator documentation.
arg_nodes
is a list of indices of nodes which is
placeholder/variable/input to the graph.
print(graph['arg_nodes'])
[0, 1, 2, 6, 7, 11, 12, 15, 16, 20, 21, 24, 25, 29, 30, 33, 34, 39, 40, 44, 45, 49, 50]
For example, nodes[3]
is not in arg_nodes
because it's an
internal node.
heads
is a list of entries as the outlet/output of the graph.
print(graph['heads'])
[[52, 0, 0]]
This example indicating that there's only one output in the graph, with index 52.
node_row_ptr
stores the history of forward path, so you can skip
constructing the entire graph in inference tasks.
attrs
can contain version numbers or similar helpful informations.