FlashAttention-3 : une attention plus rapide et plus précise grâce à l’asynchronisme et à la basse précision
(together.ai)- Le goulot d’étranglement de l’attention dans les Transformers limitait la vitesse d’entraînement et d’inférence des LLM à long contexte ; FlashAttention-3 est une nouvelle version qui vise à le réduire davantage en exploitant les fonctionnalités des GPU Hopper
- L’idée centrale consiste à utiliser l’asynchronisme des Tensor Cores et de TMA pour chevaucher calcul et déplacement de données, et à entrelacer matmul et softmax afin de réduire les temps d’inactivité du GPU
- Sur H100, FlashAttention-2 n’exploitait que 35 % des FLOPS théoriques maximaux, tandis que FlashAttention-3 atteint jusqu’à 740 TFLOPS en FP16, soit 75 % du maximum théorique du H100
- En basse précision FP8, les valeurs aberrantes des activations de LLM amplifient les erreurs ; un incoherent processing fondé sur la transformée de Hadamard réduit l’erreur de 2,6× par rapport à l’attention FP8 de référence
- FlashAttention-3 est disponible sur GitHub ; à mesure que le coût de l’attention diminue, les marges de progression augmentent pour traiter des contextes plus longs et améliorer l’efficacité de l’entraînement et de l’inférence des LLM
Objectifs et performances de FlashAttention-3
- L’attention est une couche essentielle des Transformers, mais elle devient un goulot d’étranglement majeur dans les grands modèles de langage et les applications à long contexte
- FlashAttention et FlashAttention-2 ont ouvert la voie à une approche qui accélère l’attention en réduisant les lectures et écritures en mémoire GPU ; la plupart des bibliothèques l’utilisent aujourd’hui pour accélérer l’entraînement et l’inférence des Transformers
- Cette approche a contribué à l’augmentation de la longueur de contexte des LLM ces deux dernières années, de 2–4K pour GPT-3 et OPT à 128K pour GPT-4, et jusqu’à 1M pour Llama 3
- FlashAttention-2 ne parvenait qu’à 35 % d’utilisation des FLOPS théoriques maximaux sur GPU H100, mais FlashAttention-3 améliore ce résultat en exploitant les nouvelles fonctionnalités des GPU Hopper
- Les performances publiées de FlashAttention-3 sont les suivantes
- 1,5 à 2,0× plus rapide que FlashAttention-2 en FP16
- Jusqu’à 740 TFLOPS en FP16
- 75 % d’utilisation des FLOPS théoriques maximaux du H100
- Près de 1,2 PFLOPS en FP8
- Une erreur 2,6× plus faible que l’attention FP8 de référence
Rappel du fonctionnement de FlashAttention
- FlashAttention réorganise l’ordre de calcul de l’attention et accélère le traitement avec du tiling et du recalcul, tout en réduisant l’usage mémoire par rapport à la longueur de séquence, de quadratique à linéaire
- Les blocs d’entrée sont chargés de la HBM vers la SRAM, l’attention est calculée sur ces blocs, puis la sortie est mise à jour en HBM
- Comme la grande matrice d’attention intermédiaire n’est pas écrite en HBM, les lectures et écritures mémoire diminuent, ce qui permet une accélération réelle de 2 à 4× à l’exécution
- En combinant tiling et rescaling du softmax, on peut traiter les données par blocs tout en obtenant une sortie correcte sans approximation
Fonctionnalités des GPU Hopper : WGMMA, TMA, FP8
- FlashAttention-2 peut atteindre jusqu’à 70 % des FLOPS théoriques maximaux sur les GPU Ampere A100, mais n’exploite pas pleinement les nouvelles fonctionnalités des GPU Hopper
- FlashAttention-3 utilise trois fonctionnalités de Hopper
- WGMMA : fonctionnalité warpgroup matrix multiply-accumulate qui exploite les nouveaux Tensor Cores de Hopper, avec un débit supérieur à
mma.syncsur Ampere - TMA : unité matérielle dédiée qui accélère les transferts de données entre global memory et shared memory, en prenant en charge le calcul des index et la prédication out-of-bound afin de réduire l’utilisation des registres
- FP8 : peut doubler le débit des Tensor Cores par rapport au FP16, mais représente les valeurs en virgule flottante avec moins de bits, ce qui implique un compromis avec la précision
- WGMMA : fonctionnalité warpgroup matrix multiply-accumulate qui exploite les nouveaux Tensor Cores de Hopper, avec un débit supérieur à
- FlashAttention-3 utilise les abstractions de NVIDIA CUTLASS pour exploiter les fonctionnalités de Hopper
- Le simple fait de réécrire FlashAttention pour utiliser ces nouvelles fonctionnalités fait passer les performances du forward pass FP16 d’environ 350 TFLOPS avec FlashAttention-2 à 540–570 TFLOPS
Chevauchement de GEMM et softmax grâce à l’asynchronisme
- Les principales opérations de l’attention sont les GEMM entre Q-K et P-V, ainsi que le softmax
- Sur les accélérateurs modernes, les opérations autres que matmul sont beaucoup plus lentes que les matmul, et les fonctions spéciales comme l’exponentielle du softmax sont traitées par des unités distinctes de celles du floating point multiply-add ou du matrix multiply-add
- Le H100 SXM5 fournit 989 TFLOPS en matrix multiply FP16, mais le débit des fonctions spéciales n’est que de 3,9 TFLOPS, soit 256 fois moins
- Avec une dimension de tête de 128, même si les FLOPS de matmul sont 512 fois plus nombreux que ceux de l’exponentielle, l’exponentielle peut représenter 50 % du temps par rapport au matmul
- En FP8, les FLOPS de matmul doublent, mais la vitesse de l’exponentielle reste inchangée ; exécuter matmul et softmax en parallèle devient donc encore plus important
-
Ping-pong scheduling entre warpgroups
- Le warp scheduler du GPU effectue automatiquement une partie de l’overlap en exécutant d’autres warps pendant que certains attendent les résultats de GEMM
- FlashAttention-3 utilise des barrières de synchronisation pour mieux chevaucher manuellement le GEMM et le softmax de deux warpgroups
- Le warpgroup 1 exécute d’abord le GEMM1 d’une itération et le GEMM0 de l’itération suivante
- Ensuite, pendant que le warpgroup 2 exécute le GEMM, le warpgroup 1 traite le softmax
- Ce ping-pong schedule consiste à cacher le softmax derrière le temps d’exécution du GEMM de l’autre warpgroup
- En pratique, le scheduling n’est pas aussi parfaitement net que dans le schéma, mais il fait passer le forward pass d’attention FP16 d’environ 570 TFLOPS à 620 TFLOPS pour une dimension de tête de 128 et une longueur de séquence de 8K
-
Overlap au sein d’un warpgroup
- Au sein d’un même warpgroup, il est également possible d’exécuter une partie du softmax pendant que le GEMM de ce warpgroup est en cours
- Ce pipelining fait passer le débit du forward d’attention FP16 d’environ 620 TFLOPS à 640–660 TFLOPS
- En contrepartie, il faut conserver simultanément les accumulateurs GEMM et les entrées/sorties du softmax, ce qui augmente la pression sur les registres
- Globalement, cette technique offre un compromis avantageux
Basse précision FP8 et incoherent processing
- Les activations des LLM peuvent contenir des outliers dont la magnitude est beaucoup plus élevée que celle des autres features
- Ces outliers compliquent la quantification et augmentent fortement l’erreur de quantification
- FlashAttention-3 exploite l’incoherent processing utilisé dans la littérature sur la quantification, comme QuIP
- Il multiplie les queries et les keys par une matrice orthogonale aléatoire afin de disperser les outliers et de réduire les erreurs de quantification
- L’implémentation utilise une transformée de Hadamard avec des signes aléatoires
- Si l’on note
dla dimension de tête, elle peut être appliquée à chaque tête d’attention en O(d log d) au lieu de O(d²) - La transformée de Hadamard étant memory-bandwidth bound, elle peut être fusionnée avec l’opération précédente également memory-bandwidth bound, comme le rotary embedding, sans coût supplémentaire
- Si l’on note
- Dans une expérience où Q, K et V sont générés selon une loi normale standard et où de grandes magnitudes sont ajoutées à 0,1 % des entrées pour simuler des outliers, l’incoherent processing réduit l’erreur de quantification de 2,6×
Benchmarks et disponibilité
- FlashAttention-3 est comparé non seulement à FlashAttention-2, mais aussi aux implémentations Triton et cuDNN qui utilisent déjà les nouvelles fonctionnalités matérielles des GPU Hopper
- En FP16, il affiche une accélération d’environ 1,6 à 1,8× par rapport à FlashAttention-2
- En FP8, il atteint près de 1,2 PFLOPS
- Le dépôt GitHub de FlashAttention-3 est public
- L’article de recherche est également disponible dans le même dépôt flash-attention
Optimisations restantes et intégration future
- L’article inclut, en plus des éléments abordés dans le billet de blog, des optimisations comme les séquences de longueur variable, les persistent kernels et la transposition in-kernel pour FP8
- Concevoir l’algorithme en fonction du matériel d’exécution permet d’importants gains d’efficacité et ouvre de nouvelles capacités de modèles, comme les longs contextes
- Les travaux futurs incluent l’optimisation de l’inférence des LLM et la généralisation des techniques à d’autres architectures matérielles
- FlashAttention-3 devrait être intégré dans une future version de PyTorch
1 commentaires
Avis de Hacker News
À en juger par les commentaires dans le code, Tri Dao semble travailler sur FA3 depuis avril 2022, juste après l’annonce de Hopper/H100
Il est assez intéressant qu’il ait fallu plus de deux ans pour que le code soit publié aujourd’hui ; c’est peut-être parce que de meilleures solutions sont en préparation
Les publications récentes de Tri penchent vers les architectures de type SSM et Mamba. FlashAttention a une complexité temporelle quadratique par rapport à la longueur de séquence, mais les algorithmes récents sont sous-quadratiques : ils ne se contentent donc pas de réaliser le même calcul plus efficacement, ils réduisent fortement la quantité de calcul elle-même
Dao et Gu ont montré cette année, dans un long article, que Mamba/SSM peuvent eux aussi être formulés de façon à bien s’accélérer avec les mêmes primitives matérielles dont profitent les Transformers
Prouver ou réfuter SETH résoudrait aussi le problème P vs NP, donc il est difficile de s’attendre à ce que cela arrive bientôt
La question clé est de savoir si un cas d’usage donné peut supporter ce coût
Je me demande à quel point l’algorithme FlashAttention est lié au matériel
Par exemple, cette annonce dit exploiter les fonctionnalités asynchrones du GPU H100 ; cela semble donc signifier que les cartes qui ne sont pas de la série H ne bénéficient pas de cette accélération
Par ailleurs, la bibliothèque FlashAttention réelle nécessite CUDA, mais l’algorithme semble avoir été porté vers Metal[^0]. Si l’algorithme est proche d’une fonction pure, on pourrait penser qu’il devrait être implémentable sur n’importe quel GPU/framework de machine learning
[0]: https://github.com/philipturner/metal-flash-attention
Pour les versions récentes, cela dépend du niveau d’abstraction. ThunderKittens[0] offre, comme ce qui est décrit dans l’article, un gain d’environ 1,3× à 2× par rapport à FA2 tout en restant relativement applicable de manière générale sur les GPU
Chaque nouveau matériel peut avoir des fonctionnalités spécifiques permettant d’en tirer des performances supplémentaires. En général, les fournisseurs adoptent les fonctionnalités qui les placent devant les autres, mais comme on le voit déjà avec CUDA, les API et bibliothèques se fragmentent
[0]: https://hazyresearch.stanford.edu/blog/2024-05-12-tk
J’aimerais poser la question aux spécialistes des compilateurs. Y a-t-il une chance qu’un compilateur découvre de lui-même des optimisations comme FlashAttention ? TVM et tinygrad semblent aller dans cette direction, mais j’ai du mal à croire que ce soit possible
Cela dit, le coût est élevé, donc il faut mettre en cache les résultats de cette exploration
L’optimisation par e-graphs semble bien adaptée à ce domaine. Mais elle exige un changement de paradigme important dans la façon de traiter les passes d’optimisation, si bien qu’elle n’a quasiment pas été déployée en dehors de quelques outils de niche. Par exemple, elle s’accorde mal avec les graphes d’appels traditionnels : pour déployer des e-graphs au-delà et entre les blocs de base et les boucles for, il faut fortement modifier le flot de contrôle, et
breakainsi quereturnne sont pas pris en chargeJe ne sais pas vraiment jusqu’où va l’état de l’art en optimisation de compilateurs en matière de placement des données et de maximisation de l’utilisation du processeur
J’ai vu autrefois une vidéo sur l’optimisation qui expliquait qu’une petite optimisation avait bien accéléré le programme, mais que son effet restait minime par rapport aux variations de vitesse dues aux différences de placement mémoire causées par cette optimisation, voire par des modifications aléatoires
Cette présentation portait davantage sur la distinction du signal dans le bruit, mais ce bruit lui-même indique que les compilateurs ne gèrent pas encore bien des formes bien plus simples que le problème évoqué ici
Rien que l’architecture CPU/mémoire, où les caches et les schémas d’accès influencent les performances, est complexe ; si l’on y ajoute l’architecture GPU, cela semble être un terrain encore largement inexploré
Ce sera peut-être possible un jour. Comme on parle d’IA, la question se pose aussi de savoir si une IA suffisamment intelligente pourrait le faire, mais tout dépend du sens de « suffisamment »
Comme test de très haut niveau pour un modèle d’IA, on pourrait imaginer lui donner quelque chose comme micrograd et lui demander de créer, en conservant la même interface, quelque chose de plus rapide que torch. On n’en est pas encore du tout là, mais ce serait intéressant si cela devenait possible
TVM, je peux le comprendre. À strictement parler, il fait autre chose, mais c’est un domaine assez proche
En revanche, je ne vois pas pourquoi tinygrad donne cette impression
Si quelqu’un veut porter cela vers ROCm / AMD MI300x, contactez hello@hotaisle.xyz. Je ne vous enverrai absolument aucun spam
Je peux fournir du temps de calcul pour ce travail
Sur une 4090, l’implémentation Triton de l’attention en FP8 pourrait apporter un gain de vitesse : https://triton-lang.org/main/getting-started/tutorials/06-fused-attention.html
C’est l’une des améliorations les plus importantes pour l’IA dans son ensemble. Elle permet de faire plus, plus vite, avec le même matériel, et apporte un bénéfice presque sans compromis à la plupart des utilisateurs d’IA
Je me demande pourquoi FlashAttention est environ 5 fois plus lent avec un masquage variable que sans. Si la prise en charge du masquage n’est pas bonne, les gains d’optimisation disparaissent presque
Ce serait bien qu’un expert réponde à quelques questions :)
FlashAttention est-il un remplacement drop-in de l’opération d’attention des LLM ? Peut-on l’utiliser partout où une opération d’« attention » est employée, ou faut-il entraîner séparément le LLM pour utiliser FA ?
Quel rapport FA entretient-il avec des stratégies comme GQA ou l’attention à fenêtre glissante ? S’agit-il de concepts orthogonaux, ou faut-il une implémentation FA distincte pour chaque stratégie ?
Récemment, llama.cpp a ajouté la prise en charge de FlashAttention : cela signifie-t-il qu’il a commencé à utiliser des choses comme les kernels CUDA fournis par FlashAttention ?
Enfin, cet article compare FlashAttention et Triton. Triton n’est-il pas une sorte de couche d’abstraction ? Ne peut-on pas implémenter FA avec Triton ? Je ne comprends pas bien l’expression « FlashAttention contre Triton »
https://github.com/Dao-AILab/flash-attention
FlashAttention est une méthode pour calculer la partie
Softmax(QK^T)Vde l’attention, tandis que GQA est une méthode pour calculer les matrices Q, K et V. Pour l’attention à fenêtre glissante, j’en suis moins sûr, mais il s’agit de modifier le masque d’attention qui contrôle quelles requêtes peuvent voir quelles clésJe n’ai pas utilisé llama.cpp, mais l’explication selon laquelle il aurait commencé à utiliser des kernels CUDA semble globalement correcte
La dernière question fait référence à une implémentation de FlashAttention précédemment écrite en Triton
Je suis curieux, car l’article dit que des opérations comme sigmoid sont très lentes
Les LLM modernes utilisent beaucoup de fonctions d’activation intégrant sigmoid ou Softmax, comme SiLU, Swish ou SOLU
ReLU entraîne-t-il moins de perte de performances ? Si oui, vaudrait-il mieux revenir au bon vieux ReLU ?