Skip to content

Commit 68a04ee

Browse files
author
Wenbing Li
authored
Prepare 1.6.5 release. (#366)
* Prepare 1.6.5 release. * add pytest in dependencies * disable coverage in CI * pytest path issue on Windows * one more try on version. * debug the CI build issue. * using python -m pip * installation * restore the docs sub-folder.
1 parent 89b2c2c commit 68a04ee

File tree

17 files changed

+138
-251
lines changed

17 files changed

+138
-251
lines changed

.azure-pipelines/linux-CI-nightly.yml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,12 @@ jobs:
3535
conda install -c conda-forge protobuf
3636
conda install -c conda-forge numpy
3737
conda install -c conda-forge cmake
38-
pip install $(ONNX_PATH)
39-
git clone https://github.com/microsoft/onnxconverter-common
40-
cd onnxconverter-common
41-
pip install -e .
42-
cd ..
43-
pip install -r requirements.txt
44-
pip install -r requirements-dev.txt
45-
pip install $(ORT_PATH)
46-
pip install pytest
38+
python -m pip install $(ONNX_PATH)
39+
python -m pip install git+https://github.com/microsoft/onnxconverter-common
40+
python -m pip install -r requirements.txt
41+
python -m pip install -r requirements-dev.txt
42+
python -m pip install $(ORT_PATH)
43+
python -m pip install pytest
4744
git clone --recursive https://github.com/cjlin1/libsvm libsvm
4845
cd libsvm
4946
make lib

.azure-pipelines/linux-conda-CI.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,6 @@ jobs:
7171
pytest tests --ignore=tests/sparkml --doctest-modules --junitxml=junit/test-results.xml
7272
displayName: 'pytest - onnxmltools'
7373
74-
- script: |
75-
export PYTHONPATH=$PYTHONPATH:libsvm/python
76-
python -c "import onnxconverter_common"
77-
python -c "import onnxmltools"
78-
coverage run --include=onnxmltools/** tests/main.py
79-
coverage report -m
80-
coverage html
81-
displayName: 'coverage'
82-
8374
- task: PublishTestResults@2
8475
inputs:
8576
testResultsFiles: '**/test-results.xml'

.azure-pipelines/win32-CI-nightly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
call activate py$(python.version)
5959
set PYTHONPATH=libsvm\python;%PYTHONPATH%
6060
pip install -e .
61-
pytest tests --ignore=tests/sparkml --doctest-modules --junitxml=junit/test-results.xml
61+
python -m pytest tests --ignore=tests/sparkml --doctest-modules --junitxml=junit/test-results.xml
6262
displayName: 'pytest - onnxmltools'
6363
6464
- task: PublishTestResults@2

.azure-pipelines/win32-conda-CI.yml

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,28 @@ jobs:
5555
call activate py$(python.version)
5656
python -m pip install --upgrade pip numpy
5757
echo Test numpy installation... && python -c "import numpy"
58-
pip install %COREML_PATH% %ONNX_PATH%
59-
git clone https://github.com/microsoft/onnxconverter-common
60-
cd onnxconverter-common
61-
pip install -e .
62-
cd ..
58+
python -m pip install %COREML_PATH% %ONNX_PATH%
59+
python -m pip install git+https://github.com/microsoft/onnxconverter-common
6360
echo Test onnxconverter-common installation... && python -c "import onnxconverter_common"
64-
pip install -r requirements.txt
65-
pip install -r requirements-dev.txt
66-
pip install %ONNXRT_PATH%
61+
python -m pip install -r requirements.txt
62+
python -m pip install -r requirements-dev.txt
63+
python -m pip install %ONNXRT_PATH%
6764
echo Test onnxruntime installation... && python -c "import onnxruntime"
6865
REM install libsvm from github
6966
git clone --recursive https://github.com/cjlin1/libsvm libsvm
7067
copy libsvm\windows\*.dll libsvm\python
7168
set PYTHONPATH=libsvm\python;%PYTHONPATH%
7269
dir libsvm\python
7370
echo Test libsvm installation... && python -c "import svmutil"
71+
echo "debug environment" && path
72+
python -m pip show pytest
7473
displayName: 'Install dependencies'
7574
7675
- script: |
7776
call activate py$(python.version)
7877
set PYTHONPATH=libsvm\python;%PYTHONPATH%
79-
pip install -e .
80-
pytest tests --ignore=tests/sparkml --doctest-modules --junitxml=junit/test-results.xml
78+
python -m pip install -e .
79+
python -m pytest tests --ignore=tests/sparkml --doctest-modules --junitxml=junit/test-results.xml
8180
displayName: 'pytest - onnxmltools'
8281
8382
- task: PublishTestResults@2

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ build/
2525
# test generated files
2626
.pytest_cache
2727
.cache
28+
tests/temp
2829
tests/utils/models/coreml_OneHotEncoder_BikeSharing_new.json
2930
tests/utils/models/coreml_OneHotEncoder_BikeSharing2.onnx
3031
tests/baseline/outmodels

README.md

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ ONNXMLTools enables you to convert models from different machine learning toolki
1616
* libsvm
1717
* XGBoost
1818
* H2O
19+
<p>Pytorch has its builtin ONNX exporter check <a href="https://pytorch.org/docs/stable/onnx.html">here</a> for details</p>
1920

2021
## Install
2122
You can install latest release of ONNXMLTools from [PyPi](https://pypi.org/project/onnxmltools/):
@@ -96,11 +97,6 @@ onnx_model = onnxmltools.convert_coreml(coreml_model, 'Example Model')
9697
onnxmltools.utils.save_model(onnx_model, 'example.onnx')
9798
```
9899

99-
## Spark ML to ONNX Conversion (experimental)
100-
Please refer to the following documents:
101-
* [Conversion Framework](onnxmltools/convert/README.md)
102-
* [Spark ML to ONNX Model Conversion](onnxmltools/convert/sparkml/README.md)
103-
104100
## H2O to ONNX Conversion
105101
Below is a code snippet to convert a H2O MOJO model into an ONNX model. The only pre-requisity is to have a MOJO model saved on the local file-system.
106102

@@ -136,17 +132,12 @@ Documentation for the [ONNX Model format](https://github.com/onnx/onnx) and more
136132

137133
## Test all existing converters
138134

139-
There exists a way
140-
to automatically check every converter with
135+
All converter unit test can generate the original model and converted model to automatically be checked with
141136
[onnxruntime](https://pypi.org/project/onnxruntime/) or
142137
[onnxruntime-gpu](https://pypi.org/project/onnxruntime-gpu/).
143-
This process requires the user to clone the *onnxmltools* repository.
144-
The following command runs all unit tests and generates
145-
dumps of models, inputs, expected outputs and converted models
146-
in folder ``TESTDUMP``.
147-
138+
The unit test cases are all the normal python unit test cases, you can run it with pytest command line, for example:
148139
```
149-
python tests/main.py DUMP
140+
python -m pytest --ignore .\tests\
150141
```
151142

152143
It requires *onnxruntime*, *numpy* for most models,

docs/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ to automatically check every converter with
5555
from onnxmltools import convert_sklearn
5656
from onnxmltools.utils import save_model
5757
from onnxconverter_common.data_types import FloatTensorType
58-
initial_type = [('float_input', FloatTensorType([-1, 4]))]
58+
initial_type = [('float_input', FloatTensorType([1, 4]))]
5959
onx = convert_sklearn(clr, initial_types=initial_type)
6060
save_model(onx, "rf_iris.onnx")
6161

docs/tutorial.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ to convert other model formats into ONNX. Here we will use
5454
from onnxmltools.utils import save_model
5555
from onnxmltools.convert.common.data_types import FloatTensorType
5656

57-
initial_type = [('float_input', FloatTensorType([-1, 4]))]
57+
initial_type = [('float_input', FloatTensorType([1, 4]))]
5858
onx = convert_sklearn(clr, initial_types=initial_type)
5959
save_model(onx, "logreg_iris.onnx")
6060

@@ -67,9 +67,7 @@ for this machine learning model.
6767
::
6868

6969
import onnxruntime as rt
70-
import numpy
7170
sess = rt.InferenceSession("logreg_iris.onnx")
72-
label_name = sess.get_outputs()[0].name
7371
input_name = sess.get_inputs()[0].name
7472

7573
pred_onx = sess.run([label_name], {input_name: X_test.astype(numpy.float32)})[0]

onnxmltools/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
This framework converts any machine learned model into onnx format
1010
which is a common language to describe any machine learned model.
1111
"""
12-
__version__ = "1.6.0"
12+
__version__ = "1.6.5"
1313
__author__ = "Microsoft"
1414
__producer__ = "OnnxMLTools"
1515
__producer_version__ = __version__

onnxmltools/convert/main.py

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
from ..proto import onnx
88
from .common import utils
99
import warnings
10+
import importlib
11+
1012

1113
def convert_coreml(model, name=None, initial_types=None, doc_string='', target_opset=None,
12-
targeted_onnx=onnx.__version__ , custom_conversion_functions=None, custom_shape_calculators=None):
14+
targeted_onnx=onnx.__version__, custom_conversion_functions=None, custom_shape_calculators=None):
1315
if not utils.coreml_installed():
1416
raise RuntimeError('coremltools is not installed. Please install coremltools to use this feature.')
1517

@@ -33,7 +35,7 @@ def convert_keras(model, name=None, initial_types=None, doc_string='',
3335

3436

3537
def convert_libsvm(model, name=None, initial_types=None, doc_string='', target_opset=None,
36-
targeted_onnx=onnx.__version__, custom_conversion_functions=None, custom_shape_calculators=None):
38+
targeted_onnx=onnx.__version__, custom_conversion_functions=None, custom_shape_calculators=None):
3739
if not utils.libsvm_installed():
3840
raise RuntimeError('libsvm is not installed. Please install libsvm to use this feature.')
3941

@@ -62,7 +64,8 @@ def convert_sklearn(model, name=None, initial_types=None, doc_string='', target_
6264

6365
from skl2onnx.convert import convert_sklearn as convert_skl2onnx
6466
return convert_skl2onnx(model, name, initial_types, doc_string, target_opset,
65-
custom_conversion_functions, custom_shape_calculators)
67+
custom_conversion_functions, custom_shape_calculators)
68+
6669

6770
def convert_sparkml(model, name=None, initial_types=None, doc_string='', target_opset=None,
6871
targeted_onnx=onnx.__version__, custom_conversion_functions=None,
@@ -74,18 +77,6 @@ def convert_sparkml(model, name=None, initial_types=None, doc_string='', target_
7477
return convert(model, name, initial_types, doc_string, target_opset, targeted_onnx,
7578
custom_conversion_functions, custom_shape_calculators, spark_session)
7679

77-
def convert_tensorflow(frozen_graph_def,
78-
name=None, input_names=None, output_names=None,
79-
doc_string='',
80-
target_opset=None,
81-
channel_first_inputs=None,
82-
debug_mode=False, custom_op_conversions=None):
83-
if not utils.keras2onnx_installed():
84-
raise RuntimeError('keras2onnx is not installed. Please install it to use this feature.')
85-
86-
from keras2onnx import convert_tensorflow as convert
87-
return convert(frozen_graph_def, name, input_names, output_names, doc_string,
88-
target_opset, channel_first_inputs, debug_mode, custom_op_conversions)
8980

9081
def convert_xgboost(*args, **kwargs):
9182
if not utils.xgboost_installed():
@@ -94,9 +85,91 @@ def convert_xgboost(*args, **kwargs):
9485
from .xgboost.convert import convert
9586
return convert(*args, **kwargs)
9687

88+
9789
def convert_h2o(*args, **kwargs):
9890
if not utils.h2o_installed():
9991
raise RuntimeError('h2o is not installed. Please install h2o to use this feature.')
10092

10193
from .h2o.convert import convert
10294
return convert(*args, **kwargs)
95+
96+
97+
def _collect_input_nodes(graph, outputs):
98+
nodes_to_keep = set()
99+
input_nodes = set()
100+
node_inputs = [graph.get_tensor_by_name(ts_).op for ts_ in outputs]
101+
while node_inputs:
102+
nd_ = node_inputs[0]
103+
del node_inputs[0]
104+
if nd_.type in ['Placeholder', "PlaceholderV2", 'PlaceholderWithDefault']:
105+
input_nodes.add(nd_)
106+
if nd_ in nodes_to_keep:
107+
continue
108+
109+
nodes_to_keep.add(nd_)
110+
node_inputs.extend(in_.op for in_ in nd_.inputs)
111+
112+
return input_nodes, nodes_to_keep
113+
114+
115+
def _convert_tf_wrapper(frozen_graph_def,
116+
name=None, input_names=None, output_names=None,
117+
doc_string='',
118+
target_opset=None,
119+
channel_first_inputs=None,
120+
debug_mode=False, custom_op_conversions=None):
121+
"""
122+
convert a tensorflow graph def into a ONNX model proto, just like how keras does.
123+
:param graph_def: the frozen tensorflow graph
124+
:param name: the converted onnx model internal name
125+
:param input_names: the inputs name list of the model
126+
:param output_names: the output name list of the model
127+
:param doc_string: doc string
128+
:param target_opset: the targeted onnx model opset
129+
:param channel_first_inputs: A list of channel first input (not supported yet)
130+
:param debug_mode: will enable the log and try to convert as much as possible on conversion
131+
:return an ONNX ModelProto
132+
"""
133+
import tensorflow as tf
134+
import tf2onnx
135+
136+
if target_opset is None:
137+
target_opset = onnx.defs.onnx_opset_version()
138+
139+
if not doc_string:
140+
doc_string = "converted from {}".format(name)
141+
142+
tf_graph_def = tf2onnx.tfonnx.tf_optimize(input_names, output_names, frozen_graph_def, True)
143+
with tf.Graph().as_default() as tf_graph:
144+
tf.import_graph_def(tf_graph_def, name='')
145+
146+
if not input_names:
147+
input_nodes = list(_collect_input_nodes(tf_graph, output_names)[0])
148+
input_names = [nd_.outputs[0].name for nd_ in input_nodes]
149+
g = tf2onnx.tfonnx.process_tf_graph(tf_graph,
150+
continue_on_error=debug_mode,
151+
opset=target_opset,
152+
custom_op_handlers=custom_op_conversions,
153+
inputs_as_nchw=channel_first_inputs,
154+
output_names=output_names,
155+
input_names=input_names)
156+
157+
onnx_graph = tf2onnx.optimizer.optimize_graph(g)
158+
model_proto = onnx_graph.make_model(doc_string)
159+
160+
return model_proto
161+
162+
163+
def convert_tensorflow(frozen_graph_def,
164+
name=None, input_names=None, output_names=None,
165+
doc_string='',
166+
target_opset=None,
167+
channel_first_inputs=None,
168+
debug_mode=False, custom_op_conversions=None):
169+
try:
170+
importlib.import_module('tf2onnx')
171+
except (ImportError, ModuleNotFoundError) as e:
172+
raise RuntimeError('tf2onnx is not installed, please install it before calling this function.')
173+
174+
return _convert_tf_wrapper(frozen_graph_def, name, input_names, output_names, doc_string,
175+
target_opset, channel_first_inputs, debug_mode, custom_op_conversions)

0 commit comments

Comments
 (0)