mblt-npu-python 0.0.0__tar.gz → 0.0.2__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 (22) hide show
  1. {mblt_npu_python-0.0.0/mblt_npu_python.egg-info → mblt_npu_python-0.0.2}/PKG-INFO +29 -1
  2. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/README.md +28 -0
  3. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/mblt_npu/__init__.py +3 -1
  4. mblt_npu_python-0.0.2/mblt_npu/core_mode.py +27 -0
  5. mblt_npu_python-0.0.2/mblt_npu/logging.py +77 -0
  6. mblt_npu_python-0.0.2/mblt_npu/npu_backend.py +1584 -0
  7. mblt_npu_python-0.0.2/mblt_npu/npu_target.py +1002 -0
  8. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2/mblt_npu_python.egg-info}/PKG-INFO +29 -1
  9. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/mblt_npu_python.egg-info/SOURCES.txt +3 -0
  10. mblt_npu_python-0.0.2/tests/test_npu_backend_multi_slot.py +667 -0
  11. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/tests/test_target_device.py +139 -7
  12. mblt_npu_python-0.0.0/mblt_npu/logging.py +0 -54
  13. mblt_npu_python-0.0.0/mblt_npu/npu_backend.py +0 -632
  14. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/LICENSE +0 -0
  15. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/mblt_npu/onnx_backend.py +0 -0
  16. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/mblt_npu/pytest_plugin.py +0 -0
  17. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/mblt_npu_python.egg-info/dependency_links.txt +0 -0
  18. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/mblt_npu_python.egg-info/requires.txt +0 -0
  19. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/mblt_npu_python.egg-info/top_level.txt +0 -0
  20. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/pyproject.toml +0 -0
  21. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/setup.cfg +0 -0
  22. {mblt_npu_python-0.0.0 → mblt_npu_python-0.0.2}/tests/test_onnx_backend.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mblt-npu-python
3
- Version: 0.0.0
3
+ Version: 0.0.2
4
4
  Summary: Shared NPU access for the Mobilint Python packages
5
5
  Author: Mobilint
6
6
  License: BSD-3-Clause
@@ -28,6 +28,16 @@ Dynamic: license-file
28
28
 
29
29
  # Mobilint NPU Python
30
30
 
31
+ <!-- markdownlint-disable MD033 -->
32
+ <div align="center">
33
+ <p>
34
+ <a href="https://www.mobilint.com/" target="_blank">
35
+ <img src="https://raw.githubusercontent.com/mobilint/.github/main/assets/Mobilint_Logo_Primary.png" alt="Mobilint Logo" width="60%">
36
+ </a>
37
+ </p>
38
+ </div>
39
+ <!-- markdownlint-enable MD033 -->
40
+
31
41
  Shared runtime support for applications that run MXQ models on Mobilint NPUs or ONNX models through ONNX Runtime.
32
42
  `mblt-npu-python` provides the common backend, device-selection rules, Hugging Face
33
43
  artifact resolution, and model-detail logging used by Mobilint Python packages. It
@@ -41,6 +51,10 @@ a `MobilintNPUBackend`'s fields.
41
51
 
42
52
  ## Installation
43
53
 
