Jak fuzja kerneli CUDA przyspiesza inferencję LLM
Tłumaczenie automatyczne
Ten artykuł został automatycznie przetłumaczony z angielskiego oryginału.
Fuzja kerneli CUDA łączy operacje, które w przeciwnym razie wykonywałyby się jako osobne kernele GPU. Może zmniejszyć narzut uruchamiania i uniknąć zapisywania tensora pośredniego do pamięci GPU tylko po to, by natychmiast odczytać go ponownie. Pomaga, gdy te koszty stanowią istotną część opóźnienia inferencji.
Prześledź dane pośrednie
Rozważ dodawanie rezydualne, po którym następuje normalizacja. Osobne kernele mogą zapisać wynik dodawania do głównej pamięci GPU i ponownie go odczytać na potrzeby normalizacji. Zgodna z tymi operacjami implementacja łącząca je w jednym kernelu może ponownie wykorzystać wartości pośrednie wewnątrz kernela. Oszczędza to transfery; nie usuwa operacji matematycznych ani wymagań dotyczących ich poprawności.
Fuzja obejmuje również większe operacje. DeepFusionKernel bada łączenie pełnego obliczenia sieci jednokierunkowej SwiGLU, w tym mnożeń macierzy. To więcej niż łączenie funkcji aktywacji działających na poszczególnych elementach.
FlashNorm stosuje inną transformację: włącza wyuczony współczynnik skali RMSNorm do następującej po niej operacji liniowej i odkłada ponowne skalowanie.
Sprawdź, czy fuzja pomogła
| Porównaj | Co wykazałaby poprawa |
|---|---|
| Uruchomienia kerneli i przerwy między nimi | Mniejszy narzut między małymi operacjami |
| Odczyty i zapisy HBM | Mniej transferów pośrednich |
| Wykorzystanie rejestrów i pamięci współdzielonej | Czy połączony kernel potrzebuje więcej pamięci lokalnej |
| Przenoszenie danych z rejestrów do pamięci i aktywne bloki | Czy presja na zasoby ograniczyła wykonywanie równoległe |
| Opóźnienie pełnego żądania | Czy zmiana kernela miała znaczenie dla użytkowników |
Przewodnik po optymalizacji Hopper wyjaśnia limity zasobów ograniczające ilość pracy wykonywanej jednocześnie na GPU. Łączenie operacji może zwiększyć wykorzystanie rejestrów, spowodować przenoszenie danych z rejestrów do pamięci lub ograniczyć liczbę bloków wykonywanych jednocześnie. Większy połączony kernel może więc działać wolniej dla niektórych kształtów tensorów.
Utrzymuj stałe model, precyzję, GPU, długość wejścia i rozmiar partii. Sprawdzaj wyniki numeryczne i jakość wykonania zadania, a także czas. Porównaj też dekodowanie przy małych partiach z przetwarzaniem wstępnym przy większych: zmniejszenie narzutu uruchamiania może mieć znacznie większe znaczenie dla krótkich operacji niż dla długich obliczeń macierzowych.
Przewodnik inżynierski: kernele CUDA i fuzja wiąże te metody ze skwantyzowanymi kernelami macierzowymi.