Leitfaden für LLM-Modellformaten, Konvertierung und Quantisierung

15. Dez. 2025

Ich habe verschiedene Arten von KI-Modellen getestet und damit experimentiert, darunter Stable Diffusion (SD) und Large Language Models (LLMs). Aufgrund meiner begrenzten Rechenkapazitäten (mit insgesamt 96 GB GPU-Speicher) kann ich nicht alle verfügbaren Modelle nativ ausführen. Insbesondere die neuesten LLMs (Stand Dezember 2025) sind für meine Hardware zu groß. Daher mussten verschiedene quantisierte Versionen ausgeführt werden. Da die Auswahl an verfügbaren Modellformaten und Quantisierungsoptionen erheblich gewachsen ist, fasse ich in diesem Beitrag meine Erkenntnisse zusammen (vielleicht ist das für jemanden nützlich).

Modelldateiformate

Die fünf Modelldateiformate, denen ich am häufigsten begegnet bin, sind:

In diesem Abschnitt fasse ich den Hintergrund dieser Formate zusammen.

bin: Old-School Catch-All

Obwohl bin technisch gesehen kein Format ist, handelt es sich dennoch um eine Art der Modelldarstellung, die typisch für frühere Versionen älterer Transformer-Modelle ist. Aufgrund seines generischen Formats konnten Frameworks wie PyTorch oder TensorFlow (je nach Herkunft) ihre Modellgewichte als bin speichern.

Schließlich bedeutet die Erweiterung bin einfach „Binärdatei“ und wurde in der Vergangenheit als generischer Container für Modellgewichte verwendet.

Obwohl dieses Format nach wie vor verbreitet ist und weitreichende Unterstützung findet, da es das Speichern und Laden von Modellgewichten vereinfacht, erfordert es für die Speicherung eine beträchtliche Menge an Speicherplatz. Außerdem verfügt es über keine integrierten Sicherheitsgarantien und keine Standardstruktur (was bedeutet, dass zwei „bin“-Dateien inhaltlich völlig unterschiedlich sein können).

Daher wird es hauptsächlich für ältere Modelle oder schnelle manuelle Checkpoints verwendet. Moderne Arbeitsabläufe bevorzugen strukturiertere Formate.

pt: Das native Format von PyTorch

pt ist typisch für die Training-Pipelines von PyTorch und das offizielle Speicherformat für Modelle unter PyTorch, das zum Speichern folgender Daten verwendet wird:

Es beruht auf Python pickle, und manchmal werden Dateien auch als pth gespeichert. Daher ist dieses Format ein offizielles Format, das vollständig mit PyTorch kompatibel ist und den vollständigen Trainingsstatus darstellt (sofern es so gespeichert wurde). Da es jedoch pickle verwendet, ermöglicht es auch die Ausführung von beliebigem Code, was bedeutet, dass es nicht sicher ist, es aus nicht vertrauenswürdigen Quellen zu laden. Ähnlich wie bin kann pt groß sein und langsam laden.

Daher wird pt hauptsächlich für das Training von Modellen, die Erstellung von Forschungsprototypen oder den Austausch von Checkpoints zwischen PyTorch-Teams verwendet.

safetensors: Sicher, Schnell und Framework Unabhängig

Das safetensors-Format wurde vom Team von Hugging Face entwickelt und ist ein Format, das typischerweise von Diffusionsmodellen, LLMs und allen öffentlich geteilten Modellen verwendet wird. Im Gegensatz zu pt wird das safetensors-Format von einer größeren Vielfalt an Frameworks wie PyTorch, TensorFlow, JAX usw. unterstützt.

Daher kann man sagen, dass safetensors eine moderne Alternative zu pt ist und auf zwei Ziele ausgerichtet ist:

  1. Sicherheit (kein Pickle, kein ausführbarer Inhalt, 100 % sicher beim Laden aus nicht vertrauenswürdigen Quellen)
  2. Geschwindigkeit (Zero-Copy-Speicherzuordnung, schnelleres Laden als pt)

Allerdings ist das safetensors-Format im Vergleich etwas starrer, was bedeutet, dass es nicht so mühelos für exotische (bzw. selbst definierte) Checkpoint-Strukturen verwendet werden kann.

