Skip to content

Commit acadd11

Browse files
authored
5.1 Release (#1334)
* 5.1 Release * Minor unit test fix
1 parent 22a8877 commit acadd11

File tree

182 files changed

+3823
-1824
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+3823
-1824
lines changed

coremltools/_deps/__init__.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,28 @@
99
"""
1010
from distutils.version import StrictVersion as _StrictVersion
1111
import logging as _logging
12+
from packaging import version
1213
import platform as _platform
1314
import re as _re
1415
import sys as _sys
15-
from packaging import version
1616

1717

18-
def __get_version(version):
18+
def _get_version(version):
1919
# matching 1.6.1, and 1.6.1rc, 1.6.1.dev
2020
version_regex = r"^\d+\.\d+\.\d+"
2121
version = _re.search(version_regex, str(version)).group(0)
2222
return _StrictVersion(version)
2323

2424

25+
def _warn_if_above_max_supported_version(package_name, package_version, max_supported_version):
26+
if _get_version(package_version) > _StrictVersion(max_supported_version):
27+
_logging.warning(
28+
"%s version %s has not been tested with coremltools. You may run into unexpected errors. "
29+
"%s %s is the most recent version that has been tested."
30+
% (package_name, package_version, package_name, max_supported_version)
31+
)
32+
33+
2534
# ---------------------------------------------------------------------------------------
2635

2736
_IS_MACOS = _sys.platform == "darwin"
@@ -77,8 +86,10 @@ def __get_sklearn_version(version):
7786

7887
# ---------------------------------------------------------------------------------------
7988
_HAS_XGBOOST = True
89+
_XGBOOST_MAX_VERSION = "1.4.2"
8090
try:
8191
import xgboost
92+
_warn_if_above_max_supported_version("XGBoost", xgboost.__version__, _XGBOOST_MAX_VERSION)
8293
except:
8394
_HAS_XGBOOST = False
8495

@@ -89,12 +100,12 @@ def __get_sklearn_version(version):
89100
_TF_1_MIN_VERSION = "1.12.0"
90101
_TF_1_MAX_VERSION = "1.15.0"
91102
_TF_2_MIN_VERSION = "2.1.0"
92-
_TF_2_MAX_VERSION = "2.3.1"
103+
_TF_2_MAX_VERSION = "2.5.0"
93104

94105
try:
95106
import tensorflow
96107

97-
tf_ver = __get_version(tensorflow.__version__)
108+
tf_ver = _get_version(tensorflow.__version__)
98109

99110
# TensorFlow
100111
if tf_ver < _StrictVersion("2.0.0"):
@@ -112,11 +123,7 @@ def __get_sklearn_version(version):
112123
)
113124
% (tensorflow.__version__, _TF_1_MIN_VERSION)
114125
)
115-
elif tf_ver > _StrictVersion(_TF_1_MAX_VERSION):
116-
_logging.warning(
117-
"TensorFlow version %s detected. Last version known to be fully compatible is %s ."
118-
% (tensorflow.__version__, _TF_1_MAX_VERSION)
119-
)
126+
_warn_if_above_max_supported_version("TensorFlow", tensorflow.__version__, _TF_1_MAX_VERSION)
120127
elif _HAS_TF_2:
121128
if tf_ver < _StrictVersion(_TF_2_MIN_VERSION):
122129
_logging.warn(
@@ -126,11 +133,7 @@ def __get_sklearn_version(version):
126133
)
127134
% (tensorflow.__version__, _TF_2_MIN_VERSION)
128135
)
129-
elif tf_ver > _StrictVersion(_TF_2_MAX_VERSION):
130-
_logging.warning(
131-
"TensorFlow version %s detected. Last version known to be fully compatible is %s ."
132-
% (tensorflow.__version__, _TF_2_MAX_VERSION)
133-
)
136+
_warn_if_above_max_supported_version("TensorFlow", tensorflow.__version__, _TF_2_MAX_VERSION)
134137

135138
except:
136139
_HAS_TF = False
@@ -168,7 +171,7 @@ def __get_sklearn_version(version):
168171
sys.stderr = stderr
169172
import tensorflow
170173

171-
k_ver = __get_version(keras.__version__)
174+
k_ver = _get_version(keras.__version__)
172175

173176
# keras 1 version too old
174177
if k_ver < _StrictVersion(_KERAS_MIN_VERSION):
@@ -186,7 +189,8 @@ def __get_sklearn_version(version):
186189
_HAS_KERAS_TF = False
187190
_logging.warning(
188191
(
189-
"Keras version %s detected. Last version known to be fully compatible of Keras is %s ."
192+
"Keras version %s has not been tested with coremltools. You may run into unexpected errors. "
193+
"Keras %s is the most recent version that has been tested."
190194
)
191195
% (keras.__version__, _KERAS_MAX_VERSION)
192196
)
@@ -214,8 +218,10 @@ def __get_sklearn_version(version):
214218

215219
# ---------------------------------------------------------------------------------------
216220
_HAS_TORCH = True
221+
_TORCH_MAX_VERSION = "1.9.1"
217222
try:
218223
import torch
224+
_warn_if_above_max_supported_version("Torch", torch.__version__, _TORCH_MAX_VERSION)
219225
except:
220226
_HAS_TORCH = False
221227
MSG_TORCH_NOT_FOUND = "PyTorch not found."

coremltools/converters/_converters_entry.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ def convert(
4646
compute_precision=None,
4747
skip_model_load=False,
4848
compute_units=_ComputeUnit.ALL,
49-
**kwargs
49+
useCPUOnly=False,
50+
package_dir=None,
51+
debug=False,
5052
):
5153
"""
5254
Convert a TensorFlow or PyTorch model to the Core ML model format as either
@@ -230,6 +232,24 @@ def convert(
230232
- ``coremltools.ComputeUnit.CPU_AND_GPU``: Use both the CPU and GPU, but not the
231233
neural engine.
232234
235+
useCPUOnly: bool
236+
Deprecated, to be removed in coremltools 6.0. Please use `compute_units` instead.
237+
- if True, identical to setting compute_units to `coremltools.ComputeUnit.CPU_ONLY``
238+
- if False, identical to setting compute_units to `coremltools.ComputeUnit.ALL``
239+
240+
package_dir : str
241+
Post conversion, the model is compiled to form the MLModel object ready for prediction.
242+
This requires a temporary directory to hold the mlmodelc archive.
243+
- if not None, must be a path to a directory that is used for
244+
temporarily storing the compiled model assets. If None, a temporary directory is created.
245+
246+
debug : bool
247+
This flag should generally be False except for debugging purposes
248+
Setting this flag to True:
249+
- For Torch conversion, it will print the list of supported and unsupported ops
250+
found in the model if conversion fails due to an unsupported op.
251+
- For Tensorflow conversion, it will cause to display extra logging and visualizations
252+
233253
Returns
234254
-------
235255
model : ``coremltools.models.MLModel`` or ``coremltools.converters.mil.Program``
@@ -284,9 +304,9 @@ def convert(
284304
exact_source = _determine_source(model, source, outputs)
285305
exact_target = _determine_target(convert_to, minimum_deployment_target)
286306
_validate_inputs(model, exact_source, inputs, outputs, classifier_config, compute_precision,
287-
exact_target, **kwargs)
307+
exact_target)
288308

289-
if "useCPUOnly" in kwargs and kwargs["useCPUOnly"]:
309+
if useCPUOnly:
290310
warnings.warn('The "useCPUOnly" parameter is deprecated and will be removed in 6.0. '
291311
'Use the compute_units parameter: "compute_units=coremotools.ComputeUnits.CPU_ONLY".')
292312
compute_units = _ComputeUnit.CPU_ONLY
@@ -313,7 +333,8 @@ def convert(
313333
transforms=tuple(transforms),
314334
skip_model_load=skip_model_load,
315335
compute_units=compute_units,
316-
**kwargs
336+
package_dir=package_dir,
337+
debug=debug,
317338
)
318339

319340
if exact_target == 'milinternal':
@@ -344,8 +365,7 @@ def _check_deployment_target(minimum_deployment_target):
344365
)
345366
raise TypeError(msg.format(minimum_deployment_target))
346367

347-
def _validate_inputs(model, exact_source, inputs, outputs, classifier_config, compute_precision, convert_to,
348-
**kwargs):
368+
def _validate_inputs(model, exact_source, inputs, outputs, classifier_config, compute_precision, convert_to):
349369
"""
350370
Validate and process model, inputs, outputs, classifier_config based on
351371
`exact_source` (which cannot be `auto`)
@@ -399,10 +419,6 @@ def raise_if_duplicated(input_list):
399419
raise ValueError("Input should be a list of TensorType or ImageType")
400420

401421
elif exact_source == "pytorch":
402-
if "example_inputs" in kwargs:
403-
msg = 'Unexpected argument "example_inputs" found'
404-
raise ValueError(msg)
405-
406422
if inputs is None:
407423
msg = 'Expected argument for pytorch "inputs" not provided'
408424
raise ValueError(msg)

coremltools/converters/_profile_utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Copyright (c) 2021, Apple Inc. All rights reserved.
2+
#
3+
# Use of this source code is governed by a BSD-3-clause license that can be
4+
# found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5+
16
import os
27
import time
38

coremltools/converters/mil/__init__.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,58 @@
33
# Use of this source code is governed by a BSD-3-clause license that can be
44
# found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
55

6-
from .mil import *
6+
# This import should be pruned rdar://84519338
7+
from .mil import (
8+
block,
9+
Block,
10+
BoolInputType,
11+
BoolTensorInputType,
12+
builder,
13+
Builder,
14+
curr_block,
15+
DefaultInputs,
16+
FloatInputType,
17+
FloatTensorInputType,
18+
Function,
19+
get_existing_symbol,
20+
get_new_symbol,
21+
get_new_variadic_symbol,
22+
input_type,
23+
InputSpec,
24+
IntInputType,
25+
IntOrFloatInputType,
26+
IntOrFloatOrBoolInputType,
27+
IntTensorInputType,
28+
InternalInputType,
29+
InternalScalarOrTensorInputType,
30+
InternalStringInputType,
31+
InternalVar,
32+
ListInputType,
33+
ListOrScalarOrTensorInputType,
34+
ListVar,
35+
mil_list,
36+
operation,
37+
Operation,
38+
ops,
39+
Placeholder,
40+
precondition,
41+
program,
42+
Program,
43+
PyFunctionInputType,
44+
register_op,
45+
SPACES,
46+
SUPPORT_FLOAT_TYPES,
47+
SUPPORT_INT_TYPES,
48+
ScalarOrTensorInputType,
49+
StringInputType,
50+
Symbol,
51+
TensorInputType,
52+
TupleInputType,
53+
types,
54+
var,
55+
Var,
56+
visitors
57+
)
758

859
from .frontend.torch import register_torch_op
960

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
# Copyright (c) 2020, Apple Inc. All rights reserved.
1+
# Copyright (c) 2020, Apple Inc. All rights reserved.
2+
#
3+
# Use of this source code is governed by a BSD-3-clause license that can be
4+
# found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
25

36
from .load import load

coremltools/converters/mil/backend/mil/helper.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Copyright (c) 2021, Apple Inc. All rights reserved.
2+
#
3+
# Use of this source code is governed by a BSD-3-clause license that can be
4+
# found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5+
16
import numpy as np
27
import os
38
import re

coremltools/converters/mil/backend/mil/load.py

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,56 @@
44
# found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
55

66
import logging
7-
import numpy as _np
7+
import numpy as np
88
import os
9-
import tempfile
10-
import shutil
119

12-
from coremltools.converters.mil.backend.mil.helper import *
13-
from coremltools.converters.mil.backend.backend_helper import _get_probability_var_for_classifier
1410
from .passes import mil_passes
15-
import coremltools.proto.MIL_pb2 as pm
16-
from coremltools.converters.mil.mil import types
17-
from coremltools.converters.mil.mil import Function
11+
from coremltools import _SPECIFICATION_VERSION_IOS_15
12+
from coremltools.converters.mil.backend.mil.helper import (
13+
cast_to_framework_io_dtype,
14+
create_file_value,
15+
create_immediate_value,
16+
create_list_scalarvalue,
17+
create_scalar_value,
18+
types_to_proto
19+
)
20+
from coremltools.converters.mil.backend.backend_helper import _get_probability_var_for_classifier
21+
from coremltools.converters.mil.mil import (
22+
Builder as mb,
23+
Function,
24+
mil_list,
25+
types
26+
)
1827
from coremltools.converters.mil.backend.nn.load import _set_optional_inputs
28+
from coremltools.converters.mil.input_types import ImageType, TensorType, EnumeratedShapes, RangeDim
1929
from coremltools.converters.mil.mil.ops.registry import SSAOpRegistry
2030
from coremltools.converters.mil.mil.types.symbolic import (
2131
any_symbolic,
2232
any_variadic,
2333
is_symbolic,
2434
)
35+
from coremltools.converters.mil.mil.types.type_mapping import types_int64
36+
from coremltools.libmilstoragepython import _BlobStorageWriter as BlobWriter
37+
from coremltools.models.model import _WEIGHTS_FILE_NAME
2538
from coremltools.models.neural_network.flexible_shape_utils import (
26-
NeuralNetworkImageSize,
27-
NeuralNetworkImageSizeRange,
2839
add_enumerated_image_sizes,
2940
add_multiarray_ndshape_enumeration,
41+
NeuralNetworkImageSize,
42+
NeuralNetworkImageSizeRange,
3043
set_multiarray_ndshape_range,
31-
update_image_size_range,
44+
update_image_size_range
45+
)
46+
from coremltools.proto import (
47+
FeatureTypes_pb2 as ft,
48+
MIL_pb2 as pm,
49+
Model_pb2 as ml
3250
)
3351

34-
from coremltools.libmilstoragepython import _BlobStorageWriter as BlobWriter
35-
36-
import coremltools.proto.Model_pb2 as ml
37-
import coremltools.proto.FeatureTypes_pb2 as ft
38-
from coremltools.converters.mil.input_types import ImageType, TensorType, EnumeratedShapes, RangeDim
39-
from coremltools.models.model import _WEIGHTS_FILE_NAME
40-
from coremltools.converters.mil.mil import Builder as mb
41-
from coremltools.converters.mil.mil import mil_list
42-
from coremltools import _SPECIFICATION_VERSION_IOS_15
4352

4453
def should_use_weight_file(val):
4554
return (
4655
val is not None
47-
and isinstance(val, (_np.ndarray, _np.generic))
56+
and isinstance(val, (np.ndarray, np.generic))
4857
and val.size >= 10
4958
and val.dtype in ['float16', 'float32']
5059
)
@@ -97,7 +106,7 @@ def translate_generic_op(op, parameters, blob_writer, literal_params=[]):
97106
blocks = None
98107
if len(op.blocks) > 0:
99108
blocks = [create_block(b, parameters, blob_writer) \
100-
for b in op.blocks]
109+
for b in op.blocks]
101110

102111
op_type = op.op_type
103112
attr_dict = {}
@@ -206,6 +215,9 @@ def _add_classify_op(prog, classifier_config):
206215

207216
# add the classify op now
208217
with block:
218+
# cast the int label to np.int64
219+
if isinstance(classes[0], int):
220+
classes = [np.int64(x) for x in classes]
209221
classes_var = mb.const(val=mil_list(classes))
210222
out = mb.classify(probabilities=probability_var, classes=classes_var)
211223

@@ -344,7 +356,7 @@ def load(prog, weights_dir, resume_on_errors=False, **kwargs):
344356
keytype, valtype = var.sym_type.T
345357
if types.is_str(keytype):
346358
output_feature_type.dictionaryType.stringKeyType.MergeFromString(b"")
347-
elif (keytype == types_int64):
359+
elif (keytype == types.int64):
348360
output_feature_type.dictionaryType.int64KeyType.MergeFromString(b"")
349361
else:
350362
raise ValueError("Dictionary key type not supported.")
@@ -445,7 +457,6 @@ def load(prog, weights_dir, resume_on_errors=False, **kwargs):
445457
model, input_name, lower_bounds=lb, upper_bounds=ub
446458
)
447459

448-
449460
# Set optional inputs
450461
_set_optional_inputs(model, input_types)
451462

0 commit comments

Comments
 (0)