Skip to content
espressifPublic

About

Optimised Neural Network functions for Espressif chipsets

Resources

Contributing

Stars

282 stars

Watchers

11 watching

Forks

Repository files navigation

ESP-NN

Component Registry CI

The library contains optimised NN (Neural Network) functions for various Espressif chips.

  • Supported platforms:

    • TensorFlow Lite Micro (TFLite Micro). Repo can be found here
  • Supported ESP chips include:

    • ESP32-S3 (Assembly versions optimised to benefit from vector instructions of ESP32-S3)
    • ESP32-P4 (Optimised using PIE/QACC SIMD instructions)
    • ESP32-S31 (Optimised using PIE/QACC SIMD instructions, shares ESP32-P4 kernels)
    • ESP32 (Generic optimisations)
    • ESP32-C3 (Generic optimisations)

Performance

Kernel Performance

Speedup of the optimized s8 kernels over the portable ANSI C ones (cycles, ANSI C / optimized):

Kernel Shape ESP32-S3 ESP32-P4 ESP32-S31
Convolution 1x1 input 10x10, filter 64x1x1x64 14.24 7.00 6.24
Convolution 1x1 input 8x8, filter 16x1x1x16 8.01 3.51 2.94
Depthwise conv 5x5 input 12x12, filter 8x5x5x4 4.49 1.94 1.75
Fully connected length 271, 3 outputs 5.47 8.36 5.11
Elementwise multiply 1615 elements 3.51 1.60 1.82
Max pooling 3x3 input 16x16x16 7.83 19.94 12.65
Average pooling 3x3 input 16x16x16 3.62 3.59 3.95

All kernels and shapes, with cycle counts and the setup per chip, are in docs/performance.md.

Model-Level Performance

  • Person Detection (Visual Wake Words, INT8 quantized, from esp-tflite-micro)

    • Numbers are time (ms) for invoke() call, using internal memory
    Chip CPU Freq without ESP-NN with ESP-NN
    ESP32-P4 360MHz 1395ms 73ms
    ESP32-S31 320MHz 1669ms 72ms
    ESP32-S3 240MHz 2300ms 54ms
    ESP32 240MHz 4084ms 380ms
    ESP32-C3 160MHz 3355ms 426ms
  • MobileNetV3 Small (INT8 quantized, 224x224x3, 1000 classes)

    Chip CPU Freq without ESP-NN with ESP-NN with ESP-NN, dual core
    ESP32-P4 400MHz 10980ms 388ms 253ms
    ESP32-S3 240MHz 26679ms 729ms 690ms
  • YOLO11n (INT8 quantized, 192x192x3, 80 classes, object detection)

    Chip CPU Freq without ESP-NN with ESP-NN with ESP-NN, dual core
    ESP32-P4 400MHz 52240ms 620ms 417ms
    ESP32-S3 240MHz 130753ms 1253ms 1053ms

Note:

  • The above is time taken for execution of the invoke() call
  • SPIRAM used for TensorArena.
  • Person detection on ESP32-S3 with internal RAM: 47ms
  • MobileNetV3 and YOLO11n were measured with the mobilenet_v3 and yolo_test_app examples in esp-tflite-micro, with no profiler attached; ESP32-P4 with 200MHz HEX PSRAM, ESP32-S3 with 80MHz OCT PSRAM and a 64KB data cache
  • The dual core column is with esp_nn_dual_core_enable() called once at startup, which lets the heavier kernels split their work across both cores
  • Without ESP-NN is esp-tflite-micro with esp-nn turned off, so it runs the TFLite Micro reference kernels. Turn off "Use ESP-NN optimized kernels" in idf.py menuconfig (under ESP TFLite-Micro), or set CONFIG_ESP_TFLITE_MICRO_USE_ESP_NN=n in sdkconfig.

Configuration

  • To configure, please use idf.py menuconfig and under ESP-NN select NN_OPTIMIZATIONS

  • There are two options presented:

    • Optimized versions
    • ANSI C
  • Default selection is for Optimized versions. For ESP32-S3, ESP32-P4 and ESP32-S31, assembly versions are automatically selected, whereas for other chips (viz., ESP32, ESP32-C3), generic optimisations are selected.

  • For debugging purposes, you may want to select ANSI C reference versions.

ESP32-P4: PIE Kernels in Several Tasks

  • ESP-IDF v5.x release tags (up to v5.4.4 and v5.5.5) do not save the PIE register q3 when they switch tasks.
  • So on ESP32-P4, two tasks on the same core that both run PIE code can corrupt each other's results. For example, two TFLite Micro interpreters, or ESP-NN and ESP-DSP.
  • ESP-IDF v6.0 and later save q3. So do the next v5.3, v5.4 and v5.5 releases.
  • On an older v5.x release, run the PIE kernels from one task per core.

Scratch Buffers

Some kernels need a scratch buffer that the caller owns. Size it with esp_nn_get_<op>_scratch_size() and pass it with esp_nn_set_<op>_scratch_buf() before the call. The getters also build on Linux, so tools can compute the sizes ahead of time.

For more details, including how to build the getters on Linux for a target, see docs/scratch_buffers.md.

Contributing

If you encounter an issue with ESP-NN, or wish to submit a feature request, please use the Issues section on the Github.

For general questions related to this library, please use the esp32.com forum.

Please check CONTRIBUTING.md for further information if you'd like to contribute to ESP-NN.

Copyrights and License

All original source code in this repository is Copyright (C) 2020-2026 Espressif Systems. This source code is licensed under the Apache License 2.0 as described in the file LICENSE.

About

Optimised Neural Network functions for Espressif chipsets

Resources

Contributing

Stars

282 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages