Skip to content

Commit 133d12e

Browse files
committed
sync from master
2 parents b0c8f3a + 87f5b0a commit 133d12e

36 files changed

+771
-348
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.coverage
1+
.coverage*
22
*.pyc
33
.idea
44
build

README.md

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ onnxruntime (only avaliable on linux):
3333

3434
```pip install onnxruntime```
3535

36-
For caffe2, follow the instructions here:
36+
For pytorch/caffe2, follow the instructions here:
3737

38-
```https://caffe2.ai/```
38+
```https://pytorch.org/```
3939

4040

41-
We tested with caffe2 and onnxruntime and unit tests are passing for those.
41+
We tested with pytorch/caffe2 and onnxruntime and unit tests are passing for those.
4242

4343
## Supported Tensorflow and Python Versions
44-
We tested with tensorflow 1.5-1.11 and anaconda **3.5,3.6**.
44+
We tested with tensorflow 1.5-1.12 and anaconda **3.5,3.6**.
4545

4646
# Installation
4747
## From Pypi
@@ -64,13 +64,17 @@ python setup.py bdist_wheel
6464

6565
# Usage
6666

67-
To convert a TensorFlow model, tf2onnx expects a ```frozen TensorFlow graph``` and the user needs to specify inputs and outputs for the graph by passing the input and output
67+
To convert a TensorFlow model, tf2onnx prefers a ```frozen TensorFlow graph``` and the user needs to specify inputs and outputs for the graph by passing the input and output
6868
names with ```--inputs INPUTS``` and ```--outputs OUTPUTS```.
6969

7070
```
71-
python -m tf2onnx.convert --input SOURCE_FROZEN_GRAPH_PB
72-
--inputs SOURCE_GRAPH_INPUTS
73-
--outputs SOURCE_GRAPH_OUTPUS
71+
python -m tf2onnx.convert
72+
--input SOURCE_GRAPHDEF_PB
73+
--graphdef SOURCE_GRAPHDEF_PB
74+
--checkpoint SOURCE_CHECKPOINT
75+
--saved-model SOURCE_SAVED_MODEL
76+
[--inputs GRAPH_INPUTS]
77+
[--outputs GRAPH_OUTPUS]
7478
[--inputs-as-nchw inputs_provided_as_nchw]
7579
[--target TARGET]
7680
[--output TARGET_ONNX_GRAPH]
@@ -83,21 +87,26 @@ python -m tf2onnx.convert --input SOURCE_FROZEN_GRAPH_PB
8387
```
8488

