Skip to content

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).

pipx install --python python3.12 \
  'helia-aot @ git+https://github.com/AmbiqAI/helia-aot.git@main'

Expected output:

installed package helia-aot
  These apps are now globally available
    - helia-aot

3) Verify the CLI works

helia-aot version

Expected output:

HeliaAOT version: <X.Y.Z>
helia-aot --help

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

helia-aot 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:

helia-aot convert --path convert.yaml --verbose 1

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: