Guide zur Model Quantization: Von den Grundlagen bis zum produktiven Model Serving
Automatische Übersetzung Dieser Artikel wurde automatisch aus der englischen Originalversion übersetzt.
Quantization verwendet weniger Bits zur Darstellung von Model-Werten. Ein Serving-Pfad kann Weights, Activations, den KV-Cache oder eine Kombination daraus quantisieren, wobei jedes Ziel ein anderes Serving-Problem löst.
Wähle das Ziel anhand des aktuellen Bottlenecks: Weight Memory, Activation Compute, KV-Cache-Größe, Kernels, Hardware, Calibration Data oder Quality. Ein 4-Bit-Model passt möglicherweise in den VRAM, läuft mit einem nicht optimierten Kernel jedoch langsam, wie der JarvisLabs-vLLM-Benchmark zeigt. FP8 funktioniert gut auf NVIDIA-Hopper-Hardware mit einem kompatiblen Runtime und bietet auf nicht unterstützten GPUs keinen nativen Vorteil. Die Hardware-Matrix von TensorRT-LLM zeigt die unterstützten Pfade. Bei langen Contexts oder hoher Concurrency kann KV-Cache Quantization mehr Speicher einsparen als Weight Quantization.
Wenn du als ML- oder Platform Engineer einen Quantization-Pfad für ein Model auswählst, das du ausliefern musst, ist dieser Leitfaden für dich. Nach der Lektüre solltest du in der Lage sein, einen Bottleneck vor dem Deployment einem geeigneten Format, Runtime und Validierungsplan zuzuordnen.
Einen kurzen Vergleich der Artefakte und Methoden findest du unter LLM Quantization Formats.
1. Mit dem Bottleneck beginnen
Ermittle vor der Wahl der Bit-Breite, was den Workload begrenzt. Die Ursache kann im Model Weight Memory, im Prefill Compute, in der Decode Bandwidth oder im KV-Cache liegen und nicht in der numerischen Präzision selbst.
Häufige Bottlenecks und ihre Ausgangspunkte:
| Wenn dies das Problem ist | Hier beginnen | Typische Tools | Vor dem Deployment prüfen |
|---|---|---|---|
| Model Weights passen nicht in den VRAM | W4A16 Weight-only Quantization | AWQ oder GPTQ mit llm-compressor oder GPTQModel | Perplexity, Coding, Reasoning, Instruction Following |
| High-Throughput Serving ist compute-bound | FP8 oder INT8 W8A8 | FP8 PTQ, SmoothQuant, TensorRT-LLM, vLLM | Throughput, TTFT, Task Accuracy |
| Long Context oder hohe Concurrency füllt die GPU | KV-Cache-Quantization | vLLM, TensorRT-LLM oder Transformers QuantizedCache | Long-Context-Retrieval, Latency, Safety und Quality |
| Lokale Inference auf CPU, Apple Silicon oder Desktop | GGUF-Dateien mit lokalen Tensor-Encodings | llama.cpp, Ollama, LM Studio | Prompt-Latency, RAM-Nutzung, ausgewähltes Tensor-Encoding und subjektive Output-Quality |
| Adapter-Fine-Tuning muss auf eine GPU passen | NF4 / QLoRA | bitsandbytes, peft | Fine-Tuning-Loss und Quality des gemergten Models |
| Bildgenerierungs-Pipeline ist zu groß oder zu langsam | Diffusionsspezifisches INT4 oder FP8 | SVDQuant, Nunchaku, torchao, NVIDIA ModelOpt | Visuelle Artefakte, Prompt-Ausrichtung, Latenz, VRAM |
Verwende diese Tabelle als Orientierung. In den folgenden Abschnitten wird erklärt, warum sich diese Ausgangspunkte unterscheiden.
Verwendete Notation in Serving-Rezepten
- W{x}A{y} gibt die Präzision für unterstützte Weight- und Activation-Berechnungen an, üblicherweise für GEMM-Pfade in Serving Engines. W4A16 speichert Weights in 4 Bit und hält Activations mit 16 Bit Präzision. W8A8 verwendet 8-Bit-Weights und -Activations in unterstützten Compute-Pfaden, definiert jedoch nicht automatisch den persistenten Storage-Dtype jedes Runtime-Tensors.
- FP8, INT8, INT4, NF4 sind Zahlenformate. Sie legen fest, welche Werte dargestellt werden können.
- GPTQ, AWQ, SmoothQuant, QuaRot sind Algorithmen. Sie legen fest, wie ein trainiertes Model in ein Format mit geringerer Präzision überführt wird.
- GGUF ist ein Dateiformat, das Tensoren und Metadaten für GGML- und
llama.cpp-artige Runtimes speichert. Eine GGUF-Datei kann nicht quantisierte Tensor-Typen wieF16,BF16oderF32sowie quantisierte Encodings enthalten. Zu den Presets gehörenQ4_K_M,Q5_K_M,Q8_0,IQ*,TQ*undMXFP4. Das Tensor-Encoding bestimmt die Quantization-Variante.GGUFallein beschreibt kein CUDA-artiges FP8-W8A8-Serving-Rezept. - KV cache ist der während der Generierung verwendete Attention-Cache. Er speichert bereits berechnete Keys und Values, damit das Model die gesamte Conversation nicht bei jedem Token erneut berechnen muss.
- KV-cache quantization speichert gecachte Key-/Value-Activation-Tensoren in einem Cache-Format mit geringerer Präzision, etwa FP8, INT8, INT4 oder INT2, abhängig vom Support der Runtime. Dies unterscheidet sich von Prefix Caching, PagedAttention und Offload: Diese legen fest, ob Cache-Einträge wiederverwendet werden, wie sie alloziert werden oder wo sie gespeichert sind.
- GEMM steht für General Matrix Multiply. Der größte Teil der Transformer-Inference-Zeit entfällt auf Matrixmultiplikationen.
2. Quantization ist kontrolliertes Runden
Quantization bildet Werte mit hoher Präzision auf eine kleinere Menge darstellbarer Werte ab. Das ist die zentrale Definition, die sowohl von Hugging Face Optimum als auch von TensorRT-LLM verwendet wird. Dadurch sparst du Memory und Bandwidth. Gleichzeitig entsteht Rundungsfehler.
INT4 stellt nur 16 diskrete Werte bereit. Werden BF16-Weights auf dieses Raster abgebildet, entsteht Rundungsfehler. Methoden wie GPTQ, AWQ und SVDQuant konzentrieren sich darauf, Outliers zu erhalten und den Rekonstruktionsfehler zu reduzieren. Eine gute Abbildung spart Memory bei geringem Qualitätsverlust. Eine schlechte Abbildung beeinträchtigt Reasoning, Instruction Following oder visuelle Fidelity.
Symmetric und Asymmetric Mapping
Gemäß dem affinen Mapping aus gängigen Quantization Guides bildet Quantization einen kontinuierlichen Float-Wert auf ein diskretes Raster ab.
- ist der ursprüngliche hochpräzise Wert.
- ist der quantisierte Wert.
- ist der Scale-Faktor beziehungsweise die Schrittweite.
- ist der Zero Point, also die ganzzahlige Position, die
0.0repräsentiert. - ist der Zielbereich der Ganzzahlen. Vorzeichenbehaftete 4-Bit-Werte verwenden häufig .
Symmetric Quantization zentriert das Raster um null und setzt :
Das ist hardwarefreundlich, weil die Runtime-Berechnung keinen Zero-Point-Offset subtrahieren muss. Der Quantization-Stack von PyTorch stellt diese affinen Scale- und Zero-Point-Entscheidungen als primitive Quantization-Parameter in torchao bereit.
Asymmetric Quantization verschiebt das Raster, um schiefe Wertebereiche abzudecken:
Dieses verschobene Raster kann Aktivierungen mit ausschließlich positiven Werten besser erhalten. Der Offset verursacht jedoch zusätzlichen Rechenaufwand, sofern der Kernel ihn nicht effizient verarbeitet.
Die Granularität des Scale-Faktors ist entscheidend
Der Scale-Faktor kann einen gesamten Weight-Tensor, einen einzelnen Channel oder eine kleine Gruppe von Werten abdecken. Die FP8-KV-Cache-Dokumentation von vLLM verwendet dieselbe Unterscheidung zwischen Per-Tensor- und Per-Attention-Head-Scale-Strategien. Kleinere Gruppen erhalten die Qualität in der Regel besser, benötigen jedoch mehr Scale-Metadaten.
| Granularität des Scale-Faktors | Was denselben Scale-Faktor verwendet | Auswirkung auf Qualität und Ausführung |
|---|---|---|
| Per Tensor | Die gesamte Weight-Matrix | Benötigt wenig Metadaten, aber ein einzelner Ausreißer kann das Raster aufweiten und die Präzision über den gesamten Layer hinweg reduzieren. |
| Per Channel | Eine Output-Zeile | Verhindert, dass Channels mit engen Wertebereichen denselben weiteren Wertebereich wie ein anderer Channel verwenden. Viele 8-Bit-Weight-Pfade nutzen diese Granularität. |
| Per Group | Ein Block innerhalb einer Zeile, häufig 64 oder 128 Werte | Begrenzt einen Ausreißer auf einen kleinen Block, erfordert dafür aber mehr Scale-Faktoren. AutoGPTQ verwendet group_size=128 in seinen GPTQ-Beispielen. |
Weights sind statisch, daher können ihre Scale-Faktoren offline berechnet werden, bevor du das Model lädst. Aktivierungen ändern sich mit jedem Token, wodurch ihre Wertebereiche vom Workload abhängen.
| Activation Scaling | Wann der Runtime die Skalierung auswählt | Vorteil | Fehlerfall oder Kosten |
|---|---|---|---|
| Static | Offline anhand eines Calibration Datasets | Vermeidet die Berechnung der Skalierung während der Inference. | Prompts außerhalb der kalibrierten Länge oder Verteilung können Activation Spikes abschneiden und die Ausgabe beeinträchtigen. |
| Dynamic | Bei jedem Forward Pass | Passt sich an die aktuellen Activation-Werte und den Prompt-Mix an. | Die Berechnung der Wertebereiche in jedem Layer verursacht zusätzlichen Aufwand und erfordert optimierte Kernels. |
Der KV Cache liegt zwischen diesen beiden Fällen. Keys und Values beginnen als Runtime-Activation-Tensoren: Jeder Layer berechnet sie während des Forward Pass aus den Hidden States. Nach ihrer Erzeugung sind sie keine flüchtigen Matmul-Zwischenergebnisse mehr, sondern persistenter Serving-State, den die Attention für spätere Tokens liest.
Eine Serving Engine kann diesen State in geringerer Precision speichern und die Scale-Metadaten daneben ablegen. vLLM’s Quantized KV Cache, TensorRT-LLM’s FP8 KV Cache und Transformers QuantizedCache bieten diese Speicheroption jeweils an.
Die Storage Precision des Caches bleibt von der Activation Precision getrennt, die innerhalb von Linear Kernels verwendet wird. „KV-Cache Quantization“ bezeichnet eine Cache-Optimierung, nicht jede Technik, die Cache-Einträge wiederverwendet, allokiert oder verschiebt.
PTQ und QAT finden in unterschiedlichen Phasen statt
Post-Training Quantization oder PTQ komprimiert ein trainiertes Model nachträglich. Quantization-Aware Training oder QAT setzt das Model während des Trainings Quantization Noise aus, damit es sich daran anpassen kann.
| Methode | Wann die Wertebereiche gelernt werden | Verwende sie, wenn | Zu zahlende Kosten |
|---|---|---|---|
| Weight-only PTQ | Offline für statische Weights | Das Model nicht in den Speicher passt oder Decode durch die Bandbreite begrenzt ist | Activations laufen weiterhin mit 16 Bit |
| Static PTQ | Offline anhand von Calibration Prompts | Du schnelles W8A8 Serving möchtest | Die Calibration Data muss zur Production passen |
| Dynamic PTQ | Zur Runtime, pro Batch oder Activation-Pfad | Die Input-Verteilungen stark variieren | Zusätzlicher Runtime-Aufwand und geringere Hardware-Unterstützung |
| QAT | Während des Trainings | PTQ die Qualität eines empfindlichen Models beeinträchtigt | Vollständige Trainingsinfrastruktur und deutlich mehr Compute |
Kalibrierungsdaten müssen dem Traffic entsprechen, den Sie später bedienen. Der KV-Cache-Kalibrierungspfad von vLLM verwendet beispielsweise ein kuratiertes Dataset über llm-compressor. Wenn Production-Prompts aus langen RAG-Traces bestehen, liefern kurze Wikipedia-Absätze zwar saubere Benchmark-Zahlen, aber ein fehlerhaftes Deployment. Das Model passt seine Activation-Scales an kurze Texte an und trifft dann bei echten Long-Context-Prompts auf andere Activation-Patterns. Evaluierungen der Long-Context-Quantization messen dieses Risiko direkt.
3. Zahlenformate bestimmen die Hardwareanforderungen
Das Zahlenformat legt fest, welche Werte das Model im Speicher darstellen kann. Effiziente Berechnung erfordert Runtime-Kernels und Hardware-Support für dieselbe Bitbreite und dasselbe Format. TensorRT-LLM dokumentiert sowohl die Rezeptliste als auch die Hardware-Support-Matrix.
| Format | Speicher pro Wert | Geeigneter Standard für | Wichtigster Prüfpunkt |
|---|---|---|---|
| BF16 / FP16 | 2 Byte | Baseline-Inference und training-kompatibles Serving | Hoher VRAM-Verbrauch und hoher Memory-Bandwidth-Traffic |
| FP8 | 1 Byte | High-Throughput-W8A8-Serving auf Ada, Hopper, Blackwell | Erfordert native FP8-Tensor-Cores und Runtime-Support |
| INT8 | 1 Byte | W8A8-Serving auf älterer oder Nicht-NVIDIA-Hardware | Activation-Outlier und Empfindlichkeit gegenüber statischer Calibration |
| INT4 | 0,5 Byte | W4A16, wenn der Weight-Speicher das Hauptlimit ist | Qualitätsverlust bei kleineren oder Reasoning-lastigen Models |
| FP4 / NVFP4 | ~0,5 Byte | Experimente und frühe Serving-Pfade im Blackwell-Zeitalter | Hardware-spezifische Compiler- und Runtime-Anforderungen |
| llama.cpp-GGUF-Encodings / Presets | Variabel | Lokale Inference auf CPU, Apple Silicon, Desktop und Edge | GGUF ist der Container. Das Tensor-Encoding ist die Quantization-Auswahl. |
| NF4 | 0,5 Byte | QLoRA-Adapter-Training | Für Production-Serving meist das falsche Exportformat |
BF16 und FP16 verwenden beide 16 Bit, verteilen die Präzision jedoch unterschiedlich und versagen daher auf unterschiedliche Weise. BF16 behält den 8-Bit-Exponentbereich von FP32 bei und ist schwerer zum Überlaufen zu bringen. FP16 verfügt über mehr Mantissenbits und einen engeren Exponentbereich, weshalb Aktivierungsspitzen mehr Aufmerksamkeit erfordern. Die Evaluation von Kurtic et al. verwendet ausdrücklich BF16 als Baseline beim Vergleich von FP8-, INT8- und INT4-Serving-Formaten.
FP8 hat zwei gängige Varianten. E4M3 bietet mehr Präzision und wird üblicherweise für Forward Weights und Activations verwendet. E5M2 bietet einen größeren Dynamikbereich und eignet sich besser für Gradients oder volatile Activation-Pfade. vLLM stellt beide FP8-E4M3- und E5M2-KV-Cache-Dtypes bereit. In der ACL-2025-Studie von Kurtic et al. mit dem Titel „Give Me BF16 or Give Me Death“ war FP8 W8A8 praktisch verlustfrei für die Llama-3.1-Familie über mehr als 500.000 Evals. Das Ergebnis gilt für diese Model-Familie, Eval-Suite und dieses Serving-Setup. Jede Deployment-Umgebung benötigt dennoch ihr eigenes Quality Gate.
Blackwell erweitert das Angebot um Microscaling-Formate wie MXFP8 und NVFP4. Statt einen Scale-Faktor für einen gesamten Tensor oder eine Zeile zu verwenden, nutzt Microscaling sehr kleine Blöcke. NVIDIAs NVFP4-Erklärung beschreibt 4-Bit-Floating-Point-Werte in Blöcken von 16, mit FP8-Scale-Faktoren und einem übergeordneten FP32-Scale-Faktor. Dieser Ansatz soll eine nahezu mit INT4 vergleichbare Speichergröße bei Floating-Point-Verhalten ermöglichen. Er erfordert jedoch eine passende Hardware-Architektur sowie passende Compiler- und Runtime-Unterstützung. Deshalb listet TensorRT-LLM FP4- und FP8-Support nach GPU-Generation auf.
4. Weight-only- vs. Weight-Activation-Quantization
Die Notation WxAy beschreibt die Präzision von Weights und Activations, die die GPU während der Inference auf unterschiedliche Weise belasten.
Während des Prefill verarbeitet das Model den Input-Prompt. Diese Phase ist normalerweise Compute-bound, weil die GPU große Matrixmultiplikationen ausführt. Deshalb sind W8A8-FP8/INT8-Rezepte für throughput-orientiertes Serving relevant.
Während des Decode generiert das Model jeweils einen Token. Diese Phase ist häufig Memory-Bandwidth-bound, weil die GPU fortlaufend Weights aus dem VRAM lädt, um den nächsten Token zu erzeugen. Weight-only-Papers wie GPTQ und AWQ zielen auf diese Belastung ab, indem sie die Anzahl der Weight-Bytes reduzieren.
W4A16 komprimiert Weights und belässt Activations in BF16 oder FP16. Die GPU lädt weniger Weight-Bytes und dequantisiert die Weights anschließend für die Multiplikation wieder in eine höherpräzise Darstellung. Das hilft beim Decode und bei Problemen, ein Model in den verfügbaren Speicher zu bekommen. Compute-bound Prefill profitiert möglicherweise kaum, weil die Matrixberechnung weiterhin mit 16 Bit ausgeführt wird.
W8A8 komprimiert Weights und die Activation-Tensoren, die von unterstützten Matmul-Kernels verwendet werden. Verfügt die Hardware über native Low-Precision-Tensor-Cores, kann die Serving Engine die Matrixberechnung direkt in FP8 oder INT8 ausführen. FP8 kann dadurch High-Throughput-Serving unterstützen, indem es den Memory Traffic reduziert und schnellere Arithmetik nutzt. Der KV Cache verfügt über eine eigene Storage-Einstellung. Prüfe daher den Cache Dtype oder die Cache-Implementierung der Runtime separat.
Wenn das Model nur knapp in den VRAM passt, beginnen Sie mit Weight-only Quantization, um den Memory Footprint zu reduzieren. Passt das Model zwar hinein, hat aber bei hoher Batch-Last Schwierigkeiten mit dem Throughput, evaluieren Sie FP8 oder INT8 W8A8, um die Compute-Phase zu beschleunigen. Treten Memory-Probleme nur bei langen Konversationen auf, schätzen Sie zunächst den KV-Cache-Term. Testen Sie KV-Cache Quantization, wenn dieser Term dominiert. Aktivieren Sie Prefix Caching, wenn wiederholte Prefixes dominieren.
5. Algorithmen vs. Runtime-Kernels
Quantization-Algorithmen (wie GPTQ oder AWQ) legen fest, wie die Model Weights auf eine niedrigere Präzision abgebildet werden. Runtime-Kernels (wie Marlin oder Custom Kernels von vLLM) sind der GPU-Code auf niedriger Ebene, der die Matrixmultiplikation ausführt. Ein stark komprimiertes Model läuft nur dann schnell, wenn es für sein spezifisches Quantization-Format einen optimierten Kernel gibt.
Der vLLM-Benchmark von JarvisLabs mit Qwen2.5-32B-Instruct auf einer NVIDIA H200 macht den Einfluss des Kernels sichtbar:
| Quantization / Kernel | Perplexity, niedriger ist besser | Pass@1, höher ist besser | Throughput | TTFT |
|---|---|---|---|---|
| FP16-Baseline | 6.56 | 56.1 % | 461 tok/s | 57.7 ms |
| AWQ | 6.84 | 51.8 % | 68 tok/s | 277.8 ms |
| GPTQ | 6.90 | 46.3 % | 277 tok/s | 107.1 ms |
| Marlin-GPTQ | 6.97 | 45.7 % | 712 tok/s | 51.9 ms |
| Marlin-AWQ | 6.84 | 51.8 % | 741 tok/s | 73.5 ms |
| GGUF Q4_K_M | 6.74 | 51.8 % | 93 tok/s | 958.0 ms |
| bitsandbytes | 6.67 | 51.8 % | 168 tok/s | 135.3 ms |
Übertragen Sie diese Zahlen nicht einfach auf Ihren eigenen Stack. Sie stammen von einem Model, einer GPU-Klasse und einem Software-Setup. Sie zeigen einen engeren Punkt: Der Algorithmusname auf dem Checkpoint sagt nichts darüber aus, wie schnell das Serving sein wird.
Beispielsweise verwenden AWQ und Marlin-AWQ dieselben 4-Bit-Weights. Die Marlin-Implementierung ist deutlich schneller, weil ihr CUDA-Kernel Dequantization und Matrixmultiplikation zu einer einzigen, hochoptimierten GPU-Operation fusioniert.
Benchmarken Sie die Baseline und die komprimierten Varianten mit derselben Prompt-Mischung und demselben Tool, etwa vllm bench serve:
vllm bench serve \
--model ./outputs/Qwen2.5-32B-Instruct-AWQ-W4A16 \
--dataset-name sharegpt \
--num-prompts 200 \
--input-len 1024 \
--output-len 256
Erfassen Sie Throughput, TTFT, Inter-Token-Latency, Memory Use und Task-Qualität. Wenn sich einige dieser Werte in entgegengesetzte Richtungen bewegen, müssen Sie diesen Trade-off vor dem Go-Live kennen.
Das Algorithmus-Menü
Verwenden Sie diese Tabelle als Orientierung, nicht als Ranking:
| Algorithmus | Übliches Format | Was erhalten werden soll | Hauptkosten |
|---|---|---|---|
| GPTQ | W4A16 | Layerweise Rekonstruktion mithilfe von Hessian-Schätzungen | Langsame Calibration und komplexere Verarbeitung |
| AWQ | W4A16 / W4A8 | Wichtige Activation Channels | Benötigt Calibration und fusionierte Serving-Kernels |
| SmoothQuant | W8A8 | INT8-Activation-Verhalten durch Verschieben der Outlier-Skalierung in die Weights | Skalierungstuning pro Model |
| QuaRot / SpinQuant | W4A4 / W4A8 | Geringeren Druck durch Activation-Outlier mittels Rotationen | Komplexität der Runtime-Rotationen |
| HQQ | W4A16 / W2A16 | Schnelle Weight-only-Kompression ohne Calibration | Qualität erfordert bei sehr niedrigen Bitbreiten nachgelagerte Prüfungen |
| QLoRA (NF4) | NF4 | Speicherbedarf beim Adapter-Training | Kein besonders guter Default für Serving |
| llama.cpp GGUF K-quants / IQ-quants | Gemischte Low-Bit-Tensor-Encodings | Qualität der lokalen Inference pro Byte | Nicht für Cloud-Batch-Serving ausgelegt |
Die Toolchain entwickelt sich aktiv weiter. AutoGPTQ wurde im April 2025 archiviert, und AutoAWQ wurde im Mai 2025 archiviert und offiziell deprecated. Für neue compressed-tensors-Checkpoints, die von vLLM genutzt werden, sollten Sie mit llm-compressor beginnen. Verwenden Sie GPTQModel, wenn Sie den aktiven GPTQ-Pfad mit Marlin, Machete, MoE-Speicheroptionen oder Disk-Offload benötigen.
Pruning und Distillation reduzieren die Serving-Kosten ebenfalls, allerdings über separate Workflows. 2:4 Structured Sparsity entfernt Weights in einem Muster, das NVIDIA Sparse Tensor Cores nutzen können. Distillation trainiert ein kleineres Student Model darauf, ein größeres Model zu imitieren, was für eng umrissene Tasks gut funktionieren kann. Nehmen Sie einen der beiden Pfade nur dann in die Shortlist auf, wenn das Projekt den zusätzlichen Pruning- oder Trainingsaufwand unterstützen kann.
6. Serving Memory umfasst mehr als die Weights
Der komprimierte Checkpoint ist nur ein Teil des Serving-Memory-Footprints. Dimensionieren Sie die vollständige Runtime, bevor Sie entscheiden, ob Weight Quantization ausreicht. PagedAttention weist den KV Cache als wesentlichen Bestandteil des Serving Memory aus.
Offline Quantization kann auf einzelne Layer begrenzt werden. Tools wie llm-compressor können einen Transformer-Block laden, Calibration und Quantization durchführen, den komprimierten Block schreiben und anschließend fortfahren. Dadurch bleibt der maximale GPU Memory eher in der Größenordnung des größten aktiven Layers zuzüglich der Calibration Buffer. CPU RAM und Disk für den Source Checkpoint werden weiterhin benötigt, aber die GPU muss nicht immer das vollständige BF16 Model halten.
Der maximale GPU Memory während der Offline Quantization kann eher so aussehen:
Serving ist strenger. Der vollständige komprimierte Checkpoint muss zusammen mit dem KV Cache und den Runtime Buffern resident bleiben. Der KV Cache wächst mit Context Length und der aktiven Batch Size:
Dabei gilt:
- ist die Anzahl der Layer.
- ist die Anzahl der Key-Value Attention Heads. Grouped-Query Attention reduziert diesen Wert, indem viele Query Heads weniger KV Heads gemeinsam nutzen.
- ist die Dimension jedes Heads, häufig 128 oder 256.
- ist die Anzahl der Prompt Tokens plus der generierten Tokens.
- ist die aktive Serving Batch.
- ist 2 für BF16 oder FP16 und 1 für FP8 oder INT8. Der FP8-KV-Cache-Modus von vLLM ist das Beispiel aus dem Serving Stack, das dieser Artikel verwendet.
KV-Cache Quantization verändert die Speicherung, während Reuse die Allokation verändert
Der KV Cache kann während der Inference quantisiert werden. Jeder Decode-Schritt erzeugt K- und V-Activation-Tensoren für das neue Token. Ein W8A8 Model verwendet möglicherweise bereits FP8 oder INT8 für unterstützte Projection Math, der Cache bleibt jedoch ein separates Storage-Objekt.
Viele Serving Stacks halten dieses Objekt im Model- oder Cache-Dtype. Um dies zu ändern, aktivieren Sie einen KV-Cache-Dtype, verwenden Sie einen Checkpoint mit Cache Scales oder wählen Sie eine quantisierte Cache-Implementierung.
Wenn KV-Cache Quantization aktiviert ist, schreibt die Engine Einträge als Repräsentation mit niedrigerer Precision plus Scales. Die spätere Attention dequantisiert den Cache entweder innerhalb ihres Kernels oder führt auf manchen Backends einen Teil der Attention-Operation in der quantisierten Domäne aus.
Die stabile Dokumentation zum Quantized KV Cache von vLLM stellt dies direkt über kv_cache_dtype="fp8" oder --kv-cache-dtype fp8 bereit. vLLM unterstützt die FP8-E4M3- und E5M2-Cache-Formate sowie Per-Tensor- und Per-Attention-Head-Scale-Strategien. Für die Scales stehen drei Optionen zur Verfügung: Defaults, Schätzung während der Warmup-Phase und Dataset Calibration über llm-compressor. Mit FlashAttention 3 kann vLLM Attention-Operationen außerdem in der FP8-Domäne ausführen, indem zusätzlich zu Keys und Values auch Queries quantisiert werden.
TensorRT-LLM stellt einen FP8 KV-Cache über KvCacheConfig(dtype='fp8') bereit und führt FP8 KV-Cache sowie NVFP4 KV-Cache als separate Quantization-Rezepte neben der Weight-/Activation-Quantization auf. Hugging Face Transformers bietet ebenfalls einen QuantizedCache-Pfad über cache_implementation="quantized". Dabei unterstützt hqq die Cache-Formate int2, int4 und int8, während quanto int2 und int4 unterstützt.
Gewöhnliches KV-Caching speichert zuvor berechnete Keys und Values, um deren Neuberechnung zu vermeiden. Prefix Caching verwendet Cache-Blöcke für Requests mit demselben Prefix wieder. PagedAttention reduziert Fragmentierung und verbessert die Allokation, während KV-Offloading Cache-Blöcke zwischen Memory-Tiers verschiebt. Diese Kombinationen hängen vom Runtime ab. Hugging Faces QuantizedCache unterstützt kein Offloading. vLLM dokumentiert seinen quantisierten KV-Cache getrennt von Prefix Caching und anderen Cache-Management-Features. Überprüfe jede Kombination in dem Runtime, den du deployest.
Das Qualitätsrisiko unterscheidet sich ebenfalls von Weight-only PTQ. Die KV-Cache-Quantization führt Fehler in den Attention-State ein, der bei jedem späteren Decode-Schritt gelesen wird. Teste Long-Context-Retrieval, Multi-Turn-Verhalten, Safety und Refusals, das Formatting von Tool Use sowie die Output-Latency separat. KVQuant, KIVI und die vLLM-Studie zum FP8 KV-Cache evaluieren KV-Cache-Quantization jeweils als eigenes Problem.
Modellgröße und Context Length allein bestimmen nicht, ob Cache Compression eine weitere Runde Weight Compression übertrifft. Berechne die Cache-Bytes mit der obigen Gleichung anhand der Anzahl der KV-Heads, der Head-Dimension, der aktiven Batch und des Cache-Dtypes des Modells. Vergleiche dieses Ergebnis anschließend mit den eingesparten Bytes zwischen zwei benannten Weight-Formaten, beispielsweise BF16 und INT4. Wenn der Cache größer ist, kann das Testen von FP8-KV-Cache-Quantization mehr Serving-Memory freigeben als eine weitere Reduzierung der Weights.
7. Die Hardware schränkt die Auswahl ein
Der Weight Footprint lässt sich anhand der Parameteranzahl und der Storage Precision leicht abschätzen – nach demselben Sizing-Prinzip wie in Diskussionen zum Serving-Memory rund um den KV-Cache:
| Modellgröße | BF16 Weights | FP8 / INT8 Weights | INT4 Weights |
|---|---|---|---|
| 7B / 8B | ~14–16 GB | ~7–8 GB | ~3,5–4 GB |
| 14B | ~28 GB | ~14 GB | ~7 GB |
| 32B / 34B | ~64–68 GB | ~32–34 GB | ~16–17 GB |
| 70B | ~140 GB | ~70 GB | ~35 GB |
| 109B MoE | ~218 GB gesamt | ~109 GB | ~55 GB |
Mixture-of-Experts-Modelle aktivieren möglicherweise weniger Parameter pro Token. Das vollständige Set der Weights muss jedoch weiterhin irgendwo liegen, sofern der Runtime kein Offloading unterstützt. Die Quantization Support Matrix von TensorRT-LLM behandelt MoE-Modellfamilien als Deployment-Ziele mit jeweils eigenen unterstützten Rezepten.
Deine Deployment-Hardware schränkt ein, welche Quantization-Formate praktikabel sind:
- CPU-Serving hängt von Vektorinstruktionen wie AVX-512 oder AMX ab. Eine GGUF-Datei, die über
llama.cppgeladen wird, ist der praktikable Weg. - Apple Silicon verwendet Unified Memory, sodass lokale Modelle einen großen gemeinsam genutzten RAM-Pool statt dediziertem VRAM nutzen können. GGUF und
llama.cppbleiben der gängige Weg für lokale Runtimes, da GGUF für GGML-Executoren entwickelt wurde. - NVIDIA Ampere unterstützt INT8-Tensor-Core-Serving-Pfade, aber keine native FP8-W8A8-Tensor-Core-Mathematik. Gängige Optionen sind W4A16 Weight-only Quantization oder statisches INT8, entsprechend der TensorRT-LLM-Hardware-Support-Matrix.
- NVIDIA Ada und Hopper unterstützen FP8-Serving-Pfade in TensorRT-LLM. Das FP8-W8A8-Serving ist auf diesen GPUs einen Test wert.
- NVIDIA Blackwell ergänzt NVFP4- und Microscaling-Support, aber der Softwarepfad bleibt relevant. Behandle frühe Low-Bit-Floating-Point-Stacks als versionsabhängig.
8. Calibration und Evaluation vor dem Deployment
Ein Model, das geladen werden kann, hat einen Smoke Test bestanden. Für das Deployment sind Quality- und Serving-Checks für den Ziel-Workload erforderlich. Aktuelle Quantization-Evaluierungen berichten unterschiedliche Ergebnisse für LLM-Serving, Long-Context-Tasks und Reasoning-intensive Models.
Verwende für die Calibration Prompts, die der Produktion entsprechen:
- Beziehe RAG-Traces, SQL-Queries, Agent-Historien, Code-Tasks, Tool-Call-Payloads und System Prompts aus dem Ziel-Workload ein. Static PTQ hängt davon ab, dass die Calibration-Daten der Produktionsverteilung entsprechen.
- Gleiche die Sequence Lengths ab. Kurze Single-Turn-Prompts machen das Activation-Verhalten bei langem Kontext nicht sichtbar.
- Belasse
embed_tokensundlm_headin höherer Precision, sofern die Methode oder Runtime dies erlaubt – ein gängiges Exclusion Pattern in LLM-Compressor-Rezepten. - Verwende genügend Samples, um die Activation-Ranges zu stabilisieren. Das vLLM-KV-Cache-Beispiel setzt
NUM_CALIB_SAMPLES = 512. Betrachte dies als ein dokumentiertes Beispiel, nicht als universelle Anzahl. Die richtige Sample-Anzahl hängt von Methode, Model, Sequence Length und Produktions-Workload ab. - Entferne Secrets und private User-Daten, bevor du Produktions-Logs verwendest.
Teste bei der Evaluation sowohl die Language Quality als auch das Serving-Verhalten:
- Perplexity auf einem Standardkorpus erfasst eine allgemeine Verschlechterung der Sprachqualität, aber der JarvisLabs Benchmark erinnert daran, dass sich Perplexity und Throughput unterschiedlich entwickeln können.
- Domain-spezifische Aufgaben erkennen Fehler, die Perplexity verbirgt. Verwende HumanEval für Coding, MMLU für breites Allgemeinwissen und AIME oder MATH-500 für mathematisches Reasoning, wenn diese Bereiche relevant sind.
- Formatprüfungen sind für agentische Systeme wichtig. Teste die Einhaltung des JSON-Schemas, Markdown-Output, die Form von Tool Calls und das Verweigerungsverhalten, da Evaluations von quantisierten Modellen Fehler auf Anwendungsebene übersehen können, selbst wenn die aggregierte Benchmark-Genauigkeit stabil aussieht.
- Tests mit langen Kontexten erkennen Schäden durch die Quantization des KV-Caches. Needle-in-a-Haystack ist grob, aber Ergebnisse zur Quantization langer Kontexte zeigen, warum solche Prüfungen in den Deploy-Gate gehören.
- Load Tests sollten Throughput, TTFT, Inter-Token-Latency, die maximale Batch-Kapazität und den maximalen Speicherverbrauch ausweisen. vLLM stellt diese Messwerte über
vllm bench servebereit.
Bewerte Reasoning-intensive Modelle rigoros. Quantization unter 4 Bit oder unrotierte W4A4-Quantization kann die Reasoning-Genauigkeit beeinträchtigen, selbst wenn die Perplexity des Baseline-Modells stabil aussieht. Das ist die zentrale Warnung der Studie zu quantisierten Reasoning-Modellen.
9. Workflow für das begleitende Repository
Das begleitende Repository slavadubrov/model-compression-demo soll den Entscheidungsprozess reproduzierbar machen. Es verwendet uv und konzentriert sich auf Planung, Recipes, Dry Runs und Benchmark-Konfigurationen, die auf denselben Quellen basieren wie dieser Artikel: vLLM, LLM Compressor, TensorRT-LLM und die Algorithmus-Paper.
Das öffentliche README in Revision 8b45003849e830bed2ff341a9f027b017d932c1f wurde am 16.08.2026 geprüft. Der Checkout des begleitenden Repositories ist in diesem Workspace nicht vorhanden, daher konnte ich die CLI hier nicht ausführen. Die folgenden Befehle sind illustrativ, bis du sie aus diesem gepinnten Checkout ausführst; außerdem benötigt der Benchmark-Plan noch die Zielhardware für das Serving.
Übernimm nicht den Output des FP8-Rezepte aus dieser gepinnten Revision. Sein recipe --algorithm fp8-dynamic-Befehl erzeugt ein intern inkonsistentes Modell und einen inkonsistenten Output-Pfad. Der Befehl bleibt hier ausgelassen, bis das begleitende Repository repariert ist.
Klone das Repository und prüfe die unterstützten Algorithmen:
git clone https://github.com/slavadubrov/model-compression-demo.git
cd model-compression-demo
git checkout 8b45003849e830bed2ff341a9f027b017d932c1f
uv run python demo.py list-algorithms
Beginne mit Planung und Sizing:
uv run python demo.py plan \
--model-preset qwen3-8b \
--goal fit-memory \
--hardware ampere \
--context 4096 \
--concurrency 4
uv run python demo.py estimate \
--model-preset qwen3-8b \
--scheme w4a16 \
--context 4096 \
--concurrency 4
uv run python demo.py plan \
--model-preset qwen3-0.6b \
--hardware cpu
Erzeuge anschließend ein Recipe und prüfe die Quantization per Preview, bevor du GPU-Zeit investierst:
uv run python demo.py recipe --algorithm gptq-w4a16
uv run python demo.py quantize --dry-run
uv run python demo.py quantize \
--algorithm gptq-w4a16 \
--model Qwen/Qwen3-8B \
--dry-run
Für Serving und Benchmark-Planung:
uv run python demo.py serve-command \
--algorithm fp8-dynamic \
--fp8-kv-cache \
--enable-prefix-caching
uv run python demo.py benchmark-plan \
--model Qwen/Qwen3-8B \
--algorithms gptq-w4a16,rtn-w8a16,fp8-dynamic \
--dataset-name sharegpt \
--num-prompts 200 \
--input-len 1024 \
--output-len 256 \
--output-json reports/quantization-benchmark-plan.json
Vergleiche abschließend die Base- und Compressed-Modelle anhand expliziter Schwellenwerte:
uv run python demo.py quality-eval \
--base-model Qwen/Qwen3-8B \
--compressed-model outputs/Qwen3-8B-W4A16 \
--mode all \
--lm-eval-task hellaswag \
--lm-eval-limit 50 \
--max-perplexity-delta-pct 5 \
--output-json reports/qwen3-8b-w4a16-quality.json
Führe die Arbeit in dieser Reihenfolge aus: Plane das Ziel, schätze den Speicherbedarf, führe einen Dry Run des Recipes aus, benchmarke das Serving und vergleiche anschließend die Qualität mit den Schwellenwerten. Diese Reihenfolge entspricht der in diesem Artikel beschriebenen Trennung zwischen Memory Sizing, Runtime-Benchmarking und Quality Evaluation.
10. Diffusion-Modelle benötigen einen separaten Pfad
Diffusion- und Diffusion-Transformer-Pipelines weisen ein anderes Activation-Verhalten auf als autoregressive LLMs. SVDQuant behandelt die Quantization von Diffusion-Modellen als separates Problem mit Activation-Outliers.
Autoregressive LLMs generieren jeweils einen Token. Diffusion-Modelle führen wiederholte Denoising-Schritte aus, und ihre Activation-Distributionen verschieben sich während des Prozesses. Ein standardmäßiger 4-Bit-LLM-Quantization-Durchlauf kann zwar den Speicherbedarf eines Diffusion-Modells reduzieren, aber gleichzeitig gravierende visuelle Artefakte verursachen. Auf Diffusion ausgerichtete Methoden wie SVDQuant / Nunchaku und NVIDIA ModelOpt diffusion quantization adressieren dieses abweichende Activation-Muster.
Verwende die folgenden Punkte als konservative Heuristiken, nicht als universelle Defaults. Pipeline, Komponente, Model und Runtime benötigen jeweils eigene Tests:
- Belasse den VAE beim ersten Vergleich in 16 Bit. Diese konservative Heuristik reduziert eine mögliche Quelle für Bildartefakte. Teste geringere Präzision erst, wenn die Methode und die Ziel-Pipeline dies validieren.
- Teste zuerst den DiT- oder U-Net-Backbone, da dieser häufig den größten Parameteranteil enthält. Das ist eine Heuristik; überprüfe daher Speicherbedarf, Latency und Bildqualität für die Ziel-Pipeline. Diffusion-Quantization-Methoden verfolgen denselben Ansatz auf Komponentenebene.
- Behandle Text-Encoder separat. Die Quantization von T5-XXL oder CLIP kann in einer bestimmten Pipeline Prompt-Alignment oder Text-Rendering beeinflussen. Werte sie daher unabhängig aus, statt ein generisches Transformer-Verhalten anzunehmen.
- Verwende Diffusion-aware Methoden wie SVDQuant, wenn Activation-Outliers das Hauptproblem darstellen.
- Evaluiere mit Bildern, nicht mit Textmetriken. Überprüfe Prompt-Adherence, Text-Rendering, Hauttöne, Farbbalance, feine Details, Latency und VRAM.
Wenn das Eval-Set nur einfache oder häufige Prompts enthält, entgehen dir Fehler in Edge Cases. Nimm schwierige Fälle auf: kleinen Text, Hände, wiederholte Objekte, strukturierte Layouts und Prompts mit negativen Constraints, da sich Fehler bei der Diffusion-Quantization visuell zeigen und nicht in der Perplexity von Language Models.
11. Production-Defaults
Für das Enterprise-LLM-Serving startest du mit einer BF16-Baseline in genau der Serving Engine, die du einsetzen möchtest. Wenn Throughput das Ziel ist und die Hardware dies unterstützt, teste FP8 W8A8. Wenn das Model nicht in den Speicher passt, teste AWQ oder GPTQ W4A16 mit Marlin-class Kernels. Wenn Long Context oder Concurrency das Problem darstellt, teste FP8-KV-Cache-Quantization. Wenn wiederholte Prefixes das Problem sind, aktiviere zusätzlich Prefix Caching. Rolle die komprimierte Version erst aus, wenn sowohl die Quality- als auch die Serving-Benchmarks bestehen.
Für lokale und Edge-Inference startest du mit einer GGUF-Datei unter Verwendung von Q4_K_M oder Q5_K_M. Wechsle zu einem Q8_0-GGUF, wenn der Speicher dies erlaubt und Qualität wichtiger ist als der Footprint. Unter 4 Bit zu gehen, ist ein letzter Ausweg und kein Default.
Für Fine-Tuning verwenden Sie NF4 mit QLoRA, um Adapter kostengünstig zu trainieren. Evaluieren Sie den Adapter in der Anwendung, bevor Sie ihn mergen. Exportieren Sie ihn nach dem Mergen in das tatsächlich benötigte Serving-Artefakt: eine mit llama.cpp kompatible GGUF-Datei, einen AWQ/GPTQ/compressed-tensors-Checkpoint, einen FP8-Serving-Checkpoint oder BF16.
Für Diffusion beginnen Sie mit diesen konservativen Heuristiken und testen Sie jede Kombination aus Pipeline, Model und Runtime visuell. Die Perplexity von Text sagt Ihnen nicht, ob eine Bild-Pipeline fehlerhaft ist. Verwenden Sie daher Diffusion-spezifische Evidenz wie SVDQuant und visuelle Evaluation.
Referenzen
- JarvisLabs vLLM Benchmarks: JarvisLabs, vLLM Quantization Complete Guide and Benchmarks, 2026. JarvisLabs.
- Hugging Face Optimum Quantization Guide: Hugging Face, Quantization conceptual guide. Docs.
- vLLM Quantization Docs: vLLM project, Quantization. Docs.
- vLLM Quantized KV Cache Docs: vLLM project, Quantized KV Cache. Docs.
- vLLM Benchmark Docs: vLLM project, vllm bench serve. Docs.
- LLM Compressor Docs: vLLM project, LLM Compressor. Docs.
- GPTQModel: ModelCloud, GPTQModel. GitHub.
- TensorRT-LLM Quantization: NVIDIA, TensorRT-LLM Quantization. Docs.
- NVIDIA NVFP4: NVIDIA, Introducing NVFP4 for Efficient and Accurate Low-Precision Inference. Blog.
- Hugging Face QuantizedCache: Hugging Face, Cache strategies: Quantized cache. Docs.
- NVIDIA Model Optimizer: NVIDIA, Model Optimizer. GitHub.
- torchao Quantization: PyTorch, torchao quantization overview. Docs.
- bitsandbytes Quantization: Hugging Face, bitsandbytes. Docs.
- HQQ: Dropbox, Half-Quadratic Quantization. GitHub.
- PEFT: Hugging Face, Parameter-Efficient Fine-Tuning. Docs.
- Ollama: Lokale Model-Runtime von Ollama. Website.
- LM Studio: Lokale AI-Runtime von LM Studio. Website.
- AutoGPTQ-Status: AutoGPTQ-Repository, im April 2025 archiviert. GitHub.
- AutoAWQ-Status: AutoAWQ-Repository, im Mai 2025 archiviert und deprecated. GitHub.
- GPTQ: Frantar et al., GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers, NeurIPS 2023. arXiv:2210.17323.
- Marlin: Frantar et al., MARLIN: Mixed-Precision Auto-Regressive Parallel Inference on Large Language Models, arXiv:2408.11743. arXiv:2408.11743.
- AWQ: Lin et al., AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration, MLSys 2024. arXiv:2306.00978.
- SmoothQuant: Xiao et al., SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models, ICML 2023. arXiv:2211.10438.
- QuaRot: Ashkboos et al., QuaRot: Outlier-Free 4-Bit Inference in Rotated LLMs, NeurIPS 2024. arXiv:2404.00456.
- SpinQuant: Meta AI Research, SpinQuant: LLM Quantization with Learned Rotations, arXiv:2405.16406. arXiv:2405.16406.
- QLoRA / NF4: Dettmers et al., QLoRA: Efficient Finetuning of Quantized LLMs, NeurIPS 2023. arXiv:2305.14314.
- SVDQuant / Nunchaku: MIT HAN Lab, SVDQuant: Absorbing Outliers by Low-Rank Components for 4-Bit Diffusion Models, ICLR 2025. arXiv:2411.05007, Nunchaku.
- vLLM PagedAttention: Kwon et al., Efficient Memory Management for Large Language Model Serving with PagedAttention, SOSP 2023. arXiv:2309.06180.
- Grouped-Query Attention: Ainslie et al., GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints, EMNLP 2023. arXiv:2305.13245.
- vLLM FP8 KV Cache: Kubler, Kurtic, Wilkinson et al., The State of FP8 KV-Cache and Attention Quantization in vLLM, vLLM Blog, April 2026. vLLM Blog.
- KIVI: Liu et al., KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache, ICML 2024. arXiv:2402.02750.
- KVQuant: Hooper et al., KVQuant: Towards 10 Million Context Length LLM Inference with KV Cache Quantization, NeurIPS 2024. arXiv:2401.18079.
- LLM Serving Evaluation: Kurtic et al., “Give Me BF16 or Give Me Death”? Accuracy-Performance Trade-Offs in LLM Quantization, ACL 2025. arXiv:2411.02355.
- Long-context Quantization Evaluation: Mekala et al., Does quantization affect models’ performance on long-context tasks?, arXiv:2505.20276. arXiv:2505.20276.
- Reasoning Evaluation: Quantization Hurts Reasoning? An Empirical Study on Quantized Reasoning Models, arXiv:2504.04823. arXiv:2504.04823.
- SlideSparse: SlideSparse: Fast and Flexible (2N-2):2N Structured Sparsity, arXiv:2603.05232v1. arXiv:2603.05232v1.
- HumanEval: OpenAI, HumanEval. GitHub.
- MMLU: Hendrycks et al., Measuring Massive Multitask Language Understanding. arXiv:2009.03300.
- MATH-500: Hugging Face H4, MATH-500. Dataset.
- GGUF and llama.cpp: ggml-org, GGUF file format and llama.cpp. GGUF, llama.cpp.
- Hugging Face GGUF Docs: Hugging Face, GGUF. Docs.
- Reference Repository: slavadubrov/model-compression-demo.