8589
## Parameters
86-
### input
87-
frozen TensorFlow graph, which can be created with the [freeze graph tool](#freeze_graph).
88-
### output
90+
### --input or --graphdef
91+
TensorFlow model as graphdef file. If not already frozen we'll try to freeze the model.
92+
More information about freezing can be found here: [freeze graph tool](#freeze_graph).
93+
### --checkpoint
94+
TensorFlow model as checkpoint. We expect the path to the .meta file. tf2onnx will try to freeze the graph.
95+
### --saved-model
96+
TensorFlow model as saved_model. We expect the path to the saved_model directory. tf2onnx will try to freeze the graph.
97+
### --output
8998
the target onnx file path.
90-
### inputs, outputs
91-
Tensorflow graph's input/output names, which can be found with [summarize graph tool](#summarize_graph). Those names typically end on ```:0```, for example ```--inputs input0:0,input1:0```
92-
### inputs-as-nchw
99+
### --inputs, --outputs
100+
Tensorflow model's input/output names, which can be found with [summarize graph tool](#summarize_graph). Those names typically end on ```:0```, for example ```--inputs input0:0,input1:0```. inputs and outputs are ***not*** needed for models in saved-model format.
101+
### --inputs-as-nchw
93102
By default we preserve the image format of inputs (nchw or nhwc) as given in the TensorFlow model. If your hosts (for example windows) native format nchw and the model is written for nhwc, ```--inputs-as-nchw``` tensorflow-onnx will transpose the input. Doing so is convinient for the application and the converter in many cases can optimize the transpose away. For example ```--inputs input0:0,input1:0 --inputs-as-nchw input0:0``` assumes that images are passed into ```input0:0``` as nchw while the TensorFlow model given uses nhwc.
94-
### target
103+
### --target
95104
Some runtimes need workarounds, for example they don't support all types given in the onnx spec. We'll workaround it in some cases by generating a different graph. Those workarounds are activated with ```--target TARGET```.
96-
### opset
105+
### --opset
97106
by default we uses the newest opset 7 to generate the graph. By specifieing ```--opset``` the user can override the default to generate a graph with the desired opset. For example ```--opset 5``` would create a onnx graph that uses only ops available in opset 5. Because older opsets have in most cases fewer ops, some models might not convert on a older opset.
98-
### custom-ops
107+
### --custom-ops
99108
the runtime may support custom ops that are not defined in onnx. A user can asked the converter to map to custom ops by listing them with the --custom-ops option. Tensorflow ops listed here will be mapped to a custom op with the same name as the tensorflow op but in the onnx domain ai.onnx.converters.tensorflow. For example: ```--custom-ops Print``` will insert a op ```Print``` in the onnx domain ```ai.onnx.converters.tensorflow``` into the graph. We also support a python api for custom ops documented later in this readme.
100-
### fold_const
109+
### --fold_const
101110
when set, TensorFlow fold_constants transformation will be applied before conversion. This will benefit features including Transpose optimization (e.g. Transpose operations introduced during tf-graph-to-onnx-graph conversion will be removed), and RNN unit conversion (for example LSTM). Older TensorFlow version might run into issues with this option depending on the model.
102111

103112

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Test against latest onnxruntime nightly package
2+
3+
# TODO: change onnxruntime package name when nightly package is ready
4+
5+
jobs:
6+
- template: 'templates/job_generator.yml'
7+
parameters:
8+
tf_versions: ['1.12']
9+
onnx_opsets: ['9', '8', '7']
10+
onnx_backends:
11+
onnxruntime: ['']
12+
job:
13+
displayName: 'unit_test'
14+
steps:
15+
- template: 'unit_test.yml'

ci_build/azure_pipelines/templates/setup.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,18 @@ steps:
1313
pip install $(CI_PIP_ONNX_NAME) $(CI_PIP_ONNX_BACKEND_NAME) numpy --no-deps -U
1414
fi
1515
16+
# HACK: before onnxruntime nightly package is ready, install onnxruntime from pypi test
17+
if [[ $CI_ONNXRUNTIME_FROM_PYPI_TEST == "true" ]] ;
18+
then
19+
pip install --index-url https://test.pypi.org/simple/ onnxruntime --force-reinstall
20+
fi
21+
1622
python setup.py install
1723
pip freeze --all
1824
displayName: 'Setup Environment'
1925

2026
# TODO: remove later
21-
# Anaconda python 3.6.8 h9f7ef89_1 changed dll lookup logic, numpy failes to load dll on Windows
27+
# Anaconda python 3.6.8 h9f7ef89_1 changed dll lookup logic, numpy fails to load dll on Windows
2228
# https://github.com/numpy/numpy/issues/12957
2329
# https://github.com/ContinuumIO/anaconda-issues/issues/10629
2430
# Add numpy lib path manually here

tests/backend_test_base.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ def setUp(self):
4040
tf.logging.set_verbosity(tf.logging.WARN)
4141
self.log.setLevel(logging.INFO)
4242

43+
def tearDown(self):
44+
if not self.config.is_debug_mode:
45+
utils.delete_directory(self.test_data_directory)
46+
47+
@property
48+
def test_data_directory(self):
49+
return os.path.join(self.config.temp_dir, self._testMethodName)
50+
4351
@staticmethod
4452
def assertAllClose(expected, actual, **kwargs):
4553
np.testing.assert_allclose(expected, actual, **kwargs)
@@ -72,6 +80,7 @@ def run_onnxruntime(self, model_path, inputs, output_names):
7280
def _run_backend(self, g, outputs, input_dict):
7381
model_proto = g.make_model("test")
7482
model_path = self.save_onnx_model(model_proto, input_dict)
83+
7584
if self.config.backend == "onnxmsrtnext":
7685
y = self.run_onnxmsrtnext(model_path, input_dict, outputs)
7786
elif self.config.backend == "onnxruntime":
@@ -84,7 +93,7 @@ def _run_backend(self, g, outputs, input_dict):
8493

8594
def run_test_case(self, feed_dict, input_names_with_port, output_names_with_port, rtol=1e-07, atol=0.,
8695
convert_var_to_const=True, constant_fold=True, check_value=True, check_shape=False,
87-
check_dtype=False, process_args=None, onnx_feed_dict=None):
96+
check_dtype=True, process_args=None, onnx_feed_dict=None):
8897
# optional - passed to process_tf_graph
8998
if process_args is None:
9099
process_args = {}
@@ -93,8 +102,6 @@ def run_test_case(self, feed_dict, input_names_with_port, output_names_with_port
93102
onnx_feed_dict = feed_dict
94103

95104
graph_def = None
96-
save_dir = os.path.join(self.config.temp_path, self._testMethodName)
97-
98105
if convert_var_to_const:
99106
with tf.Session() as sess:
100107
variables_lib.global_variables_initializer().run()
@@ -113,20 +120,18 @@ def run_test_case(self, feed_dict, input_names_with_port, output_names_with_port
113120
expected = sess.run(output_dict, feed_dict=feed_dict)
114121

115122
if self.config.is_debug_mode:
116-
if not os.path.exists(save_dir):
117-
os.makedirs(save_dir)
118-
model_path = os.path.join(save_dir, self._testMethodName + "_original.pb")
119-
with open(model_path, "wb") as f:
120-
f.write(sess.graph_def.SerializeToString())
123+
if not os.path.exists(self.test_data_directory):
124+
os.makedirs(self.test_data_directory)
125+
model_path = os.path.join(self.test_data_directory, self._testMethodName + "_original.pb")
126+
utils.save_protobuf(model_path, sess.graph_def)
121127
self.log.debug("created file %s", model_path)
122128

123129
graph_def = tf_optimize(input_names_with_port, output_names_with_port,
124130
sess.graph_def, constant_fold)
125131

126132
if self.config.is_debug_mode and constant_fold:
127-
model_path = os.path.join(save_dir, self._testMethodName + "_after_tf_optimize.pb")
128-
with open(model_path, "wb") as f:
129-
f.write(graph_def.SerializeToString())
133+
model_path = os.path.join(self.test_data_directory, self._testMethodName + "_after_tf_optimize.pb")
134+
utils.save_protobuf(model_path, graph_def)
130135
self.log.debug("created file %s", model_path)
131136

132137
tf.reset_default_graph()
@@ -146,9 +151,8 @@ def run_test_case(self, feed_dict, input_names_with_port, output_names_with_port
146151
self.assertEqual(expected_val.shape, actual_val.shape)
147152

148153
def save_onnx_model(self, model_proto, feed_dict, postfix=""):
149-
save_path = os.path.join(self.config.temp_path, self._testMethodName)
150-
target_path = utils.save_onnx_model(save_path, self._testMethodName + postfix, feed_dict, model_proto,
151-
include_test_data=self.config.is_debug_mode,
154+
target_path = utils.save_onnx_model(self.test_data_directory, self._testMethodName + postfix, feed_dict,
155+
model_proto, include_test_data=self.config.is_debug_mode,
152156
as_text=self.config.is_debug_mode)
153157

154158
self.log.debug("create model file: %s", target_path)

tests/common.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
import argparse
77
import os
88
import sys
9-
import tempfile
109
import unittest
1110

1211
from distutils.version import LooseVersion
12+
from tf2onnx import utils
1313
from tf2onnx.tfonnx import DEFAULT_TARGET, POSSIBLE_TARGETS
1414

1515
__all__ = ["TestConfig", "get_test_config", "unittest_main",
16-
"check_tf_min_version", "check_opset_min_version", "check_target", "skip_onnxruntime_backend",
17-
"skip_caffe2_backend", "check_onnxruntime_incompatibility"]
16+
"check_tf_min_version", "skip_tf_versions",
17+
"check_opset_min_version", "check_target", "skip_onnxruntime_backend", "skip_caffe2_backend",
18+
"check_onnxruntime_incompatibility"]
1819

1920

2021
# pylint: disable=missing-docstring
@@ -23,12 +24,12 @@ class TestConfig(object):
2324
def __init__(self):
2425
self.platform = sys.platform
2526
self.tf_version = self._get_tf_version()
26-
self.opset = int(os.environ.get("TF2ONNX_TEST_OPSET", 7))
27+
self.opset = int(os.environ.get("TF2ONNX_TEST_OPSET", 9))
2728
self.target = os.environ.get("TF2ONNX_TEST_TARGET", ",".join(DEFAULT_TARGET)).split(',')
2829
self.backend = os.environ.get("TF2ONNX_TEST_BACKEND", "onnxruntime")
2930
self.backend_version = self._get_backend_version()
3031
self.is_debug_mode = False
31-
self.temp_path = tempfile.mkdtemp()
32+
self.temp_dir = utils.get_temp_directory()
3233

3334
@property
3435
def is_mac(self):
@@ -67,28 +68,32 @@ def __str__(self):
6768
"target={}".format(self.target),
6869
"backend={}".format(self.backend),
6970
"backend_version={}".format(self.backend_version),
70-
"is_debug_mode={}".format(self.is_debug_mode)])
71+
"is_debug_mode={}".format(self.is_debug_mode),
72+
"temp_dir={}".format(self.temp_dir)])
7173

