This document shows the actual commands end users run to profile their models. This is the workflow you follow after setting up the environment.
The profiling pipeline is model-agnostic. Once you have a .pte file, the same commands work for any model.
Setup → Build Runners → Export Model → Run Pipeline → Analyze Results
# From executorch_sme2_kit/ directory
bash model_profiling/scripts/setup_repo.shThis creates:
.venv/- Python virtual environmentexecutorch/- ExecuTorch checkout
# From executorch_sme2_kit/ directory
bash model_profiling/scripts/build_runners.shThis builds:
executorch/cmake-out/mac-arm64/executor_runner(SME2 ON)executorch/cmake-out/mac-arm64-sme2-off/executor_runner(SME2 OFF)- Android runners (if
ANDROID_NDKis set)
# From executorch_sme2_kit/ directory
# Activate venv first
source .venv/bin/activate
# Export model
python model_profiling/export/export_model.py \
--model <model_name> \
--dtype fp16 \
--outdir out_<model>/artifacts/
# This creates:
# - out_<model>/artifacts/<model>_xnnpack_fp16.pte
# - out_<model>/artifacts/<model>_xnnpack_fp16.pte.etrecordModel-specific notes:
- For models in
model_profiling/models/, use the registered name - For custom models, you may need to add model registration code first
- See learning path documentation for model onboarding details
# Copy template
cp model_profiling/configs/templates/mac_template.json \
model_profiling/configs/my_experiment.json
# Edit the config:
# - Set "model" to your .pte path (e.g., "out_<model>/artifacts/<model>_xnnpack_fp16.pte")
# - Adjust "experiments" array (SME2 on/off, threads, runs, etc.)
# - Set "output_root" (e.g., "out_<model>/runs/mac")macOS:
# From executorch_sme2_kit/ directory
source .venv/bin/activate
python3 model_profiling/scripts/mac_pipeline.py \
--config model_profiling/configs/my_experiment.jsonAndroid:
# Ensure device is connected and ANDROID_NDK is set
python3 model_profiling/scripts/android_pipeline.py \
--config model_profiling/configs/android_experiment.jsonWith options:
# Run only specific experiments
python3 model_profiling/scripts/mac_pipeline.py \
--config model_profiling/configs/my_experiment.json \
--only mac_sme2_on mac_sme2_off
# Re-run analysis only (skip profiling execution)
python3 model_profiling/scripts/mac_pipeline.py \
--config model_profiling/configs/my_experiment.json \
--analysis-only
# Verbose output
python3 model_profiling/scripts/mac_pipeline.py \
--config model_profiling/configs/my_experiment.json \
--verbose
# Android with remote device
python3 model_profiling/scripts/android_pipeline.py \
--config model_profiling/configs/android_experiment.json \
--remote-device 192.168.1.100:5555Note: The pipeline automatically runs analysis after profiling, generating CSV files from ETDump. No separate analyze_results.py step needed.
This creates:
out_<model>/runs/<platform>/- Run output directoryout_<model>/runs/<platform>/manifest.json- Run metadataout_<model>/runs/<platform>/metrics.json- Timing metricsout_<model>/runs/<platform>/<model_stem>_pipeline_summary.json- Pipeline summaryout_<model>/runs/<platform>/<experiment_name>/- Per-experiment results*.etdump- ETDump trace files*_exec_all_runs_timeline.csv- Timeline CSV (all runs)*_exec_run0_timeline.csv- Timeline CSV (run 0)*_exec_ops_stats.csv- Operator statistics CSV*.log- Runner logs
Note: The pipeline automatically runs analysis after profiling. You only need to run this manually if:
- You want to re-analyze existing ETDump files
- Analysis failed during pipeline execution
# From executorch_sme2_kit/ directory
source .venv/bin/activate
python3 model_profiling/scripts/analyze_results.py \
--run-dir out_<model>/runs/macThis creates:
out_<model>/runs/mac/analysis_summary.json- Operator-level breakdown- CSV files in same directory as ETDump files (if not already generated)
python model_profiling/scripts/validate_results.py \
--results out_<model>/runs/macAfter setup and build, validate everything works:
# From executorch_sme2_kit/ directory
source .venv/bin/activate
python model_profiling/scripts/run_quick_test.pyThis runs: validate → build → export toy model → pipeline (with automatic analysis) → validate
executorch_sme2_kit/
├── .venv/ # Python environment
├── executorch/ # ExecuTorch checkout
│ └── cmake-out/
│ ├── mac-arm64/executor_runner
│ └── mac-arm64-sme2-off/executor_runner
├── model_profiling/
│ ├── scripts/ # Pipeline scripts
│ ├── export/ # Export script
│ ├── configs/ # Experiment configs
│ └── models/ # Model registry
├── out_<model>/ # Per-model outputs
│ ├── artifacts/ # Exported .pte files
│ └── runs/ # Profiling results
│ └── mac/
│ ├── manifest.json
│ ├── metrics.json
│ ├── <model_stem>_pipeline_summary.json
│ ├── <model_stem>_pipeline_summary.md
│ ├── analysis_summary.json (generated automatically by pipeline)
│ ├── <experiment_name>/ # Per-experiment directory
│ │ ├── <model_stem>_<experiment>_t<threads>.etdump
│ │ ├── <model_stem>_<experiment>_t<threads>_exec_all_runs_timeline.csv
│ │ ├── <model_stem>_<experiment>_t<threads>_exec_run0_timeline.csv
│ │ ├── <model_stem>_<experiment>_t<threads>_exec_ops_stats.csv
│ │ └── <model_stem>_<experiment>_t<threads>_latency.log
└── models/ # Legacy location (if used)
- Model-agnostic pipeline: Once you have a
.pte, the same pipeline commands work - Config-driven experiments: JSON configs define what to run, scripts execute them
- Output organization: Results go under
out_<model>/runs/<platform>/for clear organization - Version traceability: Runners stay in
executorch/cmake-out/to track ExecuTorch version
- Export model once
- Create config with two experiments (SME2 on, SME2 off)
- Run pipeline
- Analyze results to see operator-level differences
- Export model once
- Create config with
"threads": [1, 2, 4]in experiments - Run pipeline
- Compare metrics.json across thread counts
- Build trace-enabled runners (separate CMake preset)
- Create config pointing to trace-enabled runners
- Run pipeline (note: trace logging impacts timing)
- Analyze ETDump for kernel selection insights
- "executor_runner not found": Run
build_runners.shfirst - "Model not found": Check
.ptepath in config JSON - "No .etdump files": Check runner logs in experiment directory
- "Analysis failed": Ensure
.etrecordfile exists (re-export if needed)