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.

pipx install helia-aot

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 [OPTIONS] COMMAND [ARGS]...

 heliaAOT command line interface.

╭─ Options ────────────────────────────────────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                                                    │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ───────────────────────────────────────────────────────────────────────────────────────╮
│ version   Display the version of the heliaAOT library.                                           │
│ convert   Convert a model to standalone C inference module.                                      │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯

4) Inspect convert help

helia-aot convert --help

Expected output:

 Usage: helia-aot convert [OPTIONS]

 Convert a model to standalone C inference module.

╭─ Options ────────────────────────────────────────────────────────────────────────────────────────╮
│ --help  -h        Show this message and exit.                                                    │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ general ────────────────────────────────────────────────────────────────────────────────────────╮
│ --path                        PATH        Path to yaml configuration                             │
│ --transforms                  [TEXT ...]  Transforms configuration                               │
│ --operators                   [TEXT ...]  Operator attributes                                    │
│ --verbose                     INT         Verbosity level (default: 1)                           │
│ --force         --no-force                Force conversion even if output exists (default:       │
│                                           False)                                                 │
│ --log-file                    PATH        Optional log file path                                 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ model ──────────────────────────────────────────────────────────────────────────────────────────╮
│ --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 ─────────────────────────────────────────────────────────────────────────────────────────╮
│ --module.path            PATH                                Output path for the generated       │
│                                                              module. Use a directory for an      │
│                                                              unpacked module, a '.zip' suffix    │
│                                                              for a generic zip archive, or a     │
│                                                              '.pack' suffix for an               │
│                                                              Open-CMSIS-Pack archive (requires   │
│                                                              module.type=cmsis_pack). (default:  │
│                                                              output.zip)                         │
│ --module.type            <neuralspot|zephyr|cmake|nsx|cmsis  Module type (default: neuralspot)   │
│                          _pack>                                                                  │
│ --module.name            TEXT                                Module name (default: helia_aot_nn) │
│ --module.prefix          TEXT                                Prefix added to sources for unique  │
│                                                              namespace (default: aot)            │
│ --module.schedule        <table|static>                      Operator dispatch shape in the      │
│                                                              generated model: 'table' (default)  │
│                                                              keeps the runtime function-pointer  │
│                                                              table and per-node callback seam;   │
│                                                              'static' emits straight-line direct │
│                                                              calls (no table, no loop, no        │
│                                                              indirect dispatch). (default:       │
│                                                              table)                              │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ test ───────────────────────────────────────────────────────────────────────────────────────────╮
│ --test.enabled              --no-test.enabled                     Include test case (default:    │
│                                                                   False)                         │
│ --test.tolerance                                           FLOAT  Test tolerance (default: 1.0)  │
│ --test.skip-verification    --no-test.skip-verification           Skip runtime output            │
│                                                                   verification (default: False)  │
│ --test.golden-data                                         PATH   Golden input/output npz file   │
│ --test.num-iterations                                      INT    Number of times to run the     │
│                                                                   same stimulus through the      │
│                                                                   model (default: 1)             │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ memory ─────────────────────────────────────────────────────────────────────────────────────────╮
│ --memory.planner                                          <greedy>    Memory planner strategy    │
│                                                                       (default: greedy)          │
│ --memory.constraints                                      [TEXT ...]  Memory constraints         │
│                                                                       (ordered by preference)    │
│ --memory.tensors                                          [TEXT ...]  Tensor attributes          │
│ --memory.allocate-arenas      --no-memory.allocate-ar…                If true, the module will   │
│                                                                       use internal, statically   │
│                                                                       allocated arenas. If       │
│                                                                       false, the caller must     │
│                                                                       bind every region via      │
│                                                                       <prefix>_bind_arena() /    │
│                                                                       <prefix>_bind_arenas()     │
│                                                                       before model_init.         │
│                                                                       (default: True)            │
│ --memory.auto-hydrate-con…    --no-memory.auto-hydrat…                Deprecated — retained for  │
│                                                                       backwards compatibility    │
│                                                                       but no longer changes      │
│                                                                       generated runtime          │
│                                                                       behavior. model_init       │
│                                                                       always invokes             │
│                                                                       hydrate_constants between  │
│                                                                       context_init and the       │
│                                                                       operator init loop.        │
│                                                                       Override the weak          │
│                                                                       hydrate_constants symbol   │
│                                                                       for custom hydration       │
│                                                                       mechanisms (DMA / async    │
│                                                                       pre-stage / model swap).   │
│                                                                       (default: True)            │
│ --memory.dump-residency-j…    --no-memory.dump-reside…                If true, write a           │
│                                                                       machine-readable residency │
│                                                                       report                     │
│                                                                       (``<prefix>_residency.jso… │
│                                                                       alongside the emitted      │
│                                                                       module. Mirrors the        │
│                                                                       verbose log summary as     │
│                                                                       JSON for tooling that      │
│                                                                       needs to introspect arena  │
│                                                                       layout, staged-vs-cold     │
│                                                                       residency, and per-tensor  │
│                                                                       placement post-planning.   │
│                                                                       (default: False)           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ platform ───────────────────────────────────────────────────────────────────────────────────────╮
│ --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                 INT         Minimum alignment requirement in bytes      │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ documentation ──────────────────────────────────────────────────────────────────────────────────╮
│ --documentation.html    --no-documentation.html      Generate html documentation site            │
│                                                      (experimental). (default: False)            │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯

 Quick start:

 helia-aot convert --model.path model.tflite --module.path ./out

 helia-aot convert --path my-model.yaml --verbose 2

 helia-aot convert --model.path model.tflite --module.type zephyr --test.enabled

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

heliaAOT v<X.Y.Z>

Analyze
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    ========================================================================================================================

  📥  Loading model add_scalar_s8.tflite ✓ 0.0s
DEBUG      • Applying transform DEPTHWISE_TO_CONV
DEBUG      • Applying transform PRUNE_IDENTITY_OPS
DEBUG      • Applying transform TRANSPOSE_REVERSE_CONV
  🔧  Applying graph-level transforms ✓ 0.0s
WARNING   unresolved dynamic tensors remain (2): ['0', '2']. Conversion continues with placeholder dims.
DEBUG     unresolved: tensor 0 (shape_signature=(-1, 3, 10)) remains unresolved with shape=(1, 3, 10)
DEBUG     unresolved: tensor 2 (shape_signature=(-1, 3, 10)) remains unresolved with shape=(1, 3, 10)
  📐  Propagating tensor shapes ✓ 0.0s
Plan
DEBUG    Resolving operator ADD (0)
  🧩  Resolving handlers ✓ 0.0s
  ⚡  Optimizing resolved model ✓ 0.0s
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]
  🧮  Memory planning via greedy ✓ 0.0s