54
+ [![PyPI - Version](https://img.shields.io/pypi/v/mblt-npu-python?logo=pypi&logoColor=white)](https://pypi.org/project/mblt-npu-python/)
55
+ [![PyPI Downloads](https://static.pepy.tech/badge/mblt-npu-python?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://clickpy.clickhouse.com/dashboard/mblt-npu-python)
56
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mblt-npu-python?logo=python&logoColor=gold)](https://pypi.org/project/mblt-npu-python/)
57
+
44
58
  ```bash
45
59
  pip install mblt-npu-python
46
60
  ```
@@ -76,6 +90,20 @@ remain accepted when loading older configurations.
76
90
  `backend_class_for()` and `BACKEND_CLASSES` are available for integrations that
77
91
  need to inspect the supported targets.
78
92
 
93
+ ### Multi-slot MXQ execution
94
+
95
+ `max_batch_size` is aggregate capacity. At `create()`, the backend probes the
96
+ compiled per-model capacity `K` and loads `ceil(max_batch_size / K)` model slots.
97
+ Slots are distributed round-robin over the devices named by canonical target
98
+ strings and reuse one accelerator per device. `mxq_model` and `acc` continue to
99
+ refer to slot zero for compatibility; concurrent callers can use
100
+ `infer_slot(slot_index, inputs)`. Allocation failures dispose all created slots
101
+ and raise `MobilintBackendAllocError` with the failed slot and device.
102
+
103
+ Hub-backed configurations retain `name_or_path`, `revision`, and `commit_hash`
104
+ through `to_dict()` / `from_dict()`. Artifact lookup never substitutes an
105
+ unpinned revision or an unrelated cached MXQ.
106
+
79
107
  For ONNX inference, install the optional runtime extra and use `ONNXBackend`:
80
108
 
81
109
  ```bash
@@ -1,5 +1,15 @@
1
1
  # Mobilint NPU Python
2
2
 
3
+ <!-- markdownlint-disable MD033 -->
4
+ <div align="center">
5
+ <p>
6
+ <a href="https://www.mobilint.com/" target="_blank">
7
+ <img src="https://raw.githubusercontent.com/mobilint/.github/main/assets/Mobilint_Logo_Primary.png" alt="Mobilint Logo" width="60%">
8
+ </a>
9
+ </p>
10
+ </div>
11
+ <!-- markdownlint-enable MD033 -->
12
+
3
13
  Shared runtime support for applications that run MXQ models on Mobilint NPUs or ONNX models through ONNX Runtime.
4
14
  `mblt-npu-python` provides the common backend, device-selection rules, Hugging Face
5
15
  artifact resolution, and model-detail logging used by Mobilint Python packages. It
@@ -13,6 +23,10 @@ a `MobilintNPUBackend`'s fields.
13
23
 
14
24
  ## Installation
15
25
 
26
+ [![PyPI - Version](https://img.shields.io/pypi/v/mblt-npu-python?logo=pypi&logoColor=white)](https://pypi.org/project/mblt-npu-python/)
27
+ [![PyPI Downloads](https://static.pepy.tech/badge/mblt-npu-python?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://clickpy.clickhouse.com/dashboard/mblt-npu-python)
28
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mblt-npu-python?logo=python&logoColor=gold)](https://pypi.org/project/mblt-npu-python/)
29
+
16
30
  ```bash
17
31
  pip install mblt-npu-python
18
32
  ```
@@ -48,6 +62,20 @@ remain accepted when loading older configurations.
48
62
  `backend_class_for()` and `BACKEND_CLASSES` are available for integrations that
49
63
  need to inspect the supported targets.
50
64
 
65
+ ### Multi-slot MXQ execution
66
+
67
+ `max_batch_size` is aggregate capacity. At `create()`, the backend probes the
68
+ compiled per-model capacity `K` and loads `ceil(max_batch_size / K)` model slots.
69
+ Slots are distributed round-robin over the devices named by canonical target
70
+ strings and reuse one accelerator per device. `mxq_model` and `acc` continue to
71
+ refer to slot zero for compatibility; concurrent callers can use
72
+ `infer_slot(slot_index, inputs)`. Allocation failures dispose all created slots
73
+ and raise `MobilintBackendAllocError` with the failed slot and device.
74
+
75
+ Hub-backed configurations retain `name_or_path`, `revision`, and `commit_hash`
76
+ through `to_dict()` / `from_dict()`. Artifact lookup never substitutes an
77
+ unpinned revision or an unrelated cached MXQ.
78
+
51
79
  For ONNX inference, install the optional runtime extra and use `ONNXBackend`:
52
80
 
53
81
  ```bash
@@ -12,6 +12,7 @@ log_model_details reads a MobilintNPUBackend's fields.
12
12
  from .npu_backend import (
13
13
  BACKEND_CLASSES,
14
14
  DEFAULT_TARGET_DEVICE,
15
+ MobilintBackendAllocError,
15
16
  MobilintAriesBackend,
16
17
  MobilintNPUBackend,
17
18
  MobilintRegulusBackend,
@@ -21,11 +22,12 @@ from .npu_backend import (
21
22
  from .logging import log_model_details
22
23
  from .onnx_backend import ONNXBackend
23
24
 
24
- __version__ = "0.0.0"
25
+ __version__ = "0.0.2"
25
26
 
26
27
  __all__ = [
27
28
  "BACKEND_CLASSES",
28
29
  "DEFAULT_TARGET_DEVICE",
30
+ "MobilintBackendAllocError",
29
31
  "MobilintAriesBackend",
30
32
  "MobilintNPUBackend",
31
33
  "MobilintRegulusBackend",
@@ -0,0 +1,27 @@
1
+ """Shared core-mode typing and validation helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Literal, cast
6
+
7
+ CoreMode = Literal["auto", "single", "multi", "global4", "global8"]
8
+
9
+
10
+ def normalize_core_mode(core_mode: str) -> CoreMode:
11
+ """Narrow a validated core mode string to the supported literal type.
12
+
13
+ Args:
14
+ core_mode: Core mode string from user input or configuration.
15
+
16
+ Returns:
17
+ The same value narrowed to ``CoreMode``.
18
+
19
+ Raises:
20
+ ValueError: If ``core_mode`` is not one of the supported values.
21
+ """
22
+ valid_modes = {"auto", "single", "multi", "global4", "global8"}
23
+ if core_mode not in valid_modes:
24
+ raise ValueError(
25
+ f"Invalid core mode '{core_mode}'. Expected one of {sorted(valid_modes)}."
26
+ )
27
+ return cast(CoreMode, core_mode)
@@ -0,0 +1,77 @@
1
+ import hashlib
2
+ import os
3
+ from typing import TYPE_CHECKING, Optional
4
+
5
+ if TYPE_CHECKING:
6
+ from .npu_backend import MobilintNPUBackend
7
+
8
+ _VERBOSE_TRUE_VALUES = {"1", "true", "yes", "on"}
9
+
10
+
11
+ def _is_verbose_enabled() -> bool:
12
+ return os.getenv("MBLT_MODEL_ZOO_VERBOSE", "").lower() in _VERBOSE_TRUE_VALUES
13
+
14
+
15
+ def _md5_hash_from_file(file_path: str) -> str:
16
+ hash_md5 = hashlib.md5()
17
+ with open(file_path, "rb") as file_handle:
18
+ for chunk in iter(lambda: file_handle.read(8192), b""):
19
+ hash_md5.update(chunk)
20
+ return hash_md5.hexdigest()
21
+
22
+
23
+ def log_model_details(
24
+ model_path: str, npu_backend: Optional["MobilintNPUBackend"] = None
25
+ ) -> None:
26
+ """Print model metadata when verbose logging is enabled.
27
+
28
+ When the backend hosts multiple slots (``n_models > 1``), an aggregate
29
+ summary is printed once (slot count, device distribution, compiled batch
30
+ axis ``K``, total capacity ``N * K``). Per-variant input/output shapes
31
+ are read from slot 0 because every slot loads the same MXQ artifact.
32
+ """
33
+ if not _is_verbose_enabled():
34
+ return
35
+
36
+ print("Model Initialized")
37
+ print(f"Model Size: {os.path.getsize(model_path) / 1024 / 1024:.2f} MB")
38
+ print(f"Model Hash: {_md5_hash_from_file(model_path)}")
39
+
40
+ if npu_backend is not None:
41
+ print(f"Device Number: {npu_backend.dev_no}")
42
+ print(f"Core Mode: {npu_backend.core_mode}")
43
+ if npu_backend.core_mode == "single":
44
+ print(f"Target Cores: {npu_backend.target_cores}")
45
+ by_device = npu_backend.target_cores_by_device
46
+ if len(by_device) > 1:
47
+ for dev in sorted(by_device):
48
+ print(f"\tDevice {dev} Cores: {by_device[dev]}")
49
+ else:
50
+ print(f"Target Clusters: {npu_backend.target_clusters}")
51
+ by_device = npu_backend.target_clusters_by_device
52
+ if len(by_device) > 1:
53
+ for dev in sorted(by_device):
54
+ print(f"\tDevice {dev} Clusters: {by_device[dev]}")
55
+ n_models = getattr(npu_backend, "n_models", 0) or 0
56
+ if n_models > 0:
57
+ k_per_model = getattr(npu_backend, "k_per_model", 1) or 1
58
+ model_dev_no = getattr(npu_backend, "model_dev_no", [])
59
+ print(f"Backend Slots: {n_models}")
60
+ print(f"Slot Device Assignment: {list(model_dev_no)}")
61
+ print(f"K per Slot: {k_per_model}")
62
+ print(f"Total Capacity (N*K): {n_models * k_per_model}")
63
+ mxq_model = npu_backend.mxq_model
64
+ if mxq_model is None:
65
+ return
66
+ if mxq_model.get_num_model_variants() == 1:
67
+ print(f"Model Input Shape: {mxq_model.get_model_input_shape()}")
68
+ print(f"Model Output Shape: {mxq_model.get_model_output_shape()}")
69
+ else:
70
+ for i in range(mxq_model.get_num_model_variants()):
71
+ print(f"Model Variant {i}")
72
+ print(
73
+ f"\tInput Shape: {mxq_model.get_model_variant_handle(i).get_model_input_shape()}"
74
+ )
75
+ print(
76
+ f"\tOutput Shape: {mxq_model.get_model_variant_handle(i).get_model_output_shape()}"
77
+ )