Faire tourner un LLM en local sur mobile : retour d'expérience
Oui, on peut faire tourner un LLM directement sur un téléphone, mais est-ce vraiment la meilleure solution ?
Notre retour d'expérience et une piste d'alternative : héberger son LLM sur son propre serveur et le mettre à disposition des utilisateurs.
Discuter d'IA embarquée sur mobile avec Inside|app
L'idée est séduisante : un assistant conversationnel qui s'exécute entièrement sur l'appareil, sans cloud, sans envoi de données. Confidentialité, usage hors ligne, coûts maîtrisés. Nous avons mené ce projet de bout en bout.
Spoiler : c'est techniquement possible, mais ça ne vaut pas forcément le coup pour tout le monde, tout simplement parce que tous les utilisateurs n'ont pas un téléphone assez puissant.
Et si l'on tenait à garder les données « chez soi », une autre option mérite d'être envisagée : héberger son propre LLM sur son propre serveur et permettre aux utilisateurs d'y accéder depuis l'app. Voici notre parcours et cette alternative.
Pourquoi un LLM « local » et la limite du tout-appareil
Les avantages d'une exécution locale sont réels :
- Confidentialité : les conversations ne quittent pas l'environnement maîtrisé (appareil ou infra à vous).
- Hors ligne (sur appareil) ou indépendance des géants du cloud (sur votre serveur).
- Coûts : une fois le modèle en place, le coût marginal par requête reste faible.
Sur téléphone, les contraintes sont lourdes : puissance limitée, peu de RAM, batterie à préserver. En pratique, seuls les appareils les plus récents et les plus équipés offrent une expérience correcte. Pour une large base d'utilisateurs, faire tourner le LLM sur l'appareil n'est donc pas toujours pertinent.
Premier choix : moteur d'inférence
Dès le départ, nous avons été confrontés à un choix stratégique : quel moteur d'inférence utiliser ?
Une première option nous attirait : un framework « natif » pour l'écosystème Apple, avec une API Swift moderne, une intégration poussée avec le silicium (Metal, mémoire unifiée) et un soutien officiel. En revanche, ce framework ne supportait pas le format de modèles ouvert le plus répandu, celui que l'on trouve partout (répertoires communautaires, quantifications variées). Pour l'utiliser, il aurait fallu convertir systématiquement les modèles dans un format propriétaire, avec une chaîne d'outils externe. Pour un produit dont la promesse est « tu télécharges un modèle, tu le fais tourner », c'était rédhibitoire.
La seconde option reposait sur un moteur en C/C++, éprouvé en production, avec un support complet de ce format ouvert (toutes quantifications, écosystème riche). L'API côté Swift passait par une couche d'encapsulation, un peu moins « Swift-native », et la gestion mémoire devait être faite à la main par endroits. En contrepartie, nous avions la stabilité, la compatibilité avec l'immense majorité des modèles disponibles.
Notre décision : rester sur le moteur C/C++ pour la première version. La compatibilité avec le format de modèles ouvert et la stabilité primaient sur le confort d'une API 100 % Swift et sur un gain de performance marginal. Nous avons documenté les critères qui nous feraient reconsidérer l'autre option plus tard (support natif du format ouvert, adoption officielle par la plateforme, etc.).
Deuxième choix : modèles système (type « intelligence embarquée »)
Un autre sujet est apparu : les modèles fournis par le système d'exploitation, type « intelligence embarquée » sur les appareils les plus récents.
Avantages évidents : pas de téléchargement de modèle, inférence rapide, intégration OS. Nous avons étudié l'intégration de ce type de fournisseur dans notre architecture.
Les limites étaient claires : disponibilité seulement sur les appareils les plus récents (une part encore minoritaire du parc), et dépendance à une version majeure d'OS pas encore déployée partout. Inclure ce fournisseur dans la première version aurait complexifié l'architecture (détection de disponibilité, fallback, UI différenciée) tout en ne profitant qu'à une fraction des utilisateurs.
Notre décision : reporter l'intégration de ces modèles système à une version ultérieure (v1.1+). La v1 s'appuie uniquement sur des modèles au format ouvert, utilisables sur un large spectre d'appareils et d'versions d'OS.
L'architecture a été conçue pour accepter plus tard un second « fournisseur » sans refonte : un protocole commun pour le moteur de chat, des descripteurs de modèles extensibles. Aucune dette technique : nous avons simplement choisi de ne pas tout faire en même temps.
Ce que nous avons construit : stabilité et adaptation à l'appareil
Une fois les choix de moteur et de périmètre actés, nous avons structuré le produit autour de trois principes : stabilité d'abord, défense en profondeur, dégradation maîtrisée.
Gestion de la mémoire en trois couches
Un LLM en local consomme beaucoup de mémoire. Pour éviter les plantages (OOM), nous avons mis en place trois niveaux de protection :
- Contrôle avant chargement : avant de charger un modèle, on estime la mémoire nécessaire (taille du fichier, quantification, marge de sécurité). Si l'appareil n'a pas assez de marge, on bloque le chargement et on propose des modèles plus légers.
- Contexte adaptatif : la taille du contexte est ajustée en fonction des capacités de l'appareil pour limiter la consommation mémoire.
- Surveillance en cours d'exécution : pendant l'inférence, un moniteur suit la pression mémoire. En cas de tension, on réduit l'agressivité (taille de batch, cache), on prévient l'utilisateur, et en dernier recours on arrête proprement pour éviter un crash.
L'objectif est simple : ne jamais crasher. Mieux vaut une réponse plus lente ou un contexte plus court qu'un plantage.
Connaissance de l'appareil et batterie
Nous avons intégré une couche de détection des capacités : modèle d'appareil, puce, RAM, état de la batterie et thermique. Ces informations alimentent :
- le calcul du contexte et des paramètres d'inférence (batch size, nombre de threads) ;
- des profils d'alimentation : sur secteur ou batterie pleine, on privilégie la vitesse ; en batterie faible, on réduit la charge pour préserver l'autonomie.
L'utilisateur peut garder le contrôle (choix manuel du profil si besoin), mais les valeurs par défaut sont cohérentes avec son appareil.
Recommandation de modèles
Plutôt que de laisser l'utilisateur choisir aveuglément parmi une liste de modèles, nous avons mis en place un moteur de recommandation qui score chaque modèle selon : compatibilité mémoire, performance attendue, qualité (proxy par la taille), impact batterie. Chaque modèle peut recevoir des badges (recommandé, rapide, qualité, économe, équilibré) et une explication courte. L'objectif est d'éviter les mauvaises surprises (« ce modèle ne tourne pas bien sur mon téléphone ») tout en restant transparent sur les critères.
Défis rencontrés
- Mémoire : les modèles, même quantifiés, pèsent lourd. Il a fallu définir des seuils, des marges et des messages clairs pour guider l'utilisateur vers des modèles adaptés à son appareil.
- Format et écosystème : le choix du moteur d'inférence était largement dicté par le support du format de modèles dominant. Sans cela, l'expérience « télécharger un modèle et le lancer » aurait été compromise.
- Concurrence et sécurité : une architecture entièrement pensée en Swift avec acteurs et types
Sendablea permis d'éviter les data races et de garder un comportement prévisible sous charge. - Périmètre : accepter de ne pas tout inclure en v1 (modèles système, autres moteurs) a permis de livrer une base stable et maintenable, avec une feuille de route claire pour la suite.
Un projet d'IA embarquée ? Contactez-nous !
Une alternative : LLM sur votre propre serveur
Plutôt que de tout faire tourner sur le téléphone, une option souvent plus réaliste est d'héberger votre LLM sur votre propre serveur (chez vous, dans votre datacenter ou chez un hébergeur de confiance) et de proposer aux utilisateurs d'y accéder depuis l'app. Les données restent sous votre contrôle, pas chez un tiers ; vous choisissez le modèle et les paramètres ; et n'importe quel téléphone peut utiliser le service, sans dépendre de la puissance de l'appareil.
C'est un bon compromis entre confidentialité, maîtrise des coûts et expérience utilisateur sur un parc d'appareils très hétérogène. Pour beaucoup de cas d'usage, cette approche « mon LLM, mon serveur, mes utilisateurs » mérite d'être envisagée en parallèle, ou à la place, du tout-on-device.
Notre avis sur le LLM en local sur mobile
Faire tourner un LLM sur l'appareil est possible, mais ça ne vaut pas toujours le coup : la cible est étroite (appareils puissants, utilisateurs prêts à gérer modèles et paramètres).
Pour une base large, les limites matérielles rendent l'expérience fragile ou décevante. Nous avons construit une architecture pour le cas on-device, mais notre conclusion est nuancée : selon votre public et vos objectifs, héberger votre LLM sur votre propre serveur et laisser les utilisateurs s'y connecter depuis l'app peut être la solution la plus pertinente, données « locales » au sens « chez vous », sans exiger un téléphone haut de gamme.
Si vous hésitez entre on-device et self-hosted, notre agence spécialisée en intelligence artificielle peut vous accompagner.
Discuter d'IA embarquée sur mobile avec Inside|app
FAQ
Le LLM sur téléphone, c'est vraiment utilisable pour tout le monde ?
Non. En pratique, une expérience correcte demande un appareil récent et suffisamment puissant (RAM, puce). Sur un parc hétérogène, beaucoup d'utilisateurs seraient limités à des modèles très légers ou à une expérience dégradée. C'est pour cela que nous recommandons d'envisager aussi l'option « LLM sur votre propre serveur », accessible depuis n'importe quel téléphone.
Quelle alternative au tout-on-device ?
Héberger votre LLM sur votre propre serveur (local ou hébergé) et permettre aux utilisateurs d'y accéder depuis l'app. Les données restent sous votre contrôle, vous choisissez le modèle, et l'expérience ne dépend pas de la puissance du téléphone. C'est souvent le bon compromis entre confidentialité, coûts et couverture du parc.
Pourquoi privilégier la compatibilité avec un format de modèles ouvert (pour le cas on-device) ?
Pour permettre aux utilisateurs de télécharger des modèles depuis les dépôts communautaires et de les faire tourner sans étape de conversion. Un moteur qui ne supporte pas ce format imposerait des outils externes et compliquerait fortement l'expérience « tout en local ».
Comment éviter les plantages (OOM) avec un LLM en local sur appareil ?
En combinant un contrôle avant chargement (estimation mémoire + marge), un contexte adapté aux capacités de l'appareil, et une surveillance en temps réel pendant l'inférence, avec dégradation gracieuse (réduction de charge, arrêt propre) si la pression mémoire devient trop forte.
Quels sont les avantages d'un LLM local ?
Les avantages principaux sont la confidentialité (les conversations ne quittent pas votre environnement), l'usage hors ligne ou l'indépendance des géants du cloud, et des coûts maîtrisés une fois le modèle en place.
Quel moteur d'inférence choisir pour un LLM mobile ?
Pour une compatibilité maximale avec les modèles disponibles, un moteur C/C++ supportant le format ouvert dominant (GGUF) est recommandé. Il offre stabilité et accès à l'écosystème communautaire, même si l'API Swift est moins native qu'un framework propriétaire.
Comment adapter l'inférence LLM aux capacités de l'appareil ?
En intégrant une détection des capacités (modèle d'appareil, puce, RAM, batterie) et en ajustant automatiquement la taille du contexte, le batch size et le nombre de threads selon ces paramètres.