← Terug naar artikelen
August 4, 2026
5 min leestijd

Is een context van een hele dag beter dan een context van tien minuten? Flitsaandacht en de vraag over de reekslengte

Is een context van een hele dag beter dan een context van tien minuten? Flitsaandacht en de vraag over de reekslengte
#deep-learning
#attention
#Flash-Attention
#GPU
#optimization

Dit is de vraag die dit artikel moet beantwoorden: Als een transformator een hele handelsdag zou kunnen volgen met een resolutie van één seconde in plaats van een tijdsbestek van tien minuten, zou hij dan beter kunnen voorspellen?

Tot voor kort kon je dat niet eens vragen. Standaard aandachtsbehoeften O(N2)\mathcal{O}(N^2) geheugen, dus een dag van 23.400 stappen bij 12 heads in float16 vereist ongeveer 12,9 GB alleen al voor de scorematrix - meer dan de modelparameters, en meer dan de meeste kaarten je zullen geven. De vraag werd door rekenkunde afgesloten voordat iemand hem kon testen.

Flash Attention (Dao et al., 2022) opent het. Niet door de aandacht te benaderen (het berekent exact hetzelfde resultaat), maar door de berekening te herstructureren zodat deze IO-bewust is, waardoor het verkeer tussen GPU-geheugenniveaus wordt geminimaliseerd. Dat is de werkelijk interessante inhoud hier, en het grootste deel van dit artikel wordt besteed aan hoe het werkt: tegelen, de online-softmax-herhaling, de Θ(N2d2/M)\Theta(N^2 d^2 / M) IO-gebonden en herberekening met achterwaartse verwerking.

Maar het mechanisme is de katalysator, niet de claim. “Langere context is beter” is een empirische uitspraak over markten en de staande positie van deze blog – van Temporal Fusion Transformers, waaruit bleek dat traditionele transformatoren op financiële series overfit en short-lookback recurrent-modellen op hoge frequentie concurrerend blijven – gaat de andere kant op. Het artikel sluit dus af met de meting, niet met het mechanisme.

Waarom aandacht geheugengebonden is

Aandacht berekent softmax(QK/dk)V\text{softmax}(\mathbf{Q}\mathbf{K}^\top / \sqrt{d_k})\mathbf{V} — de primitief zelf, in een handelscontext, wordt behandeld in Temporal Fusion Transformers for Multi-Horizon Portfolio Forecasting. Het hele probleem bestaat uit één lijn daarvan: de tussenscorematrix S=QK/dk\mathbf{S} = \mathbf{Q}\mathbf{K}^\top/\sqrt{d_k} is N×NN \times N, het wordt in het geheugen geschreven, teruggelezen voor de softmax, opnieuw geschreven en opnieuw gelezen voor de laatste matmul - en het moet worden bewaard voor backpropagatie.

De rekenkundige intensiteit van de aandacht is min(d,N)\approx \min(d, N), dus ongeveer 64 FLOP/byte bij d=64d = 64 — ruim links van het nokpunt van de A100. Het bevindt zich op het schuine bandbreedteplafond, niet op het vlakke rekenplafond: de GPU besteedt meer tijd aan verplaatsingen S\mathbf{S} rond dan iets te vermenigvuldigen. Het raamwerk van de daklijn dat hierbij wordt gebruikt – nokpunt, schuin versus plat plafond, en waarom dezelfde redenering bepaalt of een GPU überhaupt de moeite waard is om te kopen – is gebouwd met gemeten getallen in Wanneer de GPU loont.

De geheugenhiërarchie die het algoritme exploiteert

Geheugenniveau Maat Bandbreedte Latentie
HBM (geheugen met hoge bandbreedte) 40-80 GB 2,0 TB/s ~400ns
SRAM (op de chip, gedeeld geheugen) 20MB 19 TB/s ~4ns

SRAM heeft ruwweg 10x de bandbreedte en 100x lagere latentie, bij een duizendste van de capaciteit. Alles wat Flash Attention doet, volgt uit die handel: capaciteit opgeven, bandbreedte en latentie kopen. Dezelfde "herstructureer het algoritme in plaats van hardware te kopen", gemeten op een CPU-backtest, is de backtest-snelheidsladder.

Het Flash Attention-algoritme

Flash Attention verwerkt de aandacht in tegels die zo groot zijn dat ze in SRAM passen, en komt nooit volledig tot uiting N×NN \times N matrix in HBM helemaal niet.

