amv-diffusion 2.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.
- amv_diffusion-2.1.0.dist-info/METADATA +180 -0
- amv_diffusion-2.1.0.dist-info/RECORD +39 -0
- amv_diffusion-2.1.0.dist-info/WHEEL +5 -0
- amv_diffusion-2.1.0.dist-info/entry_points.txt +7 -0
- amv_diffusion-2.1.0.dist-info/licenses/LICENSE +21 -0
- amv_diffusion-2.1.0.dist-info/top_level.txt +1 -0
- termux_diffusion/__init__.py +185 -0
- termux_diffusion/__main__.py +7 -0
- termux_diffusion/_version.py +3 -0
- termux_diffusion/adapter.py +41 -0
- termux_diffusion/canvas.py +364 -0
- termux_diffusion/cli.py +492 -0
- termux_diffusion/cluster.py +340 -0
- termux_diffusion/control/__init__.py +5 -0
- termux_diffusion/control/component.py +309 -0
- termux_diffusion/control/status.py +15 -0
- termux_diffusion/core.py +2936 -0
- termux_diffusion/data/bootstrap-manifest.json +15 -0
- termux_diffusion/data/prompt_cache/108a7149c4e70550.json +10 -0
- termux_diffusion/data/release-public-keys.json +10 -0
- termux_diffusion/data/validated-vulkan-profiles.json +298 -0
- termux_diffusion/detailer.py +283 -0
- termux_diffusion/doctor.py +128 -0
- termux_diffusion/downloader.py +111 -0
- termux_diffusion/engine.py +226 -0
- termux_diffusion/exceptions.py +158 -0
- termux_diffusion/hardware.py +985 -0
- termux_diffusion/hub.py +686 -0
- termux_diffusion/installer.py +499 -0
- termux_diffusion/locking.py +134 -0
- termux_diffusion/manifest.py +128 -0
- termux_diffusion/npu.py +267 -0
- termux_diffusion/platform.py +533 -0
- termux_diffusion/purger.py +145 -0
- termux_diffusion/py.typed +1 -0
- termux_diffusion/safety.py +150 -0
- termux_diffusion/selftest.py +178 -0
- termux_diffusion/web.py +3370 -0
- termux_diffusion/workflow.py +1345 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Copyright (c) 2026 Uno Kim / AMEVA Foundation. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR Commercial-License
|
|
3
|
+
"""Manifest schema v1 parsing, SHA-256 checksum verification, and release metadata handling."""
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
import logging
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Dict, List, Optional, Any
|
|
11
|
+
|
|
12
|
+
from .exceptions import TermuxDiffusionError
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger("termux_diffusion.manifest")
|
|
15
|
+
|
|
16
|
+
MANIFEST_SCHEMA_VERSION = 1
|
|
17
|
+
|
|
18
|
+
class ManifestError(TermuxDiffusionError):
|
|
19
|
+
"""Raised when manifest parsing, signature, or schema validation fails."""
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class ArtifactMetadata:
|
|
25
|
+
id: str
|
|
26
|
+
filename: str
|
|
27
|
+
url: str
|
|
28
|
+
sha256: str
|
|
29
|
+
size: int
|
|
30
|
+
compression: str = "tar.gz"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class PlatformRequirements:
|
|
35
|
+
os: str = "android"
|
|
36
|
+
abi: str = "arm64-v8a"
|
|
37
|
+
min_api: int = 26
|
|
38
|
+
max_api: Optional[int] = None
|
|
39
|
+
libc: str = "bionic"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class RuntimeRequirements:
|
|
44
|
+
backend: str = "auto"
|
|
45
|
+
cpu_features_required: List[str] = field(default_factory=list)
|
|
46
|
+
vulkan_required: bool = False
|
|
47
|
+
vulkan_min_version: str = "1.1"
|
|
48
|
+
shared_libraries: List[str] = field(default_factory=list)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class ReleaseManifest:
|
|
53
|
+
schema_version: int
|
|
54
|
+
package_version: str
|
|
55
|
+
release_id: str
|
|
56
|
+
channel: str
|
|
57
|
+
artifacts: Dict[str, ArtifactMetadata]
|
|
58
|
+
platform: PlatformRequirements
|
|
59
|
+
runtime: RuntimeRequirements
|
|
60
|
+
raw_data: Dict[str, Any] = field(default_factory=dict)
|
|
61
|
+
|
|
62
|
+
@classmethod
|
|
63
|
+
def from_dict(cls, data: Dict[str, Any]) -> "ReleaseManifest":
|
|
64
|
+
schema_ver = data.get("schema_version", 1)
|
|
65
|
+
if schema_ver != MANIFEST_SCHEMA_VERSION:
|
|
66
|
+
raise ManifestError(f"E_MANIFEST_SCHEMA: Unsupported manifest schema version {schema_ver}")
|
|
67
|
+
|
|
68
|
+
pkg_ver = data.get("package_version", "1.2.0")
|
|
69
|
+
release_id = data.get("release_id", "")
|
|
70
|
+
channel = data.get("channel", "stable")
|
|
71
|
+
|
|
72
|
+
plat_data = data.get("platform", {})
|
|
73
|
+
plat = PlatformRequirements(
|
|
74
|
+
os=plat_data.get("os", "android"),
|
|
75
|
+
abi=plat_data.get("abi", "arm64-v8a"),
|
|
76
|
+
min_api=plat_data.get("min_api", 26),
|
|
77
|
+
max_api=plat_data.get("max_api"),
|
|
78
|
+
libc=plat_data.get("libc", "bionic")
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
rt_data = data.get("runtime", {})
|
|
82
|
+
rt = RuntimeRequirements(
|
|
83
|
+
backend=rt_data.get("backend", "auto"),
|
|
84
|
+
cpu_features_required=rt_data.get("cpu_features_required", []),
|
|
85
|
+
vulkan_required=rt_data.get("vulkan_required", False),
|
|
86
|
+
vulkan_min_version=rt_data.get("vulkan_min_version", "1.1"),
|
|
87
|
+
shared_libraries=rt_data.get("shared_libraries", [])
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
artifacts_dict = {}
|
|
91
|
+
art_raw = data.get("artifacts", {})
|
|
92
|
+
for art_id, art_info in art_raw.items():
|
|
93
|
+
artifacts_dict[art_id] = ArtifactMetadata(
|
|
94
|
+
id=art_id,
|
|
95
|
+
filename=art_info.get("filename", f"{art_id}.tar.gz"),
|
|
96
|
+
url=art_info.get("url", ""),
|
|
97
|
+
sha256=art_info.get("sha256", ""),
|
|
98
|
+
size=art_info.get("size", 0),
|
|
99
|
+
compression=art_info.get("compression", "tar.gz")
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return cls(
|
|
103
|
+
schema_version=schema_ver,
|
|
104
|
+
package_version=pkg_ver,
|
|
105
|
+
release_id=release_id,
|
|
106
|
+
channel=channel,
|
|
107
|
+
artifacts=artifacts_dict,
|
|
108
|
+
platform=plat,
|
|
109
|
+
runtime=rt,
|
|
110
|
+
raw_data=data
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def compute_sha256(filepath: Path) -> str:
|
|
115
|
+
"""Calculate hex SHA-256 hash of given file."""
|
|
116
|
+
h = hashlib.sha256()
|
|
117
|
+
with open(filepath, "rb") as f:
|
|
118
|
+
while chunk := f.read(65536):
|
|
119
|
+
h.update(chunk)
|
|
120
|
+
return h.hexdigest().lower()
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def verify_file_sha256(filepath: Path, expected_hash: str) -> bool:
|
|
124
|
+
"""Verify that file's SHA-256 matches expected_hash."""
|
|
125
|
+
if not filepath.is_file():
|
|
126
|
+
return False
|
|
127
|
+
actual = compute_sha256(filepath)
|
|
128
|
+
return actual == expected_hash.lower().strip()
|
termux_diffusion/npu.py
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Copyright (c) 2026 Uno Kim / AMEVA Foundation. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR Commercial-License
|
|
3
|
+
"""Neural Processing Unit (NPU) and Tensor Processing Unit (TPU) hardware introspection module.
|
|
4
|
+
|
|
5
|
+
This module provides hardware probing, driver introspection, and capability reporting
|
|
6
|
+
for mobile NPU/TPU chipsets on Android Termux:
|
|
7
|
+
- Qualcomm Hexagon Tensor Processor (HTP / QNN NPU)
|
|
8
|
+
- Samsung Exynos NPU (ENN / Eden Engine)
|
|
9
|
+
- Google Tensor Edge TPU (Pixel Neural Core)
|
|
10
|
+
- Android Standard Neural Networks API (NNAPI)
|
|
11
|
+
|
|
12
|
+
Architectural Note:
|
|
13
|
+
In v1.3+, inference is driven by the native Bionic sd-cli engine using Vulkan GPU
|
|
14
|
+
compute and ARM64 NEON CPU acceleration. Direct Qualcomm QNN / Hexagon NPU subgraph
|
|
15
|
+
partitioning is the architectural blueprint for the upcoming v2.0 runtime.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import logging
|
|
19
|
+
import os
|
|
20
|
+
import platform
|
|
21
|
+
import subprocess
|
|
22
|
+
from dataclasses import dataclass, field
|
|
23
|
+
from enum import Enum
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Dict, List, Optional, Tuple
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger("termux_diffusion.npu")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class NPUVendor(Enum):
|
|
31
|
+
"""Supported mobile Neural Processing Unit hardware architectures."""
|
|
32
|
+
QUALCOMM_HEXAGON = "qualcomm_hexagon" # Snapdragon HTP (Hexagon Tensor Processor)
|
|
33
|
+
SAMSUNG_EDEN = "samsung_eden" # Exynos Dual-NPU (ENN Engine)
|
|
34
|
+
GOOGLE_EDGE_TPU = "google_edge_tpu" # Google Tensor Edge TPU
|
|
35
|
+
ANDROID_NNAPI = "android_nnapi" # Android Generic Neural Networks API
|
|
36
|
+
NONE = "none"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class NPUProfile:
|
|
41
|
+
"""Introspected mobile NPU/TPU hardware capability profile."""
|
|
42
|
+
available: bool = False
|
|
43
|
+
vendor: NPUVendor = NPUVendor.NONE
|
|
44
|
+
chipset_name: str = "Unknown"
|
|
45
|
+
driver_library: Optional[str] = None
|
|
46
|
+
dsp_architecture: str = "Unknown"
|
|
47
|
+
tops_rating: float = 0.0
|
|
48
|
+
supported_precisions: List[str] = field(default_factory=list)
|
|
49
|
+
delegate_type: str = "CPU_FALLBACK"
|
|
50
|
+
acceleration_status: str = "Not Available"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# ------------------------------------------------------------------------------
|
|
54
|
+
# NPU Driver Search Paths on Android Bionic Filesystems
|
|
55
|
+
# ------------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
QUALCOMM_QNN_LIBS = [
|
|
58
|
+
"/vendor/lib64/libQnnHtp.so",
|
|
59
|
+
"/vendor/lib64/libQnnHtpV75.so",
|
|
60
|
+
"/vendor/lib64/libQnnHtpV73.so",
|
|
61
|
+
"/vendor/lib64/libQnnHtpV69.so",
|
|
62
|
+
"/vendor/lib64/libQnnHtpV68.so",
|
|
63
|
+
"/vendor/lib64/libqnn-htp.so",
|
|
64
|
+
"/vendor/lib64/libQnnSystem.so",
|
|
65
|
+
"/vendor/lib64/libQnnCpu.so",
|
|
66
|
+
"/vendor/dsp/cdsp/libqnn_htp.so",
|
|
67
|
+
"/system/vendor/lib64/libQnnHtp.so",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
SAMSUNG_EDEN_LIBS = [
|
|
71
|
+
"/vendor/lib64/libenn_public_api.so",
|
|
72
|
+
"/vendor/lib64/libeden_nn.so",
|
|
73
|
+
"/vendor/lib64/libenn_engine.so",
|
|
74
|
+
"/system/vendor/lib64/libenn_public_api.so",
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
GOOGLE_EDGETPU_LIBS = [
|
|
78
|
+
"/vendor/lib64/libedgetpu.so",
|
|
79
|
+
"/vendor/lib64/libtflite_edgetpu.so",
|
|
80
|
+
"/vendor/lib64/libgoogle_edgetpu.so",
|
|
81
|
+
"/system/vendor/lib64/libedgetpu.so",
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
ANDROID_NNAPI_LIBS = [
|
|
85
|
+
"/system/lib64/libneuralnetworks.so",
|
|
86
|
+
"/apex/com.android.neuralnetworks/lib64/libneuralnetworks.so",
|
|
87
|
+
"/system/lib/libneuralnetworks.so",
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _read_android_prop(key: str) -> str:
|
|
92
|
+
"""Query Android system property via getprop.
|
|
93
|
+
|
|
94
|
+
반환: 값 문자열, 실패/미지원 시 "" (fail-closed).
|
|
95
|
+
"""
|
|
96
|
+
import logging as _logging
|
|
97
|
+
_npu_logger = _logging.getLogger("termux_diffusion.npu")
|
|
98
|
+
try:
|
|
99
|
+
res = subprocess.run(["getprop", key], capture_output=True, text=True, timeout=2.0)
|
|
100
|
+
val = res.stdout.strip()
|
|
101
|
+
if val and val != "unknown":
|
|
102
|
+
return val
|
|
103
|
+
except FileNotFoundError:
|
|
104
|
+
# getprop 바이너리 없음 — 비-Android 환경. fail-closed.
|
|
105
|
+
_npu_logger.debug("[npu] getprop not found (non-Android environment)")
|
|
106
|
+
except subprocess.TimeoutExpired:
|
|
107
|
+
_npu_logger.debug("[npu] getprop timed out for key=%s", key)
|
|
108
|
+
except OSError as _os_err:
|
|
109
|
+
_npu_logger.warning("[npu] getprop OSError for key=%s: %s", key, _os_err)
|
|
110
|
+
# 예상 밖 예외는 재발생
|
|
111
|
+
return ""
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _probe_first_existing_lib(paths: List[str]) -> Optional[str]:
|
|
117
|
+
"""Check physical existence of runtime library on Android filesystem."""
|
|
118
|
+
for p in paths:
|
|
119
|
+
path_obj = Path(p)
|
|
120
|
+
try:
|
|
121
|
+
if path_obj.is_file() and path_obj.stat().st_size >= 1024:
|
|
122
|
+
return str(path_obj.resolve())
|
|
123
|
+
except (OSError, PermissionError):
|
|
124
|
+
continue
|
|
125
|
+
return None
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def detect_npu_capabilities() -> NPUProfile:
|
|
129
|
+
"""Inspect the device for Qualcomm Hexagon, Samsung Exynos NPU, Google Edge TPU, and NNAPI."""
|
|
130
|
+
soc_platform = _read_android_prop("ro.board.platform").lower()
|
|
131
|
+
chipname = _read_android_prop("ro.hardware.chipname").lower()
|
|
132
|
+
hardware = _read_android_prop("ro.hardware").lower()
|
|
133
|
+
product_board = _read_android_prop("ro.product.board").lower()
|
|
134
|
+
|
|
135
|
+
# 1. Qualcomm Snapdragon Hexagon HTP Probe
|
|
136
|
+
qnn_lib = _probe_first_existing_lib(QUALCOMM_QNN_LIBS)
|
|
137
|
+
is_qualcomm = any(q in soc_platform or q in hardware or q in product_board for q in ["qcom", "snapdragon", "sm8", "sm7", "lahaina", "taro", "kalama", "pineapple"])
|
|
138
|
+
|
|
139
|
+
if qnn_lib or is_qualcomm:
|
|
140
|
+
# Determine TOPS rating based on SoC generation
|
|
141
|
+
tops = 15.0
|
|
142
|
+
dsp_arch = "Hexagon Vector Extensions (HVX)"
|
|
143
|
+
if "sm8650" in soc_platform or "pineapple" in soc_platform: # Snapdragon 8 Gen 3
|
|
144
|
+
tops = 45.0
|
|
145
|
+
dsp_arch = "Hexagon v75 HTP (45 TOPS Generative AI NPU)"
|
|
146
|
+
elif "sm8550" in soc_platform or "kalama" in soc_platform: # Snapdragon 8 Gen 2
|
|
147
|
+
tops = 35.0
|
|
148
|
+
dsp_arch = "Hexagon v73 HTP (35 TOPS NPU)"
|
|
149
|
+
elif "sm8450" in soc_platform or "taro" in soc_platform: # Snapdragon 8 Gen 1
|
|
150
|
+
tops = 27.0
|
|
151
|
+
dsp_arch = "Hexagon v69 HTP (27 TOPS NPU)"
|
|
152
|
+
|
|
153
|
+
has_driver = qnn_lib is not None
|
|
154
|
+
return NPUProfile(
|
|
155
|
+
available=has_driver,
|
|
156
|
+
vendor=NPUVendor.QUALCOMM_HEXAGON,
|
|
157
|
+
chipset_name=f"Qualcomm Snapdragon ({soc_platform or hardware})",
|
|
158
|
+
driver_library=qnn_lib,
|
|
159
|
+
dsp_architecture=dsp_arch,
|
|
160
|
+
tops_rating=tops if has_driver else 0.0,
|
|
161
|
+
supported_precisions=["INT4", "INT8", "FP16"] if has_driver else [],
|
|
162
|
+
delegate_type="QNN_HTP_DELEGATE" if has_driver else None,
|
|
163
|
+
acceleration_status="Operational (Qualcomm Hexagon Tensor Core)" if has_driver else "SoC Detected (Driver inaccessible or SELinux restricted)",
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
# 2. Samsung Exynos NPU (ENN / Eden) Probe
|
|
167
|
+
eden_lib = _probe_first_existing_lib(SAMSUNG_EDEN_LIBS)
|
|
168
|
+
is_samsung_exynos = "exynos" in chipname or "s5e" in soc_platform or "universal" in hardware
|
|
169
|
+
|
|
170
|
+
if eden_lib or is_samsung_exynos:
|
|
171
|
+
tops = 17.0
|
|
172
|
+
dsp_arch = "Samsung Exynos Dual-NPU"
|
|
173
|
+
if "2400" in chipname or "9945" in soc_platform: # Exynos 2400
|
|
174
|
+
tops = 42.0
|
|
175
|
+
dsp_arch = "Samsung Generative AI NPU (42 TOPS)"
|
|
176
|
+
elif "1480" in chipname: # Exynos 1480
|
|
177
|
+
tops = 20.0
|
|
178
|
+
dsp_arch = "Exynos AI NPU (20 TOPS)"
|
|
179
|
+
elif "1380" in chipname: # Exynos 1380
|
|
180
|
+
tops = 4.9
|
|
181
|
+
dsp_arch = "Exynos 1380 NPU (4.9 TOPS)"
|
|
182
|
+
|
|
183
|
+
has_driver = eden_lib is not None
|
|
184
|
+
return NPUProfile(
|
|
185
|
+
available=has_driver,
|
|
186
|
+
vendor=NPUVendor.SAMSUNG_EDEN,
|
|
187
|
+
chipset_name=f"Samsung Exynos ({chipname or soc_platform})",
|
|
188
|
+
driver_library=eden_lib,
|
|
189
|
+
dsp_architecture=dsp_arch,
|
|
190
|
+
tops_rating=tops if has_driver else 0.0,
|
|
191
|
+
supported_precisions=["INT8", "FP16"] if has_driver else [],
|
|
192
|
+
delegate_type="EXYNOS_ENN_DELEGATE" if has_driver else None,
|
|
193
|
+
acceleration_status="Operational (Samsung Exynos NPU)" if has_driver else "SoC Detected (Driver inaccessible or SELinux restricted)",
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# 3. Google Tensor Edge TPU (Pixel Neural Core) Probe
|
|
197
|
+
tpu_lib = _probe_first_existing_lib(GOOGLE_EDGETPU_LIBS)
|
|
198
|
+
is_google_tensor = any(t in hardware or t in product_board for t in ["zuma", "gs201", "gs101", "tensor", "cloudripper"])
|
|
199
|
+
|
|
200
|
+
if tpu_lib or is_google_tensor:
|
|
201
|
+
has_driver = tpu_lib is not None
|
|
202
|
+
return NPUProfile(
|
|
203
|
+
available=has_driver,
|
|
204
|
+
vendor=NPUVendor.GOOGLE_EDGE_TPU,
|
|
205
|
+
chipset_name=f"Google Tensor TPU ({hardware or product_board})",
|
|
206
|
+
driver_library=tpu_lib,
|
|
207
|
+
dsp_architecture="Google Edge TPU (Custom Tensor Core)",
|
|
208
|
+
tops_rating=20.0 if has_driver else 0.0,
|
|
209
|
+
supported_precisions=["INT8", "FP16"] if has_driver else [],
|
|
210
|
+
delegate_type="EDGETPU_DELEGATE" if has_driver else None,
|
|
211
|
+
acceleration_status="Operational (Google Edge TPU Core)" if has_driver else "SoC Detected (Driver inaccessible or SELinux restricted)",
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# 4. Android Generic NNAPI Runtime Probe
|
|
215
|
+
nnapi_lib = _probe_first_existing_lib(ANDROID_NNAPI_LIBS)
|
|
216
|
+
if nnapi_lib:
|
|
217
|
+
return NPUProfile(
|
|
218
|
+
available=True,
|
|
219
|
+
vendor=NPUVendor.ANDROID_NNAPI,
|
|
220
|
+
chipset_name="Android Generic NNAPI",
|
|
221
|
+
driver_library=nnapi_lib,
|
|
222
|
+
dsp_architecture="Android Neural Networks Hardware Abstraction Layer (HAL)",
|
|
223
|
+
tops_rating=5.0,
|
|
224
|
+
supported_precisions=["INT8", "FP16"],
|
|
225
|
+
delegate_type="NNAPI_DELEGATE",
|
|
226
|
+
acceleration_status="Operational (Android NNAPI HAL)",
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
return NPUProfile(
|
|
230
|
+
available=False,
|
|
231
|
+
vendor=NPUVendor.NONE,
|
|
232
|
+
chipset_name="Generic Host",
|
|
233
|
+
driver_library=None,
|
|
234
|
+
dsp_architecture="No Dedicated NPU / TPU Detected",
|
|
235
|
+
tops_rating=0.0,
|
|
236
|
+
supported_precisions=[],
|
|
237
|
+
delegate_type="CPU_FALLBACK",
|
|
238
|
+
acceleration_status="Unavailable (CPU/GPU pipeline active)",
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def get_optimal_heterogeneous_pipeline(device: str = "auto") -> Dict[str, str]:
|
|
243
|
+
"""Determine the compute processor allocation for each diffusion pipeline component.
|
|
244
|
+
|
|
245
|
+
Note:
|
|
246
|
+
In v1.3+, diffusion inference is executed via the native Bionic sd-cli engine using
|
|
247
|
+
Vulkan GPU compute and ARM64 NEON CPU math. Direct Qualcomm QNN / Hexagon
|
|
248
|
+
NPU subgraph partitioning is the architectural target for the upcoming v2.0 runtime.
|
|
249
|
+
"""
|
|
250
|
+
req = device.lower().strip()
|
|
251
|
+
|
|
252
|
+
if req == "cpu":
|
|
253
|
+
return {
|
|
254
|
+
"text_encoder": "CPU (ARM NEON FP16)",
|
|
255
|
+
"denoiser_unet": "CPU (ARM NEON DotProd/I8MM)",
|
|
256
|
+
"vae_decoder": "CPU (ARM NEON FP16)",
|
|
257
|
+
"scheduler": "CPU (Single-Core Fast Math)",
|
|
258
|
+
"summary": "CPU-Only [ARM NEON Pipeline]"
|
|
259
|
+
}
|
|
260
|
+
else:
|
|
261
|
+
return {
|
|
262
|
+
"text_encoder": "CPU / GPU (ARM NEON / Vulkan)",
|
|
263
|
+
"denoiser_unet": "GPU (Vulkan Compute Shader Pipeline)",
|
|
264
|
+
"vae_decoder": "GPU (Vulkan Compute FP16)",
|
|
265
|
+
"scheduler": "CPU (Single-Core Fast Math)",
|
|
266
|
+
"summary": "GPU-Accelerated [Vulkan Compute Shader Pipeline]"
|
|
267
|
+
}
|