- LLM in a Flash place dans la mémoire flash les paramètres de LLM plus volumineux que la DRAM, et ne charge dans la DRAM que les parties nécessaires, rendant l’inférence possible même sur des appareils à mémoire limitée
- En s’appuyant sur un modèle de coût d’inférence qui reflète les caractéristiques d’accès de la mémoire flash, l’approche réduit le volume de données transférées et favorise la lecture de blocs plus grands et continus
- Le windowing réutilise les neurones précédemment activés, et le row-column bundling exploite l’avantage de la flash pour les accès séquentiels afin de réduire les goulots d’étranglement
- En combinant ces deux techniques, il est possible d’exécuter des modèles allant jusqu’à 2 fois la taille de la DRAM disponible, avec une inférence 4 à 5 fois plus rapide sur CPU et 20 à 25 fois plus rapide sur GPU par rapport à un chargement simple
- La combinaison de la prise en compte de la sparsité, du chargement adaptatif au contexte et d’une conception orientée matériel renforce la possibilité d’exécuter des LLM sur des appareils à mémoire limitée
Inférence LLM basée sur la mémoire flash
- Les grands modèles de langage offrent de hautes performances sur diverses tâches de traitement du langage naturel, mais leurs besoins en calcul et en mémoire sont importants, ce qui rend leur exécution difficile sur des appareils dont la capacité DRAM est limitée
- LLM in a Flash répond à cette contrainte en stockant les paramètres du modèle dans la mémoire flash et en ne chargeant à la demande dans la DRAM que les données nécessaires pendant l’inférence
- Au cœur de l’approche se trouve un modèle de coût d’inférence adapté au fonctionnement de la mémoire flash
- Il est optimisé pour réduire le volume de données transférées depuis la flash
- Il est conçu pour lire les données sous forme de blocs plus grands et continus
Deux techniques pour réduire les transferts et optimiser les lectures
- Le windowing réutilise les neurones précédemment activés afin de réduire le volume de données à transférer de la flash vers la DRAM
- Le row-column bundling augmente la taille des blocs de données lus depuis la flash, en tirant parti du fait que la mémoire flash est performante pour les accès séquentiels
- Utilisées ensemble, ces deux techniques permettent d’exécuter des modèles jusqu’à 2 fois plus grands que la DRAM disponible
- Les gains de vitesse d’inférence par rapport à une méthode de chargement simple varient selon le matériel
- Sur CPU, l’inférence est 4 à 5 fois plus rapide
- Sur GPU, elle est 20 à 25 fois plus rapide
- Cette conception intègre la prise en compte de la sparsité, le chargement adaptatif au contexte et une conception orientée matériel pour rendre possible l’inférence de LLM dans des environnements à mémoire limitée
1 commentaires
Avis sur Hacker News
L’article s’appuie sur les techniques d’exploitation de la parcimonie du papier Deja Vu, déjà assez complexe, donc il m’a fallu du temps pour le comprendre.
Deja Vu considère que même les modèles dont les poids sont peu parcimonieux présentent une forte « parcimonie contextuelle » (contextual sparsity). Autrement dit, le vecteur résultat d’une multiplication matricielle contient beaucoup de zéros, mais les positions qui deviennent nulles varient selon l’entrée.
En exploitant cette parcimonie, on peut éviter de charger certaines lignes de la matrice ; pour obtenir un gain de performance, il faut prédire à l’avance quelles lignes ignorer, et cette prédiction peut se faire avec une matrice de rang faible.
Le papier d’Apple suggère que cette découverte aide non seulement les performances de chargement depuis la RAM, mais aussi le chargement depuis la mémoire flash, sans trop sacrifier la bande passante.
La matrice d’attention est relativement légère, et la partie à charger de manière parcimonieuse est le FFN. De plus, on obtient une bien meilleure parcimonie en prédisant non pas l’entrée du FFN, mais la sortie de la couche ReLU. Si l’on peut prédire que « cet emplacement du vecteur sera négatif après la multiplication matricielle et avant ReLU », on peut ne pas charger la colonne correspondante de la matrice et produire 0 en sortie.
L’idée proposée est que la plupart des lignes du FFN n’ont tout simplement pas besoin d’être chargées, et qu’il suffit de maintenir, pour chaque FFN, un cache des lignes récemment utilisées, puis de le mettre à jour depuis la flash quand c’est nécessaire. Il y a aussi davantage de corrélations entre le chargement par chunks et les couches de projection, mais l’intuition clé semble être là.
FFN signifie Feed Forward Network et, dans les transformeurs, ce sont les plus gros blocs.
Je me demande quelle proportion du modèle il devient inutile de charger avant que l’écart de performance réel commence à se faire sentir.
Par exemple, pour conserver 90 % des performances obtenues quand tout est chargé en RAM, j’aimerais savoir s’il suffit d’utiliser moitié moins de mémoire, ou s’il faut 90 %, voire 95 %.
Au final, la question est de savoir à quelle vitesse on perd en performance par rapport au maximum quand on réduit la RAM. Le graphique compare cet algorithme à l’algorithme de base dans des situations avec peu de RAM ; c’est différent, mais c’est une bonne question.
Si l’on peut obtenir de bonnes performances sans charger entièrement un modèle de 8 Go dans la mémoire d’un téléphone, c’est clairement utile.
Le papier vaut la peine d’être lu en entier, c’est un travail assez intéressant : https://arxiv.org/pdf/2312.11514
Les points mis en avant dans le papier sont deux techniques complémentaires visant à minimiser les transferts de données et à maximiser le débit de la mémoire flash.
Le windowing réutilise les activations des tokens calculés récemment et ne charge que les paramètres nécessaires aux quelques tokens précédents, ce qui réduit le nombre de requêtes d’I/O pour charger les poids.
Le row-column bundling concatène et stocke ensemble les lignes et colonnes des couches d’up-projection et de down-projection afin de lire de plus gros chunks contigus depuis la flash, ce qui augmente le débit grâce à la lecture de gros chunks.
En théorie, quand une partie du modèle est en flash, le temps d’inférence d’un token unique devrait être égal au temps d’inférence lorsque tout le modèle est en RAM, plus le temps nécessaire pour charger la partie du modèle qui se trouve en flash.
Je suppose qu’il n’est pas nécessaire de réécrire dans la flash, mais je ne suis pas spécialiste des LLM, donc je peux me tromper.
S’il y a bien plus de 10 couches, on devrait pouvoir ne garder qu’une petite partie en RAM et charger les couches une par une. La plupart des LLM ont des dizaines de couches, donc cela paraît plausible.
Si la RAM n’est pas le goulot d’étranglement pendant l’inférence, il devrait aussi être possible de faire un transfert DMA de la couche suivante depuis la flash vers la RAM pendant que l’on exécute l’inférence sur la couche courante. Sur un système à processeur unique, cela risque de mal fonctionner à cause du goulot d’étranglement de la RAM.
Sur un système biprocesseur, peut-être qu’un processeur pourrait charger la couche suivante en RAM pendant que l’autre exécute l’inférence sur la couche précédente, ce qui permettrait de faire tourner de très grands LLM avec peu de RAM.
Je suis assis en ce moment à côté d’un tas de composants pour assembler une nouvelle machine IA pour LLM. C’est une z840 biprocesseur, donc j’ai hâte d’expérimenter ce genre de choses moi-même.
Ce qui frappe, c’est que les appareils Apple ont très peu de RAM par rapport aux appareils comparables de la concurrence
Cela tient en partie au fait que les équipes logiciel d’Apple utilisent des langages plus efficaces comme Objective-C, et en partie au fait que les apps iOS n’ont pas à cibler une énorme variété de résolutions d’écran. Elles ont donc relativement moins souvent besoin de charger des textures haute résolution puis de les réduire
Par ailleurs, même en achetant à l’échelle d’Apple, la RAM ne devient pas beaucoup moins chère ; augmenter la RAM entame donc davantage les marges que l’ajout d’autres fonctionnalités
Mais comme les LLM sont par nature très gourmands en RAM, tous ces choix leur reviennent en boomerang. Quelle que soit la technique d’économie de mémoire utilisée, les concurrents avec plus de RAM pourront intégrer des modèles plus grands, meilleurs et plus intelligents
J’aimerais bientôt acheter un Mac, mais je me demande vraiment quelle quantité de RAM commander. C’est d’autant plus difficile que mon budget est limité. Si je n’avais pas cette contrainte, je prendrais au moins 32 Go
J’espère encore qu’Apple changera sa politique tarifaire sur la RAM, mais c’est probablement un vain espoir
On peut aussi voir l’implémentation correspondante : https://opensource.apple.com/source/xnu/xnu-2050.18.24/libke...
Les appareils Apple prennent également en charge une fonctionnalité appelée « jetsam », qui libère de la mémoire en terminant les apps inutilisées ou en arrière-plan afin que les apps à haute priorité continuent de tourner de façon fluide : https://developer.apple.com/documentation/xcode/identifying-...
Je suis ouvert aux recommandations de laptops Linux silencieux, ou presque sans bruit. La plupart font tourner leurs ventilateurs à fond, et je serais prêt à sacrifier une partie des performances CPU pour le silence. Ce serait aussi bien de pouvoir activer et désactiver facilement un mode silencieux
Jusqu’ici, je n’ai rien vu qui égale le silence du MacBook Air, et je serais ravi qu’on me montre un produit qui me donne tort
Évidemment, ce serait encore mieux s’il était moins cher ou si la RAM était remplaçable. J’utilise surtout mon MacBook Air pour des services web et comme terminal distant vers des serveurs Linux utilisés pour compiler de gros projets et pour de l’hébergement à la maison/en auto-hébergement
Le calendrier a clairement été avancé, mais je ne pense pas que leur hypothèse soit fausse
Je ne comprends ce sujet que de façon limitée, mais je me demande si cette approche permettrait de faire tourner des LLM hors ligne sur un téléphone
Si c’est possible, cela ouvrirait beaucoup d’applications intéressantes, comme de la modération de contenu assistée par IA sans envoyer de données confidentielles à un serveur
Par exemple, hier, une discussion GitHub sur l’exécution de LLM sur les puces Apple A-series (iPhone) a été publiée ici : https://news.ycombinator.com/item?id=38703161
J’apprécie que les articles récents parlent de LLM plutôt que d’« IA ». Cela permet de comprendre qu’il s’agit d’une technologie précise, et non d’un emballement marketing
Je me demande en quoi cela diffère de FlashAttention. C’est déroutant d’utiliser des termes similaires sans expliquer la différence dans le résumé
Modification : il semble qu’ils aient étendu deux mécanismes différents au sein du framework flash. Le titre de l’article aurait pu être meilleur, mais l’explication se trouve dans les premières pages
Dans la conclusion, je m’attendais à une section du type « comment cette fonctionnalité sera exposée aux utilisateurs », mais c’est peut-être hors du périmètre de l’article
Je me demande si ce genre de fonctionnalité remontera sous forme d’appel d’API ou de paramètre dans CoreML, par exemple avec un flag use_flash, ou si ce sera une optimisation au runtime invisible pour l’utilisateur
Je me demande aussi si quelqu’un connaît de bonnes présentations ou conférences où Apple explique la feuille de route de développement de CoreML, Metal, etc.
Apple a racheté une entreprise iranienne ?
[0]: https://www.geekwire.com/2020/exclusive-apple-acquires-xnor-...
Je sais que les approches sont différentes, mais comme les deux exploitent la mémoire flash, je m’attendais à ce que cet article mentionne au moins FlashAttention [1]
[1] https://arxiv.org/abs/2205.14135
Si je comprends bien, FlashAttention concerne un schéma d’accès qui exploite mieux la mémoire locale, en particulier la SRAM. Par exemple, en gardant les données dans le cache L1 du CPU ou dans la couche équivalente côté GPU.
En d’autres termes, FlashAttention concerne ce qui est plus rapide que la DRAM, tandis que cet article traite de la manière de mieux décharger vers ce qui est plus lent que la DRAM.
Dans « le modèle OPT 6.7B présente par exemple une sparsité de 97 % notable à l’intérieur des couches FFN », quelqu’un sait-il ce que signifie exactement cette métrique ?
Je me demande si cela veut dire que 97 % des valeurs de la couche sont à zéro, ou qu’elle peut être compressée à 3 % de sa taille.
Mais comme les 3 % activés ne sont pas fixes, on ne peut pas supprimer complètement les 97 % restants. L’article semble dire qu’en prédisant assez précisément les 3 % actifs, on peut accélérer le traitement sans trop perdre en précision.