npu-easy 0.1.0__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.
- npu_easy-0.1.0/PKG-INFO +68 -0
- npu_easy-0.1.0/README.md +47 -0
- npu_easy-0.1.0/npu_easy/__init__.py +4 -0
- npu_easy-0.1.0/npu_easy/model.py +96 -0
- npu_easy-0.1.0/npu_easy/utils.py +68 -0
- npu_easy-0.1.0/npu_easy.egg-info/PKG-INFO +68 -0
- npu_easy-0.1.0/npu_easy.egg-info/SOURCES.txt +10 -0
- npu_easy-0.1.0/npu_easy.egg-info/dependency_links.txt +1 -0
- npu_easy-0.1.0/npu_easy.egg-info/requires.txt +9 -0
- npu_easy-0.1.0/npu_easy.egg-info/top_level.txt +1 -0
- npu_easy-0.1.0/setup.cfg +4 -0
- npu_easy-0.1.0/setup.py +21 -0
npu_easy-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: npu-easy
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A zero-dependency wrapper for easy NPU usage in Python on Windows.
|
|
5
|
+
Author: Antigravity
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Provides-Extra: intel
|
|
10
|
+
Requires-Dist: onnxruntime-openvino; extra == "intel"
|
|
11
|
+
Provides-Extra: amd
|
|
12
|
+
Requires-Dist: onnxruntime-directml; extra == "amd"
|
|
13
|
+
Provides-Extra: qualcomm
|
|
14
|
+
Requires-Dist: onnxruntime; extra == "qualcomm"
|
|
15
|
+
Dynamic: author
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: provides-extra
|
|
20
|
+
Dynamic: summary
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`npu-easy` has **zero hard dependencies**. It will install quickly without downloading large packages.
|
|
29
|
+
|
|
30
|
+
### Usage Acceleration
|
|
31
|
+
To actually use NPU acceleration, you should install the appropriate ONNX Runtime version for your hardware:
|
|
32
|
+
|
|
33
|
+
- **Intel**: `pip install onnxruntime-openvino`
|
|
34
|
+
- **AMD/Generic Windows**: `pip install onnxruntime-directml`
|
|
35
|
+
- **Qualcomm**: Install `onnxruntime` and the QNN SDK.
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Basic NPU Usage
|
|
40
|
+
```python
|
|
41
|
+
from npu_easy import NPUModel
|
|
42
|
+
import numpy as np
|
|
43
|
+
|
|
44
|
+
# Automatically selects NPU if found
|
|
45
|
+
model = NPUModel("path/to/model.onnx")
|
|
46
|
+
results = model.run(np.random.randn(1, 10).astype(np.float32))
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Bonus: Multi-Hardware Bonus Feature
|
|
50
|
+
Run on NPU, GPU, and CPU all at once!
|
|
51
|
+
```python
|
|
52
|
+
from npu_easy import MultiRunner
|
|
53
|
+
|
|
54
|
+
multi = MultiRunner("path/to/model.onnx")
|
|
55
|
+
# Runs on all backends in parallel threads
|
|
56
|
+
all_results = multi.run_all(input_data)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Multi-Threading
|
|
60
|
+
Set the number of internal threads for the engine:
|
|
61
|
+
```python
|
|
62
|
+
model = NPUModel("path/to/model.onnx", intra_op_num_threads=4)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Hardware Support
|
|
66
|
+
- **Intel**: via OpenVINO Execution Provider.
|
|
67
|
+
- **AMD/NVIDIA/Integrated**: via DirectML Execution Provider.
|
|
68
|
+
- **Qualcomm**: via QNN Execution Provider.
|
npu_easy-0.1.0/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
## Installation
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
pip install .
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
`npu-easy` has **zero hard dependencies**. It will install quickly without downloading large packages.
|
|
8
|
+
|
|
9
|
+
### Usage Acceleration
|
|
10
|
+
To actually use NPU acceleration, you should install the appropriate ONNX Runtime version for your hardware:
|
|
11
|
+
|
|
12
|
+
- **Intel**: `pip install onnxruntime-openvino`
|
|
13
|
+
- **AMD/Generic Windows**: `pip install onnxruntime-directml`
|
|
14
|
+
- **Qualcomm**: Install `onnxruntime` and the QNN SDK.
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
### Basic NPU Usage
|
|
19
|
+
```python
|
|
20
|
+
from npu_easy import NPUModel
|
|
21
|
+
import numpy as np
|
|
22
|
+
|
|
23
|
+
# Automatically selects NPU if found
|
|
24
|
+
model = NPUModel("path/to/model.onnx")
|
|
25
|
+
results = model.run(np.random.randn(1, 10).astype(np.float32))
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Bonus: Multi-Hardware Bonus Feature
|
|
29
|
+
Run on NPU, GPU, and CPU all at once!
|
|
30
|
+
```python
|
|
31
|
+
from npu_easy import MultiRunner
|
|
32
|
+
|
|
33
|
+
multi = MultiRunner("path/to/model.onnx")
|
|
34
|
+
# Runs on all backends in parallel threads
|
|
35
|
+
all_results = multi.run_all(input_data)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Multi-Threading
|
|
39
|
+
Set the number of internal threads for the engine:
|
|
40
|
+
```python
|
|
41
|
+
model = NPUModel("path/to/model.onnx", intra_op_num_threads=4)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Hardware Support
|
|
45
|
+
- **Intel**: via OpenVINO Execution Provider.
|
|
46
|
+
- **AMD/NVIDIA/Integrated**: via DirectML Execution Provider.
|
|
47
|
+
- **Qualcomm**: via QNN Execution Provider.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from .utils import get_best_provider, get_all_hardware_providers
|
|
3
|
+
|
|
4
|
+
class NPUModel:
|
|
5
|
+
def __init__(self, model_path, provider=None, provider_options=None, intra_op_num_threads=None):
|
|
6
|
+
"""
|
|
7
|
+
Initializes the NPUModel with lazy imports and optional threading.
|
|
8
|
+
"""
|
|
9
|
+
try:
|
|
10
|
+
global ort
|
|
11
|
+
import onnxruntime as ort
|
|
12
|
+
except ImportError:
|
|
13
|
+
raise ImportError(
|
|
14
|
+
"onnxruntime is required for NPU inference. "
|
|
15
|
+
"Please install it using: pip install onnxruntime-directml (or onnxruntime-openvino)"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
if not os.path.exists(model_path):
|
|
19
|
+
raise FileNotFoundError(f"Model file not found: {model_path}")
|
|
20
|
+
|
|
21
|
+
self.provider = provider or get_best_provider()
|
|
22
|
+
|
|
23
|
+
sess_options = ort.SessionOptions()
|
|
24
|
+
if intra_op_num_threads:
|
|
25
|
+
sess_options.intra_op_num_threads = intra_op_num_threads
|
|
26
|
+
|
|
27
|
+
if provider_options is None:
|
|
28
|
+
provider_options = {}
|
|
29
|
+
if self.provider == 'OpenVINOExecutionProvider':
|
|
30
|
+
provider_options = {'device_type': 'NPU'}
|
|
31
|
+
elif self.provider == 'QNNExecutionProvider':
|
|
32
|
+
provider_options = {'backend_path': 'QnnHtp.dll'}
|
|
33
|
+
|
|
34
|
+
print(f"Initializing NPUModel with provider: {self.provider}")
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
self.session = ort.InferenceSession(
|
|
38
|
+
model_path,
|
|
39
|
+
sess_options=sess_options,
|
|
40
|
+
providers=[self.provider],
|
|
41
|
+
provider_options=[provider_options] if provider_options else None
|
|
42
|
+
)
|
|
43
|
+
except Exception as e:
|
|
44
|
+
print(f"Failed to initialize with {self.provider}. Falling back to CPU.")
|
|
45
|
+
self.provider = 'CPUExecutionProvider'
|
|
46
|
+
self.session = ort.InferenceSession(model_path, sess_options=sess_options, providers=['CPUExecutionProvider'])
|
|
47
|
+
|
|
48
|
+
self.input_names = [i.name for i in self.session.get_inputs()]
|
|
49
|
+
self.output_names = [o.name for o in self.session.get_outputs()]
|
|
50
|
+
|
|
51
|
+
def run(self, input_data):
|
|
52
|
+
"""
|
|
53
|
+
Runs inference on the selected hardware.
|
|
54
|
+
"""
|
|
55
|
+
input_feed = self._prepare_input(input_data)
|
|
56
|
+
return self.session.run(self.output_names, input_feed)
|
|
57
|
+
|
|
58
|
+
def _prepare_input(self, input_data):
|
|
59
|
+
if hasattr(input_data, '__array__'):
|
|
60
|
+
if len(self.input_names) != 1:
|
|
61
|
+
raise ValueError("Model has multiple inputs, but a single array was provided.")
|
|
62
|
+
return {self.input_names[0]: input_data}
|
|
63
|
+
return input_data
|
|
64
|
+
|
|
65
|
+
def get_info(self):
|
|
66
|
+
"""Returns metadata."""
|
|
67
|
+
import onnxruntime as ort
|
|
68
|
+
return {
|
|
69
|
+
"provider": self.provider,
|
|
70
|
+
"inputs": self.input_names,
|
|
71
|
+
"outputs": self.output_names,
|
|
72
|
+
"available_providers": ort.get_available_providers()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
class MultiRunner:
|
|
76
|
+
"""Bonus: Runs models on NPU, GPU, and CPU simultaneously using threading."""
|
|
77
|
+
def __init__(self, model_path):
|
|
78
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
79
|
+
hw_map = get_all_hardware_providers()
|
|
80
|
+
self.models = {}
|
|
81
|
+
|
|
82
|
+
for hw_type, providers in hw_map.items():
|
|
83
|
+
if providers:
|
|
84
|
+
print(f"Initializing {hw_type} runner with {providers[0]}")
|
|
85
|
+
self.models[hw_type] = NPUModel(model_path, provider=providers[0])
|
|
86
|
+
|
|
87
|
+
def run_all(self, input_data):
|
|
88
|
+
"""Runs the model on all initialized hardware in parallel."""
|
|
89
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
90
|
+
results = {}
|
|
91
|
+
with ThreadPoolExecutor(max_workers=len(self.models)) as executor:
|
|
92
|
+
future_to_hw = {executor.submit(m.run, input_data): hw for hw, m in self.models.items()}
|
|
93
|
+
for future in future_to_hw:
|
|
94
|
+
hw = future_to_hw[future]
|
|
95
|
+
results[hw] = future.result()
|
|
96
|
+
return results
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
def check_hardware():
|
|
5
|
+
"""Checks for NPU and GPU hardware using Windows built-in tools."""
|
|
6
|
+
found = {"NPU": [], "GPU": []}
|
|
7
|
+
npu_keywords = ['neural', 'npu', 'compute accelerator', 'movidius', 'intel ai boost', 'hexagon']
|
|
8
|
+
gpu_keywords = ['nvidia', 'geforce', 'radeon', 'intel(r) iris', 'intel(r) graphics', 'arc(tm)']
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
ps_cmd = 'powershell -Command "Get-PnpDevice | Select-Object FriendlyName | Out-String"'
|
|
12
|
+
output = subprocess.check_output(ps_cmd, shell=True, stderr=subprocess.DEVNULL).decode('utf-8', errors='ignore')
|
|
13
|
+
for line in output.splitlines():
|
|
14
|
+
line = line.strip().lower()
|
|
15
|
+
if any(k in line for k in npu_keywords):
|
|
16
|
+
found["NPU"].append(line)
|
|
17
|
+
elif any(k in line for k in gpu_keywords):
|
|
18
|
+
found["GPU"].append(line)
|
|
19
|
+
except Exception:
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
found["NPU"] = sorted(list(set(found["NPU"])))
|
|
23
|
+
found["GPU"] = sorted(list(set(found["GPU"])))
|
|
24
|
+
return found
|
|
25
|
+
|
|
26
|
+
def get_all_hardware_providers():
|
|
27
|
+
"""Returns a map of available hardware to their best ONNX providers."""
|
|
28
|
+
try:
|
|
29
|
+
import onnxruntime as ort
|
|
30
|
+
available = ort.get_available_providers()
|
|
31
|
+
|
|
32
|
+
mapping = {
|
|
33
|
+
"NPU": [p for p in ['QNNExecutionProvider', 'OpenVINOExecutionProvider'] if p in available],
|
|
34
|
+
"GPU": [p for p in ['CUDAExecutionProvider', 'ROCMExecutionProvider', 'DmlExecutionProvider'] if p in available],
|
|
35
|
+
"CPU": ['CPUExecutionProvider']
|
|
36
|
+
}
|
|
37
|
+
return mapping
|
|
38
|
+
except ImportError:
|
|
39
|
+
return {}
|
|
40
|
+
|
|
41
|
+
def get_available_npu_providers():
|
|
42
|
+
"""Returns available NPU providers. Tries onnxruntime if installed, otherwise uses hardware detection."""
|
|
43
|
+
try:
|
|
44
|
+
import onnxruntime as ort
|
|
45
|
+
available = ort.get_available_providers()
|
|
46
|
+
|
|
47
|
+
npu_priority = [
|
|
48
|
+
'QNNExecutionProvider',
|
|
49
|
+
'OpenVINOExecutionProvider',
|
|
50
|
+
'DmlExecutionProvider',
|
|
51
|
+
]
|
|
52
|
+
return [p for p in npu_priority if p in available]
|
|
53
|
+
except ImportError:
|
|
54
|
+
# If onnxruntime is not installed, we can still report what hardware we found
|
|
55
|
+
hardware = check_npu_hardware()
|
|
56
|
+
if hardware:
|
|
57
|
+
return [f"Detected Hardware: {h}" for h in hardware]
|
|
58
|
+
return []
|
|
59
|
+
|
|
60
|
+
def get_best_provider():
|
|
61
|
+
"""Returns the best provider name. Defaults to CPU if nothing else is found."""
|
|
62
|
+
npu_providers = get_available_npu_providers()
|
|
63
|
+
if npu_providers and not npu_providers[0].startswith("Detected"):
|
|
64
|
+
return npu_providers[0]
|
|
65
|
+
|
|
66
|
+
# Check if DirectML is likely available (standard on modern Windows)
|
|
67
|
+
# but we can't be sure without ORT.
|
|
68
|
+
return 'CPUExecutionProvider'
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: npu-easy
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A zero-dependency wrapper for easy NPU usage in Python on Windows.
|
|
5
|
+
Author: Antigravity
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Provides-Extra: intel
|
|
10
|
+
Requires-Dist: onnxruntime-openvino; extra == "intel"
|
|
11
|
+
Provides-Extra: amd
|
|
12
|
+
Requires-Dist: onnxruntime-directml; extra == "amd"
|
|
13
|
+
Provides-Extra: qualcomm
|
|
14
|
+
Requires-Dist: onnxruntime; extra == "qualcomm"
|
|
15
|
+
Dynamic: author
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: provides-extra
|
|
20
|
+
Dynamic: summary
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`npu-easy` has **zero hard dependencies**. It will install quickly without downloading large packages.
|
|
29
|
+
|
|
30
|
+
### Usage Acceleration
|
|
31
|
+
To actually use NPU acceleration, you should install the appropriate ONNX Runtime version for your hardware:
|
|
32
|
+
|
|
33
|
+
- **Intel**: `pip install onnxruntime-openvino`
|
|
34
|
+
- **AMD/Generic Windows**: `pip install onnxruntime-directml`
|
|
35
|
+
- **Qualcomm**: Install `onnxruntime` and the QNN SDK.
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Basic NPU Usage
|
|
40
|
+
```python
|
|
41
|
+
from npu_easy import NPUModel
|
|
42
|
+
import numpy as np
|
|
43
|
+
|
|
44
|
+
# Automatically selects NPU if found
|
|
45
|
+
model = NPUModel("path/to/model.onnx")
|
|
46
|
+
results = model.run(np.random.randn(1, 10).astype(np.float32))
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Bonus: Multi-Hardware Bonus Feature
|
|
50
|
+
Run on NPU, GPU, and CPU all at once!
|
|
51
|
+
```python
|
|
52
|
+
from npu_easy import MultiRunner
|
|
53
|
+
|
|
54
|
+
multi = MultiRunner("path/to/model.onnx")
|
|
55
|
+
# Runs on all backends in parallel threads
|
|
56
|
+
all_results = multi.run_all(input_data)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Multi-Threading
|
|
60
|
+
Set the number of internal threads for the engine:
|
|
61
|
+
```python
|
|
62
|
+
model = NPUModel("path/to/model.onnx", intra_op_num_threads=4)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Hardware Support
|
|
66
|
+
- **Intel**: via OpenVINO Execution Provider.
|
|
67
|
+
- **AMD/NVIDIA/Integrated**: via DirectML Execution Provider.
|
|
68
|
+
- **Qualcomm**: via QNN Execution Provider.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npu_easy
|
npu_easy-0.1.0/setup.cfg
ADDED
npu_easy-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="npu-easy",
|
|
5
|
+
version="0.1.0",
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
install_requires=[], # Zero hard dependencies
|
|
8
|
+
extras_require={
|
|
9
|
+
"intel": ["onnxruntime-openvino"],
|
|
10
|
+
"amd": ["onnxruntime-directml"],
|
|
11
|
+
"qualcomm": ["onnxruntime"], # Requires separate QNN SDK setup
|
|
12
|
+
},
|
|
13
|
+
author="Antigravity",
|
|
14
|
+
description="A zero-dependency wrapper for easy NPU usage in Python on Windows.",
|
|
15
|
+
long_description=open("README.md").read(),
|
|
16
|
+
long_description_content_type="text/markdown",
|
|
17
|
+
classifiers=[
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Operating System :: Microsoft :: Windows",
|
|
20
|
+
],
|
|
21
|
+
)
|