leap-model-parser 0.1.225.dev2__tar.gz → 0.1.227__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/PKG-INFO +2 -2
  2. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/contract/graph.py +1 -1
  3. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/keras_json_model_import.py +1 -1
  4. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/leap_graph_editor.py +18 -0
  5. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/model_parser.py +45 -9
  6. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/pyproject.toml +2 -2
  7. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/LICENSE +0 -0
  8. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/README.md +0 -0
  9. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/__init__.py +0 -0
  10. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/contract/__init__.py +0 -0
  11. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/contract/importmodelresponse.py +0 -0
  12. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/contract/nodedata.py +0 -0
  13. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/contract/ui_components.json +0 -0
  14. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/__init__.py +0 -0
  15. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/layerpedia/__init__.py +0 -0
  16. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/layerpedia/layerpedia.py +0 -0
  17. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/tlinspection/__init__.py +0 -0
  18. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/tlinspection/leapinspection.py +0 -0
  19. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/uicomponents/__init__.py +0 -0
  20. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/uicomponents/generatenodedata.py +0 -0
  21. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/uicomponents/tensorflowinscpection.py +0 -0
  22. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/uicomponents/ui_components.json +0 -0
  23. {leap_model_parser-0.1.225.dev2 → leap_model_parser-0.1.227}/leap_model_parser/utils/uicomponents/ui_components_config.yaml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: leap-model-parser
3
- Version: 0.1.225.dev2
3
+ Version: 0.1.227
4
4
  Summary:
5
5
  Home-page: https://github.com/tensorleap/leap-model-parser
6
6
  License: MIT
@@ -17,7 +17,7 @@ Requires-Dist: keras-data-format-converter (==0.1.22)
17
17
  Requires-Dist: leap-model-rebuilder (==0.1.7)
18
18
  Requires-Dist: numpy (>=1.22.3,<2.0.0)
19
19
  Requires-Dist: onnx (==1.13.0)
20
- Requires-Dist: onnx2kerastl (==0.0.175)
20
+ Requires-Dist: onnx2kerastl (==0.0.176)
21
21
  Requires-Dist: tensorflow (==2.12.0) ; platform_machine == "x86_64"
22
22
  Requires-Dist: tensorflow-io-gcs-filesystem (==0.34.0)
23
23
  Requires-Dist: tensorflow-macos (==2.12.0) ; platform_machine == "arm64"
@@ -47,7 +47,7 @@ class Node:
47
47
  outputs: Dict[str, ConnectionOutput] = field(default_factory=dict)
48
48
  pruning_plan_id: Optional[str] = None
49
49
  wrapper: Optional[WrapperData] = None
50
- shape: Optional[List[Optional[str]]] = None
50
+ shape: Optional[List[str]] = None
51
51
 
52
52
  def __key(self):
53
53
  return (self.id, self.name)
@@ -205,7 +205,7 @@ class KerasJsonModelImport:
205
205
  'serialized_call_kwargs': serialized_call_kwargs})
206
206
 
207
207
  def generate_regular_node(self, layer: Dict[str, Any], layer_metadata: Dict[str, Any], node_key: str,
208
- layer_name_to_inbound_nodes: Dict[str, List[Node]]):
208
+ layer_name_to_inbound_nodes: Dict[str, List[keras_node]]):
209
209
  data = layer['config']
210
210
  if layer['class_name'] in ('TFOpLambda', 'SlicingOpLambda') or layer['class_name'] in self.custom_layers:
211
211
  call_args = layer_name_to_inbound_nodes[layer['config']
@@ -127,6 +127,22 @@ class LeapGraphEditor:
127
127
  self.model_graph[new_node_id] = ground_truth_node
128
128
  return new_node_id
129
129
 
130
+ def _add_input_encoder_not_connected_to_the_model_node(self, input_name: str) -> str:
131
+ new_node_id = self._generate_new_node_id()
132
+ ground_truth_node = Node(
133
+ new_node_id,
134
+ 'Input',
135
+ position=[0, 0],
136
+ data={'name': input_name, 'output_name': input_name,
137
+ 'type': 'Input', "selected": input_name},
138
+ inputs={},
139
+ outputs={
140
+ f'{new_node_id}-{input_name}': ConnectionOutput([])
141
+ }
142
+ )
143
+ self.model_graph[new_node_id] = ground_truth_node
144
+ return new_node_id
145
+
130
146
  def _add_visualizer_node(self, visualizer_name: str, visualizer_type: str,
131
147
  user_unique_name: str, arg_names: List[str]) -> str:
132
148
  new_node_id = self._generate_new_node_id()
@@ -240,6 +256,8 @@ class LeapGraphEditor:
240
256
  if input_node_id is None:
241
257
  if input_node.type == NodeMappingType.GroundTruth:
242
258
  input_node_id = self._add_ground_truth_node(input_node.name)
259
+ elif input_node.type == NodeMappingType.Input:
260
+ input_node_id = self._add_input_encoder_not_connected_to_the_model_node(input_node.name)
243
261
  else:
244
262
  raise Exception(f'Couldnt find input node name {input_node.name}')
245
263
  elif 'Input' in input_node.type.value:
@@ -1,13 +1,13 @@
1
+ # mypy: ignore-errors
2
+
1
3
  import glob
2
4
  import json
3
5
  import ntpath
4
- import pickle
5
6
  import tarfile
6
7
  import tempfile
7
8
  from importlib.util import find_spec
8
9
  from pathlib import Path
9
10
 
10
-
11
11
  import tensorflow as tf # type: ignore
12
12
  from code_loader.contract.mapping import NodeConnection, NodeMapping # type: ignore
13
13
  from keras import Model # type: ignore
@@ -34,6 +34,7 @@ if spec is not None:
34
34
 
35
35
  onnx_imported = True
36
36
 
37
+
37
38
  class ModelParser:
38
39
  def __init__(self, should_transform_inputs_and_outputs=False,
39
40
  custom_layers=None,
@@ -54,12 +55,14 @@ class ModelParser:
54
55
  ImportModelTypeEnum.PB_TF2.value: self.convert_pb_model,
55
56
  }
56
57
 
57
- def _add_output_node_shape_to_model_schema(self, model_schema: Dict, keras_model: Model):
58
+ @staticmethod
59
+ def _add_output_node_shape_to_model_schema(model_schema: Dict, keras_model: Model):
58
60
  for i, layer in enumerate(keras_model.layers):
59
61
  model_schema['config']['layers'][i]['output_shape'] = list(layer.output_shape)
60
62
 
61
63
  def get_keras_model_and_model_graph(
62
- self, model_path: Path, model_type: ImportModelTypeEnum) -> Tuple[Dict[str, Node], List[InputInfo], Optional[Model], Optional[str]]:
64
+ self, model_path: Path, model_type: ImportModelTypeEnum) -> Tuple[
65
+ Dict[str, Node], List[InputInfo], Optional[Model], Optional[str]]:
63
66
  model_to_keras_converter: Optional[Callable[[str], Tuple[Dict[str, Node], Model, Optional[str]]]] = \
64
67
  self._model_types_converter.get(model_type.value)
65
68
  if model_to_keras_converter is None:
@@ -90,7 +93,6 @@ class ModelParser:
90
93
 
91
94
  return graph, connected_inputs, keras_model_with_weights, error_info
92
95
 
93
-
94
96
  def _get_k_model_from_pb_path(self, file_path: str):
95
97
  tar_file = tarfile.open(file_path)
96
98
  with tempfile.TemporaryDirectory() as temp_dir:
@@ -105,7 +107,8 @@ class ModelParser:
105
107
  k_model = self._load_keras_model_with_custom_layers(pb_folder_path)
106
108
  return k_model
107
109
 
108
- def generate_model_graph(self, model_path: Path, model_type: ImportModelTypeEnum) -> Tuple[Dict[str, Node], List[InputInfo]]:
110
+ def generate_model_graph(self, model_path: Path, model_type: ImportModelTypeEnum) -> Tuple[
111
+ Dict[str, Node], List[InputInfo]]:
109
112
  model_graph, connected_inputs, _, error_info = self.get_keras_model_and_model_graph(
110
113
  model_path, model_type)
111
114
  return model_graph, connected_inputs
@@ -130,23 +133,56 @@ class ModelParser:
130
133
  node.name for node in onnx_model.graph.initializer]
131
134
  input_names = list(set(input_all) - set(input_initializer))
132
135
  converted_response: ConvertedResponse = onnx_to_keras(onnx_model, input_names=input_names,
133
- name_policy='attach_weights_name', allow_partial_compilation=False)
136
+ name_policy='attach_weights_name',
137
+ allow_partial_compilation=False)
134
138
  return self.convert_to_keras_model(converted_response.converted_model, converted_response.error_info)
135
139
 
136
140
  def _load_keras_model_with_custom_layers(self, file_path: str):
137
141
  custom_objects = {}
138
142
  if self.custom_layers is not None:
139
143
  custom_objects = self.custom_layers
140
- return load_model(file_path, custom_objects=custom_objects, compile=False)
144
+
145
+ try:
146
+ return load_model(file_path, custom_objects=custom_objects, compile=False)
147
+ except OSError as e:
148
+ if 'signature' in str(e):
149
+ raise Exception('Unable to open model file. The model might be corrupted or not a valid.')
150
+ else:
151
+ raise e
152
+
141
153
 
142
154
  def convert_h5_model(self, file_path: str) -> Tuple[Dict[str, Node], Model, Optional[str]]:
143
155
  imported_model = self._load_keras_model_with_custom_layers(file_path)
144
156
  return self.convert_to_keras_model(imported_model)
145
157
 
146
- def convert_to_keras_model(self, k_model, error_info: Optional[str] = None) -> Tuple[Dict[str, Node], Model, Optional[str]]:
158
+ def convert_to_keras_model(self, k_model, error_info: Optional[str] = None) -> Tuple[
159
+ Dict[str, Node], Model, Optional[str]]:
147
160
  converted_k_model = convert_channels_first_to_last(
148
161
  k_model, self._should_transform_inputs_and_outputs, self.custom_layers)
149
162
 
163
+ from keras.saving.legacy.saved_model import json_utils # type: ignore
164
+ import numpy as np
165
+
166
+ _orig_get_json_type = json_utils.get_json_type
167
+
168
+
169
+ def _patched_get_json_type(obj): # type: ignore
170
+ # Handle numpy dtype explicitly
171
+ if isinstance(obj, np.dtype):
172
+ return obj.name # e.g. "int64"
173
+ # Make sure common numpy scalars/containers are handled robustly
174
+ if isinstance(obj, np.integer):
175
+ return int(obj)
176
+ if isinstance(obj, np.floating):
177
+ return float(obj)
178
+ if isinstance(obj, np.bool_):
179
+ return bool(obj)
180
+ if isinstance(obj, np.ndarray):
181
+ return obj.tolist()
182
+ return _orig_get_json_type(obj)
183
+
184
+ json_utils.get_json_type = _patched_get_json_type
185
+
150
186
  model_schema = json.loads(converted_k_model.to_json())
151
187
 
152
188
  return model_schema, converted_k_model, error_info
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "leap-model-parser"
3
- version = "0.1.225.dev2"
3
+ version = "0.1.227"
4
4
  description = ""
5
5
  authors = ["idan <idan.yogev@tensorleap.ai>"]
6
6
  license = "MIT"
@@ -18,7 +18,7 @@ tensorflow = {version = "2.12.0", markers = "platform_machine == 'x86_64'"}
18
18
  tensorflow-macos = {version = "2.12.0", markers = "platform_machine == 'arm64'"}
19
19
  numpy = "^1.22.3"
20
20
  onnx = "1.13.0"
21
- onnx2kerastl = "0.0.175"
21
+ onnx2kerastl = "0.0.176"
22
22
  keras-data-format-converter = "0.1.22"
23
23
  leap-model-rebuilder = "0.1.7"
24
24
  tensorflow-io-gcs-filesystem = "0.34.0"