[ Blog · IA ]

Embarquer des modèles prédictifs en local sans saturer la mémoire de vos applications

Vous voulez intégrer des réseaux de neurones directement sur le terminal de vos utilisateurs. L'idée est techniquement séduisante pour réduire la latence. Mais attention. Placer un tenseur de plusieurs gigaoctets dans un smartphone va instantanément tuer votre processus. Voyons comment compresser ces matrices sans détruire la précision mathématique.

Photo of Yanis
Yanis
Ingénieur / Développeur
·5 min read
Machine Learning on-device : embarquer des modèles prédictifs sans asphyxier la mémoire de votre application

La tyrannie de la mémoire vive face aux matrices gigantesques

Le machine learning sur serveur vous a mal habitué. Sur le cloud, vous instanciez des machines virtuelles avec des dizaines de gigaoctets de mémoire unifiée. Le code tourne, les tenseurs se chargent en mémoire vive, le modèle s'exécute paisiblement. Sur mobile, la réalité physique vous rattrape très vite. Un smartphone n'est pas un data center miniature. C'est un environnement hautement contraint où le système d'exploitation agit comme un dictateur paranoïaque.

Sur iOS, le démon Jetsam surveille la consommation de votre processus avec une sévérité absolue. Si votre application demande soudainement 500 mégaoctets pour charger un réseau de neurones convolutif, le système la tue sans sommation. Sous Android, le Low Memory Killer Daemon (LMKD) adopte exactement le même comportement.

Je me demande souvent si les ingénieurs backend mesurent l'enfer du mobile. Ils vous livrent un modèle PyTorch magnifique pesant 1.2 Go. Vous essayez de le charger dans votre application iOS. Crash. Out of Memory. Exception fatale.

C'est logique. Un paramètre de modèle en virgule flottante simple précision (FP32) pèse 4 octets. Un réseau modeste de 100 millions de paramètres pèse donc 400 mégaoctets sur le disque. Une fois désérialisé en mémoire vive, avec les buffers intermédiaires nécessaires à l'inférence, l'empreinte monte facilement à 800 mégaoctets. Aucun système d'exploitation mobile sain d'esprit ne vous laissera monopoliser une telle quantité de RAM! Votre processus sera sacrifié pour préserver l'autonomie de la batterie ou garder l'interface utilisateur fluide.

Bref. Le dévelopement d'applications IA sur terminal exige une approche totalement différente. Il faut arrêter de penser comme un data scientist. Vous devez penser comme un programmeur embarqué.

L'élagage synaptique et la quantification des tenseurs

Pour survivre, vous devez mutiler votre modèle. C'est le seul moyen. La technique la plus courante s'appelle la quantification. L'idée consiste à réduire la précision mathématique des poids synaptiques. Au lieu d'utiliser des nombres flottants sur 32 bits (FP32), vous mappez ces valeurs sur des entiers à 8 bits (INT8). Mathématiquement, vous perdez en granularité. Pratiquement, le poids de votre fichier est divisé par quatre.

Une fois que les matrices ont été compressé de cette manière, l'empreinte mémoire devient soudainement gérable. Mais la quantification n'est pas magique. Elle introduit du bruit de quantification. Votre modèle va perdre quelques pourcents de précision (accuracy).

Parfois, on observe un phénomène fascinant. La quantification INT8 agit comme une forme de régularisation. Le modèle devient moins sensible au surapprentissage. Donc, réduire la précision détruit toujours la qualité des prédictions. Quoique, en réalité, j'ai déjà vu des modèles de vision par ordinateur devenir plus robustes face au bruit visuel grâce à cette perte de précision. C'est contre-intuitif.

Vous avez accès à très peu d'options viables pour réaliser cette opération :

  • La quantification post-entraînement (Post-Training Quantization).
  • L'entraînement sensible à la quantification (Quantization-Aware Training).

