Aller au contenu principal

Module 1 — Contraintes propres à l'exécution embarquée

Le cours 08 vous a appris à servir un modèle par HTTP, avec une machine serveur pour laquelle mémoire et cœurs s'ajoutent d'un ticket de facturation. Ce cours parle d'un monde inverse : un téléphone à trois cents dollars posé sur une table dans une exploitation agricole sans couverture réseau, qui doit diagnostiquer la maladie d'une feuille de manioc en moins d'une seconde et tenir toute la journée sur une batterie. Le budget n'est plus une option de facturation, c'est un mur physique.

Le fil rouge du cours

Un agronome parcourt les rangées d'un champ, prend une photo d'une feuille suspecte et attend un diagnostic. Trente-huit maladies possibles, du mildiou de la tomate à la mosaïque du manioc. Aucune connexion : la 4G tombe à l'entrée du village. Le modèle doit tourner dans l'application, sans le moindre appel réseau, sur un Nokia G21 (2 Go de RAM, processeur d'entrée de gamme), un Samsung Galaxy A15 (4 Go, milieu de gamme) et un iPhone 12 (4 Go, avec Neural Engine). C'est ce trio qui sert de banc de mesure au module 9, et l'application finale du module 10 en tire son tableau comparatif.

Le modèle de départ est MobileNetV2 affiné sur le jeu public PlantVillage, avec la variante à un multiplicateur de largeur de 1.0 et une entrée en 224x224 pixels. En précision float32, le fichier pèse 14 Mo et le réseau atteint 96,3 % d'exactitude sur les classes tenues à l'écart. Ce sont les deux premières lignes du tableau de compromis : point de départ et plafond de qualité, avec lequel toutes les variantes suivantes se compareront.

Six contraintes, pas seulement une histoire de mémoire

Avant d'écrire une ligne de code, il faut chiffrer six budgets. Un modèle qui en respecte cinq et casse le sixième n'a pas sa place dans l'application.

ContrainteQuestion poséeOrdre de grandeur cible pour le fil rouge
Mémoire viveCombien de mégaoctets l'interprète tolère-t-il ?< 60 Mo de RAM au pic
StockageCombien pèse le fichier livré au magasin d'applications ?< 5 Mo pour l'APK/IPA final
CalculCombien de millisecondes pour une inférence ?< 250 ms sur le Nokia G21
ÉnergieCombien d'inférences par pour cent de batterie ?> 500 inférences par 1 % de batterie
RéseauCombien de requêtes vers un service tiers ?zéro, hors mise à jour du modèle
ConfidentialitéQue sort-il de l'appareil ?aucune image, aucun identifiant

Les cinq premières lignes sont mesurables au chronomètre, la sixième est juridique et contractuelle. Ne pas la traiter comme les autres est une erreur que le module 8 illustre avec le cas des permissions caméra sur iOS.

Ce que « latence » veut dire quand un utilisateur regarde l'écran

Un chiffre de latence sans contexte ne veut rien dire. La bonne unité n'est pas la milliseconde brute mais la latence perçue, qui inclut trois segments successifs : le temps que la caméra sort une image utile après l'appui sur l'obturateur (environ 40 ms), le prétraitement de l'image (redimensionnement, normalisation : 10 à 20 ms), l'inférence proprement dite, puis l'affichage du résultat (autour de 16 ms pour un écran à 60 Hz).

L'inférence n'occupe donc qu'une fraction du budget. Sur un écran à 60 Hz, le seuil de fluidité est de 16 ms par image, et le seuil au-delà duquel l'utilisateur perçoit un « ralentissement » se situe autour de 100 à 200 ms pour une action ponctuelle. Le budget d'inférence retenu pour le fil rouge est donc de 150 ms sur milieu de gamme, avec une tolérance à 250 ms sur entrée de gamme.

La latence médiane trompe presque toujours

Une latence médiane de 120 ms qui cache un 99ᵉ percentile à 850 ms fera « sauter » l'interface une inférence sur cent. Le module 9 impose de raisonner par percentiles p50/p95/p99, jamais par moyenne.

Le coût énergétique se paie deux fois

Un modèle qui exécute trop d'opérations chauffe le processeur, ce qui déclenche le contrôle thermique de l'appareil. Sur un téléphone d'entrée de gamme, la fréquence maximale du processeur est réduite au bout de trente secondes d'usage soutenu, et la latence peut doubler. Le coût énergétique se paie donc deux fois : en pourcentage de batterie, et en dégradation de la latence après quelques dizaines d'inférences consécutives.

L'ordre de grandeur à retenir : une inférence MobileNetV2 float32 sur processeur consomme environ 3 mJ, l'écran allumé une seconde en consomme 100 fois plus. L'inférence n'est presque jamais le premier coupable de la consommation d'une application, sauf si elle tourne en continu (traitement vidéo temps réel).

Le réseau absent change la conception, pas la programmation

Passer d'un modèle servi par HTTP à un modèle embarqué modifie plusieurs décisions qui étaient triviales côté serveur :

  • Mise à jour du modèle : impossible d'écraser un fichier sur un serveur. Il faut publier une nouvelle version de l'application ou télécharger le modèle à froid dans un cache local ; c'est le rôle de Firebase Model Deployment ou du système équivalent, abordé au module 7.
  • Journalisation : plus de journal centralisé. Les inférences ratées restent silencieuses jusqu'à ce qu'un utilisateur signale un problème ; d'où l'importance des tests hors ligne du module 10.
  • Métriques : l'exactitude en production ne se mesure plus par échantillon de production. Elle se déduit des retours utilisateurs et des jeux de tests actualisés en interne.

Cette bascule s'entend jusque dans le vocabulaire : le module 6 parle d'« interprète » et non de « serveur d'inférence », précisément parce que l'objet qui exécute le modèle vit dans le processus de l'application, pas dans un processus séparé.

La confidentialité n'est pas un bonus

L'un des arguments les plus forts du calcul embarqué est que l'image ne quitte jamais l'appareil. Dans le cas du fil rouge, un agriculteur photographie ses cultures : c'est de la donnée métier sensible dont l'exportation vers un serveur tiers exigerait un consentement explicite et une base légale (RGPD, LGPD au Brésil, POPI en Afrique du Sud). L'inférence locale supprime cette contrainte de bout en bout.

Le corollaire est que le modèle lui-même est un actif exposé. Un fichier .tflite embarqué dans une APK peut être extrait par n'importe quel utilisateur avec un outil de désassemblage. Les défenses (chiffrement à l'installation, service d'appel à distance pour les cas sensibles) sortent du périmètre de ce cours, mais la conscience du risque doit accompagner le choix de l'inférence embarquée.

En résumé

  • Six budgets à chiffrer avant tout code : mémoire, stockage, calcul, énergie, réseau, confidentialité — casser l'un d'eux disqualifie le modèle même si les cinq autres passent.
  • La cible de latence est la latence perçue (obturateur → affichage) et se raisonne en percentiles, jamais en moyenne.
  • Un modèle qui chauffe fait chuter la fréquence du processeur : la consommation énergétique coûte deux fois, en batterie et en latence.
  • L'inférence locale supprime la surface d'exposition des données de l'utilisateur mais expose le modèle lui-même : un .tflite embarqué est extractible.

Module suivant : la conversion d'un modèle Keras en .tflite, avec les opérateurs pris en charge et le piège du prétraitement laissé hors du modèle.