Daher wird es hauptsächlich beim Herunterladen von Modellen aus dem Internet, beim sicheren Verteilen von Modellen oder beim Ausführen großer Modelle mit hoher Leistung verwendet.

ggml: Leichtgewichtiges, CPU-freundliches Format

Das ggml-Format wurde von Georgi Gerganov (für llama.cpp) entwickelt und ist für CPU- und Small-Device-Inferenz optimiert. Es unterstützt quantisierte Modelle (4-Bit, 5-Bit, 8-Bit), wodurch die Dateigrößen reduziert werden können. Die Abkürzung steht daher für Georgi Gerganov Machine Learning.

Ich würde sagen, dass ggml das bahnbrechende Format war, da es die lokale Ausführung von Modellen im LLaMA-Stil auf Laptops und sogar Smartphones ermöglichte. Heutzutage werden LLMs oft quantisiert, um die Größe und den Speicherverbrauch drastisch zu reduzieren.

Das Format ggml ist jedoch mittlerweile veraltet und nicht standardisiert. Es lässt sich zwar schneller laden als bin, pt oder safetensors, aber immer noch langsamer als Nachfolgemodelle (wie gguf).

Daher wird ggml meist für ältere Versionen von llama.cpp oder Legacy-Modelle verwendet.

gguf: Das moderne llama.cpp Format

Laut den Betreuern von llama.cpp steht gguf für GPT-Generated Unified Format (manchmal auch als GGML Unified Format erklärt). Es ist hinsichtlich Geschwindigkeit, Metadaten, Quantisierung und Portabilität optimiert.

Daher ist gguf das neue empfohlene Format für das llama.cpp-Ökosystem. Es behebt viele Einschränkungen von ggml und bietet umfangreiche Metadaten, eine verbesserte Ladegeschwindigkeit und eine breite Tool-Unterstützung.

Allerdings hat auch gguf seine Nachteile. Beispielsweise ist es für ältere Frameworks nicht lesbar und erfordert eine Modellkonvertierung aus den ursprünglichen Gewichten.

Dennoch hat sich gguf als neuer Standard durchgesetzt und ermöglicht die Ausführung quantisierter LLMs auf Heim-PCs (einschließlich Raspberry Pi) und ist mit lokalen Inferenzengines (z. B. Ollama, llama.cpp, LM Studio, KoboldCpp usw.) kompatibel.

Weitere erwähnenswerte Formate

Obwohl ich sie nicht verwendet habe, gibt es auch andere Formate, die erwähnenswert sein könnten.

ONNX (.onnx)

Dies ist ein frameworkübergreifendes, portables Format, das von PyTorch, TensorFlow, C++, JavaScript usw. unterstützt wird. Es ist beliebt für Produktionsbereitstellungen und die Optimierung von Modellen für die Inferenz (z. B. ONNX Runtime).

H5 (.h5 / .hdf5)

Dies ist das ältere Keras/TensorFlow-Format. Es verliert zwar an Popularität, wird aber immer noch in älteren Projekten verwendet.

.ckpt

Dies ist eine generische Checkpoint-Datei, die frameworkübergreifend verwendet wird, aber nicht standardisiert ist. Sie ist in älteren Stable Diffusion-Modellen weit verbreitet, aber diese haben aufgrund ihrer Vorteile auch safetensors übernommen.

Zusammenfassung der Modellformate

Jedes dieser Dateiformate spiegelt einen Moment in der Entwicklung der Machine-Learning-Praxis wider:

Quantisierung

Sowohl ggml als auch gguf unterstützen die Quantisierung von Modellen. Bei der Quantisierung werden die Datentypen, in denen die Modellgewichte gespeichert sind, in weniger präzise Datentypen umgewandelt, um den Speicherbedarf beim Speichern des Modells zu reduzieren. Es handelt sich also um einen Kompromiss zwischen Modellgeschwindigkeit, -größe und -genauigkeit.

