模型量化与压缩
High Contrast
Dark Mode
Light Mode
Sepia
Forest
2 min read312 words

模型量化与压缩

在生产环境中部署大模型,GPU 成本是最大瓶颈。量化和压缩技术可以在保持效果的前提下大幅降低资源消耗。

量化技术概览

graph TB A[模型压缩] --> B[量化 Quantization] A --> C[蒸馏 Distillation] A --> D[剪枝 Pruning] B --> B1[PTQ 训练后量化] B --> B2[QAT 训练感知量化] B --> B3[混合精度量化] C --> C1[大模型 → 小模型] C --> C2[保留关键能力] D --> D1[结构化剪枝] D --> D2[非结构化剪枝] style A fill:#e3f2fd,stroke:#1976d2,stroke-width:3px style B fill:#e8f5e9,stroke:#388e3c,stroke-width:2px

量化方法对比

方法 精度 压缩比 推理速度 效果损失 适用场景
FP16 16-bit 2x ⭐⭐⭐ 几乎无 默认选择
INT8 8-bit 4x ⭐⭐⭐⭐ 极小 在线推理
INT4 (GPTQ) 4-bit 8x ⭐⭐⭐⭐ 轻微 资源受限
GGUF (llama.cpp) 2-6bit 5-16x ⭐⭐⭐ 可控 CPU/边缘
AWQ 4-bit 8x ⭐⭐⭐⭐⭐ 极小 生产推荐

量化管理器

"""
模型量化配置与管理
"""
from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path
class QuantMethod(Enum):
FP16 = "fp16"
INT8 = "int8"
INT4_GPTQ = "int4_gptq"
INT4_AWQ = "int4_awq"
GGUF = "gguf"
@dataclass
class QuantConfig:
"""量化配置"""
method: QuantMethod
bits: int
group_size: int = 128       # 量化分组大小
desc_act: bool = False      # 分组排序(GPTQ)
use_exllama: bool = True    # 内核选择
@property
def memory_ratio(self) -> float:
"""相对 FP32 的内存占比"""
return self.bits / 32
@dataclass
class ModelProfile:
"""模型资源档案"""
name: str
params_billion: float
fp16_memory_gb: float
quant_config: QuantConfig | None = None
@property
def estimated_memory_gb(self) -> float:
"""预估量化后显存"""
if self.quant_config is None:
return self.fp16_memory_gb
return self.fp16_memory_gb * (self.quant_config.bits / 16)
@property
def min_gpu_memory_gb(self) -> float:
"""最低 GPU 显存需求(含开销)"""
return self.estimated_memory_gb * 1.2  # 20% 开销
class QuantizationManager:
"""量化管理器"""
# 常见模型档案
MODEL_PROFILES = {
"llama-7b": ModelProfile("Llama-2-7B", 7, 14),
"llama-13b": ModelProfile("Llama-2-13B", 13, 26),
"llama-70b": ModelProfile("Llama-2-70B", 70, 140),
"qwen-7b": ModelProfile("Qwen2.5-7B", 7, 14),
"qwen-72b": ModelProfile("Qwen2.5-72B", 72, 144),
}
GPU_MEMORY = {
"A100-80GB": 80,
"A100-40GB": 40,
"H100-80GB": 80,
"L40S-48GB": 48,
"RTX4090-24GB": 24,
"T4-16GB": 16,
}
def recommend_quant(self, model_key: str, gpu: str) -> QuantConfig:
"""推荐量化方案"""
profile = self.MODEL_PROFILES.get(model_key)
gpu_mem = self.GPU_MEMORY.get(gpu, 24)
if profile is None:
return QuantConfig(method=QuantMethod.INT8, bits=8)
# FP16 能装下就不量化
if profile.fp16_memory_gb * 1.2 <= gpu_mem:
return QuantConfig(method=QuantMethod.FP16, bits=16)
# INT8 能装下
int8_mem = profile.fp16_memory_gb * 0.5 * 1.2
if int8_mem <= gpu_mem:
return QuantConfig(method=QuantMethod.INT8, bits=8)
# INT4 AWQ
int4_mem = profile.fp16_memory_gb * 0.25 * 1.2
if int4_mem <= gpu_mem:
return QuantConfig(method=QuantMethod.INT4_AWQ, bits=4)
# 极端情况:GGUF 2-bit
return QuantConfig(method=QuantMethod.GGUF, bits=3)
def estimate_throughput(self, quant: QuantConfig, gpu: str) -> dict:
"""预估推理吞吐"""
base_tps = {"A100-80GB": 100, "H100-80GB": 150, "L40S-48GB": 80,
"RTX4090-24GB": 70, "T4-16GB": 30}
base = base_tps.get(gpu, 50)
multipliers = {
QuantMethod.FP16: 1.0,
QuantMethod.INT8: 1.3,
QuantMethod.INT4_GPTQ: 1.5,
QuantMethod.INT4_AWQ: 1.8,
QuantMethod.GGUF: 0.8,
}
multiplier = multipliers.get(quant.method, 1.0)
return {
"tokens_per_second": int(base * multiplier),
"gpu": gpu,
"quant": quant.method.value,
}

部署框架选型

graph LR A{模型大小?} -->|<7B| B[llama.cpp / Ollama] A -->|7-70B| C{需要高吞吐?} A -->|>70B| D[多 GPU 张量并行] C -->|是| E[vLLM] C -->|否| F[TGI / Ollama] D --> G[vLLM + TP] D --> H[TensorRT-LLM] style A fill:#e3f2fd,stroke:#1976d2,stroke-width:3px style E fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
框架 特点 量化支持 吞吐 适用场景
vLLM PagedAttention AWQ/GPTQ/FP8 最高 高并发推理
TGI HuggingFace 官方 GPTQ/AWQ HF 生态
Ollama 一键部署 GGUF 开发/小规模
llama.cpp CPU 友好 GGUF 边缘/本地
TensorRT-LLM NVIDIA 优化 INT8/FP8 极高 A100/H100

本章小结

主题 要点
量化方法 AWQ(生产首选)/ GPTQ(兼容好)/ GGUF(CPU)
选择逻辑 FP16 能装 → 不量化; 否则 INT8 → INT4
框架选型 vLLM(高吞吐)/ TGI(HF 生态)/ Ollama(开发)
核心指标 显存占用 × 推理吞吐 × 效果损失

下一章:GPU 资源管理