modelconv 0.5.2__tar.gz → 0.5.3__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.
- {modelconv-0.5.2 → modelconv-0.5.3}/PKG-INFO +6 -4
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconv.egg-info/PKG-INFO +6 -4
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconv.egg-info/SOURCES.txt +6 -1
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconv.egg-info/requires.txt +5 -3
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/__init__.py +1 -1
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/__main__.py +19 -5
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/cli/utils.py +4 -2
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/base_exporter.py +16 -11
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/hailo/requirements.txt +1 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc3/exporter.py +4 -1
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc4/exporter.py +31 -17
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc4/requirements.txt +1 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/__init__.py +4 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/calibration_data.py +25 -2
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/config.py +90 -38
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/docker_utils.py +44 -1
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/nn_archive.py +10 -1
- modelconv-0.5.3/modelconverter/utils/onnx_compatibility.py +64 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/onnx_tools.py +24 -20
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/types.py +8 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/requirements.txt +3 -3
- modelconv-0.5.3/tests/test_benchmark/conftest.py +36 -0
- modelconv-0.5.3/tests/test_benchmark/test_benchmark_regression.py +74 -0
- modelconv-0.5.3/tests/test_utils/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_utils/test_config.py +5 -2
- modelconv-0.5.3/tests/test_utils/test_onnx_compatibility.py +112 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/LICENSE +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/README.md +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconv.egg-info/dependency_links.txt +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconv.egg-info/entry_points.txt +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconv.egg-info/top_level.txt +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/cli/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/base_analyze.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/base_benchmark.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/base_inferer.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/base_visualize.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/getters.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/hailo/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/hailo/exporter.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/hailo/inferer.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/multistage_exporter.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc2/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc2/benchmark.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc2/exporter.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc2/inferer.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc2/requirements.txt +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc3/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc3/benchmark.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc3/inferer.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc3/requirements.txt +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc4/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc4/analyze.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc4/benchmark.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc4/inferer.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/packages/rvc4/visualize.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/adb_handler.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/adb_monitor.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/constants.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/environ.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/exceptions.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/filesystem_utils.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/general.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/hub_requests.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/hubai_utils.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/image.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/layout.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/metadata.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/progress_handler.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/modelconverter/utils/subprocess.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/pyproject.toml +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/requirements-analysis.txt +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/requirements-bench.txt +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/requirements-dev.txt +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/setup.cfg +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/conftest.py +0 -0
- {modelconv-0.5.2/tests/test_packages → modelconv-0.5.3/tests/test_benchmark}/__init__.py +0 -0
- {modelconv-0.5.2/tests/test_utils → modelconv-0.5.3/tests/test_packages}/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/common.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/metrics/__init__.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/metrics/base_metric.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/metrics/mnist_metric.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/metrics/resnet_metric.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/metrics/yolov6_metric.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/onnx_inferer.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/test_cross_format_export.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/test_hailo.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/test_rvc2.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/test_rvc3.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_packages/test_rvc4.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_utils/conftest.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_utils/test_filesystem.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_utils/test_image.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_utils/test_layout.py +0 -0
- {modelconv-0.5.2 → modelconv-0.5.3}/tests/test_utils/test_modifier.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modelconv
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
4
4
|
Summary: Converter for neural models into various formats.
|
|
5
5
|
Author-email: Luxonis <support@luxonis.com>
|
|
6
6
|
Maintainer-email: Luxonis <support@luxonis.com>
|
|
@@ -17,9 +17,9 @@ Requires-Python: >=3.10
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: Pillow
|
|
20
|
-
Requires-Dist: luxonis-ml[data,gcs,nn_archive,s3]>=0.8.
|
|
21
|
-
Requires-Dist: cyclopts
|
|
22
|
-
Requires-Dist: onnx
|
|
20
|
+
Requires-Dist: luxonis-ml[data,gcs,nn_archive,s3]>=0.8.4
|
|
21
|
+
Requires-Dist: cyclopts==4.8.0
|
|
22
|
+
Requires-Dist: onnx==1.21.0
|
|
23
23
|
Requires-Dist: onnxruntime
|
|
24
24
|
Requires-Dist: onnxsim
|
|
25
25
|
Requires-Dist: docker
|
|
@@ -49,12 +49,14 @@ Requires-Dist: psutil; extra == "rvc4"
|
|
|
49
49
|
Requires-Dist: numpy<2; extra == "rvc4"
|
|
50
50
|
Requires-Dist: polars; extra == "rvc4"
|
|
51
51
|
Requires-Dist: pytest; extra == "rvc4"
|
|
52
|
+
Requires-Dist: onnx==1.18.0; extra == "rvc4"
|
|
52
53
|
Provides-Extra: hailo
|
|
53
54
|
Requires-Dist: nvidia-dali-cuda120==1.49.0; extra == "hailo"
|
|
54
55
|
Requires-Dist: nvidia-dali-tf-plugin-cuda120==1.49.0; extra == "hailo"
|
|
55
56
|
Requires-Dist: protobuf==3.20.3; extra == "hailo"
|
|
56
57
|
Requires-Dist: matplotlib==3.10.6; extra == "hailo"
|
|
57
58
|
Requires-Dist: pyparsing==2.4.7; extra == "hailo"
|
|
59
|
+
Requires-Dist: onnx==1.17.0; extra == "hailo"
|
|
58
60
|
Dynamic: license-file
|
|
59
61
|
|
|
60
62
|
# ModelConverter - Compilation Library
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modelconv
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
4
4
|
Summary: Converter for neural models into various formats.
|
|
5
5
|
Author-email: Luxonis <support@luxonis.com>
|
|
6
6
|
Maintainer-email: Luxonis <support@luxonis.com>
|
|
@@ -17,9 +17,9 @@ Requires-Python: >=3.10
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: Pillow
|
|
20
|
-
Requires-Dist: luxonis-ml[data,gcs,nn_archive,s3]>=0.8.
|
|
21
|
-
Requires-Dist: cyclopts
|
|
22
|
-
Requires-Dist: onnx
|
|
20
|
+
Requires-Dist: luxonis-ml[data,gcs,nn_archive,s3]>=0.8.4
|
|
21
|
+
Requires-Dist: cyclopts==4.8.0
|
|
22
|
+
Requires-Dist: onnx==1.21.0
|
|
23
23
|
Requires-Dist: onnxruntime
|
|
24
24
|
Requires-Dist: onnxsim
|
|
25
25
|
Requires-Dist: docker
|
|
@@ -49,12 +49,14 @@ Requires-Dist: psutil; extra == "rvc4"
|
|
|
49
49
|
Requires-Dist: numpy<2; extra == "rvc4"
|
|
50
50
|
Requires-Dist: polars; extra == "rvc4"
|
|
51
51
|
Requires-Dist: pytest; extra == "rvc4"
|
|
52
|
+
Requires-Dist: onnx==1.18.0; extra == "rvc4"
|
|
52
53
|
Provides-Extra: hailo
|
|
53
54
|
Requires-Dist: nvidia-dali-cuda120==1.49.0; extra == "hailo"
|
|
54
55
|
Requires-Dist: nvidia-dali-tf-plugin-cuda120==1.49.0; extra == "hailo"
|
|
55
56
|
Requires-Dist: protobuf==3.20.3; extra == "hailo"
|
|
56
57
|
Requires-Dist: matplotlib==3.10.6; extra == "hailo"
|
|
57
58
|
Requires-Dist: pyparsing==2.4.7; extra == "hailo"
|
|
59
|
+
Requires-Dist: onnx==1.17.0; extra == "hailo"
|
|
58
60
|
Dynamic: license-file
|
|
59
61
|
|
|
60
62
|
# ModelConverter - Compilation Library
|
|
@@ -61,12 +61,16 @@ modelconverter/utils/image.py
|
|
|
61
61
|
modelconverter/utils/layout.py
|
|
62
62
|
modelconverter/utils/metadata.py
|
|
63
63
|
modelconverter/utils/nn_archive.py
|
|
64
|
+
modelconverter/utils/onnx_compatibility.py
|
|
64
65
|
modelconverter/utils/onnx_tools.py
|
|
65
66
|
modelconverter/utils/progress_handler.py
|
|
66
67
|
modelconverter/utils/subprocess.py
|
|
67
68
|
modelconverter/utils/types.py
|
|
68
69
|
tests/__init__.py
|
|
69
70
|
tests/conftest.py
|
|
71
|
+
tests/test_benchmark/__init__.py
|
|
72
|
+
tests/test_benchmark/conftest.py
|
|
73
|
+
tests/test_benchmark/test_benchmark_regression.py
|
|
70
74
|
tests/test_packages/__init__.py
|
|
71
75
|
tests/test_packages/common.py
|
|
72
76
|
tests/test_packages/onnx_inferer.py
|
|
@@ -86,4 +90,5 @@ tests/test_utils/test_config.py
|
|
|
86
90
|
tests/test_utils/test_filesystem.py
|
|
87
91
|
tests/test_utils/test_image.py
|
|
88
92
|
tests/test_utils/test_layout.py
|
|
89
|
-
tests/test_utils/test_modifier.py
|
|
93
|
+
tests/test_utils/test_modifier.py
|
|
94
|
+
tests/test_utils/test_onnx_compatibility.py
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Pillow
|
|
2
|
-
luxonis-ml[data,gcs,nn_archive,s3]>=0.8.
|
|
3
|
-
cyclopts
|
|
4
|
-
onnx
|
|
2
|
+
luxonis-ml[data,gcs,nn_archive,s3]>=0.8.4
|
|
3
|
+
cyclopts==4.8.0
|
|
4
|
+
onnx==1.21.0
|
|
5
5
|
onnxruntime
|
|
6
6
|
onnxsim
|
|
7
7
|
docker
|
|
@@ -29,6 +29,7 @@ nvidia-dali-tf-plugin-cuda120==1.49.0
|
|
|
29
29
|
protobuf==3.20.3
|
|
30
30
|
matplotlib==3.10.6
|
|
31
31
|
pyparsing==2.4.7
|
|
32
|
+
onnx==1.17.0
|
|
32
33
|
|
|
33
34
|
[rvc2]
|
|
34
35
|
tflite2onnx
|
|
@@ -44,3 +45,4 @@ psutil
|
|
|
44
45
|
numpy<2
|
|
45
46
|
polars
|
|
46
47
|
pytest
|
|
48
|
+
onnx==1.18.0
|
|
@@ -4,7 +4,7 @@ from typing import Final
|
|
|
4
4
|
from luxonis_ml.utils import PUT_FILE_REGISTRY
|
|
5
5
|
from pydantic_extra_types.semantic_version import SemanticVersion
|
|
6
6
|
|
|
7
|
-
__version__: Final[str] = "0.5.
|
|
7
|
+
__version__: Final[str] = "0.5.3"
|
|
8
8
|
__semver__: Final[SemanticVersion] = SemanticVersion.parse(__version__)
|
|
9
9
|
|
|
10
10
|
|
|
@@ -33,6 +33,8 @@ from modelconverter.utils import (
|
|
|
33
33
|
archive_from_model,
|
|
34
34
|
docker_build,
|
|
35
35
|
docker_exec,
|
|
36
|
+
get_default_target_version,
|
|
37
|
+
get_local_docker_image,
|
|
36
38
|
in_docker,
|
|
37
39
|
resolve_path,
|
|
38
40
|
upload_to_remote,
|
|
@@ -127,7 +129,7 @@ def convert(
|
|
|
127
129
|
|
|
128
130
|
with catch_exceptions():
|
|
129
131
|
init_dirs()
|
|
130
|
-
cfg, archive_cfg, _main_stage = get_configs(path, opts)
|
|
132
|
+
cfg, archive_cfg, _main_stage = get_configs(target, path, opts)
|
|
131
133
|
main_stage = main_stage or _main_stage
|
|
132
134
|
is_multistage = len(cfg.stages) > 1
|
|
133
135
|
if is_multistage and main_stage is None:
|
|
@@ -264,7 +266,7 @@ def infer(
|
|
|
264
266
|
if path is not None:
|
|
265
267
|
config = path
|
|
266
268
|
with catch_exceptions():
|
|
267
|
-
mult_cfg, _, _ = get_configs(str(config), opts)
|
|
269
|
+
mult_cfg, _, _ = get_configs(target, str(config), opts)
|
|
268
270
|
cfg = mult_cfg.get_stage_config(stage)
|
|
269
271
|
setup_logging(
|
|
270
272
|
file="modelconverter.log", use_rich=mult_cfg.rich_logging
|
|
@@ -630,9 +632,21 @@ def launcher(
|
|
|
630
632
|
target = bound.arguments["target"]
|
|
631
633
|
|
|
632
634
|
if dev:
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
635
|
+
version = tool_version or get_default_target_version(target.value)
|
|
636
|
+
# CI invokes multiple dev docker commands per job; reuse the first
|
|
637
|
+
# local build so later commands don't rebuild the same image again.
|
|
638
|
+
if not (
|
|
639
|
+
os.getenv("CI") == "true"
|
|
640
|
+
and get_local_docker_image(
|
|
641
|
+
target.value,
|
|
642
|
+
bare_tag=tag,
|
|
643
|
+
version=version,
|
|
644
|
+
image=image,
|
|
645
|
+
)
|
|
646
|
+
):
|
|
647
|
+
docker_build(
|
|
648
|
+
target.value, bare_tag=tag, version=version, image=image
|
|
649
|
+
)
|
|
636
650
|
|
|
637
651
|
docker_exec(
|
|
638
652
|
target.value,
|
|
@@ -72,7 +72,9 @@ def init_dirs() -> None:
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
def get_configs(
|
|
75
|
-
|
|
75
|
+
target: Target,
|
|
76
|
+
path: str | None,
|
|
77
|
+
opts: list[str] | dict[str, Any] | None = None,
|
|
76
78
|
) -> tuple[Config, NNArchiveConfig | None, str | None]:
|
|
77
79
|
"""Sets up the configuration.
|
|
78
80
|
|
|
@@ -99,7 +101,7 @@ def get_configs(
|
|
|
99
101
|
if path is not None:
|
|
100
102
|
path_ = resolve_path(path, MISC_DIR)
|
|
101
103
|
if path_.is_dir() or is_nn_archive(path_):
|
|
102
|
-
return process_nn_archive(path_, overrides)
|
|
104
|
+
return process_nn_archive(target, path_, overrides)
|
|
103
105
|
cfg = Config.get_config(path, overrides)
|
|
104
106
|
|
|
105
107
|
main_stage_key = None
|
|
@@ -6,7 +6,6 @@ from pathlib import Path
|
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
8
|
import numpy as np
|
|
9
|
-
import onnx
|
|
10
9
|
from loguru import logger
|
|
11
10
|
|
|
12
11
|
from modelconverter.utils import (
|
|
@@ -20,6 +19,7 @@ from modelconverter.utils.config import (
|
|
|
20
19
|
RandomCalibrationConfig,
|
|
21
20
|
SingleStageConfig,
|
|
22
21
|
)
|
|
22
|
+
from modelconverter.utils.onnx_compatibility import save_onnx_model
|
|
23
23
|
from modelconverter.utils.subprocess import SubprocessResult
|
|
24
24
|
from modelconverter.utils.types import InputFileType, Target
|
|
25
25
|
|
|
@@ -129,7 +129,13 @@ class Exporter(ABC):
|
|
|
129
129
|
)
|
|
130
130
|
return self.input_model
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
try:
|
|
133
|
+
onnx_sim, check = simplify(str(self.input_model))
|
|
134
|
+
except Exception as e:
|
|
135
|
+
logger.warning(
|
|
136
|
+
f"Failed to simplify ONNX: {e}. Proceeding without simplification."
|
|
137
|
+
)
|
|
138
|
+
return self.input_model
|
|
133
139
|
if not check:
|
|
134
140
|
logger.warning(
|
|
135
141
|
"Provided ONNX could not be simplified. "
|
|
@@ -141,15 +147,14 @@ class Exporter(ABC):
|
|
|
141
147
|
self.input_model, "simplified.onnx"
|
|
142
148
|
)
|
|
143
149
|
logger.info(f"Saving simplified ONNX to {onnx_sim_path}")
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
onnx.save(onnx_sim, str(onnx_sim_path))
|
|
150
|
+
save_onnx_model(
|
|
151
|
+
onnx_sim,
|
|
152
|
+
onnx_sim_path,
|
|
153
|
+
save_as_external_data=self.input_model.with_suffix(
|
|
154
|
+
".onnx_data"
|
|
155
|
+
).exists(),
|
|
156
|
+
location=f"{onnx_sim_path.name}_data",
|
|
157
|
+
)
|
|
153
158
|
return onnx_sim_path
|
|
154
159
|
|
|
155
160
|
@abstractmethod
|
|
@@ -106,7 +106,10 @@ class RVC3Exporter(RVC2Exporter):
|
|
|
106
106
|
data_type=DataType.UINT8,
|
|
107
107
|
transpose=False,
|
|
108
108
|
)
|
|
109
|
-
|
|
109
|
+
suffix = ".png" if file.suffix == ".npy" else file.suffix
|
|
110
|
+
cv2.imwrite(
|
|
111
|
+
str((calibration_img_dir / file.stem).with_suffix(suffix)), img
|
|
112
|
+
)
|
|
110
113
|
|
|
111
114
|
config = {
|
|
112
115
|
"model": {
|
|
@@ -40,6 +40,7 @@ class RVC4Exporter(Exporter):
|
|
|
40
40
|
super().__init__(config=config, output_dir=output_dir)
|
|
41
41
|
|
|
42
42
|
rvc4_cfg = config.rvc4
|
|
43
|
+
self.encodings = rvc4_cfg.encodings
|
|
43
44
|
self.snpe_onnx_to_dlc = rvc4_cfg.snpe_onnx_to_dlc_args
|
|
44
45
|
self.snpe_dlc_quant = rvc4_cfg.snpe_dlc_quant_args
|
|
45
46
|
self.snpe_dlc_graph_prepare = rvc4_cfg.snpe_dlc_graph_prepare_args
|
|
@@ -186,6 +187,7 @@ class RVC4Exporter(Exporter):
|
|
|
186
187
|
args.append("--override_params")
|
|
187
188
|
elif self.quantization_mode == QuantizationMode.INT8_16_MIX:
|
|
188
189
|
self._add_args(args, ["--act_bitwidth", "16"])
|
|
190
|
+
elif self.encodings is not None:
|
|
189
191
|
args.append("--override_params")
|
|
190
192
|
|
|
191
193
|
start_time = time.time()
|
|
@@ -273,20 +275,28 @@ class RVC4Exporter(Exporter):
|
|
|
273
275
|
return self.input_list_path
|
|
274
276
|
|
|
275
277
|
def generate_io_encodings(self) -> Path:
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
"Cannot generate I/O encodings as inputs or outputs are not defined. The resulting DLC may not be compatible with DAI."
|
|
278
|
+
if self.encodings is not None:
|
|
279
|
+
encodings_dict = self.encodings.model_dump(
|
|
280
|
+
mode="json", exclude_none=True
|
|
280
281
|
)
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
282
|
+
else:
|
|
283
|
+
encodings_dict = {
|
|
284
|
+
"activation_encodings": {},
|
|
285
|
+
"param_encodings": {},
|
|
286
|
+
}
|
|
287
|
+
if not (list(self.inputs.keys()) and list(self.outputs.keys())):
|
|
288
|
+
logger.warning(
|
|
289
|
+
"Cannot generate I/O encodings as inputs or outputs are not defined. The resulting DLC may not be compatible with DAI."
|
|
290
|
+
)
|
|
291
|
+
for name in (
|
|
292
|
+
list(self.inputs.keys())
|
|
293
|
+
+ list(self.outputs.keys())
|
|
294
|
+
+ self.extra_quant_tensors
|
|
295
|
+
):
|
|
296
|
+
encodings_dict["activation_encodings"][name] = [
|
|
297
|
+
{"bitwidth": 8, "dtype": "int"}
|
|
298
|
+
]
|
|
299
|
+
encodings_path = self.intermediate_outputs_dir / "encodings.json"
|
|
290
300
|
with open(encodings_path, "w") as encodings_file:
|
|
291
301
|
json.dump(encodings_dict, encodings_file, indent=4)
|
|
292
302
|
return encodings_path
|
|
@@ -345,10 +355,14 @@ class RVC4Exporter(Exporter):
|
|
|
345
355
|
|
|
346
356
|
if self.quantization_mode == QuantizationMode.FP16_STD:
|
|
347
357
|
self._add_args(args, ["--float_bitwidth", "16"])
|
|
348
|
-
elif
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
358
|
+
elif (
|
|
359
|
+
self.quantization_mode
|
|
360
|
+
in [
|
|
361
|
+
QuantizationMode.INT8_16_MIX,
|
|
362
|
+
QuantizationMode.INT8_16_MIX_ACC,
|
|
363
|
+
]
|
|
364
|
+
or self.encodings is not None
|
|
365
|
+
):
|
|
352
366
|
io_encodings_file = self.generate_io_encodings()
|
|
353
367
|
self._add_args(
|
|
354
368
|
args,
|
|
@@ -7,7 +7,9 @@ from .docker_utils import (
|
|
|
7
7
|
docker_exec,
|
|
8
8
|
get_container_memory_available,
|
|
9
9
|
get_container_memory_limit,
|
|
10
|
+
get_default_target_version,
|
|
10
11
|
get_docker_image,
|
|
12
|
+
get_local_docker_image,
|
|
11
13
|
in_docker,
|
|
12
14
|
)
|
|
13
15
|
from .environ import environ
|
|
@@ -64,8 +66,10 @@ __all__ = [
|
|
|
64
66
|
"get_archive_input",
|
|
65
67
|
"get_container_memory_available",
|
|
66
68
|
"get_container_memory_limit",
|
|
69
|
+
"get_default_target_version",
|
|
67
70
|
"get_docker_image",
|
|
68
71
|
"get_extra_quant_tensors",
|
|
72
|
+
"get_local_docker_image",
|
|
69
73
|
"get_metadata",
|
|
70
74
|
"get_protocol",
|
|
71
75
|
"guess_new_layout",
|
|
@@ -27,15 +27,38 @@ def read_img_dir(path: Path, max_images: int) -> list[Path]:
|
|
|
27
27
|
return imgs
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
def _find_content_root(path: Path) -> Path:
|
|
31
|
+
ignored_entries = {"__MACOSX", "Thumbs.db", "desktop.ini"}
|
|
32
|
+
|
|
33
|
+
current = path
|
|
34
|
+
while True:
|
|
35
|
+
contents = [
|
|
36
|
+
p
|
|
37
|
+
for p in current.iterdir()
|
|
38
|
+
if p.name not in ignored_entries and not p.name.startswith(".")
|
|
39
|
+
]
|
|
40
|
+
subdirs = [p for p in contents if p.is_dir()]
|
|
41
|
+
files = [p for p in contents if p.is_file()]
|
|
42
|
+
|
|
43
|
+
if files:
|
|
44
|
+
return current
|
|
45
|
+
if len(subdirs) == 1:
|
|
46
|
+
current = subdirs[0]
|
|
47
|
+
else:
|
|
48
|
+
# Multiple subdirectories and no files. Return current and let read_img_dir raise an error
|
|
49
|
+
return current
|
|
50
|
+
|
|
51
|
+
|
|
30
52
|
def _get_from_remote(string: str, dest: Path, max_images: int = -1) -> Path:
|
|
31
53
|
path = download_from_remote(string, dest, max_images)
|
|
32
54
|
if path.suffix == ".zip":
|
|
33
55
|
extracted_path = path.with_suffix("")
|
|
34
56
|
if extracted_path.exists():
|
|
35
57
|
shutil.rmtree(extracted_path)
|
|
58
|
+
extracted_path.mkdir(parents=True, exist_ok=True)
|
|
36
59
|
with zipfile.ZipFile(path, "r") as zip_ref:
|
|
37
|
-
zip_ref.extractall(
|
|
38
|
-
return extracted_path
|
|
60
|
+
zip_ref.extractall(extracted_path)
|
|
61
|
+
return _find_content_root(extracted_path)
|
|
39
62
|
return path
|
|
40
63
|
|
|
41
64
|
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
+
import json
|
|
1
2
|
from itertools import chain
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Annotated, Any, Literal, cast
|
|
4
5
|
|
|
5
6
|
import onnx
|
|
6
7
|
from loguru import logger
|
|
7
|
-
from luxonis_ml.typing import PathType
|
|
8
|
+
from luxonis_ml.typing import BaseModelExtraForbid, PathType
|
|
8
9
|
from luxonis_ml.utils import LuxonisConfig
|
|
9
10
|
from onnx import TypeProto
|
|
10
11
|
from pydantic import (
|
|
11
|
-
BaseModel,
|
|
12
|
-
ConfigDict,
|
|
13
12
|
Field,
|
|
14
13
|
PositiveInt,
|
|
14
|
+
field_serializer,
|
|
15
15
|
field_validator,
|
|
16
16
|
model_validator,
|
|
17
17
|
)
|
|
18
18
|
from typing_extensions import Self
|
|
19
19
|
|
|
20
20
|
from modelconverter.utils.calibration_data import download_calibration_data
|
|
21
|
-
from modelconverter.utils.constants import MODELS_DIR
|
|
21
|
+
from modelconverter.utils.constants import MISC_DIR, MODELS_DIR
|
|
22
22
|
from modelconverter.utils.filesystem_utils import resolve_path
|
|
23
23
|
from modelconverter.utils.layout import make_default_layout
|
|
24
24
|
from modelconverter.utils.metadata import Metadata, get_metadata
|
|
25
|
+
from modelconverter.utils.onnx_compatibility import save_onnx_model
|
|
25
26
|
from modelconverter.utils.types import (
|
|
26
27
|
DataType,
|
|
27
28
|
Encoding,
|
|
@@ -40,11 +41,7 @@ NAMED_VALUES = {
|
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
|
|
43
|
-
class
|
|
44
|
-
model_config = ConfigDict(extra="forbid")
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class LinkCalibrationConfig(CustomBaseModel):
|
|
44
|
+
class LinkCalibrationConfig(BaseModelExtraForbid):
|
|
48
45
|
stage: str
|
|
49
46
|
output: str | None = None
|
|
50
47
|
script: str | None = None
|
|
@@ -68,7 +65,7 @@ class LinkCalibrationConfig(CustomBaseModel):
|
|
|
68
65
|
return script
|
|
69
66
|
|
|
70
67
|
|
|
71
|
-
class ImageCalibrationConfig(
|
|
68
|
+
class ImageCalibrationConfig(BaseModelExtraForbid):
|
|
72
69
|
path: Path
|
|
73
70
|
max_images: int = -1
|
|
74
71
|
resize_method: ResizeMethod = ResizeMethod.RESIZE
|
|
@@ -81,7 +78,7 @@ class ImageCalibrationConfig(CustomBaseModel):
|
|
|
81
78
|
return download_calibration_data(str(value))
|
|
82
79
|
|
|
83
80
|
|
|
84
|
-
class RandomCalibrationConfig(
|
|
81
|
+
class RandomCalibrationConfig(BaseModelExtraForbid):
|
|
85
82
|
max_images: int = 20
|
|
86
83
|
min_value: float = 0.0
|
|
87
84
|
max_value: float = 255.0
|
|
@@ -90,7 +87,7 @@ class RandomCalibrationConfig(CustomBaseModel):
|
|
|
90
87
|
data_type: DataType = DataType.FLOAT32
|
|
91
88
|
|
|
92
89
|
|
|
93
|
-
class OutputConfig(
|
|
90
|
+
class OutputConfig(BaseModelExtraForbid):
|
|
94
91
|
name: str
|
|
95
92
|
shape: list[int] | None = None
|
|
96
93
|
layout: str | None = None
|
|
@@ -123,7 +120,7 @@ class OutputConfig(CustomBaseModel):
|
|
|
123
120
|
return self
|
|
124
121
|
|
|
125
122
|
|
|
126
|
-
class EncodingConfig(
|
|
123
|
+
class EncodingConfig(BaseModelExtraForbid):
|
|
127
124
|
from_: Annotated[
|
|
128
125
|
Encoding, Field(alias="from", serialization_alias="from")
|
|
129
126
|
] = Encoding.RGB
|
|
@@ -225,7 +222,7 @@ class InputConfig(OutputConfig):
|
|
|
225
222
|
return value
|
|
226
223
|
|
|
227
224
|
|
|
228
|
-
class TargetConfig(
|
|
225
|
+
class TargetConfig(BaseModelExtraForbid):
|
|
229
226
|
disable_calibration: bool = False
|
|
230
227
|
|
|
231
228
|
|
|
@@ -265,6 +262,28 @@ class RVC3Config(BlobBaseConfig):
|
|
|
265
262
|
pot_target_device: PotDevice = PotDevice.VPU
|
|
266
263
|
|
|
267
264
|
|
|
265
|
+
class QuantizationOverridesItem(BaseModelExtraForbid):
|
|
266
|
+
bitwidth: Annotated[int, Literal[4, 8, 16, 32]] | None = None
|
|
267
|
+
is_symmetric: bool | None = None
|
|
268
|
+
dtype: Literal["int", "float"] | None = None
|
|
269
|
+
max: float | None = None
|
|
270
|
+
min: float | None = None
|
|
271
|
+
offset: int | None = None
|
|
272
|
+
scale: float | None = None
|
|
273
|
+
|
|
274
|
+
@field_serializer("is_symmetric", when_used="json")
|
|
275
|
+
@staticmethod
|
|
276
|
+
def serialize_is_symmetric(value: bool | None) -> str | None:
|
|
277
|
+
if value is None:
|
|
278
|
+
return None
|
|
279
|
+
return str(value)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class Encodings(BaseModelExtraForbid):
|
|
283
|
+
activation_encodings: dict[str, list[QuantizationOverridesItem]]
|
|
284
|
+
param_encodings: dict[str, list[QuantizationOverridesItem]]
|
|
285
|
+
|
|
286
|
+
|
|
268
287
|
class RVC4Config(TargetConfig):
|
|
269
288
|
snpe_onnx_to_dlc_args: list[str] = []
|
|
270
289
|
snpe_dlc_quant_args: list[str] = []
|
|
@@ -277,6 +296,37 @@ class RVC4Config(TargetConfig):
|
|
|
277
296
|
htp_socs: list[
|
|
278
297
|
Literal["sm8350", "sm8450", "sm8550", "sm8650", "qcs6490", "qcs8550"]
|
|
279
298
|
] = ["sm8550"]
|
|
299
|
+
encodings: Encodings | None = None
|
|
300
|
+
|
|
301
|
+
@model_validator(mode="after")
|
|
302
|
+
def validate_quantization_overrides(self) -> Self:
|
|
303
|
+
if "--quantization_overrides" in self.snpe_onnx_to_dlc_args:
|
|
304
|
+
if self.encodings:
|
|
305
|
+
raise ValueError(
|
|
306
|
+
"Cannot specify both `--quantization_overrides`"
|
|
307
|
+
"in `rvc4.snpe_onnx_to_dlc_args` and "
|
|
308
|
+
"`rvc4.encodings` at the same time."
|
|
309
|
+
)
|
|
310
|
+
qo_index = self.snpe_onnx_to_dlc_args.index(
|
|
311
|
+
"--quantization_overrides"
|
|
312
|
+
)
|
|
313
|
+
self.snpe_onnx_to_dlc_args.pop(qo_index)
|
|
314
|
+
encodings_json = self.snpe_onnx_to_dlc_args.pop(qo_index)
|
|
315
|
+
with open(encodings_json) as f:
|
|
316
|
+
self.encodings = Encodings.model_validate_json(json.load(f))
|
|
317
|
+
return self
|
|
318
|
+
|
|
319
|
+
@field_validator("encodings", mode="before")
|
|
320
|
+
@staticmethod
|
|
321
|
+
def validate_encodings(value: Any) -> Encodings | None:
|
|
322
|
+
if value is None:
|
|
323
|
+
return None
|
|
324
|
+
|
|
325
|
+
if isinstance(value, str):
|
|
326
|
+
value_path = resolve_path(value, MISC_DIR)
|
|
327
|
+
return Encodings(**json.loads(value_path.read_text()))
|
|
328
|
+
|
|
329
|
+
return Encodings(**value)
|
|
280
330
|
|
|
281
331
|
@model_validator(mode="after")
|
|
282
332
|
def _validate_fp16(self) -> Self:
|
|
@@ -286,7 +336,7 @@ class RVC4Config(TargetConfig):
|
|
|
286
336
|
return self
|
|
287
337
|
|
|
288
338
|
|
|
289
|
-
class SingleStageConfig(
|
|
339
|
+
class SingleStageConfig(BaseModelExtraForbid):
|
|
290
340
|
input_model: Path
|
|
291
341
|
input_bin: Path | None = None
|
|
292
342
|
input_file_type: InputFileType
|
|
@@ -592,14 +642,9 @@ def _get_onnx_node_info(
|
|
|
592
642
|
f"Output value info for node '{node_name}' not found."
|
|
593
643
|
)
|
|
594
644
|
|
|
595
|
-
shape =
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
if any(dim == 0 for dim in shape):
|
|
599
|
-
raise ValueError(
|
|
600
|
-
"Dynamic shapes are not supported. "
|
|
601
|
-
f"Shape of node '{node_name}' is {shape}."
|
|
602
|
-
)
|
|
645
|
+
shape = _get_static_onnx_shape(
|
|
646
|
+
output_value_info.type.tensor_type, f"node '{node_name}'"
|
|
647
|
+
)
|
|
603
648
|
data_type = output_value_info.type.tensor_type.elem_type
|
|
604
649
|
|
|
605
650
|
return shape, DataType.from_onnx_dtype(data_type)
|
|
@@ -613,12 +658,7 @@ def _get_onnx_tensor_info(
|
|
|
613
658
|
def extract_tensor_info(
|
|
614
659
|
tensor_type: TypeProto.Tensor,
|
|
615
660
|
) -> tuple[list[int], DataType]:
|
|
616
|
-
shape =
|
|
617
|
-
if any(dim == 0 for dim in shape):
|
|
618
|
-
raise ValueError(
|
|
619
|
-
"Dynamic shapes are not supported. "
|
|
620
|
-
f"Shape of tensor '{tensor_name}' is {shape}."
|
|
621
|
-
)
|
|
661
|
+
shape = _get_static_onnx_shape(tensor_type, f"tensor '{tensor_name}'")
|
|
622
662
|
return shape, DataType.from_onnx_dtype(tensor_type.elem_type)
|
|
623
663
|
|
|
624
664
|
for tensor in chain(model.graph.input, model.graph.output):
|
|
@@ -638,6 +678,21 @@ def _get_onnx_tensor_info(
|
|
|
638
678
|
raise NameError(f"Tensor '{tensor_name}' not found in the ONNX model.")
|
|
639
679
|
|
|
640
680
|
|
|
681
|
+
def _get_static_onnx_shape(
|
|
682
|
+
tensor_type: TypeProto.Tensor, tensor_name: str
|
|
683
|
+
) -> list[int]:
|
|
684
|
+
shape = []
|
|
685
|
+
for dim in tensor_type.shape.dim:
|
|
686
|
+
if dim.HasField("dim_value") and dim.dim_value > 0:
|
|
687
|
+
shape.append(dim.dim_value)
|
|
688
|
+
else:
|
|
689
|
+
raise ValueError(
|
|
690
|
+
"Dynamic shapes are not supported. "
|
|
691
|
+
f"Shape of {tensor_name} is {[d.dim_value for d in tensor_type.shape.dim]}."
|
|
692
|
+
)
|
|
693
|
+
return shape
|
|
694
|
+
|
|
695
|
+
|
|
641
696
|
def _get_onnx_inter_info(
|
|
642
697
|
model_path: Path, name: str
|
|
643
698
|
) -> tuple[list[int] | None, DataType | None]:
|
|
@@ -690,12 +745,9 @@ def generate_renamed_onnx(
|
|
|
690
745
|
if output_name in rename_dict:
|
|
691
746
|
node.output[i] = rename_dict[output_name]
|
|
692
747
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
)
|
|
700
|
-
else:
|
|
701
|
-
onnx.save(model, str(output_path))
|
|
748
|
+
save_onnx_model(
|
|
749
|
+
model,
|
|
750
|
+
output_path,
|
|
751
|
+
save_as_external_data=model_data_path is not None,
|
|
752
|
+
location=f"{output_path.name}_data",
|
|
753
|
+
)
|