heliaPROFILER
hpx profiles LiteRT (.tflite) and ExecuTorch (.pte) models on real
Ambiq Apollo silicon.
One command resolves an inference engine, builds temporary NSX firmware,
flashes the target, captures measurements, and writes a portable result bundle.
Alpha. heliaPROFILER is pre-1.0. Breaking changes may land on minor versions until v1.0. Pin an exact version in production pipelines.
📖 Full docs: https://ambiqai.github.io/helia-profiler/
Why hpx
- Per-layer PMU breakdowns — cycles, instructions, cache, and (on Cortex-M55 boards) MVE and memory counter groups, one row per layer.
- Power & energy per inference — GPIO-gated Joulescope capture (JS110/JS220/JS320) uses a dedicated transport-free firmware image to isolate the inference window from setup/teardown and capture traffic.
- Four engines, one per run —
tflm(vanilla TFLM baseline),helia-rt(Ambiq's optimized TFLM interpreter),helia-aot(Ambiq's ahead-of-time model compiler), andexecutorch(Cortex-M ExecuTorch programs, on thearmornsCMSIS-NN provider). Selected explicitly — never auto-detected. - Multiple toolchains —
arm-none-eabi-gcc,armclang, and ATfE, so you can compare build/runtime trade-offs without changing your model. - Memory placement control — place the heliaRT tensor arena in TCM, SRAM, or PSRAM and weights in TCM, SRAM, MRAM, or PSRAM; heliaAOT exposes per-tensor placement through its engine configuration, and ExecuTorch places each of its five runtime buffers independently.
- Four capture transports — lossless RTT by default, plus USB CDC, UART, and diagnostic SWO, with probe, port, and target-reset helpers for bring-up.
- Host-only model analysis — inspect MACs, parameters, tensor sizes, and heliaAOT graph transforms without connecting hardware.
- Run comparison and regression policy — compare two result bundles, inspect the largest layer deltas, and apply versioned metric thresholds.
- Model Explorer overlays — export per-layer metrics as JSON overlays for Model Explorer.
- Config-file driven — a frozen, immutable
hpx.ymlschema merges with CLI flags, with strict validation and did-you-mean suggestions for typos. - Multi-board — Apollo3, Apollo4, and Apollo5-family EVBs. Run
hpx boardsfor the exact list your install supports. - Verifiable result bundles — summaries, per-layer data, provenance, validity/comparability issues, and a SHA-256 manifest designed for scripts as well as people.
- Hardware-in-the-loop validation —
hpx validateruns canonical MLPerf Tiny models end-to-end across engines, toolchains, transports, and memory placements, and emits a portable bundle two runs can be compared from. - Typed Python API — call
profile()directly or use immutable, branchableSessionworkflows in notebooks and automation.
Install
See the Quick install for Nix, uv, and pip setup.
Quick taste
hpx doctor # check toolchain + dependencies
hpx profile model.tflite # profile with defaults
hpx profile model.tflite --power # add Joulescope power capture
hpx profile --config hpx.yml # reproducible, config-driven run
hpx analyze model.tflite # inspect the model without hardware
hpx compare results/baseline results/change # compare two completed runs
hpx validate --suite smoke # prove the whole bench works
hpx profile defaults to heliaRT, GNU Arm, RTT, apollo510_evb, per-layer
CPU counters, 100 measured iterations, and 5 warmups. Select a different
engine, board, toolchain, transport, memory plan, PMU selection, or output
directory explicitly on the command line or in YAML.
Layer Op ARM_PMU_CPU_CYCLES ARM_PMU_INST_RETIRED
0 CONV_2D 123,456 98,765
1 DEPTHWISE_CONV_2D 45,678 34,567
...
Power: 1.234 mA avg 12.345 mW avg x.xxx µJ / inference
(Illustrative sample only — see Getting Started for a real walkthrough.)
Development
uv sync --locked --all-groups --extra aot --extra analysis
uv run ruff check .
uv run ty check src/helia_profiler tests
uv run pytest -q
pytest deselects the hardware marker by default, so the whole unit suite
runs with no board attached. Hardware cases run through hpx validate (or
pytest -m hardware).
For software-only capture tests or standalone review probes, install the device guard before importing HPX:
uv run python tools/software_only.py pytest -m 'not hardware and not compile_hw and not host_integration' -q
uv run pytest -m 'host_integration and not hardware and not compile_hw' -q
uv run python tools/software_only.py python /path/to/probe.py
Standalone probes can import sibling helpers; the checkout src directory
retains precedence over the probe directory.
The launcher blocks Joulescope, J-Link and USB driver imports and provides inert serial constructors and port discovery that raise until replaced with fakes. Callbacks copied after startup retain those inert operations even if a later monkeypatch changes the original module. Installation rejects already imported HPX/device modules. Selecting a pytest marker alone does not provide this guard.
Python children must use sys.executable and retain the launcher's bootstrap and
checkout src prefix in PYTHONPATH, plus PYTHONSAFEPATH=1;
a sitecustomize hook guards children and grandchildren before
their scripts run. Stripped environments, startup flags that suppress the hook,
shells, preexec_fn callbacks and external commands are rejected. Mock external
tool calls in these tests. Pure statistics tests supply timebase metadata without
loading the vendor package.
host_integration identifies tests whose assertions require real host compilers,
Git, packaging, shell scripts, or interpreter isolation. These still run in the
ordinary CI suite, separately from hardware tests. Their fixtures use temporary
files, inert device sentinels and fake external commands where needed; they do
not contact boards. The guard's own negative controls belong here because they
must compare guarded and unguarded child interpreters. Compiler discovery happens
at test setup, so collecting or deselecting these tests does not launch a compiler.
To inspect either selection, add --collect-only -q to its command above.
This is an accidental-access guard for trusted Python tests, not an OS sandbox: trusted interpreter startup/site files are assumed, and direct native device I/O or deliberate removal of the guard is outside its boundary. Run hardware tests separately through the existing explicit hardware workflow with board ownership. The guard does not alter production capture behavior or claim hardware validation.
The launcher's own tests run fresh interpreters against inert vendor sentinels, including unguarded negative controls; run them outside the launcher:
uv run pytest --confcutdir=tools/tests tools/tests/test_software_only.py -q
Pre-commit hooks
One-time setup after cloning:
uv tool install pre-commit==4.6.0
pre-commit install
Nix contributors can run nix develop .#contrib to get pre-commit 4.6.0
alongside the HPX tools, then run pre-commit install once. The default
nix develop environment is unchanged; entering either shell does not install hooks.
This installs both hook stages the repo uses: pre-commit (formatting,
whitespace/YAML/JSON/TOML checks, ruff, and a gate requiring every
TODO(...)/FIXME(...)/HACK(...) marker to carry a reference) and
prepare-commit-msg (strips AI-tool attribution trailers from the commit
message). pre-push is left untouched, so git-lfs's own pre-push hook
keeps working. Secret scanning is server-side: GitHub secret scanning and
push protection are enabled on the repository, so a pushed secret is
rejected regardless of local hooks.
Run every hook against the whole tree with pre-commit run --all-files.
CI runs the identical .pre-commit-config.yaml, so a clean local run means
a clean CI run. Hook revisions are bumped deliberately via pre-commit autoupdate in its own reviewed PR, not ad hoc.
The docs site lives in astro-site/ (Astro and Starlight on @ambiqai/helia-ui);
npm ci && npm run build there builds it, npm run dev serves it, and the
check chain in .github/workflows/docs.yml is what CI runs. It deploys to
GitHub Pages on a release and on docs-only pushes to main.
See Documentation release checks for browser
validation, manual publishing and post-deployment verification.
Repository workflows use the committed uv.lock for reproducibility. PyPI
installations continue to resolve the compatible dependency ranges published in
pyproject.toml.
Architectural rules, module responsibilities, and the repo workflows that
should stay stable are documented in AGENTS.md — worth reading
before a first change, whether you are a person or an agent.
License
Apache-2.0
Fixed-fixture PSRAM weights
The fixture API supports SRAM or DTCM working memory with PSRAM weights for heliaAOT and upstream LiteRT Micro on Apollo510 EVB. AOT uses externally bound arenas; Micro constructs its interpreter from the PSRAM flatbuffer. Both load complete weights once from MRAM staging before model initialization and timing. MRAM staging remains part of the firmware image. Internal state policy and input restoration are unchanged.
Pass the compiled build's psram_weights descriptor to
FixtureCaptureRequest.psram_weights. The descriptor binds expected payloads
and PSRAM clock to the exact image. Capture requires the bounded placement
terminal and verifies ready/XIP status, active ranges and payload checksums.
A linker map alone cannot establish runtime PSRAM placement. A build rendered
without compilation has an unbound descriptor and cannot authorize capture.
This additive interface is fixture API 3.5; it does not include a streaming or
numerical qualification claim. Placement validation uses the canonical target
bank extents and implemented backing paths rather than benchmark recipe pairs.
Static working arenas currently use SRAM or DTCM; dynamic PSRAM working arenas,
other fixture reset targets, and NOR/RRAM loader declarations are separate
adapter gaps. External AOT fixture binding currently requires PSRAM weights.
Operator timing binding compares the effective working and weight banks recorded
in the build receipt; legacy receipts without those banks are refused.
Ordinary profile operator timings cannot be bound to PSRAM fixture builds: their
active payload, external arena layout and loader configuration are not recorded
by that profile binding.
Metadata
Release files for helia-profiler 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| helia_profiler-0.2.0.tar.gz | 1.2 MB | Without provenance | Details for helia_profiler-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| helia_profiler-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for helia_profiler-0.2.0-py3-none-any.whl |
Total release size: 2.2 MB
Release files / helia_profiler-0.2.0.tar.gz
| Download URL | helia_profiler-0.2.0.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1d05659fffdec2549ff8624248182c81ba12a1656be4b5535f10fbf5a068c30c
|
|
BLAKE2b-256 checksum How to use checksums |
eca226a777f1584786dbf9e911b2cd5d87a39c263ad0fdf86dc8d8781b7e62c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / helia_profiler-0.2.0-py3-none-any.whl
| Download URL | helia_profiler-0.2.0-py3-none-any.whl |
|---|---|
| Size | 912.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
14c3e54413b91a77048ef2aff349638f24d344464e3f667cda6c6aa8eb811173
|
|
BLAKE2b-256 checksum How to use checksums |
e9257bff8a672b5a00c46961055da400b82c47b1f74d207bf1a06e482821b0ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for helia-profiler 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.