Rate this Page

Pico2: A simple MNIST Tutorial#

Deploy your PyTorch models directly to Raspberry Pi Pico2 microcontroller with ExecuTorch.

What You’ll Build#

A 28×28 MNIST digit classifier running on memory constrained, low power microcontrollers:

  • Input: ASCII art digits (0, 1, 4, 7)

  • Output: Real-time predictions via USB serial

  • Memory: <400KB total footprint

Prerequisites#

which arm-none-eabi-gcc # --> arm/ethos-u-scratch/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin/

Step 1: Generate pte from given example Model#

python export_mlp_mnist.py # Creates balanced_tiny_mlp_mnist.pte
  • Note: This is hand-crafted MNIST Classifier (proof-of-concept), and not production trained. This tiny MLP recognizes digits 0, 1, 4, and 7 using manually designed feature detectors.

Step 2: Build Firmware for Pico2#

# Generate model

python export_mlp_mnist.py # Creates balanced_tiny_mlp_mnist.pte

# Build Pico2 firmware (one command!)

./executorch/examples/rpi/build_firmware_pico.sh --model=balanced_tiny_mlp_mnist.pte   # This creates executorch_pico.uf2, a firmware image for Pico2

Output: executorch_pico.uf2 firmware file (examples/raspberry_pi/pico2/build/)

Note: ‘build_firmware_pico.sh’ script converts given model pte to hex array and generates C code for the same via this helper script. This C code is then compiled to generate final .uf2 binary which is then flashed to Pico2.

Step 3: Flash to Pico2#

Hold BOOTSEL button on Pico2 Connect USB → Mounts as ^RPI-RP2^ drive Drag & drop ^executorch_pico.uf2^ file Release BOOTSEL → Pico2 reboots with your model

Step 4: Verify Deployment#

Success indicators:

  • LED blinks 10× at 500ms → Model running ✅

  • LED blinks 10× at 100ms → Error, check serial ❌

View predictions:

# Connect serial terminal
screen /dev/tty.usbmodem1101 115200
# Expected output:

Something like:

=== Digit 7 ===
############################
############################
                        ####
                       ####
                      ####
                     ####
                    ####
                   ####
                  ####
                 ####
                ####
               ####
              ####
             ####
            ####
           ####
          ####
         ####
        ####
       ####
      ####
     ####
    ####
   ####
  ####
 ####
####
###

Input stats: 159 white pixels out of 784 total
Running neural network inference...
✅ Neural network results:
  Digit 0: 370.000
  Digit 1: 0.000
  Digit 2: -3.000
  Digit 3: -3.000
  Digit 4: 860.000
  Digit 5: -3.000
  Digit 6: -3.000
  Digit 7: 1640.000  PREDICTED
  Digit 8: -3.000
  Digit 9: -3.000

� PREDICTED: 7 (Expected: 7)  CORRECT!

Memory Optimization Tips#

Pico2 Constraints#

  • 520KB SRAM (runtime memory)

  • 4MB Flash (model storage)

  • Keep models small:

Common Issues#

  • “Memory allocation failed” → Reduce model size and use quantization

  • “Operator missing” → Use selective build: ^–operators=add,mul,relu^

  • “Import error” → Check ^arm-none-eabi-gcc^ toolchain setup.

In order to resolve some of the issues above, refer to the following guides:

Firmware Size Analysis#

cd <root of executorch repo>
ls -al examples/raspberry_pi/pico2/build/executorch_pico.elf
  • Overall section sizes

arm-none-eabi-size -A examples/raspberry_pi/pico2/build/executorch_pico.elf
  • Detailed section breakdown

arm-none-eabi-objdump -h examples/raspberry_pi/pico2/build/executorch_pico.elf
  • Symbol sizes (largest consumers)

arm-none-eabi-nm --print-size --size-sort --radix=d examples/raspberry_pi/pico2/build/executorch_pico.elf | tail -20

Model Memory Footprint#

  • Model data specifically

arm-none-eabi-nm --print-size --size-sort --radix=d examples/raspberry_pi/pico2/build/executorch_pico.elf | grep -i model
  • Check what’s in .bss (uninitialized data)

arm-none-eabi-objdump -t examples/raspberry_pi/pico2/build/executorch_pico.elf | grep ".bss" | head -10
  • Memory map overview

arm-none-eabi-readelf -l examples/raspberry_pi/pico2/build/executorch_pico.elf

Next Steps#

Scale up your deployment#

  • Use real production trained model

  • Optimize further → INT8 quantization, pruning

Happy Inference!#

Result: PyTorch model → Pico2 deployment in 4 simple steps 🚀 Total tutorial time: ~15 minutes

Conclusion: Real-time inference on memory constrained, low power microcontrollers, a complete PyTorch → ExecuTorch → Pico2 demo MNIST deployment