Während Modelle in voller Größe in der Regel Fließkommadarstellungen verwenden (d.h. F16 für 16-Bit-Fließkommawerte oder F32 für 32-Bit-Fließkommawerte), reduziert die Quantisierung die Genauigkeit durch die Verwendung kleinerer Darstellungen. Die Suffixe der Modelldateien (Q4_K_M, Q6_K oder Q8_0) geben Aufschluss darüber, wie anspruchsvoll oder leistungsfähig das Modell ist.

Das Suffix kann in vier Teile unterteilt werden:

  1. Verbesserte Quantisierung: Das Präfix I steht für einen ganzzahligen oder verbesserten Quantisierer.
  2. Quantisierungsstufe: Q gefolgt von einer Ziffer (z. B. Q4, Q6, Q8 usw.), die die Anzahl der Bits in jedem quantisierten Gewichtsspeicher angibt.
  3. Das Quantisierungsformat: K steht für gruppierte Quantisierung (verwendet Skala und Nullpunkt pro Gruppe), 0 steht für ungruppiert (Quantisierung im älteren Stil) und 1 steht für ein anderes älteres Quantisierungsformat.
  4. Die Quantisierungsgenauigkeit: S für geringe Genauigkeit (am schnellsten, geringere Genauigkeit), M für mittlere Genauigkeit oder L für hohe Genauigkeit (am langsamsten, höhere Genauigkeit).

Das bedeutet, dass das Beispiel Q4_K_M ein quantisiertes Modell mit 4 Bits pro Gewicht einer Variante mittlerer Genauigkeit/Qualität des K-Schemas ist.

Der Quantisierungsprozess wandelt nicht einfach Fließkommawerte in ganzzahlige Darstellungen um (hier würde ein Wert von 0,327 auf 0 gerundet werden), da Modellgewichte in der Regel nahe Null liegen und nicht den gesamten Bereich der Ganzzahlen nutzen (z. B. 0 bis 255 einer vorzeichenlosen 8-Bit-Ganzzahl). Daher werden eine Skala \(d\) und ein Nullpunktversatz \(m\) verwendet, um den Bereich des von der Quantisierung verwendeten Datentyps optimal zu nutzen:

\[ w = d \cdot q + m\]

Bei der Wiederherstellung des Gewichts \(w\) aus dem quantisierten Wert \(q\) liegt das Ergebnis nahe am ursprünglichen Wert, entspricht jedoch nicht genau diesem. Für die meisten Anwendungen ist dieser Quantisierungsverlust jedoch akzeptabel.

Modellperplexität

Es ist möglich zu messen, inwieweit die Quantisierung die Modellgenauigkeit beeinträchtigt. Die Metrik, die dies tut, wird als Perplexität bezeichnet. Die Perplexität misst, wie gut ein Sprachmodell Text vorhersagt. Eine niedrigere Perplexität bedeutet weniger "Verwirrung" des Modells und ein Verhalten, das näher an der Originalversion ohne Quantisierung liegt. Beim Vergleich von Quantisierungsschemata ist vor allem die relative Perplexität wichtig, d.h. die Perplexität des quantisierten Modells im Vergleich zu seinem Gegenstück mit voller Genauigkeit FP16 oder FP32. Wenn Sie ./llama-quantize --help im Projekt llama.cpp ausführen, wird eine Tabelle mit allen unterstützten Quantisierungsvarianten und ihren Perplexitywerten angezeigt (die Zahlen basieren auf dem Vicuna-13B-Modell):

Allowed quantization types:
   2  or  Q4_0    :  4.34G, +0.4685 ppl @ Llama-3-8B
   3  or  Q4_1    :  4.78G, +0.4511 ppl @ Llama-3-8B
  38  or  MXFP4_MOE :  MXFP4 MoE
   8  or  Q5_0    :  5.21G, +0.1316 ppl @ Llama-3-8B
   9  or  Q5_1    :  5.65G, +0.1062 ppl @ Llama-3-8B
  19  or  IQ2_XXS :  2.06 bpw quantization
  20  or  IQ2_XS  :  2.31 bpw quantization
  28  or  IQ2_S   :  2.5  bpw quantization
  29  or  IQ2_M   :  2.7  bpw quantization
  24  or  IQ1_S   :  1.56 bpw quantization
  31  or  IQ1_M   :  1.75 bpw quantization
  36  or  TQ1_0   :  1.69 bpw ternarization
  37  or  TQ2_0   :  2.06 bpw ternarization
  10  or  Q2_K    :  2.96G, +3.5199 ppl @ Llama-3-8B
  21  or  Q2_K_S  :  2.96G, +3.1836 ppl @ Llama-3-8B
  23  or  IQ3_XXS :  3.06 bpw quantization
  26  or  IQ3_S   :  3.44 bpw quantization
  27  or  IQ3_M   :  3.66 bpw quantization mix
  12  or  Q3_K    : alias for Q3_K_M
  22  or  IQ3_XS  :  3.3 bpw quantization
  11  or  Q3_K_S  :  3.41G, +1.6321 ppl @ Llama-3-8B
  12  or  Q3_K_M  :  3.74G, +0.6569 ppl @ Llama-3-8B
  13  or  Q3_K_L  :  4.03G, +0.5562 ppl @ Llama-3-8B
  25  or  IQ4_NL  :  4.50 bpw non-linear quantization
  30  or  IQ4_XS  :  4.25 bpw non-linear quantization
  15  or  Q4_K    : alias for Q4_K_M
  14  or  Q4_K_S  :  4.37G, +0.2689 ppl @ Llama-3-8B
  15  or  Q4_K_M  :  4.58G, +0.1754 ppl @ Llama-3-8B
  17  or  Q5_K    : alias for Q5_K_M
  16  or  Q5_K_S  :  5.21G, +0.1049 ppl @ Llama-3-8B
  17  or  Q5_K_M  :  5.33G, +0.0569 ppl @ Llama-3-8B
  18  or  Q6_K    :  6.14G, +0.0217 ppl @ Llama-3-8B
   7  or  Q8_0    :  7.96G, +0.0026 ppl @ Llama-3-8B
   1  or  F16     : 14.00G, +0.0020 ppl @ Mistral-7B
  32  or  BF16    : 14.00G, -0.0050 ppl @ Mistral-7B
   0  or  F32     : 26.00G              @ 7B

Wie hier auf Github erläutert, ändert sich die Perplexität je nach Größe des Modells oder Wahl der Quantisierung:

Perplexität vs Größe

Es ist zu beachten, dass die x-Achse (Modellgröße in GiB) logarithmisch ist. Die verschiedenen Kreise im Diagramm zeigen die Perplexität verschiedener Quantisierungsmischungen, und die ausgefüllten Quadrate stehen für das ursprüngliche FP16-Modell (d.h., für jede Zeile wurde Q2_KQ3_KQ4_KQ5_KQ6_KQ7_KFP16 verwendet). Die verschiedenen Farben geben die verwendete LLaMA-Variante an (7B in Schwarz, 13B in Rot, 30B in Blau, 65B in Magenta). Die gestrichelten Linien wurden der Übersichtlichkeit halber hinzugefügt, um besser beurteilen zu können, wie nahe die quantisierten Modelle an die „FP16“-Perplexität herankommen. Wie aus diesem Diagramm ersichtlich ist, ist die Generierungsleistung, gemessen anhand der Perplexität, im Grunde eine ziemlich gleichmäßige Funktion der Größe des quantisierten Modells, und die Quantisierungstypen ermöglichen es dem Benutzer, das quantisierte Modell mit der besten Leistung auszuwählen, unter Berücksichtigung der Grenzen seiner Rechenressourcen (im Hinblick auf die Möglichkeit, das Modell vollständig in den Speicher zu laden, aber auch im Hinblick auf die Inferenzgeschwindigkeit, die in der Regel von der Modellgröße abhängt).

Bemerkenswert ist vielleicht, dass die Perplexität des 6-Bit-quantisierten Modells (Q6_K) innerhalb von 0,1 % oder besser vom ursprünglichen FP16-Modell liegt.

Modelle Konvertieren

Manchmal werden Modelle auf Hugging Face in einem Rohformat bereitgestellt, das für die lokale Ausführung zu groß ist. Daher ist es notwendig, das Modell von einem Format in ein anderes zu konvertieren. Der Konvertierungsprozess umfasst:

Hier ist llama.cpp mein bevorzugtes Tool geworden, und im folgenden Abschnitt erkläre ich, wie man Modelle mit llama.cpp konvertiert.

