🛠 Inference IA accélérée par les instructions vectorielles
Objectifs
Comprendre ce que les instructions vectorielles du LX7 (absentes de l'ESP32 et du S2) apportent à l'inférence réseau de neurones quantifiée int8 : les bibliothèques ESP-NN (couches) et ESP-DSP (signal) les exploitent, ce qui permet à l'ESP32-S3 de faire tourner ESP-WHO (détection de visage) ou ESP-Skainet (reconnaissance vocale hors ligne). Vous mesurerez vous-même le gain avec une couche entièrement connectée calculée par esp_nn_fully_connected_s8, la primitive phare d'ESP-NN.
Matériel
- 1 carte ESP32-S3 (les variantes N8R8/N16R8 avec PSRAM octale sont à l'aise pour les gros modèles)
- IDE Arduino avec core esp32 >= 2.0.14 (ESP-NN est fourni en composant du core) ou projet ESP-IDF v5.x avec la composante esp-nn
- 1 câble USB
Code complet
// Couche fully-connected int8 acceleree (ESP-NN, cote Arduino via esp32 core)
// Outils -> Board: "ESP32S3 Dev Module" ; ajouter "esp_nn" aux includes paths
#include "esp_nn.h"
#define ENTREES 64
#define SORTIES 8
// Poids et biases quantifies int8 (ici des valeurs demo)
static int8_t poids[SORTIES][ENTREES];
static int32_t biais[SORTIES];
static int8_t entrée[ENTREES];
static int8_t sortie[SORTIES];
void setup {
Serial.begin(115200);
for (int i = 0; i < SORTIES; i++) {
biais[i] = 0;
for (int j = 0; j < ENTREES; j++)
poids[i][j] = (int8_t)((i * 7 + j * 13) % 251 - 125);
}
for (int j = 0; j < ENTREES; j++) entrée[j] = (int8_t)(j % 127);
setCpuFrequencyMhz(240);
dl_nn_version; // version d'ESP-NN liee
uint32_t t0 = micros;
for (int k = 0; k < 1000; k++) {
esp_nn_fully_connected_s8(
entrée, ENTREES, 0, // activations, taille, zéro-point
poids, SORTIES, 0, // poids, sortie, zéro-point poids
biais, 1033, 12, // biais, mult, shift (quantification)
sortie, -128, 127); // tampon sortie, plage int8
}
uint32_t t1 = micros;
Serial.printf("1000 FC %dx8 : %lu us (ESP-NN vectoriel)\n",
ENTREES, (unsigned long)(t1 - t0));
Serial.printf("sortie[0] = %d\n", sortie[0]);
}
void loop { delay(1000); }
Vérification attendue
La console affiche la version d'ESP-NN puis le temps mis pour mille couches 64×8 int8 — de l'ordre de quelques centaines de microsecondes sur un cœur à 240 MHz, soit un débit qui autorise des modèles d'audio ou de capteurs à plusieurs dizaines d'inférences par seconde. En comparant avec une boucle de référence écrite à la main (sans esp_nn), l'écart visible démontre l'effet des instructions vectorielles du LX7. Pour un cas réel, utiliser TensorFlow Lite for Microcontrollers avec le delegate ESP-NN, ou directement ESP-WHO/ESP-Skainet.
Erreurs fréquentes
- Croire que le simple fait d'être sur S3 accélère tout : seules les bibliothèques vectorisées (ESP-NN, ESP-DSP, delegate TFLite ESP-NN) tirent parti du LX7 ; un float naïf n'y gagne presque rien.
- Quantification mal paramétrée : multiplier/décaler (mult/shift) incohérents entre l'entraînement et le déploiement produit des sorties fausses mais sans erreur d'exécution.
- Oublier la PSRAM sur les gros modèles : un modèle visage (ESP-WHO) sature la RAM interne de 512 Ko ; prendre une variante R (PSRAM octale sur GPIO35/36/37) et activer « Support of PSRAM » dans le menu Outils.
- Ne pas monter la fréquence : certains builds tournent par défaut à 160 MHz ; setCpuFrequencyMhz(240) avant la mesure.
- Wi-Fi pendant l'inférence : la radio ajoute de la latence et de la contention cache/PSRAM ; mesurer performances radio coupée.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
clignotante.inoArduinobouton-led.inoArduinorespiration.inoArduinodht22.inoArduinooled-i2c.inoArduinoserveur-web.inoArduino