L'élagage (pruning) est une autre méthode redoutable. Vous forcez les poids synaptiques proches de zéro à devenir exactement zéro. Votre matrice devient creuse (sparse). Les algorithmes de compression classiques comme ZIP ou LZ4 vont alors compresser le fichier du modèle de manière spectaculaire. Attention cependant. Une matrice creuse prend toujours autant de place en mémoire vive si votre moteur d'inférence ne supporte pas nativement les opérations sur tenseurs creux (sparse tensors). Vous gagnez de la place sur le disque dur du téléphone, pas dans la RAM.

Déléguer la charge aux puces neuronales matérielles

Le processeur central (CPU) d'un smartphone déteste les multiplications matricielles. Il n'est pas conçu pour ça. Le faire travailler sur une inférence de réseau de neurones va vider la batterie en quelques minutes. Vous devez absolument transférer cette charge de calcul vers des coprocesseurs spécialisés.

Apple possède le Neural Engine (ANE). Qualcomm intègre ses Hexagon DSP. Google a ses propres Tensor Processing Units (TPU) sur les puces Tensor. Ces composants matériels sont capables d'exécuter des milliers d'opérations MAC (Multiply-Accumulate) par cycle d'horloge avec une consommation électrique dérisoire.

Vous devez absolument utiliser TensorFlow Lite sur Android pour garantir la compatibilité maximale avec l'écosystème matériel. Même si, honnêtement, PyTorch Mobile offre un pontage bien plus stable avec les architectures modernes via Vulkan, donc fuyez TFLite dès que vous visez des puces récentes. L'écosystème est un véritable champ de mines.

Ils faut que vous surveilliez le comportement du compilateur lors de la délégation. C'est là que les vrais problèmes commencent. Les API fournies par les constructeurs, comme CoreML chez Apple ou NNAPI chez Android, sont des boîtes noires terrifiantes. Vous leur donnez votre modèle quantifié. Vous priez pour que le coprocesseur accepte toutes les couches (layers) de votre réseau.

Parce que si le NPU décide que votre couche de convolution personnalisée n'est pas supportée et qu'il la renvoie au CPU sans prévenir...

Le CPU, lui, il chauffe. L'inférence devient hybride. Les données font des allers-retours désastreux entre le processeur neuronal et le processeur central. La latence explose. L'application saccade. La promesse du machine learning on-device s'effondre.

Je vous invite à consulter la page principale de notre site pour voir comment nous abordons généralement l'ingénierie logicielle avancée. L'opacité des API matérielles est un sujet qui nous passionne.

Memory mapping et gestion thermique du silicium: le cœur du problème

Même avec un modèle quantifié à 50 mégaoctets tournant sur un NPU, comment le charger sans alerter le système d'exploitation ? La réponse tient en un appel système UNIX vieux de plusieurs décennies : mmap().

Le memory mapping permet de mapper le fichier de votre modèle directement dans l'espace d'adressage virtuel de votre application. Vous ne lisez pas le fichier avec un fread() pour le copier dans des variables allouées par malloc(). Vous demandez au noyau de faire correspondre une plage d'adresses mémoire au fichier sur le stockage flash.

Le système d'exploitation charge uniquement les pages mémoire nécessaires au moment exact où le processeur neuronal en a besoin. C'est ce qu'on appelle le lazy loading via page faults. Votre empreinte mémoire résidente (Resident Set Size) reste extrêmement basse. L'OS est content. Votre processus survit.

C'est d'ailleurs le socle de notre méthodologie lors de la conception de moteurs d'inférence propriétaires. Ne copiez jamais un modèle en RAM. Mappez-le.

Cependant, vous allez rapidement faire face à un mur physique.

  • La résistance thermique du châssis en aluminium ou en verre.
  • Le throttling agressif imposé par le kernel pour éviter la surchauffe.
  • La fragmentation inévitable de la mémoire virtuelle au fil des inférences.
  • L'absence de support matériel pour les fonctions d'activation exotiques.
  • Les quotas stricts d'allocation imposés par le démon de gestion de mémoire.
  • La latence catastrophique du bus de données entre le stockage flash et la puce.

