Który plik w ogóle pobrać — Q4_K_M, Q5_K_S, a może to dziwne IQ2_XXS? Przychodzisz po jeden model, a zastajesz tabelę na dwadzieścia wierszy: Q4_K_M, Q5_K_S, Q6_K, Q8_0, niżej jeszcze IQ2_XXS i IQ3_XS, każdy z inną wagą w gigabajtach. Człowiek stoi nad tym jak nad półką z olejami silnikowymi w markecie — wszystkie coś tam obiecują, wszystkie mają cyferki, a ty nie wiesz, czy 5W-40 to lepiej, czy gorzej niż 10W-30. Nowi ludzie zadają to pytanie mniej więcej co drugi dzień: „którą wersję pobrać?".

I najczęściej ktoś rzuca: „bierz Q4_K_M i się nie zastanawiaj". Dobra rada — ale zostawia cię z tym samym uczuciem, co „wlej 5W-40 i jedź". Działa, tylko dalej nie wiesz, co te znaczki znaczą. A one nie są przypadkowe. Każda litera i każda cyfra w Q4_K_M coś konkretnie mówi: ile bitów, jaka rodzina, ile precyzji odzyskujesz z powrotem. Jak raz to rozłożysz, ta tabela przestaje być loterią, a robi się listą z parametrami. Rozbierzmy ją.

Skąd w ogóle biorą się te nazwy

Zanim rozbierzemy nazwy, jedno pytanie: po co w ogóle tniemy? Model w oryginale trzyma każdą wagę na 16 bitach (format F16/BF16). Kwantyzacja to zwykłe upakowanie tych samych, już wytrenowanych liczb ciaśniej — nie douczanie, nie trening od nowa, tylko kompresja. To ważne rozróżnienie, bo ludzie mylą to z fine-tuningiem: tu nic się nie uczy, tylko chudnie.1 O tym, jak liczby idą w dół i czemu jakość spada tak zaskakująco mało, rozgryzaliśmy szerzej przy okazji wyboru wersji modelu.

GGUF (GPT-Generated Unified Format — binarny format plików modeli spod llama.cpp) każdemu z tych sposobów cięcia daje nazwę. I ta nazwa nie jest marketingowa — to zapis, jak dokładnie wagi są zakodowane w pliku. Format jest zaskakująco regularny: QN_K_X. N to przybliżona liczba bitów na wagę, _K to nazwa rodziny (tak zwane k-quanty), a przyrostek X (S/M/L) mówi, ile tensorów w modelu dostaje podbitą precyzję.1 Jak to raz przeczytasz jak zdanie, a nie jak szyfr, reszta wchodzi sama.

Q4_K_M — rozłóżmy to na trzy kawałki

Weźmy najsłynniejszy przykład i przejedźmy po nim znak po znaku.

Q — to po prostu „quantized". Standardowa kwantyzacja na liczbach całkowitych. Nic ciekawego, ozdobnik.

4 — przybliżona liczba bitów na wagę. I tu pierwsza pułapka, w którą wpada każdy: to przybliżenie, nie dokładna wartość. Wydaje się, że Q4 znaczy „równo 4 bity na liczbę". Nieprawda. Realnie, na modelu Llama-3.1-8B zmierzono, że Q4_K_M waży 4,89 bita na wagę, a nie 4.2 Skąd ta nadwyżka? Właśnie z ostatniej litery — za chwilę.

_K — rodzina „k-quant". To był przełom z połowy 2023 roku (PR #1684 od ikawrakowa).3 Zamiast kodować każdy blok wag osobno i głupio, k-quanty pracują na super-blokach: większa grupa wag współdzieli metadane, a skala i minimum każdego mniejszego bloku są kodowane osobno, z własną precyzją. W praktyce: Q4_K i Q5_K mają super-bloki z 8 bloków po 32 wagi, a Q2_K, Q3_K i Q6_K — z 16 bloków po 16 wag.3 Dzięki temu ta sztuczka trzyma jakość dużo lepiej niż stare, proste cięcie.

