7B 模型 FP16 权重约 14GB 显存,一张 12GB 的消费卡直接 OOM;但量化到 INT4 后只需约 4GB,就能在同一张卡上跑起来还留出上下文空间。量化不是玄学,是一次”精度换显存”的可度量交易:本文给出显存估算、量化选型、部署与回归验证的完整流程。

前置准备

硬件与工具:一张 12GB 以上显存的 NVIDIA 卡;安装 llama.cpp 或 vLLM:

# 路线一:llama.cpp(GGUF 量化,CPU/GPU 混合,最省资源)
git clone https://github.com/ggerganov/llama.cpp && cd llama.cpp
pip install -r requirements.txt

# 路线二:vLLM(AWQ/GPTQ,GPU 服务化吞吐更高)
pip install vllm
  • GGUF:llama.cpp 生态格式,量化档位 q4_k_m / q5_k_m / q8_0
  • AWQ/GPTQ:校准数据感知的量化,同比特下通常比朴素 RTN 更保精度

步骤一:估算显存需求

先算账再动手,避免盲目下载:

def vram_gb(params_b, bits, ctx_tokens=4096, kv_bytes_per_token=0.5*1024*1024/1024/1024*1024):
weight = params_b * 1e9 * bits / 8 / 1024**3 # 权重显存
kv = ctx_tokens * kv_bytes_per_token / 1024**3 * 13 # KV cache 粗估(13%系数示例)
return round(weight + kv + 1.0, 2) # +1GB 运行时开销

print(vram_gb(7, 16), "GB (FP16)") # 约 14+ GB
print(vram_gb(7, 4), "GB (INT4)") # 约 4.5 GB

结论:12GB 卡跑 7B,INT4 是唯一可行档位;INT8(约 8GB)也能跑但上下文要收紧。

步骤二:量化模型(GGUF 路线)

下载 FP16 权重后转换为 GGUF 并量化到 q4_k_m:

# 转换为 GGUF
python convert_hf_to_gguf.py ./model-7b-fp16 --outfile model-7b-f16.gguf

# 量化到 q4_k_m(精度/体积平衡档)
./llama-quantize model-7b-f16.gguf model-7b-q4_k_m.gguf q4_k_m

vLLM 路线则直接用社区已量化好的 AWQ 权重,无需自己校准:

pip download --no-deps solidcodes-7b-awq  # 示意:替换为实际 AWQ 模型 ID

步骤三:启动推理服务

llama.cpp 起一个 OpenAI 兼容接口:

./llama-server -m model-7b-q4_k_m.gguf -ngl 99 --port 8080 -c 4096

vLLM 起 AWQ 模型:

python -m vllm.entrypoints.openai.api_server \
--model your-org/model-7b-awq --quantization awq --max-model-len 4096

两条路线都暴露 /v1/chat/completions,业务代码无需改动。

步骤四:质量与速度回归

量化必须过回归关,用同一批样例对比 FP16 与量化版:

import openai, time
client = openai.Client(base_url="http://localhost:8080/v1", api_key="x")

cases = ["解释什么是梯度下降", "写一首五言绝句", "9.11 和 9.9 哪个大?"]
for q in cases:
t = time.time()
r = client.chat.completions.create(model="q4", messages=[{"role":"user","content":q}])
print(round(time.time()-t, 2), "s |", r.choices[0].message.content[:60])
  • 主观题看答案是否仍连贯、无乱码与复读
  • 客观题(数学/指令遵循)记录准确率,掉点超过 5 个百分点就升档到 q5/q8
  • 记录 tokens/s 与首 token 延迟,作为容量规划基线

常见问题

  • 量化后输出复读/乱码:档位过低或校准不匹配,升 q5_k_m 或换 AWQ 重 quant
  • 仍然 OOM:上下文太长,KV cache 吃满——降 -c 或开 vLLM 的 block 限制
  • CPU 推理太慢:llama.cpp 加 -ngl 99 把全部层放 GPU;无 GPU 时选 moe 小模型而非硬跑 7B
  • 困惑度怎么测:llama.cpp 的 perplexity 工具对比 FP16/量化版,涨幅 <10% 一般可接受

小结

单卡部署的本质是显存预算分配:权重(靠量化压缩)+ KV cache(靠上下文长度控制)+ 运行时开销。先估算、再选档、后回归,量化就从”碰运气”变成一条可复现的工程流水线:FP16 算账 → INT4 量化 → 服务化 → 质量/速度双回归,任何一环不达标就回到选型调整档位。