Il team MoonMath AI ha recentemente rilasciato un bf16 forward attention kernel specifico per l’AMD MI300X, scritto in HIP, non in assembly, ed è open-source sotto licenza MIT. Questo nuovo componente mostra un miglioramento di performance rispetto alla propria versione AITER v3 su ogni forma e modalità di arrotondamento di test. L’accesso a livello di hardware è stato fornito da HotAisle, un fornitore di cloud con tecnologia AMD.

Che cos'è l’Attention?

Le attenzioni rappresentano una fusione chiave di operazioni, come softmax(QKᵀ/√d)·V, al cuore di ogni transformer. Il MI300X è un GPU data-center CDNA3 di AMD, che utilizza l’architettura ISA targetgfx942. Questo kernel è eseguito esclusivamente su questo hardware.

Sommario

MoonMath AI apre una versione HIP di un attention kernel in bf16 per l’AMD MI300X, scritto in HIP non assembly (MIT). Il kernel supera AITER v3 in termini di forma per geomean 1.18× / 1.15× / 1.08×, con un massimo di 1.26×. La tecnica chiave prevede utilizzare wrapper asm a una sola istruzione per poter scegliere opcode mentre il compilatore assegna i registri. La maggior parte del vantaggio deriva dal posizionamento della memoria — K in LDS, V caldo in L1, Q e accumulatori nei registri. Un esempio reale di utilizzo, un PR di SGLang, ha accelerato WAN2.1 diffusion video di 1.23×, senza regressione nella qualità.

Understanding Kernel

Un kernel è un piccolo programma che si esegue direttamente su molti core GPU per svolgere un calcolo specifico, qui, l’attention math, al massimo della velocità offerta dall’hardware. Il kernel calcola la forward attention in bf16 sul MI300X solo. Accetta input in BSHD o BHSD, senza trasposizione. La dimensione di testa è fissa a 128. Sono supportati qualsiasi lunghezza di sequenza, incluso l’attention cross.

Rimangono restrizioni reali. Non esiste un mask causale, né GQA né batching variabile. Le uscite sono in bf16 e vengono eseguite esclusivamente sul hardware gfx942.

Controllo Rigoroso Sui Numeri

Ogni modalità di arrotondamento replica le regole AITER per modalità arrotondamento. Ogni uscita finita si trova entro 1 bf16 ULP da AITER. La gestione di NaN e Inf è identica a livello di bit, e i risultati sono deterministici.

Trucchetto Core: Wrapper asm a una sola istruzione

La tecnica chiave evita un dilemma comune. Gli intrinseci del compilatore tengono pulito il codice, ma permettono al compilatore di riordinare o rinominare gli operandi. L'assembly inline puro dà controllo diretto ma costringe alla gestione manuale dei registri e indirizzi.

MoonMath avvolge esattamente un’istruzione in una funzione _device forceinline. I vincoli estesi asm descrivono gli operandi. Il team ricerca seleziona l’opcode. Il compilatore si occupa comunque di assegnare i registri e tracciare il flusso di dati.

Ad esempio:

"// in/out collegati allo STESSO VGPR → nessun rinnominamento accumulatore, nessuna istruzione vmov.
_device forceinline void asmmfma(bf16x4t a, bf16x4t b, fp32x4_t& c) {

asm volatile("vmfmaf3216x16x16bf16 %0, %1, %2, %0"

: "+v"(c) : "v"(a), "v"(b));

}"

Il vincolo "+v"(c) collega l'accumulatore di input e output allo stesso VGPR. Nessuna istruzione di copia viene generata. Ciò mantiene il kernel vicino a un normale HIP. Ciò consente comunque di controllare macchina istruzione per istruzione.

Architettura: Otto Onde, Due Gruppi, Due Barriere

Un’unità CDNA3 computazionale ha quattro unità SIMD. Il blocco di testo standard è costituito da quattro ondate. MoonMath invece esegue otto ondate per blocco, divise in due gruppi da quattro ciascuno.

I due gruppi eseguono la sequenza QK, softmax, O += PV. Sono sfasati di una fase. Mentre un gruppo satura il core matriciale, l’altro esegue softmax e carica. Quindi si scambiano, in modo che il core matriciale non resti mai inattivo.

Le sbarre di sincronizzazione sono due speriterazione. Una si trova al momento della transizione di fase e una al limite dell’iterazione. Le attese per contatore gestiscono la restante sincronizzazione.

Dove Vivono I Dati

La velocità maggiore deriva dal posizionamento della memoria.

    • K scorre da HBM verso LDS, doppio buffering tra le otto onde.

    • V rimane caldo in L1, letto ad ogni PV matmul.
    • Q e accumulatori vivono nei registri.

La squadra ha scelto la forma 16×16×16 MFMA al posto di 32×32×8. Sia la forma che la struttura hanno la stessa capacità di throughput. Ogni tile accumula 4 elementi fp32 per lane, invece di 16. Maggior spazio di accumulo libera spazio per un prelezione più profonda e un terzo tile Q.

    • Scelta Numero di onde per blocco: 8 (due gruppi da 4) - Per pianificare direttamente la pipeline, condividere una copia K.
    • Scelta Forma MFMA: 16×16×16 bf16 - Stessa capacità throughput, minore pressione su VGPR, migliore efficienza energetica.
    • Scelta Posizione di K: LDS, buffer doppio, 32 KiB - Condiviso da tutte le 8 onde, scambiato per iterazione.
    • Scelta Posizione di V: L1, residente, con prelettura - Riletto attraverso PV, mantenuto caldo intenzionalmente.
    • Scelta Posizione di Q + accumulatori: VGPRs - Letti ad ogni iterazione, mai ricaricati.

Due ulteriori vantaggi chiudono il divario. Un terzo tile Q (3Q) aumenta la riutilizzazione dei dati caricati per ciascun tile K e V. Una scissione KV nella coda a stile Flash-Decoding recupera la sponda frammentata attraverso i 304 CUs del MI300X. Questi risultati crescono esponenzialmente. Spostando V in L1 e riservando LDS per il terzo tile Q, si ha un notevole miglioramento.

Read original article →
← Back to news