量化部署决策树

是否在H100上部署?
├─ 是 → FP8量化(原生加速,精度最佳)
└─ 否 → 显存是否足够FP16?
         ├─ 是 → FP16(无精度损失)
         └─ 否 → INT8还是INT4?
                  ├─ 精度要求高 → INT8 (W8A8)
                  └─ 显存优先 → INT4 (GPTQ/AWQ)

GPTQ量化

# 使用AutoGPTQ进行量化
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig

# 量化配置
quantize_config = BaseQuantizeConfig(
    bits=4,              # 4-bit量化
    group_size=128,      # 分组大小
    desc_act=False,      # 是否按激活降序排列
)

# 准备校准数据
calibration_data = load_calibration_dataset(n_samples=128, max_length=512)

# 加载模型并量化
model = AutoGPTQForCausalLM.from_pretrained(
    "Qwen/Qwen3-32B",
    quantize_config,
)
model.quantize(calibration_data)

# 保存量化模型
model.save_quantized("./qwen3-32b-gptq-4bit")

AWQ量化

# 使用AutoAWQ进行量化
from awq import AutoAWQForCausalLM

model = AutoAWQForCausalLM.from_pretrained("Qwen/Qwen3-32B")

quant_config = {
    "zero_point": True,
    "q_group_size": 128,
    "w_bit": 4,
    "version": "GEMM"
}

model.quantize(
    calibration_data,
    quant_config=quant_config
)
model.save_quantized("./qwen3-32b-awq-4bit")

vLLM部署量化模型

# GPTQ模型部署
vllm serve ./qwen3-32b-gptq-4bit \
  --quantization gptq \
  --dtype float16 \
  --tensor-parallel-size 1 \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.9

# AWQ模型部署
vllm serve ./qwen3-32b-awq-4bit \
  --quantization awq \
  --dtype float16 \
  --max-model-len 8192

# FP8模型部署(H100)
vllm serve ./model \
  --quantization fp8 \
  --kv-cache-dtype fp8

Ollama部署

# 从GGUF文件创建Ollama模型
cat > Modelfile <<EOF
FROM ./qwen3-32b-q4_k_m.gguf
PARAMETER num_ctx 8192
PARAMETER temperature 0.7
EOF

ollama create my-qwen -f Modelfile
ollama run my-qwen

量化效果对比

以Qwen3-32B为例(单卡A100 80GB):

方案模型大小显存占用推理速度精度损失
FP1664GB68GB1.0x0%
INT832GB36GB1.5x~1%
GPTQ-INT416GB20GB2.0x~4%
AWQ-INT416GB20GB2.1x~3%
GGUF-Q4_K_M18GB22GB1.8x~4%

校准数据准备

def prepare_calibration_data(domain_texts, n_samples=128, max_length=512):
    """准备量化校准数据"""
    samples = []
    
    for text in domain_texts:
        # 截取合适长度的片段
        tokens = tokenizer.encode(text)
        
        for i in range(0, len(tokens) - max_length, max_length // 2):
            chunk = tokens[i:i + max_length]
            samples.append(tokenizer.decode(chunk))
            
            if len(samples) >= n_samples:
                break
        
        if len(samples) >= n_samples:
            break
    
    return samples

量化后评估

async def eval_quantized_model(model_path, benchmarks):
    """评估量化模型的性能"""
    results = {}
    
    for bench_name, bench in benchmarks.items():
        original_score = bench.load_baseline("fp16")
        quantized_score = await bench.evaluate(model_path)
        
        results[bench_name] = {
            "original": original_score,
            "quantized": quantized_score,
            "degradation": (original_score - quantized_score) / original_score * 100
        }
        
        if results[bench_name]["degradation"] > 5:
            print(f"⚠️ {bench_name}: {results[bench_name]['degradation']:.1f}% degradation")
    
    return results

常见问题

OOM(显存不足)

  • 使用更激进的量化(INT4)
  • 减少max-model-len
  • 使用CPU offload

精度损失过大

  • 检查校准数据是否代表目标领域
  • 尝试更大的group_size(如256)
  • 尝试AWQ(通常比GPTQ精度更好)
  • 使用混合精度:关键层FP16,其余INT4

速度没有提升

  • 确保使用支持量化加速的推理引擎(vLLM/TensorRT-LLM)
  • 检查GPU是否支持量化计算(如INT4需要 Ampere+架构)
  • 确认KV Cache也在使用量化

结语

量化部署是让大模型在有限硬件上运行的关键技术。GPTQ和AWQ是INT4量化的两大主流方案,FP8在H100上提供了更好的精度-效率平衡。根据硬件条件和精度需求选择合适的量化方案,配合vLLM等推理引擎,可以在消费级硬件上部署百亿参数模型。

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。