Command-line interface for tinyml-modelmaker.
mmcli is a self-contained native binary (macOS, Linux, Windows) that drives the
tinyml-modelmaker training and compilation pipeline entirely from the command line —
no YAML config file required (though one can optionally be used as a base).
It ships with one small example dataset built into the binary
(generic_audio_classification, 18 KB); the other nine are fetched on first
use from this project's own GitHub release mirror (see Datasets
below), so mmcli init --dataset still gets you to a running project in a
single command whenever the network is reachable. Air-gapped machines can
preload every dataset ahead of time via MMCLI_DATASETS.
mmcli is a single native binary (~31.8 MB, measured on macOS) that does
not bundle tinyml_modelmaker, PyTorch, or TVM. Instead it:
- Translates your CLI arguments into the config dict that
tinyml_modelmakerexpects - Writes a temporary YAML file
- Calls
$MMCLI_PYTHON run_tinyml_modelmaker.py <tempfile>as a subprocess
This means tinyml_modelmaker runs in your existing Python 3.10 environment with all
its native dependencies (including MPS/Metal for macOS training).
Compilation on macOS:
mmcli compileandmmcli runare fully supported on macOS. Compilation always requires ti_mcu_nnc (TVM) for the NPU stage, plus a device-family compiler that depends on the target:
Target family Devices Compiler Env var C2000 DSP F28xxx, F29xxx cl2000C2000_CG_ROOTARM Cortex-M / SimpleLink / Sitara MSPM0, CC, AM tiarmclangARM_LLVM_CGT_PATHSet the env var to the toolchain root; mmcli resolves the binary at
<root>/bin/<compiler>. Falls back toPATHif the env var is not set. Runmmcli diagnoseto verify tool detection before running a compile job.On macOS ARM64, the process may exit with code 245 after the pipeline completes — this is a known crash in the onnxsim C extension during Python shutdown and does not affect output artifacts (
compilation/artifacts/mod.ais written before it).
# Create and activate a Python 3.10 venv
python3.10 -m venv ~/.venv-tinyml
source ~/.venv-tinyml/bin/activate
# Install tinyml_modelmaker from the release tag
pip install "tinyml_modelmaker @ git+https://github.com/musicalplatypus/tinyml-tensorlab.git@PlatypusCLI_1.0.0_Release#subdirectory=tinyml-modelmaker"Add to your ~/.zshrc (or ~/.bash_profile):
export MMCLI_PYTHON="$HOME/.venv-tinyml/bin/python"Option A — Use the pre-built binary:
cp dist/mmcli /usr/local/bin/mmcli # or anywhere on your PATHOption B — Download from GitHub Releases:
Pre-built binaries for macOS (arm64), Linux (x86_64), and Windows (x86_64) are published automatically on the Releases page.
Option C — Build it yourself (requires any Python + PyInstaller in an active venv):
git clone --branch PlatypusCLI_1.0.0_Release https://github.com/musicalplatypus/tinyml-cli.git
cd tinyml-cli
source ~/.venv-ai/bin/activate # any venv with PyInstaller
pip install pyinstaller -q
pip install -e .
bash build_macos.sh # macOS → dist/mmcli
bash build_linux.sh # Linux → dist/mmcli
powershell build_windows.ps1 # Windows → dist/mmcli.exeCreate a new project directory pre-populated with a dataset, ready for training.
mmcli init -t TASK --dataset DATASET_NAME -p PROJECT_DIR [-m MODULE]
mmcli init --list [-t TASK] [-m MODULE]
| Flag | Short | Description |
|---|---|---|
--list |
-l |
List available datasets (no extraction) |
--task |
-t |
Task type (required for extraction) |
--dataset |
Name of the example dataset (required for extraction) | |
--project |
-p |
Path for the new project directory (required for extraction) |
Analyze a project's dataset/ directory and report sample count, class distribution, sequence length, and size bucket.
mmcli analyze -i PROJECT_DIR [--format FORMAT] [-o OUTPUT_FILE]
Phase 5 Features:
--format json|csv|yaml- Export analysis results in specified format-o FILE- Write output to file instead of stdout
Query the model registry and display available options.
mmcli info -m MODULE [-t TASK_TYPE] [-d DEVICE] [--format FORMAT] [-o OUTPUT_FILE]
Phase 5 Features:
--format json|csv|yaml- Export information in specified format-o FILE- Write output to file instead of stdout
Score every tinyml-modelzoo example against your task, device, and variables to recommend the best-matching models.
mmcli recommend -t TASK_TYPE -d DEVICE [--format FORMAT] [-o OUTPUT_FILE] [OPTIONS]
Phase 5 Features:
--format json|csv|yaml- Export recommendations in specified format-o FILE- Write output to file instead of stdout
Compare model configurations to find the best fit for your needs.
mmcli compare -m MODULE --model1 MODEL1 --model2 MODEL2 [--device DEVICE] [--format FORMAT] [-o OUTPUT_FILE]
Phase 5 Features:
--format json|csv|yaml- Export comparison results in specified format-o FILE- Write output to file instead of stdout
Run diagnostic checks to identify common issues.
mmcli diagnose [--full] [--error MESSAGE] [--format FORMAT] [-o OUTPUT_FILE]
Phase 5 Features:
--full- Run extended diagnostics (includes disk space, etc.)--error MESSAGE- Get fix suggestion for a specific error message--format json|csv|yaml- Export diagnostic results in specified format-o FILE- Write output to file instead of stdout
Train a model using the tinyml-modelmaker pipeline.
mmcli train -m MODULE -t TASK_TYPE -d DEVICE [-n MODEL_NAME] -i PROJECT_DIR [--progress]
Phase 5 Features:
--progress- Display progress bar during training
Compile a pre-trained ONNX model for a target microcontroller.
mmcli compile -m MODULE -t TASK_TYPE -d DEVICE [-n MODEL_NAME] -o OUTPUT_FILE [--progress]
Phase 5 Features:
--progress- Display progress bar during compilation
Run the full tinyml-modelmaker pipeline.
mmcli run -m MODULE -t TASK_TYPE -d DEVICE [-n MODEL_NAME] -i PROJECT_DIR [--progress]
Phase 5 Features:
--progress- Display progress bar during training and compilation |--module|-m| AI module (auto-detected from dataset if omitted) |
Examples:
# List all available datasets
mmcli init --list
# List datasets for a specific module
mmcli init --list -m vision
# Create a project for arc fault classification
mmcli init -t arc_fault --dataset arc_fault_classification -p ./my_arc_project
# Then train with it
mmcli train -m timeseries -t arc_fault -d F28P55 -n CLS_1k_NPU -i ./my_arc_projectTip: Run
mmcli init --listto see all available datasets, ormmcli info -m timeseries -t <task>for task-specific details.
Analyse a project's dataset/ directory and report sample counts, per-class
distribution, minimum sequence length, and a size bucket
(tiny / small / medium / large). Feed the bucket to mmcli recommend
via --dataset-size-bucket to improve model selection accuracy.
mmcli analyze -i PROJECT_DIR
| Flag | Short | Description |
|---|---|---|
--project |
-i |
Project directory containing dataset/ (or the dataset folder itself) (required) |
Example:
mmcli analyze -i ./my_project
# → reports class counts and emits: dataset size bucket: mediumScore every tinyml-modelzoo example against your task, device, and optional dataset characteristics, then print a ranked shortlist of the best-matching models and feature-extraction presets.
mmcli recommend -t TASK -d DEVICE [options]
| Flag | Short | Description |
|---|---|---|
--task |
-t |
Task type (required) |
--device |
-d |
Target MCU device (required) |
--module |
-m |
AI module — auto-inferred from --task when omitted |
--variables N |
Sensor channel count — boosts score +2 for an exact match | |
--dataset-size-bucket |
tiny / small / medium / large — output of mmcli analyze |
|
--top N |
Number of ranked matches to display (default: 5) | |
--modelzoo-path DIR |
Explicit path to the tinyml-modelzoo repo root |
Scoring: task (+1) · device (+1) · module (+1) · variables exact (+2) · size (+1) = max 6.
Examples:
mmcli recommend -t motor_fault -d F28P55 --variables 3 --dataset-size-bucket small
mmcli recommend -t arc_fault -d F28P55 --top 10
mmcli recommend -t generic_timeseries_forecasting -d MSPM0G5187Use the recommended model name with mmcli train -n <model> and the feature
extraction preset with --feature-extraction <preset>.
Train a model and export model.onnx. Compilation is skipped.
mmcli train -m MODULE -t TASK -d DEVICE -n MODEL -i PROJECT_DIR [options]
mmcli train -m MODULE -t TASK -d DEVICE --nas SIZE -i PROJECT_DIR [options]
| Flag | Short | Description |
|---|---|---|
--module |
-m |
timeseries or vision |
--task |
-t |
Task type (see list below) |
--device |
-d |
Target device (e.g. F28P55) |
--model |
-n |
Model name from catalog (optional with --nas) |
--project |
-i |
Path to project directory containing dataset/ |
--config |
-c |
Optional base YAML file (CLI args override) |
--feature-extraction |
Feature extraction preset name | |
--epochs |
Training epochs | |
--batch-size |
Batch size | |
--lr |
Learning rate | |
--gpus |
Number of GPUs (0 = CPU/MPS, default on macOS) | |
--quantization |
NO_QUANTIZATION or QUANTIZATION_TINPU |
|
--run-name |
Output folder name (supports {date-time}, {model_name}) |
|
--output |
Root output directory | |
--compile-model |
0 (default) or 1 to enable torch.compile (CUDA recommended) |
|
--native-amp |
Enable native mixed precision (CUDA recommended, not for MPS) | |
--report |
Generate a live-updating HTML training report (charts + confusion matrix) | |
--nas |
NAS model size preset: s, m, l, xl (classification only) |
|
--nas-epochs |
NAS search epochs (default: 10) | |
--nas-optimize |
NAS resource target: Memory (default) or Compute |
Example:
mmcli train \
-m timeseries \
-t generic_timeseries_classification \
-d F28P55 \
-n CLS_1k_NPU \
-i ./data/my_project \
--epochs 30 \
--batch-size 256Compile a pre-trained ONNX file. No training data needed. Supported on Linux, Windows, and macOS. Requires ti_mcu_nnc (TVM) plus a device-family compiler:
- C2000 targets (F28xxx/F29xxx):
cl2000— setC2000_CG_ROOT - ARM targets (MSPM0, CC, AM):
tiarmclang— setARM_LLVM_CGT_PATH
Run mmcli diagnose to verify tool availability.
mmcli compile -m MODULE -t TASK -d DEVICE -n MODEL -o ONNX_FILE [options]
| Flag | Short | Description |
|---|---|---|
--onnx |
-o |
Path to existing ONNX model file (required) |
--preset |
Compilation preset (default: default_preset) |
|
| (common flags above) |
Example:
mmcli compile \
-m timeseries \
-t generic_timeseries_classification \
-d F28P55 \
-n CLS_1k_NPU \
-o ./data/projects/my_run/model.onnxTrain then compile. Accepts all flags from both train and compile. Compilation
requires ti_mcu_nnc (TVM) plus a device-family compiler (see mmcli compile above).
Supported on Linux, Windows, and macOS. Run mmcli diagnose to verify tools before
running.
mmcli run \
-m timeseries \
-t generic_timeseries_classification \
-d F28P55 \
-n CLS_1k_NPU \
-i ./data/my_dataset \
--quantization QUANTIZATION_TINPUEnd-to-end device deployment in five subcommands. Run them in sequence after
mmcli run (or mmcli compile) has produced compilation/artifacts/mod.a.
mmcli deploy check-sdk -d F28P55
mmcli deploy check-sdk -d CC1312 --sdk-path ~/ti/simplelink_cc13xx_sdk_7.10.00| Flag | Description |
|---|---|
-d / --device |
Target MCU device (required) |
--sdk-path PATH |
Explicit SDK root path (skips auto-detection) |
Validates that the 4 files needed for CCS (mod.a, tvmgen_default.h,
test_vector.c, user_input_config.h) all exist.
mmcli deploy artifacts -t motor_fault --run-id 20240115_143022 --model-id CLS_1k_NPU
# Add --no-quantization for float model artifacts
# Add --tinyml-base <PATH> if checkout is not at ~/tinyml-tensorlab| Flag | Description |
|---|---|
-t / --task |
Task type (required) |
--run-id RUN_ID |
Timestamp run directory name (e.g. 20240115_143022) (required) |
--model-id MODEL_ID |
Model name from training config (e.g. CLS_1k_NPU) (required) |
--no-quantization |
Use base (float) golden vectors instead of quantized |
--tinyml-base PATH |
tinyml-tensorlab root (default: ~/tinyml-tensorlab) |
mmcli deploy create \
-d F28P55 -t motor_fault \
--run-id 20240115_143022 --model-id CLS_1k_NPU \
--project-name my_motor_fault_project| Flag | Description |
|---|---|
-d / --device |
Target MCU device (required) |
-t / --task |
Task type (required) |
--run-id RUN_ID |
Training run timestamp directory name (required) |
--model-id MODEL_ID |
Model name from training artifacts (required) |
--project-name NAME |
Name for the new CCS project folder (required) |
--device-type CCS_TYPE |
CCS device type string — auto-resolved from --device when omitted |
--sdk-path PATH |
Explicit SDK root path (overrides auto-detection) |
--ccs-templates-path PATH |
Explicit AI examples directory (overrides --sdk-path) |
--no-quantization |
Use base (float) golden vectors |
--tinyml-base PATH |
tinyml-tensorlab root (default: ~/tinyml-tensorlab) |
CCS device type strings (auto-resolved from --device):
| Device | CCS type |
|---|---|
| F28P55 | f28p55x |
| F28P65 | f28p65x |
| F28004 | f28004x |
| MSPM0G3507 | mspm0g3507 |
| MSPM0G5187 | mspm0g5187 |
| AM263 | am263 |
| CC2755 | cc2755 |
| CC1312 | cc1312 |
| CC1314 | cc1314 |
| CC1352 | cc1352 |
mmcli deploy build \
--project-path /path/to/project \
--ccs-path /opt/ti/ccs1260| Flag | Description |
|---|---|
--project-path PATH |
CCS project folder (required) |
--ccs-path PATH |
CCS installation root (required) |
--workspace PATH |
Eclipse workspace directory (default: /tmp/ccs_ws_<pid>) |
--build-type |
full (default) or incremental |
Connect the device via USB/JTAG before running this.
mmcli deploy flash \
--project-path /path/to/project \
--ccs-path /opt/ti/ccs1260| Flag | Description |
|---|---|
--project-path PATH |
CCS project folder (required) |
--ccs-path PATH |
CCS installation root (required) |
--project-name NAME |
Project binary name (defaults to folder name) |
--ccxml PATH |
Device .ccxml target config file (auto-searched if omitted) |
--out-file PATH |
Explicit path to the .out binary (auto-searched if omitted) |
mmcli ships with exactly one dataset built into the binary
(generic_audio_classification, 18 KB). The other nine are fetched on first
use from this project's own GitHub release mirror —
releases/download/datasets-<version>/<filename> on
musicalplatypus/tinyml-cli
— not from TI. TI's original CDN (software-dl.ti.com) moved its paths in
production and now 404s, so the nine datasets were mirrored to this
project's own release assets from their digest-verified bytes.
| Dataset Name | Task Type | Size | Description | Source |
|---|---|---|---|---|
generic_timeseries_classification |
classification | 2.5 MB | Synthetic waveforms (sawtooth, sine, square) | fetched |
generic_timeseries_regression |
regression | 885 KB | Synthetic regression data | fetched |
generic_timeseries_anomalydetection |
anomaly detection | 4.0 MB | Amplitude/frequency anomalies | fetched |
generic_timeseries_forecasting |
forecasting | 69 KB | Simulated thermostat temperatures | fetched |
arc_fault_classification |
arc_fault | 13 MB | DC arc fault currents (DSI sensor) | fetched |
ecg_classification |
ecg_classification | 4.4 MB | ECG 2-class heartbeat (normal vs abnormal) | fetched |
fan_blade_fault |
motor_fault | 54 MB | Fan blade vibration (3-axis accelerometer) | fetched |
pir_detection |
pir_detection | 1.5 MB | PIR motion detection (human vs non-human) | fetched |
mnist_image_classification |
image_classification | 45 MB | MNIST handwritten digits (28×28 images) | fetched |
generic_audio_classification |
audio_classification | 18 KB | Synthetic 2-class audio (yes/no), 16kHz sine-wave WAVs | bundled |
Every dataset lookup (mmcli init --dataset <name>, mmcli datasets path <name>,
mmcli datasets pull <name>) resolves in this order:
MMCLI_DATASETS, if set to an existing directory. Setting this variable disables all fetching, unconditionally — it is the offline/air-gapped escape hatch, not a path override with a network fallback. A dataset not found insideMMCLI_DATASETSis treated as unavailable even if it could otherwise be downloaded.- The bundled directory inside the binary — only
generic_audio_classificationlives here now. - The version-scoped cache,
~/.cache/mmcli/datasets/<version>/(honoursXDG_CACHE_HOME). The version is part of the path deliberately, so bumping the mirrored dataset release can never silently reuse a zip fetched under an older version. - Download from the GitHub release mirror, sha256-verified against the registry before it is written into the cache.
mmcli datasets list # human table: name, state, size, description
mmcli datasets list --format json # committed JSON interface (name/version/state/bytes/...)
mmcli datasets pull fan_blade_fault # download + sha256-verify; cache short-circuits a repeat pull
mmcli datasets path generic_audio_classification # print the resolved on-disk path, or exit non-zerostate in datasets list is one of bundled, cached, downloadable, or
unavailable — computed live against the current machine's disk and
environment, not a static registry field.
If a cached zip's on-disk bytes no longer match its recorded sha256 (disk
corruption, an interrupted write, manual tampering), datasets pull
discards it and re-downloads automatically — it never serves the bad
bytes — and reports the repair with a WARNING on stderr and a REPAIRED
success line on stdout, rather than silently looking identical to a clean
cache hit. The command still exits 0: the repair succeeded.
mmcli datasets pull --progress-json <name> emits newline-delimited JSON
events on stderr, one object per line, flushed immediately — unaffected by
whether stderr is a terminal. It is intended for tools driving mmcli as a
subprocess (e.g. PlatypusStudio) that need a determinate byte count instead
of an indeterminate spinner. This is a committed interface.
Event shapes (verbatim structure; values below are from a real captured
run of generic_timeseries_forecasting, a 71 KB dataset):
{"v":1,"event":"integrity-repair","dataset":"generic_timeseries_forecasting","total_bytes":71053}
{"v":1,"event":"start","dataset":"generic_timeseries_forecasting","total_bytes":71053}
{"v":1,"event":"progress","dataset":"generic_timeseries_forecasting","bytes":65536,"total_bytes":71053}
{"v":1,"event":"result","dataset":"generic_timeseries_forecasting","outcome":"downloaded","total_bytes":71053}
Ordering and content guarantees:
- Every object carries
"v":1and"dataset". integrity-repair, when it occurs, precedesstart(see the corrupted- cache-entry section above — that WARNING and this event report the same condition).- At most one
start;progressonly ever follows astart.progressis throttled (at most every 200 ms or 1 MiB, whichever comes first) so a large transfer does not flood the pipe with one event per read chunk; a finalprogressat 100% is always emitted beforeresult. resultis always the last event, and is emitted only on success.outcomeis one of exactlycache-hit,downloaded,forced-redownload,integrity-repair— the same four outcomes as the plain-text success lines above.- On a failed transfer, no
resultis emitted; the existingERROR: ...line and non-zero exit are unchanged. - Events never carry a filesystem path, a URL, or a hostname — only a dataset name and byte counts.
Without --progress-json, datasets pull output is unchanged: no JSON is
ever printed, and the flag has no effect on init --dataset's auto-fetch
policy (--progress-json is datasets pull-only).
Unlike the old fully-bundled build, a first mmcli init --dataset <name> for
one of the nine mirrored datasets needs network access unless it is already
cached or MMCLI_DATASETS supplies it. To meet this in the docs rather than
as a surprise mid-command:
init --datasetonly auto-fetches when stderr is an interactive terminal. Pass--fetchto force a fetch, or--no-fetchto refuse and print the exactmmcli datasets pull <name>command to run instead.- A non-interactive invocation (piped, scripted, CI) never fetches implicitly — it prints that same refusal and exits non-zero, rather than starting an unnarrated multi-megabyte transfer.
MMCLI_DATASETSdisables fetching everywhere, including insideinit --dataset.
On a machine with network access:
# 1. Pull all nine fetchable datasets into the local cache.
for n in arc_fault_classification ecg_classification fan_blade_fault \
generic_timeseries_anomalydetection generic_timeseries_classification \
generic_timeseries_forecasting generic_timeseries_regression \
mnist_image_classification pir_detection; do
mmcli datasets pull "$n"
done
# 2. Assemble an offline directory from the version-scoped cache. The cached
# filenames are already the *local* names MMCLI_DATASETS resolves by.
mkdir -p ~/mmcli-offline-datasets
cp ~/.cache/mmcli/datasets/*/*.zip ~/mmcli-offline-datasets/
# 3. The tenth dataset has no download URL — it ships inside the binary and
# is never fetched. Its bundled copy lives inside a PyInstaller onefile
# temp directory that is deleted the instant the process exits, so
# printing its path (`datasets path`) and piping that into a following
# `cp` does not work — the file is already gone by the time `cp` runs.
# Materialize it instead by letting `init --dataset` extract it into a
# throwaway project (extraction happens while mmcli is still running),
# then re-zip the result under the name MMCLI_DATASETS expects:
mmcli init --dataset generic_audio_classification -t audio_classification \
-p /tmp/mmcli-audio-seed
(cd /tmp/mmcli-audio-seed/dataset && zip -qr \
~/mmcli-offline-datasets/generic_audio_classification.zip .)
rm -rf /tmp/mmcli-audio-seedThen move ~/mmcli-offline-datasets/ to the air-gapped machine, and there:
export MMCLI_DATASETS=~/mmcli-offline-datasets
mmcli datasets list --format json # all ten report state "bundled", none "downloadable"All ten zips must be present in the directory named by MMCLI_DATASETS
before exporting it — once set, that variable disables fetching entirely, so
a missing zip is not recoverable by falling back to the network. Files
resolved via MMCLI_DATASETS are not sha256-checked (that directory is
explicitly user-managed), so the re-zipped copy of the tenth dataset — byte-
different from, but content-identical to, the original — resolves and
extracts correctly.
Fallback for manual/proxied downloads: if you must fetch a zip through a
browser or a proxy instead of datasets pull, note that five of the nine
mirrored datasets are stored under a different name than the one
MMCLI_DATASETS expects (ti_name, the original TI provenance record, vs.
the registry's local filename). Rename after downloading:
Local name (what MMCLI_DATASETS expects) |
Original name |
|---|---|
fan_blade_fault.zip |
fan_blade_fault_dsi.zip |
mnist_image_classification.zip |
mnist_classes.zip |
pir_detection.zip |
pir_detection_classification_dsk.zip |
arc_fault_classification.zip |
arc_fault_classification_dsi.zip |
ecg_classification.zip |
ecg_classification_2class.zip |
The remaining four mirrored datasets keep the same name on both sides.
Show supported task types, models, devices, feature extraction presets, and available example datasets.
mmcli info -m MODULE [-t TASK] [-d DEVICE]
| Flag | Short | Description |
|---|---|---|
--module |
-m |
timeseries or vision (required) |
--task |
-t |
Task type to show details for. Omit to list all task types. |
--device |
-d |
Target device to filter models. |
Examples:
mmcli info -m timeseries # list task types
mmcli info -m timeseries -t arc_fault # details for arc_fault
mmcli info -m timeseries -t arc_fault -d F28P55 # models for F28P55mmcli --dry-run train \
-m timeseries -t generic_timeseries_classification \
-d F28P55 -n CLS_1k_NPU -i ./datammcli train --config examples/hello_world/config.yaml \
--epochs 50 --device F29H85mmcli --verbose train ...Generate a self-contained HTML report with live-updating accuracy/loss charts and a heatmap confusion matrix:
mmcli train \
-m timeseries \
-t generic_timeseries_classification \
-d F28P55 \
-n CLS_1k_NPU \
-i ./data/my_project \
--reportThe report is written to <project_dir>/run/report.html and auto-refreshes
every 5 seconds while training is in progress. Once training completes, the
auto-refresh is removed and the final report includes the confusion matrix
and file-level classification summary (if available).
Instead of picking a model from the catalog (-n), you can let NAS automatically
discover an optimal architecture for your dataset. NAS is supported for
classification tasks only (timeseries and vision).
When --nas is set, --model/-n becomes optional — a synthetic name like
NAS_m is generated automatically.
Important: For timeseries tasks, you must specify
--feature-extractionwith a preset that is appropriate for your dataset when using--nas.With catalog models (
-n), the feature extraction configuration is provided automatically by the model description. NAS has no catalog entry, so the pipeline does not know which feature extraction to apply. Without this flag, training will fail with "Not enough dimensions present" because the raw sensor data has not been transformed into the feature representation that the classification pipeline expects.
To see which feature extraction presets are available for your task:
mmcli info -m timeseries -t generic_timeseries_classificationCommon presets for generic timeseries classification include:
Generic_256Input_FFTBIN_16Feature_8FrameGeneric_1024Input_FFTBIN_32Feature_32Frame
| Flag | Description |
|---|---|
--nas SIZE |
Enable NAS with a model size preset: s (small), m (medium), l (large), xl (extra-large). Controls the search space complexity and resulting model size. |
--nas-epochs N |
NAS search epochs (default: 10). Higher values explore more architectures but take longer. |
--nas-optimize MODE |
Resource optimization target: Memory (fewer parameters, default) or Compute (fewer MACs, lower latency). |
--feature-extraction |
Feature extraction preset (required for timeseries NAS). Use mmcli info to list available presets. |
# Basic NAS — medium-sized model with feature extraction
mmcli train \
-m timeseries \
-t generic_timeseries_classification \
-d F28P55 \
-i ./data/my_project \
--nas m \
--feature-extraction Generic_256Input_FFTBIN_16Feature_8Frame \
--epochs 50
# NAS with explicit search budget and compute optimization
mmcli train \
-m timeseries \
-t motor_fault \
-d F28P55 \
-i ./data/motor_project \
--nas l \
--nas-epochs 20 \
--nas-optimize Compute \
--feature-extraction Generic_256Input_FFTBIN_16Feature_8Frame
# NAS for vision classification (no --feature-extraction needed)
mmcli train \
-m vision \
-t image_classification \
-d F29H85 \
-i ./data/image_project \
--nas s
# Dry-run to inspect NAS config without running
mmcli --dry-run train \
-m timeseries -t generic_timeseries_classification \
-d F28P55 -i ./data/my_project --nas m \
--feature-extraction Generic_256Input_FFTBIN_16Feature_8Framegeneric_timeseries_classification · arc_fault · ecg_classification
motor_fault · blower_imbalance · pir_detection · image_classification
Timeseries:
generic_timeseries_classification · generic_timeseries_regression
generic_timeseries_anomalydetection · generic_timeseries_forecasting
arc_fault · motor_fault · blower_imbalance · pir_detection
Vision:
image_classification
F280013 F280015 F28003 F28004 F2837 F28P55 F28P65
F29H85 F29P58 F29P32
MSPM0G3507 MSPM0G3519 MSPM0G5187
MSPM33C32 MSPM33C34
AM263 AM263P AM261 AM13E2
CC2755 CC1352 CC1354 CC35X1
Classification: CLS_100_NPU CLS_500_NPU CLS_1k_NPU CLS_2k_NPU
CLS_4k_NPU CLS_6k_NPU CLS_8k_NPU CLS_13k_NPU CLS_20k_NPU
CLS_55k_NPU CLS_ResAdd_3k CLS_ResCat_3k
Regression: REGR_1k REGR_2k REGR_3k REGR_4k REGR_10k REGR_13k
REGR_500_NPU REGR_2k_NPU REGR_6k_NPU REGR_8k_NPU REGR_20k_NPU
Anomaly Detection: AD_1k AD_4k AD_16k AD_17k AD_Linear
AD_500_NPU AD_2k_NPU AD_6k_NPU AD_8k_NPU AD_10k_NPU AD_20k_NPU
Forecasting: FCST_3k FCST_13k FCST_LSTM8 FCST_LSTM10
FCST_500_NPU FCST_1k_NPU FCST_2k_NPU FCST_4k_NPU FCST_6k_NPU
FCST_8k_NPU FCST_10k_NPU FCST_20k_NPU
Application-specific: ArcFault_model_200_t ArcFault_model_300_t
ArcFault_model_700_t ArcFault_model_1400_t
MotorFault_model_1_t MotorFault_model_2_t MotorFault_model_3_t
FanImbalance_model_1_t FanImbalance_model_2_t FanImbalance_model_3_t
ECG_55k_NPU PIRDetection_model_1_t
Tip: Run
mmcli info -m timeseries -t <task>to see models available for a specific task.
# macOS
bash build_macos.sh # arm64 (Apple Silicon, default)
ARCH=x86_64 bash build_macos.sh # Intel Mac
ARCH=universal2 bash build_macos.sh # fat binary (both)
# Linux / Windows
bash build_linux.sh # → dist/mmcli
powershell build_windows.ps1 # → dist/mmcli.exeCopy dist/mmcli anywhere on your PATH. No Python environment needed to
run the binary — only MMCLI_PYTHON must point to a Python 3.10 install
that has tinyml_modelmaker.
| Variable | Default | Description |
|---|---|---|
MMCLI_PYTHON |
python or python3 on PATH |
Python interpreter with tinyml_modelmaker installed |
MMCLI_MODELMAKER |
auto-detected | Path to tinyml-modelmaker source dir (only needed if auto-detection fails) |
MMCLI_DATASETS |
unset (fetch from the GitHub release mirror; only generic_audio_classification is bundled) |
Directory of dataset zips to use instead of fetching. Setting it disables all dataset fetching — see Datasets. |
ARM_LLVM_CGT_PATH |
(none) | Root of the ARM LLVM toolchain. When set, mmcli looks for tiarmclang at $ARM_LLVM_CGT_PATH/bin/tiarmclang. Falls back to PATH if unset. Required for compilation when tiarmclang is not on PATH. |
C2000_CG_ROOT |
~/bin/ti-cgt-c2000_* |
Root of the TI C2000 CGT installation. Required for compilation of C2000 targets (F28P55, F28P65, etc.) on all platforms. Download from TI's website. |
Tests run automatically on every push and pull request via GitHub Actions:
- test-cli.yml — Tiers 1–4 on Linux and Windows
- release.yml — Build binaries for macOS, Linux, and Windows on tag push
To create a release:
git tag v1.0.0
git push origin v1.0.0All user inputs are sanitized before use:
- Command arguments are stripped of shell metacharacters (
;,$,`,|) - File paths are validated to prevent directory traversal
- Environment variables are cleaned before subprocess calls
All subprocess calls use shell=False with argument arrays to prevent command injection.
Project paths must be relative or within safe directories (not absolute paths starting with /).
For more information, see SECURITY.md and docs/SECURITY_MODEL.md.