Veni AI
Modelloptimierung

LLM-Quantisierung und Modelloptimierung: INT8, INT4 und GPTQ

Optimierung großer Sprachmodelle durch Quantisierung, INT8/INT4-Konvertierung, GPTQ-, AWQ-Techniken und Strategien zur Beschleunigung der Inferenz.

Veni AI Technical Team5 Ocak 20254 dk okuma
LLM-Quantisierung und Modelloptimierung: INT8, INT4 und GPTQ

LLM-Quantisierung und Modelloptimierung: INT8, INT4 und GPTQ

Quantisierung ist der Prozess der Umwandlung von Modellgewichten und Aktivierungen in numerische Formate mit geringerer Präzision. Dieser Prozess reduziert den Speicherverbrauch und die Inferenzzeit erheblich.

Grundlagen der Quantisierung

Warum Quantisierung?

MetrikFP32FP16INT8INT4
Bits/Parameter321684
7B Modellgröße28GB14GB7GB3.5GB
Relative Geschwindigkeit1x1.5-2x2-4x3-5x

Zahlenformate

1FP32: 1 bit sign + 8 bit exponent + 23 bit mantissa 2FP16: 1 bit sign + 5 bit exponent + 10 bit mantissa 3BF16: 1 bit sign + 8 bit exponent + 7 bit mantissa 4INT8: 8 bit integer (-128 to 127) 5INT4: 4 bit integer (-8 to 7)

Quantisierungsarten

Post-Training Quantization (PTQ)

Quantisierung nach dem Training:

1import torch 2 3def quantize_tensor(tensor, bits=8): 4 # Min-max scaling 5 min_val = tensor.min() 6 max_val = tensor.max() 7 8 # Calculate scale and zero point 9 scale = (max_val - min_val) / (2**bits - 1) 10 zero_point = round(-min_val / scale) 11 12 # Quantize 13 q_tensor = torch.round(tensor / scale + zero_point) 14 q_tensor = torch.clamp(q_tensor, 0, 2**bits - 1) 15 16 return q_tensor.to(torch.uint8), scale, zero_point 17 18def dequantize_tensor(q_tensor, scale, zero_point): 19 return (q_tensor.float() - zero_point) * scale

Quantization-Aware Training (QAT)

Quantisierungssimulation während des Trainings:

1class QuantizedLinear(nn.Module): 2 def __init__(self, in_features, out_features, bits=8): 3 super().__init__() 4 self.weight = nn.Parameter(torch.randn(out_features, in_features)) 5 self.bits = bits 6 7 def forward(self, x): 8 # Fake quantization during training 9 q_weight = fake_quantize(self.weight, self.bits) 10 return F.linear(x, q_weight) 11 12def fake_quantize(tensor, bits): 13 scale = tensor.abs().max() / (2**(bits-1) - 1) 14 q = torch.round(tensor / scale) 15 q = torch.clamp(q, -2**(bits-1), 2**(bits-1) - 1) 16 return q * scale # Straight-through estimator

GPTQ (Accurate Post-Training Quantization)

Schichtweise Quantisierung mit optimaler Rekonstruktion:

1from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig 2 3# Quantization config 4quantize_config = BaseQuantizeConfig( 5 bits=4, # INT4 6 group_size=128, # Group quantization 7 desc_act=False, # Disable activation order 8 damp_percent=0.1 # Dampening factor 9) 10 11# Model quantization 12model = AutoGPTQForCausalLM.from_pretrained( 13 "meta-llama/Llama-2-7b-hf", 14 quantize_config 15) 16 17# Quantize with calibration data 18model.quantize(calibration_data) 19 20# Save 21model.save_quantized("llama-2-7b-gptq")

Funktionsprinzip von GPTQ

11. Für jede Schicht: 2 a. Hessian-Matrix berechnen (bestimmt die Wichtigkeit der Gewichte) 3 b. Weniger wichtige Gewichte quantisieren 4 c. Verbleibende Gewichte aktualisieren (Fehlerkompensation) 5 d. Zur nächsten Spalte wechseln 6 72. Gruppenquantisierung: 8 - 128 Gewichtgruppen → 1 Skalierungsfaktor 9 - Bessere Genauigkeit, etwas mehr Speicherverbrauch

AWQ (Activation-aware Weight Quantization)

Wichtige Gewichte basierend auf Aktivierungsverteilungen erhalten:

1from awq import AutoAWQForCausalLM 2 3model = AutoAWQForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf") 4 5quant_config = { 6 "zero_point": True, 7 "q_group_size": 128, 8 "w_bit": 4, 9 "version": "GEMM" 10} 11 12model.quantize( 13 tokenizer=tokenizer, 14 quant_config=quant_config, 15 calib_data=calibration_samples 16) 17 18model.save_quantized("llama-2-7b-awq") 19## BitsAndBytes-Quantisierung 20 21Hugging Face-Integration: 22 23```python 24from transformers import AutoModelForCausalLM, BitsAndBytesConfig 25import torch 26 27# 8-bit quantization 28bnb_config_8bit = BitsAndBytesConfig( 29 load_in_8bit=True, 30 llm_int8_threshold=6.0, 31 llm_int8_has_fp16_weight=False 32) 33 34# 4-bit quantization (NF4) 35bnb_config_4bit = BitsAndBytesConfig( 36 load_in_4bit=True, 37 bnb_4bit_quant_type="nf4", # or "fp4" 38 bnb_4bit_compute_dtype=torch.bfloat16, 39 bnb_4bit_use_double_quant=True # Nested quantization 40) 41 42model = AutoModelForCausalLM.from_pretrained( 43 "meta-llama/Llama-2-7b-hf", 44 quantization_config=bnb_config_4bit, 45 device_map="auto" 46)

llama.cpp und GGUF

Format optimiert für CPU-Inferenz:

1# Model conversion 2python convert.py llama-2-7b-hf --outfile llama-2-7b-f16.gguf --outtype f16 3 4# Quantization 5./quantize llama-2-7b-f16.gguf llama-2-7b-q4_k_m.gguf q4_k_m

GGUF-Quantisierungsstufen

FormatBitsGröße (7B)Qualität
Q2_K2.52.7GBNiedrig
Q3_K_M3.43.3GBMittel-Niedrig
Q4_K_M4.54.1GBMittel
Q5_K_M5.54.8GBGut
Q6_K6.55.5GBSehr gut
Q8_087.2GBAm besten

Verwendung von GGUF mit Python

1from llama_cpp import Llama 2 3llm = Llama( 4 model_path="llama-2-7b-q4_k_m.gguf", 5 n_ctx=4096, 6 n_threads=8, 7 n_gpu_layers=35 # GPU offloading 8) 9 10output = llm( 11 "What is artificial intelligence?", 12 max_tokens=256, 13 temperature=0.7 14)

Benchmark-Vergleich

Leistungsmetriken

1Model: Llama-2-7B 2Hardware: RTX 4090 3 4| Method | Memory | Tokens/s | Perplexity | 5|--------|--------|----------|------------| 6| FP16 | 14GB | 45 | 5.47 | 7| INT8 | 7GB | 82 | 5.49 | 8| GPTQ-4 | 4GB | 125 | 5.63 | 9| AWQ-4 | 4GB | 130 | 5.58 | 10| GGUF Q4| 4GB | 95 (CPU) | 5.65 |

Inferenzoptimierung

Schnelle Inferenz mit vLLM

1from vllm import LLM, SamplingParams 2 3llm = LLM( 4 model="TheBloke/Llama-2-7B-GPTQ", 5 quantization="gptq", 6 tensor_parallel_size=2 7) 8 9sampling_params = SamplingParams( 10 temperature=0.8, 11 max_tokens=256 12) 13 14outputs = llm.generate(["Hello, "], sampling_params)

Flash-Attention-Integration

1from transformers import AutoModelForCausalLM 2 3model = AutoModelForCausalLM.from_pretrained( 4 "meta-llama/Llama-2-7b-hf", 5 torch_dtype=torch.float16, 6 attn_implementation="flash_attention_2" 7)

Auswahlkriterien

Quantisierungs-Auswahlmatrix

1Use Case → Recommended Method 2 3Production API (GPU available): 4 → GPTQ or AWQ (4-bit) 5 6Edge/Mobile: 7 → GGUF Q4_K_M 8 9Fine-tuning required: 10 → QLoRA (4-bit BitsAndBytes) 11 12Maximum quality: 13 → INT8 or FP16 14 15Maximum speed: 16 → AWQ + vLLM

Fazit

Quantisierung ist eine entscheidende Optimierungstechnik, die LLMs zugänglicher und schneller macht. Die Wahl der richtigen Methode hängt vom Use Case und den Hardwareeinschränkungen ab.

Bei Veni AI bieten wir Beratung zur Modelloptimierung an.

İlgili Makaleler