7B模型塞8G显存,量化3个坑

4 阅读3分钟

上个月想把一个 7B 的开源模型在本地跑起来做内部工具,FP16 一加载,14G 显存直接干穿,机器就一张 16G 的卡,还得留显存给 KV cache。查了下方案,量化呗——INT4 量化后 7B 模型只要 4-6G 显存,听起来完美。

结果真上手,一晚上踩了 3 个坑,量化不是把 bits 改小那么简单。下面挨个说。

坑 1:量化第一步就 OOM,device_map="auto" 是个坑

最开始用 AutoAWQ 量化,照着文档写了 device_map="auto",校准数据集用了默认的 128 条样本。结果一跑,CUDA out of memory,量化进程直接被杀。

一开始以为是卡不行,后来才搞明白:device_map="auto" 会把整个模型权重一次性加载到显存,再逐层做量化校准。7B 模型 FP16 权重本身就 14G,加上校准过程中的中间激活,16G 显存根本扛不住。

解决方式很直接:

  • device_map 改成 "sequential",逐层加载、量化、卸载,显存峰值直接砍掉一半
  • 校准样本数从 128 降到 64,精度几乎没影响(PPL 差不到 0.5%),但显存占用明显下降

改完之后,量化过程显存峰值稳定在 11G 左右,顺利跑完。

CUDA OOM 与逐层加载对比

坑 2:贪心上 Q2_K,结果推理反而更慢

量化完了,部署的时候又犯了个错。既然 Q4_K_M 能省显存,那 Q2_K 不是更省?速度应该更快吧?

直接换了 Q2_K 的 GGUF 模型跑 llama.cpp,结果傻眼了:Q4_K_M 能跑 58 tokens/s,Q2_K 只有 38 tokens/s,慢了 35%,显存是省了,但速度反而降了。

查了下原因:Q2_K 的量化粒度太细,解码的时候需要频繁反量化和重加载 scale 参数,kernel 反而更复杂。Q4_K_M 是目前实测的甜点——4-bit 混合精度,关键层保留更高精度,解码 kernel 已经高度优化,速度最快,精度损失也只有 2% 左右。

结论:别盲目追低比特,Q4_K_M 是大多数场景的最佳选择。Q2_K 只在显存硬不够的时候才考虑。

坑 3:自己量化的模型,vLLM 加载报 divisible 错误

第三个坑最隐蔽。GPTQ 量化完一个 7B 模型,用 vLLM 部署,一启动就报 ValueError: ... must be divisible by ...,模型加载不进去。

排查了半天才发现:自己用 GPTQ 量化的模型,intermediate size(FFN 层的隐藏维度)和官方发布的量化版不一致。vLLM 加载 GPTQ 模型时会做维度对齐校验,自量化模型的配置对不上就报错。

解决方式两条路:

  • 省事的:直接用官方或社区已量化好的模型(HuggingFace 上大部分主流模型都有 GPTQ/AWQ 版),别自己量化
  • 必须自己量化的:量化时确保配置和官方一致,量化后用 transformers 先加载验证配置,再上 vLLM

我后来直接换成了社区的 AWQ 版,vLLM 一行命令启动,再也没报过错。

Q4_K_M 与 Q2_K 推理速度对比

踩完的结论

调完这几轮,7B 模型终于在 8G 显存里跑起来了,推理速度 50+ tokens/s,精度和 FP16 比几乎感觉不出来。几个直接能用的结论:

  • vLLM 部署:选 AWQ 或 GPTQ 量化版,优先用社区已量化好的,别自己折腾
  • llama.cpp/Ollama 部署:选 GGUF Q4_K_M,这是速度和精度的甜点,别碰 Q2_K
  • 量化时 OOMdevice_mapsequential,校准样本降到 64
  • 量化后必测:别只看 PPL,拿真实任务跑一遍,PPL 涨 1-3% 算健康,任务级效果才是硬标准

量化不是万能药,但用对了确实能把大模型塞进小显存。这几个坑我踩过了,你直接跳过。

📌 更多 AI 实战干货、踩坑记录,欢迎关注公众号 「你的应急食品」


📌 更多 AI 实战干货、踩坑记录,欢迎关注公众号 「你的应急食品」