M — i tu jest cała finezja, którą prawie wszyscy przegapiają. S/M/L (Small/Medium/Large) nie znaczą „mały/średni/duży model". Znaczą: ile tensorów w środku dostaje podniesioną precyzję.1 Bo model to nie jednorodna zupa liczb — jedne tensory (np. te od atencji attention.wv albo feed_forward.w2) są dla jakości ważniejsze niż inne. Wariant M mówi: „te newralgiczne kawałki potnij łagodniej, resztę ostrzej".3 To dlatego Q4_K_M waży te 4,89 bita zamiast 4 — bo część wag siedzi wyżej niż na czterech bitach. To nie jest jedna globalna liczba bitów, to mieszanka.

Czyli Q4_K_M czytasz tak: „około czterobitowa, rodzina k-quant, ze średnim miksem podbitych tensorów". Trzy słowa, nie szyfr.

Ile realnie ważą — bo teoria kłamie o ułamek

Skoro cyfra po Q to przybliżenie, to najlepiej patrzeć na liczby zmierzone na prawdziwym modelu. Oto oficjalna tabela llama.cpp dla Llama-3.1-8B (dla porównania: oryginał w F16 to 14,96 GiB, a plik źródłowy waży 32,1 GB).2

WariantBity/wagęRozmiar (Llama-3.1-8B)
Q4_K_S4,674,36 GiB
Q4_K_M4,894,58 GiB
Q5_K_S5,575,21 GiB
Q5_K_M5,705,33 GiB
Q6_K6,566,14 GiB
Q8_08,507,95 GiB
F1616,0014,96 GiB

Widać z tego dwie rzeczy. Raz — każdy kolejny bit kosztuje mniej więcej pół–jeden gigabajt na modelu tej klasy, więc skok z Q4_K_M na Q6_K to jakieś półtora giga VRAM-u więcej za coraz mniej odczuwalny zysk jakości (a ile pamięci realnie zeżre dany plik z kontekstem, wyliczasz osobnym wzorem). Dwa — Q8_0 to niemal bezstratna referencja; różnicy między nim a F16 w ślepym teście raczej nie wychwycisz, a plik jest o połowę lżejszy. Dlatego Q8_0, choć technicznie to stary „legacy" format, wciąż żyje i ma się świetnie.1

A ile to daje na dużym modelu? Oficjalna tabela pokazuje Q4_K_M jako jedyny przykład: Llama 3.1 8B chudnie z 32,1 GB do 4,9 GB, 70B z 280,9 GB do 43,1 GB, a monstrualne 405B z 1625 GB do 249 GB.2 Cztery bity zamiast szesnastu i nagle model, który potrzebował serwerowni, mieści się na jednej porządnej karcie.

Dlaczego akurat Q4_K_M jest tym „domyślnym"

No dobra, ale skąd się wziął ten konsensus, że Q4_K_M to bezpieczny strzał? Tu muszę cię uczciwie zderzyć z rzeczywistością: llama.cpp nigdzie formalnie nie ogłasza żadnego „oficjalnego domyślnego" kwantu.2 To mit, który sam sobie chodzi po forach. Ale nie wziął się znikąd.

Po pierwsze, Q4_K_M ląduje w dokumentacji jako przykładowa komenda — kiedy README pokazuje, jak w ogóle uruchomić llama-quantize, robi to właśnie na nim:2

./build/bin/llama-quantize model-bf16.gguf model-Q4_K_M.gguf Q4_K_M

Po drugie — i ważniejsze — cztery bity to punkt, w którym krzywa „rozmiar kontra jakość" ma najładniejsze kolano. Poniżej zaczynasz tracić jakość szybciej, niż zyskujesz na rozmiarze. Powyżej płacisz gigabajtami za coraz mniejszy zysk. Q4_K_M siedzi dokładnie w tym słodkim punkcie, dlatego społeczność go pokochała. Ale to konsensus praktyczny, nie dekret ze specyfikacji — i warto to trzymać w głowie, zanim ktoś ci powie, że „tak trzeba".

A te dziwne IQ z wieloma iksami?

