Jak uruchomiliśmy 744-miliardowy model AI na własnych GPU i przyspieszyliśmy go x36?

16 lipca 2026
Krzysztof Bender
Jak uruchomiliśmy 744-miliardowy model AI na własnych GPU i przyspieszyliśmy go x36?
3 min.

Od crashującego poda do 188 tokenów na sekundę: praktyczna historia self-hostingu GLM-5.2 na vLLM, z problemami, których nie zobaczycie w tutorialach. Krótko i na temat.

Coraz więcej firm (w tym naszych klientów) chce uruchamiać duże modele językowe u siebie, ze względu na poufność danych, koszty przy dużym wolumenie albo po prostu kontrolę. Internet jest pełen poradników „vllm serve i działa”. Ta historia jest o tym, co się dzieje, gdy model ma 744 miliardy parametrów, architekturę sprzed trzech miesięcy i nic nie działa od pierwszego strzału.

Punkt wyjścia

  • Model: GLM-5.2 otwarty model 744B parametrów (MoE: na token pracuje ~40B), z natywnym kontekstem 1M tokenów i architekturą DSA (dynamic sparse attention).
  • Sprzęt: jeden węzeł z 4× NVIDIA H200 (łącznie 564 GB VRAM) w klastrze OpenShift/OKD.
  • Cel: OpenAI-kompatybilne API , wszystko zadeployowane przez Helm, odtwarzalne z repo.

Zastaliśmy: pod vLLM w CrashLoopBackOff i to był dopiero początek.

Ściana #1: GGUF wyleciał z vLLM

Model w kwantyzacji 2-bitowej (GGUF, 239 GB) nie chciał wstać: Load format 'gguf’ is not supported. Okazało się, że obsługa GGUF została wydzielona z głównego repozytorium do osobnego pluginu. Lekcja pierwsza: image: latest w infrastrukturze AI to proszenie się o kłopoty. Przypięliśmy wersję i doinstalowaliśmy plugin.

Ściana #2: plugin nie zna naszej architektury

Unknown gguf model_type: glm_moe_dsa. Plugin mapuje nazwy tensorów z pliku GGUF na nazwy, których oczekuje model w vLLM  i po prostu nie znał architektury GLM-5.2. Zastosowaliśmy własny adapter: mapę 1431 tensorów, zbudowaną na „meta-modelu” (transformers potrafi zbudować strukturę modelu bez ładowania wag, same nazwy parametrów). Całość zwalidowaliśmy lokalnie na laptopie, zanim dotknęliśmy klastra, bo każda nieudana próba na klastrze to 10+ minut ładowania wag.

Ściany #3–5: chirurgia na tensorach

Dalej było tylko ciekawiej. Trzy przypadki, w których format pliku i implementacja silnika mówią innymi językami:

  1. vLLM trzyma pewne projekcje attention sfuzowane i nieskwantyzowane, a w pliku GGUF przychodzą osobno i skwantyzowane. Rozwiązanie: dekwantyzacja w locie.
  2. Jeden typ warstwy w tej wersji vLLM w ogóle nie umiał ładować skwantyzowanych wag, wymuszenie ścieżki float.
  3. Najlepsze: plik GGUF nie zawiera tensora kv_b_proj, którego oczekuje vLLM. llama.cpp przy konwersji tnie go na dwa inne (w tym jeden transponowany) na potrzeby swoich optymalizacji.
  4.  Trzeba było przeczytać kod konwertera i odwrócić jego matematykę: reshape -> transpozycja -> konkatenacja -> [28672×512]. Jedna pomyłka w wymiarach i model generowałby szum.

Wynik: model wstał i odpowiadał. Prędkość: 5 tokenów na sekundę. Na sprzęcie za setki tysięcy złotych. No… nie tego się spodziewaliśmy.

Dlaczego tak wolno? 

Tu jest intuicja, którą warto zabrać z tego tekstu nawet, jeśli nic więcej Was nie obchodzi. Podczas dekodowania większość aktywnych wag modelu musi zostać ponownie odczytana z pamięci GPU dla każdego kolejnego tokenu. W naszym przypadku oznaczało to około 20 GB odczytu na token. Dekodowanie nie jest ograniczone mocą obliczeniową, tylko przepustowością pamięci. Eksperymentalne kernele GGUF w vLLM po prostu nie wyciskały tej przepustowości. Zmieniliśmy kwantyzację na AWQ-INT4 (410 GB, natywne kernele Marlin w vLLM): 89 tok/s. Siedemnaście razy szybciej – bez zmiany sprzętu. Ufff… : ) 

Wisienka na naszym LLMowym torcie: spekulacja z 85% skutecznością

Skoro odczyt wag na token jest drogi, a weryfikacja kilku tokenów naraz kosztuje prawie tyle co jednego (znów: memory-bound) – wchodzi speculative decoding. GLM-5.2 ma wbudowaną warstwę MTP (multi-token prediction), wytrenowaną razem z modelem, która zgaduje kolejne tokeny. Silnik weryfikuje zgadnięcia jednym przejściem – zachowując jakość odpowiedzi modelu bazowego. Haczyk: nasz checkpoint AWQ nie zawierał warstwy MTP, a oficjalna istnieje tylko w FP8. Zrobiliśmy więc „przeszczep”: doszyliśmy 1569 tensorów FP8 do checkpointu INT4 (nowy katalog to hardlinki, zero kopiowania 400 GB) i nauczyliśmy vLLM mieszanej kwantyzacji małym patchem wpinanym przez import-hook Pythona – bez budowania własnego obrazu, bez roota, w pełni odwracalnie z poziomu Helma.

Skuteczność spekulacji: 80–87% zgadniętych tokenów. Efekt końcowy:

36× szybciej niż pierwsza działająca wersja. Ten sam sprzęt, ta sama jakość modelu.

Przy kilku równoległych żądaniach mamy w szczycie nawet 295 tok/s.

…ale o tym napiszemy inną historię.

Stack: OpenShift/OKD, vLLM 0.24, GLM-5.2 (754B MoE), 4× NVIDIA H200, Open WebUI. Wszystkie liczby ze środowiska testowego – pojedyncza sekwencja, realne API.

To dopiero początek naszych eksperymentów z self-hostingiem dużych modeli. AI rozwija się w zawrotnym tempie, dlatego traktujemy ten projekt jako kolejny etap nauki.