FlashAttention-3: Schnellere und präzisere Attention durch Asynchronität und geringe Präzision
(together.ai)- Der Attention-Engpass von Transformern hat die Trainings- und Inferenzgeschwindigkeit von LLMs mit langem Kontext begrenzt, und FlashAttention-3 ist eine neue Version, die dies mithilfe von Hopper-GPU-Funktionen stärker reduzieren soll
- Der Kern besteht darin, die Asynchronität von Tensor Core und TMA zu nutzen, um Berechnung und Datenbewegung zu überlappen, und matmul und softmax verschränkt anzuordnen, um GPU-Leerlaufzeiten zu verringern
- Auf H100 erreichte FlashAttention-2 nur 35 % der theoretischen maximalen FLOPS, FlashAttention-3 kommt in FP16 jedoch auf bis zu 740 TFLOPS, also bis zu 75 % des H100-Theoriewerts
- Bei niedriger FP8-Präzision vergrößern Ausreißer in LLM-Aktivierungen die Fehler, daher senkt incoherent processing auf Basis der Hadamard-Transformation den Fehler gegenüber einer FP8-Attention-Basislinie um das 2,6-Fache
- FlashAttention-3 wurde auf GitHub veröffentlicht, und je stärker die Attention-Kosten sinken, desto größer wird der Spielraum für längere Kontexte und effizienteres LLM-Training sowie effizientere Inferenz
Ziele und Leistung von FlashAttention-3
- Attention ist die Kernschicht von Transformern, wird aber bei großen Sprachmodellen und Anwendungen mit langem Kontext zum zentralen Engpass
- FlashAttention und FlashAttention-2 haben einen Ansatz etabliert, der Attention durch geringere GPU-Speicher-Lese- und Schreibzugriffe beschleunigt; die meisten Bibliotheken nutzen ihn heute zur Beschleunigung von Transformer-Training und -Inferenz
- Dieser Ansatz hat dazu beigetragen, dass die Kontextlänge von LLMs in den letzten zwei Jahren von 2–4K bei GPT-3 und OPT auf 128K bei GPT-4 und 1M bei Llama 3 gestiegen ist
- FlashAttention-2 erreichte auf H100-GPUs nur 35 % der theoretischen maximalen FLOPS, doch FlashAttention-3 steigert dies durch neue Funktionen der Hopper-GPU
- Die veröffentlichten Leistungswerte von FlashAttention-3 sind wie folgt
- In FP16 1,5- bis 2,0-mal schneller als FlashAttention-2
- Bis zu 740 TFLOPS in FP16
- 75 % Auslastung der theoretischen maximalen FLOPS von H100
- Nahezu 1,2 PFLOPS in FP8
- 2,6-mal geringerer Fehler gegenüber einer FP8-Attention-Basislinie
Rückblick auf den FlashAttention-Ansatz
- FlashAttention beschleunigt Attention, indem die Reihenfolge der Attention-Berechnung neu angeordnet wird und Tiling sowie Neuberechnung genutzt werden; zugleich sinkt der Speicherbedarf in Bezug auf die Sequenzlänge von quadratisch auf linear
- Eingabeblöcke werden aus HBM in SRAM geladen, Attention wird auf diesen Blöcken ausgeführt, und anschließend wird die Ausgabe in HBM aktualisiert
- Da die große zwischengelagerte Attention-Matrix nicht in HBM geschrieben wird, verringern sich Speicher-Lese- und Schreibzugriffe, was in der tatsächlichen Laufzeit 2- bis 4-fache Beschleunigung ermöglichen kann
- Wenn Tiling und Softmax-Rescaling zusammen eingesetzt werden, lässt sich blockweise verarbeiten und dennoch ohne Approximation die korrekte Ausgabe erhalten
Hopper-GPU-Funktionen: WGMMA, TMA, FP8
- FlashAttention-2 kann auf der Ampere-A100-GPU bis zu 70 % der theoretischen maximalen FLOPS erreichen, nutzt die neuen Funktionen der Hopper-GPU jedoch nicht ausreichend aus
- FlashAttention-3 verwendet drei Hopper-Funktionen
- WGMMA: die Warpgroup-Matrix-Multiply-Accumulate-Funktion, die die neuen Tensor Cores von Hopper nutzt und einen höheren Durchsatz als
mma.syncvon Ampere bietet - TMA: eine dedizierte Hardwareeinheit zur Beschleunigung des Datentransfers zwischen global memory und shared memory, die Indexberechnung und out-of-bound predication übernimmt und so den Registerverbrauch senkt
- FP8: kann den Tensor-Core-Durchsatz gegenüber FP16 verdoppeln, bringt aber wegen der geringeren Bitzahl zur Darstellung von Fließkommazahlen einen Genauigkeits-Trade-off mit sich
- WGMMA: die Warpgroup-Matrix-Multiply-Accumulate-Funktion, die die neuen Tensor Cores von Hopper nutzt und einen höheren Durchsatz als
- FlashAttention-3 nutzt die Abstraktionen von NVIDIA CUTLASS, um Hopper-Funktionen einzusetzen
- Schon das reine Neuschreiben von FlashAttention zur Nutzung dieser neuen Funktionen verbessert die FP16-Forward-Pass-Leistung von etwa 350 TFLOPS bei FlashAttention-2 auf 540–570 TFLOPS
Überlappung von GEMM und Softmax durch Asynchronität
- Die Hauptoperationen von Attention sind GEMM zwischen Q-K und P-V sowie softmax
- Auf modernen Beschleunigern sind nicht-matmul-Operationen viel langsamer als matmul, und Spezialfunktionen wie die Exponentialfunktion in softmax werden auf anderen Einheiten verarbeitet als floating point multiply-add oder matrix multiply-add
- H100 SXM5 bietet bei FP16-Matrix-Multiplikation 989 TFLOPS, während der Durchsatz für Spezialfunktionen bei 3,9 TFLOPS liegt, also 256-mal niedriger
- Bei einer Head-Dimension von 128 kann die Exponentialfunktion trotz eines 512-fach höheren matmul-FLOPS-Werts zeitlich 50 % gegenüber matmul ausmachen
- In FP8 wird matmul doppelt so schnell, die Exponentialgeschwindigkeit bleibt aber gleich, weshalb die parallele Ausführung von matmul und softmax noch wichtiger wird
-
Pingpong-Scheduling zwischen Warpgroups
- Der Warp-Scheduler der GPU führt automatisch einen gewissen Overlap aus, indem er andere Warps ausführt, während einige Warps auf GEMM-Ergebnisse warten
- FlashAttention-3 nutzt Synchronisationsbarrieren, um GEMM und softmax zweier Warpgroups manuell stärker zu überlappen
- Warpgroup 1 führt zuerst GEMM1 einer Iteration und GEMM0 der nächsten Iteration aus
- Danach verarbeitet Warpgroup 1 softmax, während Warpgroup 2 GEMM ausführt
- Dieses Pingpong-Schedule versteckt softmax hinter der GEMM-Ausführungszeit der anderen Warpgroup
- Das tatsächliche Scheduling ist nicht ganz so sauber wie im Diagramm, erhöht aber beim FP16-Attention-Forward-Pass mit Head-Dimension 128 und Sequenzlänge 8K den Durchsatz von etwa 570 TFLOPS auf 620 TFLOPS
-
Overlap innerhalb einer Warpgroup
- Auch innerhalb einer einzelnen Warpgroup kann ein Teil von softmax ausgeführt werden, während GEMM dieser Warpgroup läuft
- Dieses Pipelining steigert den FP16-Attention-Forward-Durchsatz von etwa 620 TFLOPS auf 640–660 TFLOPS
- Dafür müssen jedoch GEMM-Akkumulatoren und Softmax-Ein- und Ausgaben gemeinsam gehalten werden, was den Registerdruck erhöht
- Insgesamt bietet diese Technik einen vorteilhaften Trade-off
Niedrige FP8-Präzision und incoherent processing
- LLM-Aktivierungen können Ausreißer enthalten, deren Magnitude deutlich größer ist als die der übrigen Features
- Ausreißer erschweren die Quantisierung und vergrößern den Quantisierungsfehler stark
- FlashAttention-3 nutzt incoherent processing, wie es in Quantisierungsarbeiten wie QuIP verwendet wird
- Dazu werden query und key mit einer zufälligen orthogonalen Matrix multipliziert, um Ausreißer zu verteilen und Quantisierungsfehler zu verringern
- In der Implementierung wird eine Hadamard-Transformation mit zufälligem Vorzeichen verwendet
- Wenn die Head-Dimension
dist, kann dies pro Attention-Head in O(d log d) statt O(d²) ausgeführt werden - Die Hadamard-Transformation ist memory-bandwidth-bound; wird sie mit einer vorausgehenden Operation fusioniert, die ebenfalls memory-bandwidth-bound ist, etwa Rotary Embedding, lässt sie sich ohne Zusatzkosten ausführen
- Wenn die Head-Dimension
- In einem Experiment, in dem Q, K und V aus einer Standardnormalverteilung erzeugt und 0,1 % der Einträge mit großer Magnitude versehen wurden, um Ausreißer zu simulieren, verringerte incoherent processing den Quantisierungsfehler um das 2,6-Fache
Benchmarks und Veröffentlichungsstatus
- FlashAttention-3 wurde nicht nur mit FlashAttention-2 verglichen, sondern auch mit Triton- und cuDNN-Implementierungen, die bereits neue Hardwarefunktionen der Hopper-GPU nutzen
- In FP16 zeigt sich gegenüber FlashAttention-2 eine Beschleunigung von etwa 1,6- bis 1,8-mal
- In FP8 werden nahezu 1,2 PFLOPS erreicht
- Das FlashAttention-3-GitHub-Repository wurde veröffentlicht
- Das Paper ist ebenfalls im selben flash-attention-Repository verfügbar
Weitere Optimierungen und künftige Integration
- Das Paper enthält neben den im Blog behandelten Inhalten auch Optimierungen wie variable length sequence, persistent kernel und in-kernel transpose für FP8
- Wenn Algorithmen passend zur Ausführungshardware entworfen werden, können große Effizienzgewinne und neue Modellfunktionen wie längere Kontexte erschlossen werden
- Zu den künftigen Arbeiten gehören die Optimierung der LLM-Inferenz und die Verallgemeinerung der Techniken auf andere Hardwarearchitekturen
- Es wird erwartet, dass FlashAttention-3 in zukünftige PyTorch-Releases integriert wird
1 Kommentare
Hacker-News-Kommentare
Wenn man sich die Code-Kommentare ansieht, wirkt es so, als hätte Tri Dao bereits im April 2022, direkt nach der Ankündigung von Hopper/H100, an FA3 gearbeitet.
Es ist etwas interessant, dass es bis zur heutigen Veröffentlichung des Codes mehr als zwei Jahre gedauert hat; möglicherweise liegt das daran, dass noch bessere Lösungen in Vorbereitung sind.
Tris jüngere Paper-Historie neigt sich eher zu SSM- und Mamba-artigen Architekturen. FlashAttention hat in Bezug auf die Sequenzlänge quadratische Zeitkomplexität, während neuere Algorithmen quasisubquadratisch sind, also nicht nur dieselbe Berechnung effizienter ausführen, sondern den Rechenaufwand selbst deutlich reduzieren.
Dao und Gu zeigten dieses Jahr in einem langen Paper, dass sich Mamba/SSM ebenfalls so formulieren lassen, dass sie gut durch dieselben Hardware-Primitivoperationen beschleunigt werden können, von denen Transformer profitieren.
Würde man SETH beweisen oder widerlegen, wäre damit auch das P-vs-NP-Problem gelöst, daher ist kaum zu erwarten, dass das bald geschieht.
Entscheidend ist, ob ein bestimmter Anwendungsfall diese Kosten tragen kann.
Ich frage mich, wie stark der FlashAttention-Algorithmus an die Hardware gebunden ist.
In dieser Ankündigung heißt es zum Beispiel, dass die asynchronen Funktionen der H100-GPU genutzt werden; das scheint also zu bedeuten, dass man diesen Geschwindigkeitsgewinn auf Karten außerhalb der H-Serie nicht bekommt.
Außerdem benötigt die eigentliche FlashAttention-Bibliothek CUDA, aber der Algorithmus scheint nach Metal portiert worden zu sein[^0]. Wenn der Algorithmus eher etwas wie eine reine Funktion ist, müsste er sich dann nicht auf jeder GPU bzw. in jedem Machine-Learning-Framework implementieren lassen?
[0]: https://github.com/philipturner/metal-flash-attention
Bei neueren Versionen hängt es vom Abstraktionsniveau ab. ThunderKittens[0] liefert, ähnlich wie im Beitrag beschrieben, gegenüber FA2 etwa einen 1,3- bis 2-fachen Geschwindigkeitsgewinn und ist dabei relativ allgemein auf GPUs anwendbar.
Mit jeder neuen Hardware kann es hardwarespezifische Funktionen geben, die zusätzliche Leistung herausholen. Üblicherweise übernehmen Vendoren Funktionen, die anderen einen Vorsprung verschaffen, aber wie schon bei CUDA werden APIs und Bibliotheken dabei fragmentiert.
[0]: https://hazyresearch.stanford.edu/blog/2024-05-12-tk
Ich würde gern die Compiler-Leute fragen: Besteht die Möglichkeit, dass ein Compiler Optimierungen wie FlashAttention selbst findet? TVM und tinygrad scheinen in diese Richtung zu gehen, aber ich finde es schwer zu glauben, dass das möglich ist.
Da die Kosten dafür jedoch hoch sind, muss man die Ergebnisse dieser Suche cachen.
e-graph-Optimierung scheint für diesen Bereich gut geeignet zu sein. Dafür wäre allerdings ein großer Paradigmenwechsel bei der Verarbeitung von Optimierungs-Pässen nötig, weshalb es abgesehen von einigen Nischen-Tools kaum verbreitet wurde. Es passt zum Beispiel nicht gut zu traditionellen Aufrufgraphen; um e-graphs über und zwischen Basic Blocks und for-Schleifen hinweg einzusetzen, müsste man den Kontrollfluss stark verändern, und
breaksowiereturnwerden ebenfalls nicht unterstützt.Ich weiß allerdings nicht genau, wo der aktuelle Stand der Compiler-Optimierung im Hinblick auf Datenlayout und die Maximierung der Prozessorauslastung liegt.
Ich habe einmal einen Vortrag über Optimierung gesehen, in dem kleine Optimierungen zwar die Geschwindigkeit erhöhten, ihr Effekt aber gering war im Vergleich zu den Geschwindigkeitsschwankungen durch Unterschiede im Speicherlayout, die durch diese Optimierungen oder sogar durch zufällige Änderungen entstanden.
Der Vortrag konzentrierte sich eher darauf, das Signal im Rauschen zu erkennen, aber dieses Rauschen selbst ist ein Hinweis darauf, dass Compiler hier selbst mit viel einfacheren Formen des angesprochenen Problems nicht besonders gut umgehen können.
Schon die CPU-/Speicherarchitektur ist komplex, wenn es darum geht, wie Cache und Zugriffsmuster die Geschwindigkeit beeinflussen; nimmt man noch die GPU-Architektur dazu, ist das Gebiet wohl noch weitgehend unerforscht.
Vielleicht wird es eines Tages möglich sein. Da es um KI geht, stellt sich auch die Frage, ob eine hinreichend kluge KI das erledigen könnte, aber das hängt davon ab, was „hinreichend“ bedeutet.
Als Test auf sehr hohem Niveau für ein KI-Modell könnte man sich vorstellen, ihm etwas wie micrograd zu geben und zu verlangen, bei gleicher Schnittstelle etwas zu bauen, das schneller ist als torch. Davon sind wir noch nicht einmal annähernd dort, aber falls es möglich wird, wäre das interessant.
TVM erscheint mir nachvollziehbar. Genau genommen macht es etwas anderes, ist aber ziemlich nah dran.
Bei tinygrad weiß ich allerdings nicht, warum das diesen Eindruck vermittelt hat.
Falls jemand das auf ROCm / AMD MI300x portieren möchte, bitte bei hello@hotaisle.xyz melden. Ich sende garantiert keinen Spam.
Ich kann Rechenzeit für diese Arbeit spenden.
Auf einer 4090 könnte man mit der Triton-Implementierung von FP8-Attention trotzdem einen Geschwindigkeitsschub bekommen: https://triton-lang.org/main/getting-started/tutorials/06-fused-attention.html
Das ist eine der wichtigsten Verbesserungen in der gesamten KI. Sie ermöglicht es, auf derselben Hardware mehr und schneller zu tun, und bringt den meisten KI-Nutzern fast ohne Kompromisse Vorteile.
Ich frage mich, warum FlashAttention mit variabler Maskierung ungefähr 5-mal langsamer ist als ohne. Wenn gute Unterstützung für Maskierung fehlt, verschwindet der Optimierungseffekt fast vollständig.
Es wäre schön, wenn ein Experte ein paar Fragen beantworten könnte :)
Ist FlashAttention einfach ein Drop-in-Ersatz für die Attention-Berechnung in LLMs? Kann man es überall verwenden, wo die „Attention“-Operation eingesetzt wird, oder muss ein LLM eigens darauf trainiert werden, FA zu verwenden?
In welchem Verhältnis steht FA zu Strategien wie GQA oder Sliding-Window-Attention? Sind das zueinander orthogonale Konzepte, oder braucht jede Strategie eine eigene FA-Implementierung?
Kürzlich hat
llama.cppUnterstützung für FlashAttention hinzugefügt — heißt das, dass dort nun etwas wie die von FlashAttention bereitgestellten CUDA-Kernels verwendet werden?Und zuletzt: In diesem Artikel werden FlashAttention und Triton verglichen. Ist Triton nicht eher so etwas wie eine Abstraktionsschicht? Kann man FA nicht in Triton implementieren? Die Formulierung „FlashAttention vs. Triton“ ist mir nicht ganz klar
https://github.com/Dao-AILab/flash-attention
FlashAttention ist eine Methode zur Berechnung des
Softmax(QK^T)V-Teils der Attention, während GQA eine Methode zur Berechnung der Q-, K- und V-Matrizen ist. Sliding-Window-Attention ist, soweit ich nicht ganz sicher bin, eine Änderung der Attention-Maske, die steuert, welche Queries welche Keys sehen können.Ich habe
llama.cppzwar nicht verwendet, aber die Beschreibung, dass dort nun CUDA-Kernels übernommen werden, scheint im Großen und Ganzen zuzutreffen.Zur letzten Frage: Gemeint ist eine frühere FlashAttention-Implementierung, die in Triton geschrieben wurde.
Weil in diesem Artikel gesagt wird, dass Operationen wie sigmoid sehr langsam sind, frage ich mich Folgendes:
Moderne LLMs verwenden oft Aktivierungsfunktionen wie SiLU, Swish und SoLU, in denen sigmoid oder Softmax enthalten sind.
Hat ReLU geringere Performance-Einbußen? Falls ja, wäre es dann vielleicht besser, wieder zum guten alten ReLU zurückzukehren?