Zero-hard-dependency ONNX Runtime provider selection, diagnostics, and benchmarking for NPUs, GPUs, and CPUs.
Project description
npu-easy
npu-easy is a small, zero-hard-dependency wrapper around ONNX Runtime. It
discovers installed execution providers, prefers an NPU, can fall back to a
GPU or CPU, and reports exactly which provider is active.
Install
Install the package with the runtime extra for your hardware:
# Intel Core Ultra NPU through OpenVINO
pip install "npu-easy[intel]"
# Qualcomm Snapdragon NPU through QNN
pip install "npu-easy[qualcomm]"
# Broad Windows GPU support through DirectML
pip install "npu-easy[directml]"
# NVIDIA CUDA
pip install "npu-easy[nvidia]"
# CPU only
pip install "npu-easy[cpu]"
Provider wheels have their own Python, architecture, driver, and operating
system requirements. In particular, Qualcomm NPU inference requires a
compatible Windows ARM64 onnxruntime-qnn wheel. DirectML targets GPUs, not
NPUs.
Diagnose The Machine
The diagnostics command works even before ONNX Runtime is installed:
npu-easy info
python -m npu_easy info --json
It reports detected NPU/GPU devices, Python and platform details, installed execution providers, the selected provider, and installation guidance.
Quick Start
import numpy as np
from npu_easy import NPUModel
model = NPUModel("model.onnx")
outputs = model.run(np.random.randn(1, 10).astype(np.float32))
print(model.get_info()["provider"])
Automatic selection uses this order:
- Qualcomm QNN or Intel OpenVINO NPU
- TensorRT, CUDA, MIGraphX, DirectML, ROCm, Core ML, or OpenVINO GPU
- ONNX Runtime CPU
Explicit Providers And Fallback
Choose a provider and inspect whether fallback occurred:
model = NPUModel(
"model.onnx",
provider="QNNExecutionProvider",
provider_options={"backend_type": "htp"},
)
info = model.get_info()
print(info["requested_provider"], info["provider"], info["used_fallback"])
For validation or benchmarking, disable CPU fallback so unsupported models do not appear to be accelerated:
from npu_easy import ProviderInitializationError
try:
model = NPUModel(
"model.onnx",
provider="QNNExecutionProvider",
allow_cpu_fallback=False,
)
except ProviderInitializationError as error:
print(error)
You can also pass a provider preference list:
model = NPUModel(
"model.onnx",
provider=[
"QNNExecutionProvider",
"DmlExecutionProvider",
"CPUExecutionProvider",
],
)
Multiple Inputs And Named Outputs
outputs = model.run(
{
"tokens": token_array,
"attention_mask": mask_array,
}
)
named_outputs = model.run_named(input_array)
Warmup, Benchmarking, And Profiling
model.warmup(input_array, iterations=5)
metrics = model.benchmark(input_array, runs=100, warmup_runs=10)
print(metrics["median_ms"], metrics["p95_ms"])
profiled_model = NPUModel(
"model.onnx",
enable_profiling=True,
profile_file_prefix="profiles/model",
)
profiled_model.run(input_array)
profile_path = profiled_model.end_profiling()
Threading and graph settings are also configurable:
model = NPUModel(
"model.onnx",
intra_op_num_threads=4,
inter_op_num_threads=2,
graph_optimization_level="all",
execution_mode="sequential",
)
Compare Hardware
MultiRunner creates one strict runner per available device class. Accelerator
runners do not silently fall back to CPU by default.
from npu_easy import MultiRunner
runner = MultiRunner("model.onnx")
all_outputs = runner.run_all(input_array)
benchmarks = runner.benchmark_all(input_array, runs=50)
print(runner.get_info())
Use devices=("NPU", "CPU") to limit the comparison. Initialization failures
for unavailable or unsupported accelerators are exposed by
runner.get_info()["initialization_errors"].
Provider Notes
- OpenVINO uses
device_type="NPU"by default. - QNN uses
backend_type="htp"by default. - Standalone
onnxruntime-qnn2.x plugins are registered automatically and matched to their reported NPU, GPU, or CPU device. - TensorRT uses CUDA as its accelerator fallback when both are installed.
- DirectML is a broad Windows GPU provider. New Windows deployment work may also consider Windows ML, while DirectML remains supported by ONNX Runtime. Its required sequential execution and disabled memory-pattern settings are applied automatically.
- Model operator support and quantization requirements vary by provider.
Development
pip install -e ".[dev]"
pytest
ruff check .
python -m build
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file npu_easy-0.3.0.tar.gz.
File metadata
- Download URL: npu_easy-0.3.0.tar.gz
- Upload date:
- Size: 28.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1565c2382562e9721e01ae2a9b81c78e237b9ed8cc7d52f4fc5824584e9fffee
|
|
| MD5 |
c45bf832214308a750c740fda8e5147d
|
|
| BLAKE2b-256 |
a7e60d7c7033aad8eb630e6c894e1537455f07764614f3f6424dee20aee524fa
|
Provenance
The following attestation bundles were made for npu_easy-0.3.0.tar.gz:
Publisher:
python-publish.yml on kai9987kai/npu_easy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
npu_easy-0.3.0.tar.gz -
Subject digest:
1565c2382562e9721e01ae2a9b81c78e237b9ed8cc7d52f4fc5824584e9fffee - Sigstore transparency entry: 1746879390
- Sigstore integration time:
-
Permalink:
kai9987kai/npu_easy@e698789c23ebb353a205eff7b87c3b1c57f3da28 -
Branch / Tag:
refs/tags/2.0 - Owner: https://github.com/kai9987kai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e698789c23ebb353a205eff7b87c3b1c57f3da28 -
Trigger Event:
release
-
Statement type:
File details
Details for the file npu_easy-0.3.0-py3-none-any.whl.
File metadata
- Download URL: npu_easy-0.3.0-py3-none-any.whl
- Upload date:
- Size: 26.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02e03c35170b1379f65ff594fd849a0cabeb090c4ad4f2a0ee824a7ed5e28924
|
|
| MD5 |
7e8be24d52fb7eda6e209daac2e89b11
|
|
| BLAKE2b-256 |
e6b8fe114eb965ac2c82ba1310dc8db539f4c58fa0ed23cb789f1134ed57b8eb
|
Provenance
The following attestation bundles were made for npu_easy-0.3.0-py3-none-any.whl:
Publisher:
python-publish.yml on kai9987kai/npu_easy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
npu_easy-0.3.0-py3-none-any.whl -
Subject digest:
02e03c35170b1379f65ff594fd849a0cabeb090c4ad4f2a0ee824a7ed5e28924 - Sigstore transparency entry: 1746879539
- Sigstore integration time:
-
Permalink:
kai9987kai/npu_easy@e698789c23ebb353a205eff7b87c3b1c57f3da28 -
Branch / Tag:
refs/tags/2.0 - Owner: https://github.com/kai9987kai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e698789c23ebb353a205eff7b87c3b1c57f3da28 -
Trigger Event:
release
-
Statement type: