Quantisierte Modelle bewerten: Perplexity, KL-Divergenz & echte Task-Evals
Woher weiß ich, dass IQ3_M noch gut genug ist? Wie man den Qualitätsverlust einer Quantisierung misst – mit llama-perplexity, KL-Divergenz gegen das Basismodell und einer kleinen eigenen Task-Eval.

Im Quantisierungs-Post habe ich Qwen3-32B auf 16 GB gebracht – aber eine Frage blieb offen: Woher weiß ich, dass IQ3_M nicht heimlich dümmer ist? „Läuft und klingt plausibel“ ist keine Messung. Hier die drei Ebenen, mit denen ich Quantisierungen tatsächlich bewerte.
Ebene 1: Perplexity – nützlich, aber trügerisch
Perplexity (PPL) misst, wie „überrascht“ das Modell von echtem Text ist – niedriger ist besser. llama.cpp bringt das Werkzeug mit:
# Testtext (z. B. wikitext) einmal besorgen, dann pro Quant messen
./llama-perplexity -m qwen3-32b-bf16.gguf -f wiki.test.raw -ngl 99
./llama-perplexity -m qwen3-32b-IQ3_M.gguf -f wiki.test.raw -ngl 99Typisch bekommst du etwas wie PPL = 6.41 (bf16) vs. PPL = 6.78 (IQ3_M). Die Falle: PPL ist ein Durchschnitt über generischen Text. Ein Modell kann bei Wikitext fast identisch aussehen und trotzdem bei deinen Aufgaben einbrechen. PPL ist ein Rauchmelder, kein Qualitätsurteil.
Ebene 2: KL-Divergenz – der ehrliche Vergleich
Viel aussagekräftiger ist die Frage: Wie weit weicht die Wahrscheinlichkeitsverteilung des quantisierten Modells von der des Originals ab? Genau das misst die KL-Divergenz – und llama.cpp kann sie direkt gegen ein Basismodell berechnen.
# 1. Referenz-Logits vom vollen Modell einmal aufzeichnen
./llama-perplexity -m qwen3-32b-bf16.gguf -f eval.txt \
--kl-divergence-base qwen3-32b.kld -ngl 99
# 2. Quantisiertes Modell gegen diese Referenz vergleichen
./llama-perplexity -m qwen3-32b-IQ3_M.gguf -f eval.txt \
--kl-divergence-base qwen3-32b.kld --kl-divergence -ngl 99Das gibt u. a. Mean KLD und – für mich der wichtigste Wert – den Anteil der Tokens, an denen sich die Top-Vorhersage ändert. Faustregel aus meiner Praxis:
Mean KLD < 0,1→ praktisch nicht unterscheidbar vom Original.0,1–0,5→ brauchbar, leichte Drift.> 0,5→ sichtbarer Qualitätsverlust, zu aggressiv quantisiert.
Anders als PPL sagt die KLD nicht „ist das Modell gut“, sondern „wie viel vom Original ist noch übrig“ – genau die Frage bei Quantisierung.
Ebene 3: Echte Task-Eval – die einzige, die zählt
Am Ende entscheidet, ob das Modell meine Aufgaben löst. Dafür halte ich ein kleines Set fester Prompts mit prüfbarer Antwort – eine Mini-Eval, die ich gegen jeden Quant laufen lasse. Über den llama-server-Endpunkt geht das mit ein paar Zeilen Python:
import json, urllib.request
CASES = [
{"prompt": "Gib NUR die Zahl zurück: 17 * 23 =", "expect": "391"},
{"prompt": "Antworte mit einem Wort: Hauptstadt von Australien?", "expect": "Canberra"},
{"prompt": "Gültiges JSON für {name: Alain, jahr: 2026}, nur das Objekt:",
"expect": '{"name": "Alain", "jahr": 2026}'},
]
def ask(prompt: str) -> str:
body = json.dumps({"prompt": prompt, "temperature": 0, "n_predict": 32}).encode()
req = urllib.request.Request("http://localhost:8080/completion", body,
{"Content-Type": "application/json"})
return json.loads(urllib.request.urlopen(req).read())["content"].strip()
passed = sum(c["expect"] in ask(c["prompt"]) for c in CASES)
print(f"{passed}/{len(CASES)} bestanden")Entscheidend ist temperature: 0 – deterministisch, sonst misst du Zufall. Die Fälle sollten deine Domäne treffen: Wer das Modell für Code nutzt, packt Code-Aufgaben hinein (genau wie beim imatrix-Kalibrierungstext im Quantisierungs-Post). Für weichere Aufgaben ersetzt man den Exact-Match durch einen LLM-als-Richter – aber dann bewusst mit einem stärkeren Modell als Prüfer.
Der Workflow in einem Satz
PPL als schneller Rauchmelder, KL-Divergenz als ehrliches Maß für „wie nah am Original“, und die eigene Task-Eval als letztes Wort. Erst dieses Trio macht aus „fühlt sich okay an“ eine Entscheidung: IQ3_M behalten oder doch eine Stufe höher gehen.
Verwandt: Qwen3-32B manuell quantisieren liefert die Modelle, die hier auf den Prüfstand kommen.