Partitie Q\mathbf{Q} naar binnen Tr=N/BrT_r = \lceil N/B_r \rceil rijblokken en K,V\mathbf{K}, \mathbf{V} naar binnen Tc=N/BcT_c = \lceil N/B_c \rceil kolomblokken, met Br,BcB_r, B_c zo gekozen dat een tegel plus de accumulators op de chip passen. Herhaal voor elk queryblok alle sleutelwaardeblokken:

For each query block Q_i:
    Initialize: O_i = 0, m_i = -inf, l_i = 0    # output, running max, running sum
    For each KV block (K_j, V_j):
        1. Load Q_i, K_j, V_j from HBM to SRAM
        2. Compute S_ij = Q_i @ K_j^T / sqrt(d)  # in SRAM
        3. Compute local max: m_ij = rowmax(S_ij)
        4. Compute P_ij = exp(S_ij - m_ij)        # in SRAM
        5. Compute local sum: l_ij = rowsum(P_ij)
        6. Update running statistics:
           m_new = max(m_i, m_ij)
           l_new = l_i * exp(m_i - m_new) + l_ij * exp(m_ij - m_new)
           O_i = O_i * (l_i * exp(m_i - m_new) / l_new)
                + P_ij @ V_j * (exp(m_ij - m_new) / l_new)
           m_i = m_new, l_i = l_new
    Write O_i to HBM

De online softmax-herhaling

De truc die tegelen mogelijk maakt is online softmax. Een naïeve softmax heeft twee passages over de rij nodig: één om de max te vinden (voor numerieke stabiliteit), één om te exponentiëren en te normaliseren. Twee passages over een rij die u weigert op te slaan is een tegenstrijdigheid - dus Flash Attention houdt statistieken bij en schaalt gaandeweg opnieuw.

Na blokken 1,,j1, \ldots, j:

m(j)=max(m(j1),max(Sij))m^{(j)} = \max(m^{(j-1)}, \max(\mathbf{S}_{ij})) (j)=(j1)em(j1)m(j)+keSijkm(j)\ell^{(j)} = \ell^{(j-1)} \cdot e^{m^{(j-1)} - m^{(j)}} + \sum_k e^{S_{ijk} - m^{(j)}}

en de uitgangsaccumulator wordt gecorrigeerd met dezelfde factor:

Oi(j)=(j1)(j)em(j1)m(j)Oi(j1)+1(j)emijm(j)PijVj\mathbf{O}_i^{(j)} = \frac{\ell^{(j-1)}}{\ell^{(j)}} \cdot e^{m^{(j-1)} - m^{(j)}} \cdot \mathbf{O}_i^{(j-1)} + \frac{1}{\ell^{(j)}} \cdot e^{m_{ij} - m^{(j)}} \cdot \mathbf{P}_{ij}\mathbf{V}_j

Elke keer dat een nieuw blok het lopende maximum verhoogt, wordt de eerder geaccumuleerde uitvoer met terugwerkende kracht opnieuw geschaald em(j1)m(j)e^{m^{(j-1)} - m^{(j)}} – alsof de nieuwe max vanaf het begin bekend was. Het resultaat is algebraïsch identiek aan de softmax met twee doorgangen. In de exacte rekenkunde is dit geen benadering; het is een reassociatie. (Bij eindige precisie is het een ander afrondingspad, wat ertoe doet – zie de nauwkeurigheidscontrole hieronder.)

IO-complexiteit

Dit is de formele verklaring van de overwinning. Flash-aandacht wordt uitgevoerd

Θ(N2d2M)\Theta\left(\frac{N^2 d^2}{M}\right)

HBM-toegangen, waar MM is SRAM-grootte, tegen Θ(Nd+N2)\Theta(Nd + N^2) voor de standaarduitvoering. Merk dat op MM verschijnt in de noemer: hoe groter het kladblok op de chip, hoe minder round-trips. Daarom wordt het algoritme uitgedrukt in termen van de geheugenhiërarchie in plaats van het aantal FLOP's. Voor typisch d=64d = 64 En M100M \approx 100 KB is de verhouding in het voordeel van Flash Attention met ongeveer 5-10x minder toegangen.

Achterwaartse pass: opnieuw berekenen in plaats van opslaan

