Skip to main content
ExecuTorch is PyTorch’s runtime for on-device inference. It takes a PyTorch model, lowers it to a compact .pte program, and runs it on phones, single-board computers, and microcontrollers with backends such as XNNPACK and CMSIS-NN. In this tutorial, you’ll connect PyTorch to Edge Impulse with two custom blocks: a learning block that trains a model and exports both ONNX (for Studio) and an ExecuTorch .pte, and a deployment block that packages a trained impulse into a .pte with a small runtime harness. At the end, you’ll have a reusable PyTorch-to-edge pipeline in your own organization.
This tutorial uses the Edge Impulse CLI and Docker. Install the Edge Impulse CLI and Docker before you start.

How the blocks fit together

Edge Impulse works with TensorFlow, TFLite, and ONNX, while ExecuTorch consumes PyTorch programs. The two blocks bridge that gap at different stages of the pipeline. The learning block is available to all users. The deployment block is an enterprise feature.

1. Train a PyTorch model with a custom learning block

The learning block trains a compact CNN on your project’s image data and outputs an ONNX model that Edge Impulse converts to TFLite for deployment.
This walkthrough uses the image classifier (executorch-pytorch-classification-block). The same block ships in four modality variants — image, audio (keyword spotting), time-series, and object detection. See Source code for all of them; the steps below are identical, only the input data and parameters.json differ.

Block structure

The block contains the standard custom learning block files:
The parameters.json file declares the block as a machine learning block that operates on images and expects pixels scaled to 0..1:

Handle the data format

Edge Impulse provides image data as pre-scaled float32 arrays in NHWC (batch, height, width, channels) order. PyTorch expects NCHW, so the training script transposes the arrays before training:
You only transpose for training. Because the block outputs ONNX, Edge Impulse applies the equivalent transpose on-device automatically.

Export ONNX and ExecuTorch

After training, the block writes model.onnx for Studio and, when the --export-pte flag is set, an ExecuTorch program:
executorch==0.4.0 requires torch==2.5.0. Pin the two together and install the CPU wheels from https://download.pytorch.org/whl/cpu to avoid pulling CUDA packages into the build.

Test the block locally

Download processed data from a project that has an image impulse, then run the container:
You’ll find out/model.onnx and out/model.pte when the run finishes.

Push to Edge Impulse

The block then appears under Create impulse → Add learning block in Studio.
ExecuTorch learning block added to an image impulse in Edge Impulse Studio

The ExecuTorch learning block added to an image impulse in Studio

Train and test in Studio

With the block added to your impulse, train it from the Learning page, then verify it generalizes on the Model testing page.
Training results for the PyTorch classifier in Edge Impulse Studio

Training the PyTorch classifier (93.3% validation accuracy)

Model testing results on the held-out test set in Edge Impulse Studio

Model testing on the held-out test set

2. Export to ExecuTorch with a custom deployment block

Only available on the Enterprise planThis feature is only available on the Enterprise plan. Review our plans and pricing or sign up for our free expert-led trial today.
The custom deployment block takes a trained impulse and produces an ExecuTorch deliverable. Because ExecuTorch consumes PyTorch, the block converts the exported ONNX model to PyTorch with onnx2torch, then lowers it to a .pte. The full source is in executorch-deploy.

Block structure

Edge Impulse calls the entrypoint with the path to deployment-metadata.json, which points to the input and output folders:
The block converts the model, copies in the runtime harness and label map, then writes deploy.zip to the output folder. See deployment-metadata.json for the full input schema.

Test the block locally

The resulting deploy.zip contains model.pte, the source model.onnx, labels.txt, and the app/ harness.

Push to Edge Impulse

The block then appears as a Custom block option on the project Deployment page.
Deployment page showing the ExecuTorch .pte export target in Edge Impulse Studio

The trained impulse's Deployment page, with the ExecuTorch .pte export target

Run the ExecuTorch program

On a Linux or ARM target with the ExecuTorch Python runtime installed, load the .pte and run a forward pass:
Compare the output against the original PyTorch model to confirm the conversion is faithful.
The ONNX to PyTorch to ExecuTorch path works for common CNN graphs. Exotic operators may need a custom partitioner or manual conversion with app/convert.py. Validate on your target model before relying on it in production.

Source code

Every block in this series is open source. The learning block comes in four modality variants that share the same structure — pick the one that matches your data. They all export an ONNX model for Studio plus an optional ExecuTorch .pte.

Try it on Android

The ExecuTorch Android demo loads a bare .pte and runs it on-device with the XNNPACK CPU backend — no Edge Impulse C++ SDK and no TFLite. Each block’s DSP (image scaling, motion spectral analysis, audio MFE) is hand-ported to Kotlin so the .pte only runs the neural network. Every product flavor bundles a different exported model under its own app id, so you can install them side by side.
ExecuTorch static-buffer flavor showing the output scores after one inference

Static-buffer: one forward pass over a fixed input buffer

ExecuTorch image classification flavor running live on a phone

Image classification running live on-device

ExecuTorch FOMO object-detection flavor running live on a phone

FOMO object detection running live on-device

ExecuTorch keyword-spotting flavor running live on a phone

Keyword spotting: live mic through the Kotlin MFE

Grab a prebuilt APK from the Releases page and sideload it — no build required:
Extending to the Edge Impulse C++ SDK (later work). This demo runs a bare .pte and hand-ports each block’s DSP to Kotlin, so every new modality means re-implementing signal processing by hand. A future iteration could instead reuse Studio’s exact DSP by linking the Edge Impulse C++ SDK through JNI. That would involve exporting the full impulse as a C++ library, cross-compiling the SDK for Android (arm64-v8a) with the NDK, and calling run_classifier over a JNI bridge so raw sensor data flows straight into the SDK’s DSP — removing the hand-ported Kotlin code entirely. You would then decide whether ExecuTorch still runs the neural network (SDK for DSP only) or the SDK handles both, and reconcile the input scaling and tensor layout between the two paths. See example-android-inferencing for a JNI-based reference.

Next steps