Faire tourner un modèle à 30 images par seconde pour de la réalité augmentée génère une chaleur intense. Le processeur atteint 80 degrés Celsius. Le système d'exploitation intervient. Il abaisse drastiquement la fréquence d'horloge. C'est le thermal throttling. Votre inférence qui prenait 15 millisecondes en prend soudainement 120. L'expérience utilisateur devient saccadée. Vous ne pouvez pas lutter contre la thermodynamique.

Des architectures adaptées pour l'inférence locale

Vous ne pouvez pas prendre un modèle conçu pour le cloud et le forcer à rentrer dans un téléphone. Vous devez concevoir ou choisir des architectures nativement pensées pour le mobile. Les convolutions standards sont trop coûteuses. Utilisez des convolutions séparables en profondeur (depthwise separable convolutions). Elles réduisent drastiquement le nombre de calculs tout en maintenant une expressivité mathématique correcte.

Regardez l'architecture de MobileNet ou de YOLOv8 nano. Ces réseaux sont taillés pour l'environnement on-device. Leurs concepteurs ont calculé l'empreinte mémoire de chaque carte de caractéristiques (feature map) générée pendant le passage avant (forward pass).

Dans le domaine du traitement du langage naturel (NLP), c'est encore plus complexe. Les transformeurs (Transformers) consomment une mémoire colossale à cause du mécanisme d'attention (Self-Attention) dont la complexité spatiale est quadratique par rapport à la longueur de la séquence. Utiliser MobileBERT est un strict minimum. Vous devez réduire la taille du vocabulaire. Vous devez limiter la taille du contexte.

Certains de nos clients ont essayé de contourner ces limitations en chargeant des morceaux de modèles séquentiellement. Jetez un œil à nos références pour comprendre l'ampleur des projets que nous auditons. Charger des poids à la volée depuis le disque flash pendant l'exécution crée des goulots d'étranglement I/O épouvantables. Le bus de stockage des smartphones n'est pas conçu pour ce type d'accès aléatoire intensif.

Soyez pragmatiques. Si votre modèle prédictif nécessite 2 gigaoctets de mémoire pour fonctionner correctement, il n'a rien à faire sur un terminal mobile. Revoyez votre architecture. Fusionnez vos couches. Quantifiez vos poids en INT8. Mappez vos fichiers en mémoire. Exploitez le NPU. C'est à ce prix que votre application survivra dans la poche de vos utilisateurs.

Faire tourner des algorithmes complexes sur un smartphone relève de l'orfèvrerie. Vous devez jongler entre la précision prédictive et les limites physiques du matériel. Optimisez vos tenseurs. Déléguez aux puces dédiées. L'intelligence artificielle mobile exige une rigueur architecturale implacable pour ne pas fondre littéralement dans les mains de vos utilisateurs.

[ Team ]

Entrust your project
to our app experts.

Our experts in web, mobile and AI applications build your project, delivering superior technical and functional quality within shorter timeframes.

Kosmos team — portrait 1
Kosmos team — portrait 2
Kosmos team — portrait 3
Kosmos team — portrait 4
Kosmos team — portrait 5
Kosmos team — portrait 7
Kosmos team — portrait 6
15
Experts
100+
Projects delivered
78%
Loyal clients
4.9/5
Average rating
[ Press ]

They talk about us.

Explore the mentions and analyses that spotlight our work and our innovations across the business and tech press.

Free quote · no commitment

Let's discuss your project.

Describe your project. Our team replies within 24 hours with free technical scoping, along with a clear estimate of costs and timelines. No commitment.

  • Reply within 24 hours from a project manager
    or engineer.
  • Technical scoping and quote, with no fees.
  • No commitment, your data stays
    confidential.
Quick estimate

Free scoping & estimate in less than 24h

Describe your project and we'll get back to you with a costed estimate and a roadmap.

Call us
01 76 50 66 44
Monday to Saturday, 9 AM to 6:30 PM