Voor terugpropagatie door aandacht is normaal gesproken de P\mathbf{P} matrix die de voorwaartse pass net weigerde te behouden. Flash Attention berekent de tegels opnieuw Q,K\mathbf{Q}, \mathbf{K} tijdens de achterwaartse pass, waarbij alleen de uitvoer wordt opgeslagen O\mathbf{O} en de softmax-statistieken (m,)(m, \ell) - beide O(N)\mathcal{O}(N), niet O(N2)\mathcal{O}(N^2). Het ruilt een bescheiden hoeveelheid overtollige rekenkunde in voor de geheugenterm die het hele probleem vormde. Dit is hetzelfde koopje als gradiëntcontrolepunten, toegepast op tegelgranulariteit binnen een enkele operator.

FA2: parallellisme

Flash Attention 2 (Dao, 2023) behield het algoritme en corrigeerde de planning:

  1. Minder niet-matmul FLOP's. FA1 besteedde realtime aan herschalen, max-finding en machtsverheffen - operaties die op CUDA-kernen draaien, niet op tensor-kernen. FA2 stelt het herschalen uit tot het einde van de binnenste lus.
  2. Parallelisme over sequentielengte. FA1 parallelliseert alleen over batch en heads. FA2 parallelliseert ook via queryblokken. Dit is specifiek van belang voor de handelssituatie, waarbij je vaak één zeer lange reeks per asset en een batchgrootte van 1-4 hebt – precies het regime waarbij batch-en-head-parallellisme de GPU uithongert.
  3. Warp-werkpartitionering. Elke warp neemt een andere subset van queryblokken in plaats van een scoreberekening te splitsen en te reduceren over warps, waardoor een cross-warp-reductie wordt verwijderd.

Gerapporteerd resultaat: ~70% van de theoretische piek-FLOP's op de A100 versus ~35% voor FA1.

FA3: Hopper-mechanica

Flash Attention 3 (Dao, Shah, 2024) is architectuurspecifiek voor H100:

  1. Asynchrone warp-specialisatie. Hopper's Tensor Memory Accelerator (TMA) beweegt HBM → SRAM asynchroon. FA3 splitst warps op in producenten die TMA-belastingen uitgeven voor het volgende KV-blok en consumenten die op het huidige blok rekenen, zodat de gegevensbeweging zich achter de rekenkunde verschuilt.
  2. Interleaved matmul en softmax. QiKj\mathbf{Q}_i\mathbf{K}_j^\top één blok draait op tensorkernen, terwijl de softmax van het vorige blok op CUDA-kernen draait - twee verschillende hardware-eenheden, echt gelijktijdig in plaats van in tijd gesneden.
  3. FP8 met incoherente verwerking. H100 doet FP8 met een doorvoersnelheid van 2x FP16. Naïeve KP8-aandacht wordt tenietgedaan door uitschieters; FA3 roteert vectoren willekeurig vóór bloksgewijze kwantisering om de uitbijtergrootte over coördinaten te spreiden, gerapporteerd met een 2,6x lagere numerieke fout dan naïeve FP8.
Versie GPU Gebruik Versnellen versus standaard
FA1 A100 ~35% 2-4x
FA2 A100 ~70% 5-7x
FA3 (FP16) H100 ~75% 3-5x tegen FA2
FA3 (FP8) H100 ~75% 1,6x versus FA3 FP16

Bij causale maskering krijgt handelen korting

Causale maskering is verplicht voor tijdreeksen – het model mag geen rekening houden met de toekomst – en bij betegelen is dit geen extra kostenpost, maar een bespaarde kostenpost. Elke tegel waarvan de sleutels volledig in de toekomst liggen ten opzichte van de zoekopdrachten, wordt ronduit overgeslagen, nooit geladen en nooit berekend, waardoor ongeveer de helft van het werk wordt bespaard. In PyTorch is dit het geval is_causal=True; niets anders is vereist.

De integratie bestaat uit acht regels

Bijna geen enkele code die je nodig hebt, gaat over Flash Attention. Verwissel het expliciete scorematrixpad voor de gefuseerde kernel:

scores = torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(d_head)
scores = scores.masked_fill(causal_mask, float("-inf"))
out = torch.matmul(torch.softmax(scores, dim=-1), v)

out = torch.nn.functional.scaled_dot_product_attention(
    q, k, v,
    dropout_p=self.dropout if self.training else 0.0,
    is_causal=True,
)

Dat is de hele verandering. q, k, v zijn gevormd (batch, heads, seq, head_dim); het causale masker is verdwenen omdat de kernel het bouwt. Voor een compleet geannoteerd PyTorch-handelsmodel om dit in te plaatsen – invoerprojectie, blokken en een 3-klasse omhoog/plat/omlaag-kop – gebruik DeepLOB, en voor een volledige trainingspijplijn zie Temporal Fusion Transformers. Het bouwen van een vierde exemplaar van die steiger hier zou niets leren.

Vereisten: rekencapaciteit >= 8.0 (A100, H100, RTX 3090+), half-precisie-ingangen, PyTorch >= 2.0. Controleer het snelle pad dat daadwerkelijk wordt gebruikt torch.backends.cuda.sdp_kernel diagnostiek en torch.cuda.max_memory_allocated() — SDPA valt stilletjes terug naar de wiskundekernel als een voorwaarde faalt, en een stille terugval lijkt precies op een werkend model dat alleen maar traag is.

De meting: loont de langere context?

Alles hierboven zegt dat een context van 32K of 128K nu betaalbaar is. Het zegt niets over of het nuttig is. Het eerlijke experiment:

Train dezelfde architectuur bij N{512,4096,32768}N \in \{512, 4096, 32768\} met SDPA-Flash op de BTC-serie die elders in deze serie wordt gebruikt, waarbij parameters, optimalisatie en doel vast worden gehouden, zodat de reekslengte de enige variabele is. Meld twee dingen:

  1. Kosten. Gemeten wandklok per tijdperk en torch.cuda.max_memory_allocated() bij elk NN.
  2. Voordeel. Voorspellende prestaties buiten de steekproef versus NN, op een voorwaartse split.

Een eerdere versie van dit artikel bevatte een tabel met geheugencijfers per reekslengte die analytisch was afgeleid van de O(N)\mathcal{O}(N) activatie formule. Die rijen zijn verwijderd: ze zijn nooit gemeten en ze waren het niet eens met de eigen geheugenbudgetberekeningen van het artikel. Een afgeleid getal dat in een resultatentabel wordt weergegeven, is een verzonnen resultaat, en deze blog verzendt deze niet.

De interessante eigenschap van dit experiment is dat het in beide richtingen publiceerbaar is. Als out-of-sample prestaties monotoon stijgen NN, dat het hele lange-contextprogramma rechtvaardigt. Als het op een paar duizend stappen blijft liggen, of degradeert, is dat een sterker stuk – een aanvulling op het eerlijke negatieve – en het zou betekenen dat de geheugenmuur nooit de bindende beperking is geweest voor de handel in transformatoren.

Meer context is meer capaciteit, dus meer overfitting oppervlak

Er is een specifieke reden om een vlakke of negatieve uitkomst te verwachten. Tijdelijke fusietransformatoren documenteert al dat traditionele transformatoren die naïef zijn toegepast op financiële reeksen overfit zijn – ze missen temporele inductieve vertekeningen, en recurrente modellen met een korte terugblik blijven op hoge frequentie concurrerend. Het uitbreiden van de context van 512 naar 32.768 stappen voegt geen informatie toe die evenredig is aan de lengte; de marginale 32.000ste vertraging van een bijna efficiënte prijsreeks levert heel weinig op. Wat het op betrouwbare wijze toevoegt, is de waarde van de parameters die moeten passen.

Dus het vegen voorbij NN moet worden behandeld zoals het is: een zoektocht naar modellen, met dezelfde machinerie die deze blog op elke andere zoekopdracht toepast. Drie reekslengtes maal wat er verder varieert, is een proeftelling, en de winnaar moet een Deflated Sharpe Ratio behalen die is berekend op basis van die proeftelling en een PBO-poort, en niet alleen zijn buren verslaan. Anders is "lange context-overwinning" niet te onderscheiden van het kiezen van het beste uit drie luidruchtige runs.

Een nauwkeurigheidscontrole, want "exact" is veel werk

Flash-aandacht is exact in exacte rekenkunde. De aanbeveling die eraan is verbonden – uitvoeren in fp16 of bf16, en op H100 overweeg FP8 – is dat niet. Dat zijn afzonderlijke claims en de tweede domineert in de praktijk: het opnieuw associëren van een bedrag en het terugbrengen naar de halve nauwkeurigheid zijn beide verstoringen, en het artikel dat de bestelgarantie introduceerde, mag dan niet met de precisie zwaaien.

De blog beschikt al over het juiste instrument. De GPU-precisieval bepaalt de standaard: lage precisie waarschuwt je niet, het retourneert plausibele onzin, en je bewijst de juistheid met een pariteitsorakel op een stroomafwaartse discrete hoeveelheid – handelstellingen – niet door op de curven te letten. Hier toegepast:

  • Bereken de aandacht met SDPA-Flash in bf16 en met een fp64-referentie-implementatie op identieke ingangen; rapporteer max relatieve fout op de uitgangstensor.
  • Breng dit door naar de beslissing: rapporteer voor een model dat een label omhoog/vlak/omlaag afgeeft hoeveel labels er tussen de twee paden omdraaien, als een fractie van het totale aantal beslissingen.

Een klein, beperkt, verklaarbaar meningsverschil is de handtekening van een correct, snel pad. Een onbegrensde aanbeveling betekent dat de FP8-aanbeveling nooit veilig was voor dit model. Geen van beide nummers is bekend totdat het wordt uitgevoerd.

Wanneer moet je ernaar grijpen?

Gecomprimeerd tot de beslissing, die dezelfde vorm heeft als de GPU-beslissingsgids:

  • Meer dan ~2K tijdstappen op een CUDA GPU: ja, onvoorwaardelijk. Het is een wijziging van één regel die exacte uitvoer oplevert, en de winst groeit met NN. Er is geen scenario waarin je het gematerialiseerde wilt hebben N×NN \times N pad in plaats daarvan.
  • Onder ~512 tijdstappen, op CPU, of met niet-aandachtsarchitecturen (CNN's, SSM's zoals Mamba): irrelevant. Links van de rand vormen de vaste overheadkosten de hele kosten en aandacht was nooit uw knelpunt.
  • De bovenstaande drempels zijn folklore, geen metingen — ze komen uit de algemene literatuur, en de crossover op uw eigen model en kaart is een benchmark van tien regels. Voer het uit in plaats van te vertrouwen op de ronde getallen.

Conclusie

Flash-aandacht is een schoon en echt belangrijk resultaat: door de geheugenhiërarchie te respecteren en de softmax opnieuw te associëren, berekent het de exacte aandacht met O(N)\mathcal{O}(N) geheugen in plaats van O(N2)\mathcal{O}(N^2), en de Θ(N2d2/M)\Theta(N^2 d^2 / M) IO bound legt precies uit waarom. Het adopteren ervan in een handelstransformator is een verandering van één regel zonder nauwkeurigheidskosten in exacte rekenkunde en een grote geheugenwinst.

Wat het niet doet, is de vraag bovenaan beantwoorden. Het verandert "een context van een hele dag is onmogelijk" in "een context van een hele dag is goedkoop", wat een verandering in de kosten van het experiment is, en niet het resultaat ervan. De herinneringsmuur die naar beneden komt, is een uitnodiging om te meten, en de meting maakt dit van een papieren samenvatting tot een bevinding.

Referenties

  1. Dao, T., Fu, D.Y., Ermon, S., Rudra, A., Re, C. "FlashAttention: snelle en geheugenefficiënte exacte aandacht met IO-bewustzijn." NeurIPS (2022). arXiv:2205.14135
  2. Dao, T. "FlashAttention-2: snellere aandacht met beter parallellisme en werkpartitionering." ICLR (2024). arXiv:2307.08691
  3. Dao, T., Shah, J. "FlashAttention-3: snelle en nauwkeurige aandacht met asynchronie en lage precisie." NeurIPS (2024). arXiv:2407.08608
  4. Vaswani, A., et al. "Aandacht is alles wat je nodig hebt." NeurIPS (2017).
  5. Milakov, M., Gimelshein, N. "Online normalisatieberekening voor softmax." arXiv:1805.02867 (2018).
Disclaimer: De informatie in dit artikel is uitsluitend bedoeld voor educatieve en informatieve doeleinden en vormt geen financieel, beleggings- of handelsadvies. Het handelen in cryptovaluta brengt een aanzienlijk risico op verlies met zich mee.

Auteurs

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Blijf de markt voor

Abonneer je op onze nieuwsbrief voor exclusieve AI-handelsinzichten, marktanalyses en platformupdates.

We respecteren je privacy. Je kunt je op elk moment afmelden.