HeliaAOT Walkthrough
This guide walks through a full HeliaAOT flow: install, verify, inspect convert help, convert a model, and repeat with a YAML config.
What HeliaAOT Does Not Do
- Training, quantization, or dataset handling (do these upstream and feed in a ready model).
- Runtime scheduling on dynamic shapes; the emitted code assumes static shapes and buffer sizes.
Limitations to Keep in Mind
- Operator support is currently limited to the kernels registered in this repo; check the registries reference before relying on a layer.
- Mixed-precision flows are constrained by the available kernels.
- Generated sources are static; rebuild when the model, platform, or planner settings change.
1) Pick a small model to convert
Sample models live here:
2) Install HeliaAOT (pipx)
The pipx interpreter must be Python >=3.11,<3.13 (for example, python3.12).
Expected output:
3) Verify the CLI works
Expected output:
Expected output:
usage: helia-aot [-h] <command> ...
positional arguments:
<command>
version Display the version of the HeliaAOT library.
convert Convert a model to standalone C inference module.
options:
-h, --help show this help message and exit
4) Inspect convert help
Expected output:
usage: helia-aot convert [-h] [--path PATH] [--model.path PATH] [--model.subgraph INT] [--model.type TEXT] [--model.name TEXT] [--model.description TEXT] [--model.version TEXT] [--module.path PATH]
[--module.type [neuralspot|zephyr|cmake]] [--module.name TEXT] [--module.prefix TEXT] [--test.enabled | --no-test.enabled] [--test.tolerance TEXT]
[--test.skip-verification | --no-test.skip-verification] [--test.golden-data TEXT] [--transforms [TEXT ...]] [--memory.planner [greedy]] [--memory.constraints TEXT]
[--memory.tensors [TEXT ...]] [--memory.allocate-arenas | --no-memory.allocate-arenas] [--platform.name TEXT] [--platform.cpu TEXT] [--platform.speeds [INT ...]]
[--platform.memories JSON] [--platform.capabilities [TEXT ...]] [--platform.preferred-memory-order [TEXT ...]] [--platform.min-alignment TEXT] [--operators [TEXT ...]]
[--documentation.html | --no-documentation.html] [--verbose INT] [--force | --no-force] [--log-file TEXT]
options:
-h, --help show this help message and exit
--path PATH Path to yaml configuration
--model.path PATH Path to target model file (default: model.tflite)
--model.subgraph INT Subgraph index (default: 0)
--model.type TEXT Model type (e.g., tflite, litert)
--model.name TEXT Model name (default: model)
--model.description TEXT
Description of the model
--model.version TEXT Model version (default: v1.0.0)
--module.path PATH Base path for output module. Can also be a zip file.
--module.type [neuralspot|zephyr|cmake]
Module type (default: neuralspot)
--module.name TEXT Module name (default: helia_aot_nn)
--module.prefix TEXT Prefix added to sources for unique namespace (default: aot)
--test.enabled Include test case (default: False)
--no-test.enabled
--test.tolerance TEXT
Test tolerance (default: 1.0)
--test.skip-verification
Skip runtime output verification (default: False)
--no-test.skip-verification
--test.golden-data TEXT
Golden input/output npz file
--transforms [TEXT ...]
Transforms configuration
--memory.planner [greedy]
Memory planner strategy (default: greedy)
--memory.constraints TEXT
Memory constraints (ordered by preference)
--memory.tensors [TEXT ...]
Tensor attributes
--memory.allocate-arenas
If true, the module will use internal, statically allocated arenas. If false, the user must populate arena_buffers and arena_sizes before init. (default: True)
--no-memory.allocate-arenas
--platform.name TEXT Target platform name (default: apollo510_evb)
--platform.cpu TEXT CPU core type (e.g., cortex-m55)
--platform.speeds [INT ...]
List of supported clock speeds in MHz
--platform.memories JSON
Memory sizes in bytes
--platform.capabilities [TEXT ...]
List of SoC capabilities
--platform.preferred-memory-order [TEXT ...]
Preferred memory order for allocations
--platform.min-alignment TEXT
Minimum alignment requirement in bytes
--operators [TEXT ...]
Operator attributes
--documentation.html Generate html documentation site (experimental). (default: False)
--no-documentation.html
--verbose INT Verbosity level (default: 1)
--force Force conversion even if output exists (default: False)
--no-force
--log-file TEXT Optional log file path
5) Convert the model (CLI or YAML)
helia-aot convert \
--model.path add_scalar_s8.tflite \
--module.path ./out \
--module.name add_scalar_s8 \
--module.type zephyr \
--test.enabled \
--verbose 3
Expected output (verbose 3):
INFO Started AOT conversion
INFO Step: Loading model add_scalar_s8.tflite...
DEBUG ====================================================================================================
DEBUG AIR Operator ADD (id: 0)
DEBUG ====================================================================================================
DEBUG Tensors:
DEBUG - Inputs: (['0', '1'])
DEBUG - Outputs: (['2'])
DEBUG - Local: ([])
DEBUG Options:
DEBUG - activation: none
DEBUG ====================================================================================================
INFO Step completed in 0.01s
INFO Step: Applying graph-level transforms...
DEBUG - Applying transform DEPTHWISE_TO_CONV
DEBUG - Applying transform PRUNE_IDENTITY_OPS
DEBUG - Applying transform TRANSPOSE_REVERSE_CONV
INFO Step completed in 0.00s
INFO Step: Resolving handlers...
DEBUG Resolving operator ADD (0)
INFO Step completed in 0.00s
INFO Step: Memory planning via greedy...
DEBUG Tensor lifetimes:
DEBUG - Tensor 0: Lifetime from operator 0 to 0
DEBUG - Tensor 1: Lifetime from operator 0 to 0
DEBUG - Tensor 2: Lifetime from operator 0 to 0
DEBUG Memory allocation:
DEBUG - Tensor 1: dtcm[0:1]
DEBUG - Tensor 0: dtcm[0:30]
DEBUG - Tensor 2: dtcm[32:62]
INFO Step completed in 0.00s
INFO Step: Emitting code as zephyr module...
DEBUG Tensor 0 - Allocated size: 30, Arena: dtcm
DEBUG Tensor 1 - Allocated size: 1, Arena: dtcm
DEBUG Tensor 2 - Allocated size: 30, Arena: dtcm
INFO Step completed in 0.08s
INFO Step: Exporting module: out
INFO Step completed in 0.00s
INFO AOT conversion completed
Or generate it locally:
cat <<'EOF' > convert.yaml
# Example config using add_scalar_s8.tflite; adjust paths and options for your model.
model:
path: add_scalar_s8.tflite
name: add_scalar_s8
module:
path: ./out
name: add_scalar_s8
type: zephyr
test:
enabled: true
EOF
Convert:
Expected output (verbose 1):
INFO Started AOT conversion
INFO Step: Loading model add_scalar_s8.tflite...
INFO Step completed in 0.06s
INFO Step: Applying graph-level transforms...
INFO Step completed in 0.00s
INFO Step: Resolving handlers...
INFO Step completed in 0.00s
INFO Step: Memory planning via greedy...
INFO Step completed in 0.00s
INFO Step: Emitting code as zephyr module...
INFO Step completed in 0.16s
INFO Step: Exporting module: out
INFO Step completed in 0.00s
INFO AOT conversion completed
If you see AOT conversion completed and the out/ directory is created, your conversion was successful.
6) Generated output highlight
After conversion, the output directory looks like this:
out/add_scalar_s8/
├── includes-api/
├── src/
├── zephyr/
│ ├── CMakeLists.txt
│ ├── Kconfig
│ └── module.yml
├── LICENSE
└── README.md
For more detail on module contents, see the Module Layout reference.
7) Integrate the generated output
Your output module is ready to drop into an application. Follow one of these guides to integrate and build: