Offloading warstw
Jak działa
Model dzieli się na warstwy (bloki transformera). Część warstw pozostaje na stałe w VRAM, a pozostałe przechowywane są w RAM CPU lub na dysku NVMe. Podczas przebiegu forward, gdy potrzebna jest warstwa spoza GPU, jej wagi kopiuje się przez PCIe do VRAM, wykonuje obliczenia i zwalnia miejsce dla następnej warstwy; aktywacje przechodzą przez kolejne warstwy sekwencyjnie. Aby ukryć opóźnienia transferu, stosuje się prefetching (asynchroniczne wczytywanie kolejnej warstwy podczas liczenia bieżącej) i nakładanie transferu na obliczenia. Offloadować można nie tylko wagi warstw, ale i KV cache oraz stany optymalizatora (w treningu, np. ZeRO-Offload). Liczba warstw trzymanych na GPU (np. parametr n-gpu-layers w llama.cpp) steruje kompromisem między zużyciem VRAM a prędkością.
Rozwiązany problem
Duże modele nie mieszczą się w całości w pamięci VRAM pojedynczego GPU, a zakup większej liczby akceleratorów bywa niemożliwy lub nieopłacalny. Offloading warstw rozwiązuje to, trzymając w VRAM tylko część modelu i przechowując resztę w tańszej, obfitszej pamięci CPU lub na dysku NVMe; warstwy są sprowadzane do GPU tuż przed użyciem. Umożliwia to inferencję (a częściowo trening) modeli większych niż VRAM, kosztem spadku prędkości wynikającego z transferu przez PCIe.
Kluczowe mechanizmy
Mocne strony i ograniczenia
Komponenty
Decyzja, które warstwy (lub tensory) trzymać w VRAM, a które w RAM CPU lub na dysku, sterowana budżetem pamięci.
Kopiowanie wag warstwy z pamięci CPU/dysku do VRAM tuż przed obliczeniami i ich zwolnienie po użyciu.
Asynchroniczne wczytywanie kolejnej warstwy podczas liczenia bieżącej, aby ukryć opóźnienia transferu za obliczeniami.
Implementacja
Transfer wag przez PCIe jest wielokrotnie wolniejszy niż odczyt z VRAM; nadmierny offload dramatycznie obniża liczbę tokenów na sekundę.
Przy długim kontekście KV cache może przekroczyć VRAM, nawet gdy wagi zostały zoffloadowane, powodując błąd braku pamięci.
Ewolucja
Microsoft DeepSpeed wprowadza offload stanów optymalizatora i parametrów do CPU/NVMe, umożliwiając trening modeli wielokrotnie większych niż VRAM.
llama.cpp (n-gpu-layers), Hugging Face Accelerate (device_map) i FlexGen upowszechniają offload warstw w inferencji na sprzęcie konsumenckim.
Hiperparametry (konfigurowalne osie)
Ile warstw trzymać w VRAM; reszta jest offloadowana do CPU/dysku.
Gdzie przechowywane są offloadowane dane: pamięć CPU lub dysk NVMe.
Złożoność obliczeniowa
Złożoność czasowa: t ~ t_compute + (bajty offloadowanych warstw) / przepustowosc PCIe. Złożoność przestrzenna: VRAM ~ (warstwy na GPU / wszystkie warstwy) x rozmiar modelu.
Przepustowość PCIe 4.0 x16 to ~32 GB/s, wobec ~1-3 TB/s przepustowości VRAM nowoczesnych GPU — stąd każda offloadowana warstwa znacząco spowalnia generację. W praktyce llama.cpp pozwala płynnie regulować n-gpu-layers: im więcej warstw mieści się w VRAM, tym wyższa liczba tokenów/s; pełny offload na CPU redukuje prędkość do poziomu inferencji CPU.
Wąskie gardło obliczeniowe
Wąskim gardłem jest przepustowość magistrali PCIe między CPU/dyskiem a GPU; to ona, a nie moc obliczeniowa, ogranicza prędkość przy offloadzie.
Paradygmat wykonania
Wszystkie warstwy są wykonywane; różnica dotyczy lokalizacji pamięci wag.
Offloading nie zmienia grafu obliczeń ani nie wprowadza routingu; steruje jedynie miejscem przechowywania i transferem wag.
Równoległość
Transfer i obliczenia można nakładać (prefetching), ale zależność między warstwami wymusza sekwencyjny przepływ aktywacji; równoległość między urządzeniami warunkowa względem magistrali.
Wymagania sprzętowe
GPU wykonuje obliczenia warstw, ale korzyść z offloadu zależy od szybkiej magistrali (PCIe 4.0/5.0, NVLink) i dużej, szybkiej pamięci CPU.
Warstwy offloadowane mogą być liczone bezpośrednio na CPU (np. hybryda w llama.cpp), gdy transfer do GPU nie opłaca się dla danej warstwy.