Modell erhalten

Typischerweise sieht ein Hugging Face-Modellordner in etwa so aus:

model/
  config.json
  tokenizer.json / tokenizer.model / vocab files
  model-00001-of-00004.safetensors
  model-00002-of-00004.safetensors
  model-00003-of-00004.safetensors
  model-00004-of-00004.safetensors

Händisch

Am einfachsten ist es, das Modell über einen Browser herunterzuladen, indem Sie https://huggingface.co/models aufrufen, das gewünschte Modell auswählen, auf files and versions klicken und jede Datei des Modells manuell herunterladen. Bei größeren Modellen kann dies recht mühsam sein.

Git LFS

Alternativ kann Git LFS (Large File System) verwendet werden. Dazu muss LFS installiert werden:

git lfs install

Anschließend kann das Modell-Repository geklont werden:

git clone https://huggingface.co/<user>/<model-name>

Dadurch werden alle Dateien des Modells automatisch heruntergeladen.

Hugging Face CLI

Wenn man sich anmeldet, um ein Modell herunterzuladen, kann man die Hugging Face CLI verwenden, um das Modell-Repository automatisch herunterzuladen. Das CLI kann wie folgt installiert werden:

pip install huggingface_hub

Dann muss man sich mit folgenden Daten anmelden:

huggingface-cli login

Und schließlich kann das Repository wie folgt heruntergeladen werden:

huggingface-cli download <user>/<model-name> --local-dir ./model

Konvertierung

Verwendung des geladenen Repository

Zunächst muss der Konverter (z.B. llama.cpp) beschafft werden. Für gguf ist die am häufigsten verwendete Toolchain llama.cpp, die wie folgt heruntergeladen und eingerichtet werden kann:

git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp

# if you want to use the Python converter
pip install -r requirements.txt

# if you want to quantize and/or run models
cmake -B build
cmake --build build --config Release

Das Konvertierungsskript kann wie folgt ausgeführt werden:

python3 convert_hf_to_gguf.py \
  /path/to/model \
  --outfile /path/to/output/model.gguf \
  --vocab-type auto

Hier ist /path/to/model der Ordner, der Folgendes enthält:

Das Skript lädt dann automatisch die Konfiguration, liest alle safetensor-Shards, führt sie zusammen und schreibt eine Fließkomma-gguf-Datei.

Zu diesem Zeitpunkt wurde eine „Basis“-gguf-Datei erstellt (oft f16), die (je nach Modell) sehr groß sein kann.

Um kleinere Dateien zu erhalten (z.B. Q4_K_M, Q5_0 usw.), muss man quantisieren:

./llama-quantize \
  /path/to/output/model.gguf \
  /path/to/output/model-Q4_K_M.gguf \
  Q4_K_M

Docker

Alternativ kann man das offizielle Docker-Image herunterladen, wodurch die händische Installation von Abhängigkeiten entfällt:

docker pull ghcr.io/ggml-org/llama.cpp:full

Einen Docker-Container kann dann wie folgt gestartet werden und dann können dieselben Befehle wie oben verwenden werden.

docker run --rm -it \
  -v $HOME/llama-models:/models \
  --entrypoint /bin/bash \
  ghcr.io/ggml-org/llama.cpp:full

Alternativ kann man auch nur die Konvertierungs-/Quantisierungsbefehle mit Docker ausführen:

docker run --rm -it \
  -v $HOME/llama-models:/models \
  ghcr.io/ggml-org/llama.cpp:full \
  --convert /models \
  --outfile OUTFILE \
  --outtype OUTTYPE

Hier ist der Parameter /models das Verzeichnis, das die Modelldatei enthält (es kann durch eine Huggingface-Repository-ID ersetzt werden, wenn das Modell noch nicht heruntergeladen wurde). Der Parameter OUTFILE (optional) ist der Pfad, in den das konvertierte/quantisierte Modell geschrieben wird (Standard ist basierend auf dem Eingabeverzeichnis). Der Parameter OUTTYPE (optional) gibt das Ausgabeformat des Modells an und kann sein:

Weitere Informationen zu llama.cpp und seinem Docker-Image finden Sie hier.