Perplexity taille un moteur sur mesure pour Qwen sur les Mac M5
Perplexity publie Lily, un moteur local en Rust et Metal conçu pour accélérer Qwen3.6-35B-A3B sur les Mac équipés d’une puce M5, avec des gains surtout visibles pendant la génération.
Faire tenir un grand modèle dans la mémoire d’un Mac ne suffit pas. Encore faut-il que la machine puisse lire ses poids, traiter une longue instruction et produire sa réponse à une vitesse acceptable. Avec Lily, Perplexity abandonne les outils généralistes pour construire un moteur consacré à une seule architecture et à une génération de Mac.
Le projet accompagne Hybrid Compute, une fonction qui répartit les tâches entre des modèles distants et un modèle exécuté localement. Les premiers prennent en charge la recherche et le raisonnement, tandis que le second peut travailler avec les fichiers et les applications de l’ordinateur. Pour que cette division reste discrète, Perplexity devait accélérer la partie locale.
Lily est écrit en Rust et utilise des opérations Metal développées pour les processeurs Apple. PyTorch et MLX ne participent pas à son exécution. Le chargement du modèle, la gestion de la conversation, la génération et les opérations effectuées par le processeur graphique sont regroupés dans un même programme.
Ce choix tranche avec MLX et MLX-LM, les outils d’Apple habituellement utilisés pour exécuter des modèles sur ses machines. Leur avantage tient à leur compatibilité avec de nombreuses architectures. Lily adopte la direction inverse : il sacrifie cette polyvalence pour organiser chaque opération autour d’un seul modèle.
Ce modèle est Qwen3.6-35B-A3B. Il compte 35 milliards de paramètres, mais n’en active qu’environ 3 milliards pour chaque jeton traité. Un système de routage choisit huit spécialistes parmi 256, auxquels s’ajoute un spécialiste commun utilisé pour toutes les entrées.
Cette organisation réduit la quantité de calcul nécessaire, mais rend l’exécution plus irrégulière. Deux jetons successifs peuvent mobiliser des parties différentes du modèle. Le moteur doit déterminer les spécialistes concernés, rassembler les données correspondantes puis charger leurs poids sans multiplier les échanges inutiles avec le processeur central.
Qwen3.6-35B-A3B combine également dix couches d’attention complète avec trente couches Gated DeltaNet. Les premières relisent une mémoire dont la taille augmente avec la conversation. Les secondes résument les informations précédentes dans un état récurrent de taille fixe.
Ces deux mécanismes n’imposent pas la même charge à l’ordinateur. L’attention devient progressivement plus coûteuse lorsque le contexte s’allonge, tandis que l’état récurrent doit être mis à jour dans l’ordre des jetons. Lily prépare donc des chemins d’exécution différents selon la couche, la longueur du texte et la phase de génération.
Perplexity distingue en effet le « prefill » du « decode ». Le prefill correspond au traitement de la demande, de l’historique et des documents fournis avant l’apparition du premier mot. Plusieurs centaines ou milliers de jetons peuvent alors être traités ensemble.
Le decode commence ensuite. Le modèle produit généralement sa réponse un jeton après l’autre. Cette étape réutilise peu les mêmes poids à un instant donné et dépend davantage de la vitesse à laquelle la machine peut déplacer les données depuis sa mémoire.
Cette différence explique l’approche de Lily. Pendant le prefill, le moteur privilégie les opérations matricielles capables de réutiliser un même bloc de poids sur de nombreuses lignes. Pendant le decode, il emploie un parcours davantage adapté à une seule ligne et tente surtout de réduire le volume lu à chaque nouveau jeton.
La mémoire unifiée des Mac permet au processeur central et au processeur graphique d’accéder au même espace physique. Le modèle n’a donc pas besoin d’être copié intégralement d’une mémoire à l’autre. Cette architecture ne rend toutefois pas les transferts gratuits : la bande passante reste une limite dès que les poids doivent être relus pour chaque élément généré.
Le point de contrôle utilisé par Lily est quantifié sur 4 bits. Les 35 milliards de paramètres occupent ainsi environ 19,4 Go, contre approximativement 70 Go dans un format bfloat16. Les valeurs compressées sont accompagnées d’une échelle et d’un biais permettant de les reconstruire au moment de leur utilisation.
L’une des principales optimisations consiste à effectuer cette reconstruction directement pendant la multiplication matricielle. Lily ne crée pas une version complète et temporaire des poids dans la mémoire unifiée. Il développe seulement un petit bloc, le conserve brièvement dans une mémoire rapide du processeur graphique, l’utilise puis passe au suivant.
Selon une comparaison interne réalisée sur une instruction de 512 jetons, cette intégration aurait augmenté la vitesse du prefill de 77,4 %. Le résultat mesure l’effet de cette modification dans Lily lui-même et non son avance sur MLX-LM.
Le routage des spécialistes demeure lui aussi sur le processeur graphique. Le moteur compte les jetons affectés à chacun, calcule leurs positions puis rassemble les données correspondantes sans demander au processeur central de valider chaque étape.
Cette organisation lance davantage de petites opérations, mais évite les interruptions nécessaires pour transférer les décisions d’un composant à l’autre. Dans le test de Perplexity à 512 jetons, le maintien du routage sur le processeur graphique aurait presque doublé la vitesse du prefill.
Les spécialistes ne reçoivent pas tous le même nombre de jetons. Lily adapte donc la taille des blocs de calcul à leur charge réelle. Un bloc trop petit multiplie les préparations, tandis qu’un bloc trop grand laisse une partie des unités de calcul sans travail lorsque peu de données ont été dirigées vers un spécialiste.
Le moteur conserve également l’état récurrent de Gated DeltaNet dans les registres pendant le parcours de l’instruction. Il évite ainsi de l’écrire puis de le relire à chaque étape. Perplexity rapporte un gain de 5,6 % sur un prefill de 2 048 jetons, plus modeste que celui obtenu sur les spécialistes puisque ces derniers représentent l’essentiel du temps de traitement.
Pour les longues instructions, Lily travaille par blocs