Zjeżdżasz w tabeli niżej i trafiasz na drugą rodzinę: IQ2_XXS, IQ3_XS, IQ4_NL. Wyglądają jak k-quanty, które napiły się kawy. To i-quanty (i-quants) — nowsza rodzina, zaprojektowana pod jeden cel: wycisnąć sensowną jakość z naprawdę niskich bitów, tam gdzie zwykłe k-quanty się już sypią.1

Sekret jest w dwóch rzeczach. I-quanty operują na większych super-blokach po 256 wag i — to kluczowe — wyliczają wagi z pomocą tak zwanej importance matrix, w skrócie imatrix.1 Co to jest? Wyobraź sobie, że przed kompresją przepuszczasz model przez zestaw tekstów kalibracyjnych i patrzysz, które wagi naprawdę się aktywują, a które ledwo drgają. Imatrix to per-tensor tablica, która to zapamiętuje — dla każdej pozycji notuje, jak mocno ta waga „pracowała".4 Potem, przy cięciu, algorytm chroni ważne wagi kosztem tych mało istotnych. Zamiast tłuc wszystko po równo, oszczędza tam, gdzie boli najmniej.

Litery za IQ układają się od najostrzejszego cięcia w górę: XXS (extra-extra-small), XS, S, M. Oto co to daje w liczbach, znów na Llama-3.1-8B:2

WariantBity/wagęRozmiar
IQ1_S2,001,87 GiB
IQ2_XXS2,382,23 GiB
IQ2_M2,932,74 GiB
IQ3_XXS3,253,04 GiB
IQ4_XS4,464,17 GiB
IQ4_NL4,684,38 GiB

Zauważ jedno: IQ4_XS waży 4,17 GiB, czyli mniej niż Q4_K_S (4,36 GiB) przy porównywalnej klasie. To właśnie ta magia imatrixa — więcej jakości na bit. Cena? I-quanty bywają wolniejsze w inferencji na słabszym sprzęcie, bo używają tablic przeglądowych, i mają sens głównie wtedy, gdy walczysz o każdy gigabajt — na przykład wciskasz model 70B na kartę, która teoretycznie go nie uniesie.

Dlaczego to ważne dla lokalnego LLM

Nie daj się nabrać na jeden zbieg okoliczności: „i" w i-quant i „i" w imatrix to nie ten sam mechanizm. Imatrix (flaga --imatrix) działa uniwersalnie — możesz nim wesprzeć również k-quanty i stare legacy quanty. A i-quanty teoretycznie da się zrobić i bez niego, tyle że są zaprojektowane, żeby chodzić najlepiej właśnie z imatrixem.1 Dwie różne rzeczy, które przypadkiem zaczynają się na tę samą literę.

Legacy, czyli dziadkowie formatu

Zanim były k-quanty, były proste cięcia: Q4_0, Q4_1, Q5_0, Q5_1, Q8_0. Dzielą wagi na płaskie bloki po 32 i kodują je najprościej jak się da — warianty _0 wzorem waga = q × skala, a _1 dokładają jeszcze minimum bloku (+ block_minimum).1 Bez super-bloków, bez finezji. Dokumentacja GGUF opisuje je wprost jako „metodę przestarzałą, dziś rzadko używaną" — z jednym wyjątkiem. Q8_0 przeżył wszystkich, bo na ośmiu bitach kompresja i tak niczego istotnego nie gubi, więc służy jako wygodna, niemal bezstratna referencja.1 Reszta to eksponaty muzealne — jeśli widzisz świeży model wypuszczony tylko w Q4_0, to znak, że coś jest nie tak z tym uploadem.

Dla porządku: świat GGUF ma jeszcze kilka egzotów, na które możesz się natknąć. Q8_K to nie format do dystrybucji, tylko typ roboczy do liczenia iloczynów skalarnych wewnątrz kwantów 2–6 bit.1 A z najnowszych — TQ1_0/TQ2_0 (kwantyzacja ternarna) i MXFP4 (4-bitowy microscaling float) to zupełnie młodsze rodziny niż klasyczne k- i i-quanty.1 Ale to już inna bajka.

Zrób to sam — i nie strzel sobie w stopę

Jak sam chcesz coś skwantyzować, narzędzie to llama-quantize z repo ggml-org/llama.cpp. Podstawa jest banalna — podajesz źródło, cel i typ. Ale są trzy grabie, na które warto uważać.