7274
@staticmethod
7375
def load():
7476
config = TestConfig()
7577
# if not launched by pytest, parse console arguments to override config
7678
if "pytest" not in sys.argv[0]:
7779
parser = argparse.ArgumentParser()
78-
parser.add_argument('--backend', default=config.backend,
80+
parser.add_argument("--backend", default=config.backend,
7981
choices=["caffe2", "onnxmsrtnext", "onnxruntime"],
8082
help="backend to test against")
81-
parser.add_argument('--opset', type=int, default=config.opset, help="opset to test against")
83+
parser.add_argument("--opset", type=int, default=config.opset, help="opset to test against")
8284
parser.add_argument("--target", default=",".join(config.target), choices=POSSIBLE_TARGETS,
8385
help="target platform")
8486
parser.add_argument("--debug", help="output debugging information", action="store_true")
85-
parser.add_argument('unittest_args', nargs='*')
87+
parser.add_argument("--temp_dir", help="temp dir")
88+
parser.add_argument("unittest_args", nargs='*')
8689

8790
args = parser.parse_args()
8891
config.backend = args.backend
8992
config.opset = args.opset
9093
config.target = args.target.split(',')
9194
config.is_debug_mode = args.debug
95+
if args.temp_dir:
96+
config.temp_dir = args.temp_dir
9297

9398
# Now set the sys.argv to the unittest_args (leaving sys.argv[0] alone)
9499
sys.argv[1:] = args.unittest_args
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
model_checkpoint_path: "model"
2+
all_model_checkpoint_paths: "model"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
�[>�V�?
134 Bytes
Binary file not shown.
19.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)