Wchodzisz na Hugging Face po świeży model, otwierasz stronę i widzisz listę plików jak menu w barze mlecznym, w którym wszystko nazywa się prawie tak samo. Q4_K_M, Q5_K_S, Q6_K, Q8_0, IQ4_XS, gdzieś niżej jakiś BF16 na 30 gigabajtów. Wszystkie kończą się na .gguf, wszystkie są tego samego modelu, a ty stoisz i myślisz: dobra, ale który? I skąd się to w ogóle wzięło, skoro autor modelu wrzucił coś zupełnie innego?
To jest ten moment, w którym większość ludzi bierze na chybił trafił ten Q4_K_M, bo tak radzą na Reddicie, odpala i idzie dalej. I słusznie — działa. Ale pod tym jednym plikiem stoi cała cicha fabryka: ludzie, narzędzia, konwersje i format, który ktoś kiedyś usiadł i zaprojektował, żebyś ty mógł zrobić dwuklik. Warto wiedzieć, co tam mruczy pod maską — bo dzięki temu przestajesz zgadywać, a zaczynasz wybierać świadomie.
Co to w ogóle jest, ten GGUF
Zacznijmy od rozczarowania, bo lepiej od razu: GGUF to nie jest model. To nie nowa architektura, nie nowy sposób trenowania, nie magiczny AI od ggerganova. To pojemnik. Format pliku — dosłownie „GGML Universal File” — do trzymania modelu na dysku tak, żeby silnik inferencyjny mógł go szybko wczytać i zacząć gadać.1 Model (Llama, Qwen, Mistral — cokolwiek) rodzi się gdzie indziej, w treningu na klastrze, którego rachunku za prąd żaden z nas nie chciałby zobaczyć. GGUF to dopiero opakowanie, w które ten wytrenowany model się przepakowuje na koniec, pod kątem tego, że odpalisz go u siebie na jednej karcie.
Format wymyślił Georgi Gerganov, ten sam, który stoi za llama.cpp i biblioteką ggml.2 GGUF jest następcą kilku starszych formatów o równie uroczych nazwach — GGML, GGMF, GGJT — które po drodze się wykruszyły. I tu pierwsza pułapka, w którą łatwo wdepnąć: GGML i GGUF to nie synonimy. GGML to ten stary, w dużej mierze wyparty format pliku (i przy okazji wciąż nazwa biblioteki tensorowej pod spodem), a GGUF to jego młodszy, mądrzejszy brat z porządnymi metadanymi.1
Co siedzi w tym jednym pliku
To jest właśnie sedno, dla którego GGUF wygrał. Otwórz sobie w głowie taki plik jak pudełko z przegródkami:
- Nagłówek — na samym początku cztery bajty
GGUF(magic number, bajt po bajcie0x47 0x47 0x55 0x46), zaraz za nimi numer wersji formatu, liczba tensorów i sterta metadanych.1 - Metadane klucz-wartość — i tu robi się ciekawie. Zamiast beztypowej listy liczb jak w starych formatach, GGUF trzyma nazwane pola w hierarchii z kropkami:
general.architecture,llama.context_length,general.quantization_version. Kluczgeneral.architecture(czym ten model właściwie jest) musi być zawsze, a jak model jest skwantowany, to musi być teżgeneral.quantization_version.1 - Tokenizer — w środku, w tym samym pliku. To jest ten myk, którego naprawdę brakowało wcześniej. GGUF potrafi wnieść cały tokenizer: natywne tablice tokenów, scores i merges, albo pełny
tokenizer.jsonprosto z Hugging Face, albo szablony czatu w Jinja.1 Dlatego jeden.ggufwystarcza — nie musisz dociągać pięciu plików obok. - Same wagi — na końcu surowe dane tensorów, wyrównane do granicy (domyślnie co 32 bajty, klucz
general.alignment), żeby silnik mógł je wczytać przezmmapbez mielenia całego pliku.1
To „wszystko w jednym pliku” jest dokładnie tym, co robi z GGUF format do lokalnej inferencji. Ściągasz jeden plik i masz komplet: wagi, architekturę i tokenizer. Nie ma cyrku z dociąganiem config.json, tokenizer.json i trzech innych obok. Silnik typu llama.cpp bierze go przez mmap i startuje w sekundę, bez deserializacji. Mniej ruchomych części to mniej rzeczy, które ci się rozjadą o 23:00, gdy chcesz tylko o coś zapytać model.
Skąd biorą się wszystkie te warianty
No dobra, a czemu tego samego modelu jest dwadzieścia sztuk? Bo GGUF wspiera całą tęczę typów tensorów: pełną precyzję (F32, F16, BF16), serię K (Q2_K do Q6_K), stare legacy (Q4_0, Q8_0), nowszą serię IQ opartą na macierzy istotności (IQ4_XS, IQ2_XXS) i egzotykę w stylu ternarnego TQ1_0.1 Każdy z tych Q-ów to inny schemat ściśnięcia wag. Q4_K upycha wagę w jakichś 4,5 bita, Q6_K w 6,56, Q2_K w 2,63 — i to są dokładnie te przegródki, w których leży cały kompromis rozmiar/jakość/szybkość.2
I tu druga pułapka: te warianty to nie są różne modele. Q4_K_M, Q5_K_S, Q8_0 tego samego modelu to te same wagi bazowe, tylko skompresowane innym sitem. Grubszy plik = bliżej oryginału i wolniej, chudszy = mniej VRAM-u i szybciej, ale z lekkim ubytkiem jakości. Co ważne, to jest kwantyzacja post-training — bierzesz gotowy, wytrenowany model i ściskasz go po fakcie. Nie mylić z trenowaniem od zera w niskiej precyzji. W nazewnictwo tych literek zagłębialiśmy się osobno tutaj, bo to temat na własny wpis.
Kto to wszystko właściwie robi
Teraz najlepsze. Ten Q4_K_M, który ściągasz — bardzo często nie zrobił go autor modelu. Autor wrzuca zwykle wagi w safetensors i może jedną-dwie wersje GGUF, a resztę tego bufetu produkują ludzie z boku: community-quantizerzy. Konta jak bartowski czy mradermacher (dawniej głośny TheBloke) siedzą i masowo mielą cudze modele na wszystkie możliwe warianty, dzień po dniu, jak taka lokalna piekarnia GGUF-ów.
Jak to robią bez klastra? Dwiema drogami. Pierwsza to skrypt convert_hf_to_gguf.py prosto z repo llama.cpp — łyka wagi z Hugging Face i wypluwa GGUF, obsługuje kupę architektur (w tym multimodalne i MoE), ma opcje --outtype (bierzesz f16, bf16, q8_0… — czym te „szesnastki" różnią się od siebie, jest tu), --vocab-only, --split-max-size do krojenia wielkich plików, a nawet --remote, żeby konwertować prosto z Huba.3 Druga droga jest jeszcze leniwsza: ggml-org/gguf-my-repo, gotowy Space na Hugging Face, gdzie wklejasz repo, klikasz i dostajesz komplet kwantyzacji bez kompilowania czegokolwiek u siebie.4
# klasyczna droga: własny build llama.cpp
python convert_hf_to_gguf.py ./Qwen2.5-7B-Instruct \
--outtype f16 --outfile qwen2.5-7b-f16.gguf
# a potem osobno kwantyzacja narzędziem llama-quantize do Q4_K_M itd.
Sam Hugging Face traktuje ten format jak pełnoprawnego obywatela: masz filtr library=gguf, który pokazuje wszystko, co gęgnięte (hf.co/models?library=gguf), a na stronie konkretnego pliku podejrzysz metadane i listę tensorów wprost z przeglądarki, bez ściągania.2 Praktyczny wniosek: skoro warianty sypie kto chce, sprawdzaj, czyje repo bierzesz. Zerknij na autora, na to, czy imatrix był użyty, czy karta modelu ma ręce i nogi. Na co patrzeć przy świeżym modelu rozkładaliśmy w osobnej notce.
GGUF kontra safetensors: to nie jest ranking
Skoro autor wrzuca safetensors, a ty odpalasz GGUF — który jest lepszy? Źle postawione pytanie. To dwa pojemniki do dwóch różnych rzeczy.
| GGUF | safetensors | |
|---|---|---|
| Co trzyma | wagi + architektura + tokenizer, w jednym pliku | tylko tensory, goła macierz liczb |
| Metadane / tokenizer | w środku | osobno (config.json, tokenizer.json) |
| Kwantyzacja | tak, to jego chleb (Q4_K_M, IQ…) | zwykle pełna precyzja lub bf16/fp16 |
| Pod co skrojony | inferencja przez llama.cpp/ggml, CPU/GPU | trening/inferencja w PyTorch, transformers, diffusers |
| Po co powstał | jeden plik gotowy do odpalenia | bezpieczna, szybka (zero-copy) alternatywa dla .bin/pickle |
Safetensors narodził się z zupełnie innej potrzeby: żeby nie ładować cudzych wag przez pickle (który potrafi odpalić dowolny kod przy wczytaniu) i żeby robić to szybko, bez kopiowania w pamięci.5 To rekomendowany format wag na Hugging Face — ale trzyma wyłącznie tensory. Chcesz z niego odpalić model, musisz dorzucić config i tokenizer obok. GGUF ten cały komplet nosi w sobie i dokłada kwantyzację. Nie „lepszy/gorszy” — inne zadanie. Jak chcesz to potem faktycznie uruchomić garścią flag, jest o tym osobny poradnik.
Wróć do tego menu
Wróć teraz do tego menu na Hugging Face, do listy dwudziestu plików kończących się na .gguf. Już nie wygląda jak bar mleczny, w którym wszystko nazywa się tak samo. Widzisz teraz, że ktoś wziął model wytrenowany na drugim końcu świata, przepuścił go przez convert_hf_to_gguf.py, upchał wagi, architekturę i tokenizer do jednego pudełka z przegródkami, ścisnął sitem Q4_K_M i wrzucił na Huba, żebyś ty mógł go zassać jednym plikiem i usłyszeć, jak mruczy pod biurkiem. Cała ta cicha fabryka — od klastra treningowego, przez konto bartowskiego, po twój dysk — sprowadza się do jednego czterobajtowego napisu na początku pliku: GGUF. Reszta to już tylko ty i pytanie, który wariant dziś bierzesz.
Specyfikacja formatu: struktura pliku, magic number
GGUF(0x47 0x47 0x55 0x46), wersje 1–3, wyrównaniegeneral.alignment, wymagane klucze metadanych, typy tensorów i osadzanie tokenizera, historia jako następca GGML/GGMF/GGJT — ggml-org/ggml,docs/gguf.md. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎Twórca formatu (@ggerganov), integracja z Hub (tag
library=gguf, viewer metadanych i tensorów), narzędziegguf-my-repo, porównanie z safetensors oraz tabela typów kwantyzacji z bitami-na-wagę — Hugging Face Hub docs, GGUF. ↩︎ ↩︎ ↩︎Mechanizm konwersji modeli HF do GGUF, obsługiwane architektury i opcje
--outtype,--vocab-only,--split-max-size,--remote— llama.cpp,convert_hf_to_gguf.py. ↩︎Narzędzie, którym community-quantizerzy konwertują i kwantyzują dowolne wagi HF do GGUF bez lokalnej kompilacji
llama.cpp— ggml-org/gguf-my-repo (Hugging Face Space). ↩︎Definicja safetensors jako bezpiecznego (bez deserializacji pickle), zero-copy formatu przechowywania samych tensorów oraz jego rola w ekosystemie transformers/diffusers/candle — Hugging Face, dokumentacja safetensors. ↩︎