Po pierwsze — tnij zawsze z oryginału (F16/BF16/F32), nie z już skwantyzowanego pliku. Requantyzacja (flaga --allow-requantize) potrafi „poważnie obniżyć jakość", ostrzega o tym sama dokumentacja.2 To jak przegrywanie MP3 z MP3 — za każdym razem gorzej.

Po drugie — flaga --pure wyłącza całą tę inteligentną mieszankę k-quantów i tnie wszystkie tensory do jednego typu.2 Brzmi kusząco („czysto!"), ale odbierasz sobie właśnie to, za co _M jest dobre. Zostaw domyślny miks.

Po trzecie — jak kwantyzujesz model multimodalny, nie tnij komponentów mmproj (enkoder obrazu/dźwięku i projektory) tak agresywnie jak reszty. Dokumentacja zaleca trzymać je w bf16 albo q8 (czym bf16 różni się od zwykłej „szesnastki" f16, jest tutaj), bo mają bezpośredni wpływ na jakość tego, co trafia do modelu, a oszczędność pamięci przy niższym kwancie i tak jest znikoma.2

# z importance matrix, dla i-quantów i lepszych niskobitowych k-quantów:
./build/bin/llama-quantize --imatrix model.imatrix \
  model-f16.gguf model-IQ3_M.gguf IQ3_M

Cała lista pokręteł — --tensor-type (regex per tensor), --output-tensor-type, --token-embedding-type, --leave-output-tensor, --prune-layers — czeka w dokumentacji narzędzia.2 Ale szczerze? Na co dzień pobierasz gotowca z Hugging Face i cała ta zabawa sprowadza się do jednego pytania: który wiersz w tabeli kliknąć.

I tu wracamy do tej półki z olejami. Bo kiedy już wiesz, że Q4_K_M to „czterobitowa, k-quant, średni miks", Q6_K to „szóstka bez wariantów, bo i po co", a IQ2_XXS to „dwa bity ratowane imatrixem na modelu, który normalnie by się nie zmieścił" — ta tabela na Hugging Face przestaje być ścianą szyfrów. Robi się listą z jasnymi parametrami, gdzie każdy znaczek mówi, ile zapłacisz pamięcią i ile odzyskasz jakości.

Bierz Q4_K_M, jak masz miejsce i nie chcesz myśleć. Schodź do IQ, jak walczysz o ostatni gigabajt. Idź w Q6_K albo Q8_0, jak karta ci pozwala i chcesz mieć pewność. Ale już nie zgadujesz — czytasz. A to jest dokładnie ta różnica między człowiekiem, który wlewa „ten niebieski olej, bo ładny", a takim, co spojrzał na spód i wie, po co sięga.

Przypisy · źródła


  1. Hugging Face Hub — dokumentacja formatu GGUF: wzory wag i teoretyczne bits-per-weight każdego typu (Q2_K…Q6_K, IQ…), definicja super-bloków, rozróżnienie legacy quantów od k- i i-quantów, statusy Q8_0 i Q8_K, wzmianki o TQ1_0/TQ2_0 i MXFP4. huggingface.co/docs/hub/gguf↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  2. llama.cpp — dokumentacja narzędzia llama-quantize: tabele zmierzonych bits/weight i rozmiarów dla Llama-3.1-8B, przykładowa komenda Q4_K_M, flagi (--pure, --allow-requantize, --imatrix), zalecenie ws. mmproj oraz tabela rozmiarów 8B/70B/405B. tools/quantize/README.md↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  3. k-quants (Q2_K…Q6_K), ikawrakow — wprowadzenie rodziny k-quantów, definicja super-bloków oraz miksu tensorów kryjącego się pod przyrostkami S/M/L. Pull Request #1684, ggml-org/llama.cpp↩︎ ↩︎ ↩︎

  4. Importance Matrix calculation, ikawrakow — wprowadzenie mechanizmu imatrix, per-tensor tablicy istotności wag używanej do priorytetyzacji precyzji przy kwantyzacji. Pull Request #4861, ggml-org/llama.cpp↩︎