Emit
DEBUG    Tensor 0 - Allocated size: 30, Arena: dtcm
DEBUG    Tensor 1 - Allocated size: 1, Arena: dtcm
DEBUG    Tensor 2 - Allocated size: 30, Arena: dtcm
  📝  Emitting code as zephyr module ✓ 0.1s
  📦  Exporting module ✓ 0.0s

───────────────────────────────────────────────────────────────── Results ──────────────────────────────────────────────────────────────────

  Model       model  · subgraph 0 · 1 operators
  Module      add_scalar_s8  · zephyr · prefix aot · schedule table
  Platform    apollo510_evb  · cortex-m55 · MCU, USB, PSRAM, DSP, MVE, FP16

Arenas
 Region   Kind                               Size    Capacity
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 dtcm     scratch                            62 B    512.0 KB   ╌╌╌╌╌╌╌╌╌╌╌╌╌╌   0%
 dtcm     constant (cold) · 1 tensors         1 B    512.0 KB   ╌╌╌╌╌╌╌╌╌╌╌╌╌╌   0%

╭─ Output → out ───────────────────────────╮
│  add_scalar_s8/  7 sources · 10 headers  │
╰───────────────────────────── 0.1s total ─╯

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

heliaAOT v<X.Y.Z>

Analyze
  📥  Loading model add_scalar_s8.tflite ✓ 0.0s
  🔧  Applying graph-level transforms ✓ 0.0s
WARNING   unresolved dynamic tensors remain (2): ['0', '2']. Conversion continues with placeholder dims.
  📐  Propagating tensor shapes ✓ 0.0s
Plan
  🧩  Resolving handlers ✓ 0.0s
  ⚡  Optimizing resolved model ✓ 0.0s
  🧮  Memory planning via greedy ✓ 0.0s
Emit
  📝  Emitting code as zephyr module ✓ 0.1s
  📦  Exporting module ✓ 0.0s

───────────────────────────────────────────────────────────────── Results ──────────────────────────────────────────────────────────────────

  Model       add_scalar_s8  · subgraph 0 · 1 operators
  Module      add_scalar_s8  · zephyr · prefix aot · schedule table
  Platform    apollo510_evb  · cortex-m55 · MCU, USB, PSRAM, DSP, MVE, FP16

Arenas
 Region   Kind                               Size    Capacity
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 dtcm     scratch                            62 B    512.0 KB   ╌╌╌╌╌╌╌╌╌╌╌╌╌╌   0%
 dtcm     constant (cold) · 1 tensors         1 B    512.0 KB   ╌╌╌╌╌╌╌╌╌╌╌╌╌╌   0%

╭─ Output → out ───────────────────────────╮
│  add_scalar_s8/  7 sources · 10 headers  │
╰───────────────────────────── 0.1s total ─╯

If the closing Results frame renders (with the Output panel pointing at your module) 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: