From 7b616a613103743decca27658f0f2b0c1df6f7d9 Mon Sep 17 00:00:00 2001 From: "Joshua Z. Zhang" Date: Mon, 2 Oct 2017 15:27:41 -0700 Subject: [PATCH] [DOC] add json spec intro (#62) * add json spec intro * fix error * fix name attrs * rename and move to top * address boolean values * update title --- docs/index.rst | 1 + docs/json_spec.rst | 212 +++++++++++++++++++++++++++++++++++ python/nnvm/frontend/onnx.py | 5 +- 3 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 docs/json_spec.rst diff --git a/docs/index.rst b/docs/index.rst index d4a3243aab96..df61dca776f8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,5 +14,6 @@ Contents tutorials/index how_to/contribute how_to/deploy + json_spec api/python/index dev/index diff --git a/docs/json_spec.rst b/docs/json_spec.rst new file mode 100644 index 000000000000..31f2d2dc5c07 --- /dev/null +++ b/docs/json_spec.rst @@ -0,0 +1,212 @@ +NNVM Graph JSON Specification +============================= + +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. + +Getting started +--------------- + +A serialized NNVM graph in JSON format can be deserialized by any JSON +parser. + +.. code:: python + + # 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 <#nodes>`__ | Yes | The nodes in graph. | ++--------------------------------------+------------+-----------------------------------+ +| `arg\_nodes <#arg_nodes>`__ | Yes | Indices of input nodes. | ++--------------------------------------+------------+-----------------------------------+ +| `heads <#heads>`__ | Yes | Indices of output nodes. | ++--------------------------------------+------------+-----------------------------------+ +| `node\_row\_ptr <#node_row_ptr>`__ | Optional | Depth first search row indices. | ++--------------------------------------+------------+-----------------------------------+ +| `attr <#attr>`__ | Optional | Additional information. | ++--------------------------------------+------------+-----------------------------------+ + +nodes +----- + +Explained by the name itself, ``nodes`` are either placeholders or +computational nodes in NNVM graph. The ``nodes`` are stored in list. + +.. code:: python + + 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 +---------- + +``arg_nodes`` is a list of indices of nodes which is +placeholder/variable/input to the graph. + +.. code:: python + + 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 +----- + +``heads`` is a list of entries as the outlet/output of the graph. + +.. code:: python + + print(graph['heads']) + +:: + + [[52, 0, 0]] + +This example indicating that there's only one output in the graph, with +index 52. + +node\_row\_ptr +-------------- + +``node_row_ptr`` stores the history of forward path, so you can skip +constructing the entire graph in inference tasks. + +attrs +----- + +``attrs`` can contain version numbers or similar helpful informations. diff --git a/python/nnvm/frontend/onnx.py b/python/nnvm/frontend/onnx.py index a433485520d5..8df61bf25065 100644 --- a/python/nnvm/frontend/onnx.py +++ b/python/nnvm/frontend/onnx.py @@ -367,9 +367,10 @@ def from_onnx(graph): Returns ------- - nnvm.Symbol + sym : nnvm.Symbol Compatible nnvm symbol - dict of tvm.ndarray + + params : dict of str to tvm.ndarray Dict of converted parameters stored in tvm.ndarray format """ g = GraphProto()