numer 04 phile 01 z 02
421 tok/s. Albo 167. Zależy, o co pytasz
Zmieniłem model na ten sam model.
Ta sama karta, ta sama architektura, te same wagi — tylko inny format liczb i inny silnik. NVFP4 zamiast GGUF w Q5. Miało być „dwa razy szybciej". Pierwszy pomiar dał czterdzieści sześć procent i przez chwilę wyglądało to na kolejną obietnicę z internetu, która nie przeżyła kontaktu z własnym sprzętem.
Potem zmierzyłem jeszcze pięć razy i dostałem pięć różnych odpowiedzi. Wszystkie prawdziwe.
Pierwsza liczba, która kłamała
Prompt, czterysta tokenów wyjścia, temperatura zero. NVFP4: sto sześćdziesiąt siedem tokenów na sekundę. GGUF: sto czternaście. Czterdzieści sześć procent w górę — miło, ale to nie jest żadne „dwa razy".
Problem polegał na tym, że mierzyłem nie to, co myślałem. Model, którego używam, potrafi rozumować przed odpowiedzią, i robi to domyślnie. Większość z tych czterystu tokenów to nie była odpowiedź, tylko rozmyślanie po drodze. Dopiero z wyłączonym rozumowaniem liczby zrobiły się porównywalne: dwieście dwanaście kontra sto czterdzieści cztery.
Wniosek pierwszy, banalny i kosztowny: jeśli nie wiesz, co dokładnie generuje model w czasie pomiaru, nie mierzysz prędkości silnika, tylko długość jego wywodu. Rozumowanie kosztowało dwadzieścia procent przepustowości. Nie dlatego, że tokeny rozumowania są wolniejsze — jest ich po prostu więcej i są inne.
Skąd się bierze rozrzut
Oba silniki, które porównywałem, używają przewidywania w przód. Mały, szybki model zgaduje kilka następnych tokenów, duży sprawdza je hurtem i akceptuje te, które trafił. Kiedy zgadywanie idzie dobrze, dostajesz kilka tokenów za cenę jednego przebiegu. Kiedy idzie źle, płacisz za zgadywanie i nic z tego nie masz.
A teraz kluczowe: jak dobrze idzie zgadywanie, zależy od tego, co piszesz.
Kazałem wygenerować dwadzieścia pięć funkcji CRUD dla pięciu modeli danych. Identyczny schemat, powtarzalny do bólu, dokładnie ten rodzaj kodu, który człowiek pisze na autopilocie. Dla małego modelu zgadującego to wymarzone warunki — po trzeciej funkcji wie dokładnie, co będzie w czwartej.
kod schematyczny, NVFP4: 421 tok/s
kod schematyczny, GGUF: 162 tok/s
Czterysta dwadzieścia jeden. Wobec dwustu dwunastu na zwykłym kodzie i stu sześćdziesięciu siedmiu z rozumowaniem. Ta sama karta, ten sam model, ten sam format — dwa i pół raza rozrzutu w zależności od treści.
I co ciekawsze: GGUF też skorzystał na przewidywalności, ale tylko o dwanaście procent. NVFP4 przyspieszył dwukrotnie względem siebie. Przewaga formatu urosła z czterdziestu siedmiu procent do stu sześćdziesięciu.
Prefill, czyli ta liczba, która naprawdę boli
Dekodowanie widać. Prefill — czyli przemielenie tego, co wysłałeś, zanim padnie pierwszy token — widać dopiero wtedy, gdy czekasz.
prefill, NVFP4: ~7550 tok/s
prefill, GGUF: ~2706 tok/s
Dwa i osiem dziesiątych raza. Przy pracy z narzędziem agentowym, które przy każdym kroku wysyła kilkanaście tysięcy tokenów kontekstu, to jest różnica między „chwila" a „idę po kawę". Znam to z autopsji: pojedyncze zapytanie potrafiło mielić prawie osiem minut, i przez długi czas byłem przekonany, że problemem jest generowanie. Nie było. Generowanie szło w porządku — zabijał prefill.
Trzy sposoby, żeby skłamać sobie w pomiarze
Zanim wyszły powyższe liczby, zmierzyłem kilka rzeczy nieprawdziwych. Wszystkie trzy są łatwe do popełnienia i żadna nie wygląda na błąd.
Dziewięćdziesiąt dwa tysiące tokenów na sekundę. Tyle wyszło mi w prefillu za drugim razem. Wysłałem ten sam długi prompt dwa razy pod rząd i za drugim razem silnik nie liczył nic — oddał gotowy stan z pamięci podręcznej. Sześć tysięcy tokenów w sześćdziesiąt dziewięć milisekund. Piękny wynik, zero wartości. Lekarstwo: każde zapytanie z unikalną treścią, inaczej mierzysz cache.
Dwadzieścia tokenów na sekundę zamiast stu czternastu. Pierwszy przebieg po przełączeniu modelu zawsze jest fałszywy, bo w zmierzonym czasie siedzi ładowanie wag do pamięci karty. Trzeba odrzucić pierwszy wynik albo rozgrzać silnik przed pomiarem — inaczej wyjdzie ci, że nowy format jest sześć razy wolniejszy od starego.
Rozumowanie wliczone w wynik. Opisane wyżej. Dwadzieścia procent różnicy między „mierzę odpowiedź" a „mierzę myślenie".
Wszystkie trzy mają wspólny mianownik: nie mierzyłem tego, co chciałem zmierzyć, a wynik wyglądał wiarygodnie. To najgorszy rodzaj błędu, bo nie krzyczy.
Ta sama karta, cztery rozmowy naraz
Do tej pory wszystko dotyczyło jednego zapytania na raz. Ale jest druga oś, o której się rzadko mówi, bo nie mieści się w jednej liczbie z nagłówka.
Okno kontekstu i równoległość biją się o tę samą pamięć. Trzymam zwykle dwieście sześćdziesiąt dwa tysiące tokenów okna i jedną kolejkę — wygodne, gdy wrzucasz cały projekt. Ale to samo można przestawić: mniejsze okno, więcej równoległych sesji.
Trzydzieści dwa tysiące okna, cztery kolejki:
1 sesja: 215 tok/s
2 sesje: 433 tok/s (skalowanie 2,02x)
4 sesje: 720 tok/s (skalowanie 3,35x)
Dwie sesje skalują się praktycznie liniowo. Cztery dają trzy i pół raza. Łącznie siedemset dwadzieścia tokenów na sekundę z jednej karty — wobec stu czterdziestu czterech, które wyciskałem ze starej konfiguracji przy jednej kolejce.
Pięciokrotność. Na tym samym sprzęcie. Zapłacone oknem kontekstu i trzema gigabajtami pamięci mniej.
To zmienia sposób myślenia o karcie. Przestaje być „maszyną do jednej rozmowy", a staje się czymś, co obsłuży redakcję, kilka zadań w tle i jeszcze zostanie. Pod warunkiem, że nie potrzebujesz wielkiego okna — a w większości zadań nie potrzebujesz.
Więc ile to daje?
Zależy, o co pytasz. Wszystkie te liczby pochodzą z tego samego popołudnia, z tej samej karty i tego samego modelu:
z rozumowaniem 1,46x
bez rozumowania 1,47x
kod schematyczny 2,60x
prefill 2,80x
cztery sesje równolegle 5,00x
Nie ma tu żadnej sprzeczności. Jest pięć różnych pytań i pięć uczciwych odpowiedzi. Problem zaczyna się wtedy, gdy ktoś weźmie jedną z nich, wsadzi do nagłówka i nazwie ją „wydajnością formatu".
Bo liczba z cudzego benchmarku nie jest parametrem modelu. Jest zapisem tego, co ten ktoś wtedy mierzył: jakim promptem, jak długim, z rozumowaniem czy bez, po rozgrzewce czy przed, z trafieniem w cache czy bez, przy jednej sesji czy przy czterech.
Zmiana formatu naprawdę się opłaciła. Najbardziej tam, gdzie się tego nie spodziewałem — w prefillu i w równoległości, a nie w tym jednym ładnym numerku z dekodowania.
Ale dowiedziałem się tego dopiero wtedy, gdy przestałem szukać jednej liczby.