Profile a model
Get one valid result bundle from a board and know what every line of the terminal panel means. You will learn the shape of a run, the difference between the two cycle totals it prints, and where the arena and binary numbers come from.
Hardware and wiring
Section titled “Hardware and wiring”An Apollo510 EVB connected to the host over its J-Link USB port. Nothing else: the default transport is RTT over the debug connection, so no serial cable and no power instrument. Validate your setup confirms the probe sees the board.
Software prerequisites
Section titled “Software prerequisites”hpx (pip install helia-profiler) and a clone of the repository for the
quickstart config and model, the GNU Arm toolchain, CMake and Ninja
on PATH, SEGGER J-Link software, and on Linux the udev rule
(Install). hpx doctor must report the
toolchain and J-Link as found.
Config file
Section titled “Config file”examples/quickstart/hpx_rt.yml:
model: path: kws_model.tflite arena_size: 131072engine: type: helia-rt config: variant: release-with-logstarget: board: apollo510_evb toolchain: arm-none-eabi-gccprofiling: pmu_counters: cpu: default memory: default per_layer: true iterations: 3 warmup: 1power: enabled: falseoutput: format: csv dir: ./results/results_rtThe model path is relative to the config file, so run from
examples/quickstart/ or pass the model on the command line. Every key is
on the generated configuration reference.
cd examples/quickstarthpx profile --config hpx_rt.ymlOr without a file, from anywhere:
hpx profile examples/quickstart/kws_model.tflite --board apollo510_evb --engine helia-rtThe first run resolves and builds the NSX dependency workspace, which takes minutes; later runs reuse it.
Expected output
Section titled “Expected output”The results panel of the nightly case named under Validated on (the
Memory and Plan vs measured tables that follow it are on
Memory placement; the arena progress bar and the
host wall-clock subtitle are omitted):
─────────────────────────────────── Results ──────────────────────────────────── Engine helia-rt Compatibility qualified Board apollo510_evb Layers 13 Total cycles 2,060,239 Clean E2E cycles 2,051,232 (-0.4% vs per-layer sum) Total MACs 2,656,768 Total OPS 5,321,596 Cycles/MAC 0.78 Parameters 22,604Top Layers by Cycles # Operator Cycles % MACs Cyc/MAC 1 CONV_2D 337,348 16.4% 320,000 1.1 2 DEPTHWISE_CONV_2D 216,207 10.5% 72,000 3.0 3 DEPTHWISE_CONV_2D 216,205 10.5% 72,000 3.0 4 DEPTHWISE_CONV_2D 216,194 10.5% 72,000 3.0 5 DEPTHWISE_CONV_2D 216,192 10.5% 72,000 3.0 Arena 29,780 / 32,768 bytes 91% Model 53,744 bytes Binary Sections Section Size text 278,596 data 154,796 bss 86,260 reserved 365,404 total 885,056 Validity: VALID╭─ Output → results/… ───────────╮│ profile_results.csv ││ summary.json ││ run_metadata.json ││ nsx.lock ││ result_manifest.json │╰────────────────────────────────╯How to read it
Section titled “How to read it”Clean E2E cyclesis the inference cost: the firmware ran the model warm, back to back, with no per-layer instrumentation, and averaged 46 inferences.Total cyclesis the sum of the instrumented per-layer rows and is 0.4% higher because every operator was bracketed by a counter read. Publish the clean number (Latency and per-layer).Top Layers by Cyclesranks the per-layer rows;Cyc/MACdivides by the operator’s multiply-accumulates from the host-side model analysis. A depthwise convolution at 3.0 cycles per MAC next to a full convolution at 1.1 is the usual shape: depthwise has less arithmetic per byte moved.Arena 29,780 / 32,768is the interpreter’s allocation against the configuredarena_size; a run that reports the arena does not fit stops before flashing. The quickstart config asks for 131,072 bytes, which is what this model needs with headroom; the nightly case used 32,768.Validity: VALIDand an empty issue list mean the run is a measurement. ADEGRADEDorINVALIDverdict lists codes to look up on the issue codes page.- The five files are described on Output files;
summary.jsonhas every number above in machine-readable form.
Variations
Section titled “Variations”- Other boards, same config with
--board: the same nightly run profiled this model onapollo330mP_evb(2,056,992 clean cycles, Cortex-M55),apollo3p_evb(10,186,141, Cortex-M4, DWT cycle counter only) andapollo4l_blue_evb(8,683,558, Cortex-M4); those bundles ship beside the Apollo510 one. Cortex-M4 boards capture cycles only, not the PMU groups (Boards and targets). - More iterations:
--iterations 20 --warmup 5tightens the per-layer median; the clean window is sized separately bywindow_target_ms. - Another engine or toolchain: Compare engines, Compare toolchains.
- A JSON bundle:
--output-format jsonwritesprofile_results.jsoninstead of the CSV.
Validated on
Section titled “Validated on”| Board | apollo510_evb (Apollo510, Cortex-M55, lp clock tier, 96 MHz as recorded in the bundle’s run_metadata.json) |
| Run | nightly hardware validation run 35078330526, 2026-09-16 09:15 UTC, suite complete, hpx 0.1.6 at source commit 0714893 |
| Case | apollo510_evb-kws-rt-ns-arm-none-eabi-gcc-rtt-auto, verdict valid, no issues |
| Model | kws_model.tflite, SHA-256 935c513a…bdf038, the same bytes as the quickstart file |
| nsx modules | baseline hpx-neuralspotx-0.8.1-2026-09: nsx-helia-rt helia-rt-v1.20.0 (edb3a25), nsx-cmsis-nn aaeb145, nsx-ambiq-sdk a9f4ec2, nsx-pmu-armv8m 5725c06, nsx-board-apollo510-evb packaged with neuralspotx 0.8.1 |
| Toolchain | arm-none-eabi-gcc 15.2.1 (Arm GNU Toolchain 15.2.Rel1), CMake 4.1.2 |
| Differences from the config above | the nightly case used arena_size: 32768, pmu_counters: {cpu: default} and output.format: csv; the quickstart config adds the memory group and a larger arena |
| Bundle | examples/results/hardware-validation-2026-09-16/apollo510_evb-kws-rt-ns-arm-none-eabi-gcc-rtt-auto/ |