py2edg 0.1.0__py3-none-any.whl
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.
- py2edg/__init__.py +80 -0
- py2edg/_imports.py +60 -0
- py2edg/api.py +593 -0
- py2edg/benchmark.py +307 -0
- py2edg/cli.py +142 -0
- py2edg/converter.py +349 -0
- py2edg/devices.py +329 -0
- py2edg/optimizer.py +256 -0
- py2edg/quantizer.py +259 -0
- py2edg/recipe.py +180 -0
- py2edg/report.py +166 -0
- py2edg-0.1.0.dist-info/METADATA +286 -0
- py2edg-0.1.0.dist-info/RECORD +17 -0
- py2edg-0.1.0.dist-info/WHEEL +5 -0
- py2edg-0.1.0.dist-info/entry_points.txt +2 -0
- py2edg-0.1.0.dist-info/licenses/LICENSE +21 -0
- py2edg-0.1.0.dist-info/top_level.txt +1 -0
py2edg/__init__.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""
|
|
2
|
+
╔══════════════════════════════════════════════════════════════════════╗
|
|
3
|
+
║ Py2Edg v0.1.0 ║
|
|
4
|
+
║ One-line edge deployment for Computer Vision models ║
|
|
5
|
+
║ by Mouissat Rabah Abderrahmane ║
|
|
6
|
+
╚══════════════════════════════════════════════════════════════════════╝
|
|
7
|
+
|
|
8
|
+
Convert, quantize, optimize, and benchmark CV models for edge devices
|
|
9
|
+
with a single function call.
|
|
10
|
+
|
|
11
|
+
Quick Start:
|
|
12
|
+
>>> import py2edg as rcv
|
|
13
|
+
>>>
|
|
14
|
+
>>> # Convert PyTorch model to optimized ONNX
|
|
15
|
+
>>> result = rcv.convert("model.pt", target="onnx", quantize="fp16")
|
|
16
|
+
>>>
|
|
17
|
+
>>> # Full deployment pipeline: convert + optimize + benchmark
|
|
18
|
+
>>> report = rcv.deploy("model.pt", device="rpi4", quantize="int8")
|
|
19
|
+
>>>
|
|
20
|
+
>>> # Benchmark any model
|
|
21
|
+
>>> stats = rcv.benchmark("model.onnx", input_shape=(1, 3, 640, 640))
|
|
22
|
+
>>>
|
|
23
|
+
>>> # Compare original vs optimized
|
|
24
|
+
>>> rcv.compare("model.pt", "model_opt.onnx", input_shape=(1, 3, 640, 640))
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
__version__ = "0.1.0"
|
|
28
|
+
__author__ = "Mouissat Rabah Abderrahmane"
|
|
29
|
+
__license__ = "MIT"
|
|
30
|
+
|
|
31
|
+
# ── High-level API (the magic) ──
|
|
32
|
+
from py2edg.api import (
|
|
33
|
+
convert,
|
|
34
|
+
deploy,
|
|
35
|
+
benchmark,
|
|
36
|
+
compare,
|
|
37
|
+
profile,
|
|
38
|
+
validate,
|
|
39
|
+
inspect_model,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# ── Device Profiles ──
|
|
43
|
+
from py2edg.devices import (
|
|
44
|
+
DeviceProfile,
|
|
45
|
+
get_device,
|
|
46
|
+
list_devices,
|
|
47
|
+
register_device,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# ── Deployment Recipe ──
|
|
51
|
+
from py2edg.recipe import (
|
|
52
|
+
DeployRecipe,
|
|
53
|
+
load_recipe,
|
|
54
|
+
save_recipe,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# ── Report ──
|
|
58
|
+
from py2edg.report import DeployReport
|
|
59
|
+
|
|
60
|
+
__all__ = [
|
|
61
|
+
# API
|
|
62
|
+
"convert",
|
|
63
|
+
"deploy",
|
|
64
|
+
"benchmark",
|
|
65
|
+
"compare",
|
|
66
|
+
"profile",
|
|
67
|
+
"validate",
|
|
68
|
+
"inspect_model",
|
|
69
|
+
# Devices
|
|
70
|
+
"DeviceProfile",
|
|
71
|
+
"get_device",
|
|
72
|
+
"list_devices",
|
|
73
|
+
"register_device",
|
|
74
|
+
# Recipe
|
|
75
|
+
"DeployRecipe",
|
|
76
|
+
"load_recipe",
|
|
77
|
+
"save_recipe",
|
|
78
|
+
# Report
|
|
79
|
+
"DeployReport",
|
|
80
|
+
]
|
py2edg/_imports.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Lazy import helpers for optional dependencies."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import importlib
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class _LazyModule:
|
|
10
|
+
"""Delay ImportError until the module is actually used."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, name: str, install_hint: str):
|
|
13
|
+
self._name = name
|
|
14
|
+
self._hint = install_hint
|
|
15
|
+
self._mod = None
|
|
16
|
+
|
|
17
|
+
def _load(self):
|
|
18
|
+
if self._mod is None:
|
|
19
|
+
try:
|
|
20
|
+
self._mod = importlib.import_module(self._name)
|
|
21
|
+
except ImportError:
|
|
22
|
+
raise ImportError(
|
|
23
|
+
f"'{self._name}' is required for this operation.\n"
|
|
24
|
+
f"Install it with: pip install {self._hint}"
|
|
25
|
+
)
|
|
26
|
+
return self._mod
|
|
27
|
+
|
|
28
|
+
def __getattr__(self, item: str) -> Any:
|
|
29
|
+
return getattr(self._load(), item)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def require(module_name: str, install_hint: str | None = None):
|
|
33
|
+
"""Import a module or raise a helpful error."""
|
|
34
|
+
hint = install_hint or module_name
|
|
35
|
+
try:
|
|
36
|
+
return importlib.import_module(module_name)
|
|
37
|
+
except ImportError:
|
|
38
|
+
raise ImportError(
|
|
39
|
+
f"'{module_name}' is required for this operation.\n"
|
|
40
|
+
f"Install it with: pip install {hint}"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def is_available(module_name: str) -> bool:
|
|
45
|
+
"""Check if a module is importable."""
|
|
46
|
+
try:
|
|
47
|
+
importlib.import_module(module_name)
|
|
48
|
+
return True
|
|
49
|
+
except ImportError:
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# ── Pre-built lazy imports ──
|
|
54
|
+
torch = _LazyModule("torch", "torch")
|
|
55
|
+
torchvision = _LazyModule("torchvision", "torchvision")
|
|
56
|
+
onnx = _LazyModule("onnx", "onnx")
|
|
57
|
+
onnxruntime = _LazyModule("onnxruntime", "onnxruntime")
|
|
58
|
+
tensorflow = _LazyModule("tensorflow", "tensorflow")
|
|
59
|
+
openvino = _LazyModule("openvino", "openvino")
|
|
60
|
+
onnxsim = _LazyModule("onnxsim", "onnxsim")
|