模型量化与本地部署#
一句话答案#
量化是把 FP16/BF16 权重用 scale(和 zero-point)映射到 INT8/INT4 等低比特整数,显存按比例缩小、decode 阶段因为是访存瓶颈而提速;INT8 几乎无损,INT4 有小损且模型越小越敏感。主流 PTQ 方法 GPTQ(逐层 Hessian 误差补偿)、AWQ(按激活幅度保护显著权重)、GGUF k-quants(CPU/Apple 友好)、NF4(QLoRA)各有归宿,新 GPU 上 FP8 和 FP4(NVFP4/MXFP4)正在成为默认;部署栈上 GPU 生产选 vLLM/SGLang/TensorRT-LLM,本地与边缘选 llama.cpp/Ollama,全部走 OpenAI-compatible 接口。私有化部署的本质取舍是”数据安全 + 长期成本 + 延迟可控”换”模型能力上限”。
核心要点
1. 显存估算:先算清楚能不能放下#
总显存 ≈ 权重(参数量 × 每参数字节)+ KV Cache(随上下文与并发线性增长)+ 激活/临时 buffer + 框架开销(通常再留 10–20%)。权重部分的量级:
| 模型 | FP16/BF16(2B/参数) | INT8(1B) | INT4(~0.5B,含 scale 开销约 0.55B) |
|---|---|---|---|
| 7B/8B | ~14–16 GB | ~7–8 GB | ~4–5 GB |
| 14B | ~28 GB | ~14 GB | ~8 GB |
| 70B/72B | ~140 GB | ~70 GB | ~36–40 GB |
KV Cache 每 token = 2 × layers × kv_heads × head_dim × bytes(公式推导见 LLM推理优化)。Llama-3-8B(32 层、GQA 8 个 KV 头、head_dim 128、FP16)≈ 128 KB/token,8K 上下文约 1 GB;70B(80 层)≈ 320 KB/token,32K 上下文就要 10 GB。结论:单卡 24 GB 跑 7B 要留够上下文,跑 70B 必须 INT4 + 多卡或 CPU offload;GQA/MLA 等结构对 KV 显存影响见 注意力机制变体与位置编码。
2. 量化原理:scale、zero-point 与粒度#
把浮点 x 映射到 b 位整数:q = clamp(round(x / s) + z, q_min, q_max),反量化 x̂ = s · (q − z)。
- 对称量化:z = 0,s = max|x| / (2^(b−1) − 1),实现简单、适合权重(近似零均值);非对称量化:s = (max − min)/(2^b − 1),多一个 zero-point,适合分布偏斜的激活。
- 粒度:per-tensor(整张矩阵一个 s,误差大)→ per-channel(每输出通道一个 s)→ per-group(每 64/128 个权重一组 s,GPTQ/AWQ/GGUF 的默认做法,精度与开销的折中)。组越小越准,但 scale 本身占显存(INT4 g128 约多 5–10%)。
- 离群值(outlier)问题:LLM 的激活存在少数幅度大几十倍的通道(LLM.int8() 论文观察到约 6.7B 以上模型普遍出现),一个 outlier 会把整组的 s 撑大、其余值全被压到几个整数级。这是”权重好量化、激活难量化”的根源,也是各方法差异所在。
- 为什么量化能提速:decode 阶段每生成一个 token 要把全部权重读一遍,是访存瓶颈(memory-bound),权重体积减半读取时间就减半;prefill 与大 batch 是计算瓶颈,weight-only 量化要先反量化再乘,几乎不提速甚至变慢——这也是 W8A8/FP8 存在的理由。
3. 训练后量化(PTQ)主流方法对比#
| 方法 | 位宽/形态 | 核心思想 | 典型用途 |
|---|---|---|---|
| GPTQ | W4A16,g128 | 逐层量化:用少量校准数据算 Hessian(H = 2XXᵀ),逐列量化并把误差补偿到未量化的列上(OBQ 思路),最小化该层输出误差 | GPU 推理,Marlin 内核快;工具用 GPTQModel 或 llm-compressor(AutoGPTQ 已归档) |
| AWQ | W4A16,g128 | 发现约 1% 按激活幅度衡量的”显著权重”贡献大头;不搞混合精度,而是对这些通道做 per-channel 放大(激活对应缩小,数学等价)再量化,降低其相对误差;无需反向传播,对指令模型泛化更稳 | GPU 推理,vLLM/SGLang 原生支持;工具用 llm-compressor 或 GPTQModel(AutoAWQ 已停止维护,并入 vLLM 的 llm-compressor) |
| GGUF k-quants | Q2_K~Q8_0,常用 Q4_K_M / Q5_K_M | llama.cpp 格式;分块 + 超级块两级 scale,按张量重要性混合位宽(“K_M” = medium),可配 importance matrix 校准 | CPU / Apple Silicon Metal / 消费级显卡,单文件分发 |
| bitsandbytes NF4 | 4-bit NormalFloat | 按正态分布分位数设计 16 个量化格点(信息论最优),再对 scale 二次量化(double quant);加载时即时量化,无需校准 | QLoRA 训练基座(见 LoRA微调原理)、快速实验;推理速度不占优 |
| SmoothQuant(W8A8) | 权重+激活 INT8 | 用 per-channel 系数 s 把激活的 outlier “平移”到权重上(X/s · sW),让两者都好量化,跑真正的 INT8 GEMM | 高并发、prefill 多的服务,真正省算力 |
| FP8(E4M3/E5M2) | 权重/激活/KV 8 位浮点 | Hopper/Ada 及之后 GPU 原生支持,动态范围比 INT8 大得多、几乎无需校准 | 新一代 GPU 上的默认选择,vLLM/SGLang/TensorRT-LLM 都支持,可用 llm-compressor 或 NVIDIA Model Optimizer 产出 |
| FP4(NVFP4 / MXFP4) | 4 位浮点 E2M1 + 块级 scale | MXFP4 是 OCP 标准,每 32 个值共享一个 2 的幂次 scale;NVFP4 每 16 个值共享一个 FP8 scale,外加一个张量级 FP32 scale,块更小、精度更好 | Blackwell 张量核原生支持,旧卡只能省显存不提速;gpt-oss 以 MXFP4 发布;vLLM、llama.cpp 已支持,各硬件内核成熟度不一,以官方文档为准 |
QAT(量化感知训练)在训练中插入伪量化让模型适应低比特,效果最好但要训练成本,通常是模型厂商出官方低比特版本时才用。
4. 量化对精度的影响规律#
- INT8/FP8 权重几乎无损(困惑度变化通常在小数点后),INT4 有小幅退化,3-bit 以下明显掉点;小模型更敏感(1–3B 的 INT4 掉得比 70B 的 INT4 多得多),因为冗余少。
- 任务敏感度:数学推理、代码、长链多步任务对量化最敏感,闲聊与摘要几乎无感;务必在自己的评测集上看指标(方法见 LLM评测方法),不能只看困惑度。
- MoE 模型:权重巨大但每 token 只激活少数专家,量化主要为了”放得下”;难点是每个专家分到的校准样本少,GPTQ/AWQ 统计不充分,需要更大的校准集或按专家分别校准(架构见 MoE混合专家架构)。
- 激活量化比权重量化难(outlier),所以 W4A16 普及得最早;W8A8/FP8 依赖硬件内核和 SmoothQuant 类预处理。
- KV Cache 量化:FP8/INT8 KV 基本无损、能把长上下文并发翻倍;INT4 KV(如 KIVI 的 per-channel Key + per-token Value)开始有可感知损失。
5. 部署栈选型与服务化#
| 场景 | 栈 | 特点 |
|---|---|---|
| GPU 生产高吞吐 | vLLM | PagedAttention + 连续批处理,模型与量化格式支持最广,社区默认选项 |
| 多轮/Agent/结构化输出多 | SGLang | RadixAttention 前缀缓存命中率高,约束解码与多调用编排快 |
| NVIDIA 上极致延迟 | TensorRT-LLM | 编译成引擎、内核最优,但构建链路重、换模型麻烦 |
| 本地/边缘/Mac | llama.cpp(引擎)/ Ollama(模型管理 + API,基于 GGML 的自有引擎)/ LM Studio(GUI) | GGUF、CPU+GPU 混合 offload、单机开箱即用;Mac 上还可用 MLX |
HF 的 TGI 已进入维护模式、GitHub 仓库于 2026-03 归档,官方推荐改用 vLLM/SGLang,新部署不建议再选。
所有主流栈都暴露 OpenAI-compatible 的 /v1/chat/completions,应用层只换 base_url 即可切换,调用细节见 [LLM API调用与流式输出](/topics/llm-serving/LLM API调用与流式输出)。压测要看四个指标:TTFT(首 token 延迟,受 prefill 与排队影响)、TPOT/ITL(每 token 间隔,受 decode 访存影响,量化主要改善它)、吞吐(tokens/s,连续批处理拉高)、并发下的 goodput(满足 SLO 的有效吞吐)。国产卡路线(昇腾 MindIE / vLLM-Ascend、海光 DCU 等)在信创场景下也已能跑主流开源模型,但算子与量化格式支持需逐个验证。
6. 私有化部署的决策框架#
- 必须私有化:数据不能出域(合规、涉密)、需要离线运行、需要自定义微调权重、流量大且稳定(自建成本能摊薄)。成本对比核心是利用率:一张 GPU 跑满时单 token 成本远低于 API,闲着就是纯亏;长尾/低频场景 API 更省(测算方法见 AI应用成本优化)。
- 代价:开源模型与最强闭源模型有能力差距,且需要自己负责升级、评测、SRE;常见做法是混合路由——敏感数据与高频简单任务走私有化小/中模型,复杂任务脱敏后走 API。
- 选型顺序:先定模型尺寸(能力门槛 + 显存)→ 定量化方案(GPU 选 AWQ/GPTQ/FP8,Blackwell 上可评估 NVFP4,CPU/Mac 选 GGUF Q4_K_M 起步)→ 定推理栈 → 压测 TTFT/吞吐 → 用业务评测集验证量化损失。
面试回答(2分钟版)
量化就是把 FP16 权重映射到低比特整数,公式是 q = round(x/s) + z,关键参数是 scale 和 zero-point,粒度上从 per-tensor 到 per-channel 到 per-group,group 128 是现在的主流。为什么能省显存很直观——7B 模型 FP16 是 14 GB,INT8 就 7 GB,INT4 不到 5 GB;为什么能提速是因为 decode 阶段是访存瓶颈,权重读得少就快,但 prefill 是计算瓶颈,weight-only 量化帮助不大,所以才有 W8A8 和 FP8。第一,方法上 GPTQ 是逐层用 Hessian 做误差补偿,AWQ 是发现约 1% 激活幅度大的显著权重、用通道缩放保护它们,这两个是 GPU 上 INT4 的主流;GGUF 的 k-quants 是 llama.cpp 用的,CPU 和 Mac 友好;NF4 是 bitsandbytes 的,主要给 QLoRA 训练用;SmoothQuant 把激活的 outlier 平移到权重上实现 W8A8,FP8 在 Hopper 上基本是免费的,Blackwell 又加了 FP4 张量核,NVFP4 和 MXFP4 开始普及。第二,精度规律是 INT8 几乎无损、INT4 小损、模型越小越敏感、数学和代码任务最敏感,MoE 因为每个专家校准样本少更难量化,KV Cache 量化到 FP8 基本无损。第三,部署栈上生产 GPU 用 vLLM 或 SGLang,追求极致延迟用 TensorRT-LLM,本地用 llama.cpp 和 Ollama,全部走 OpenAI-compatible 接口,压测看 TTFT、每 token 间隔和吞吐。最后,私有化不是因为便宜而是因为数据安全和可控,成本能不能算过来取决于 GPU 利用率,实际常做混合路由,敏感和高频任务走私有模型,复杂任务走 API。
追问与易错
追问方向:
- 24 GB 显存的单卡能跑什么? → 7B/8B FP16 勉强放下但上下文只剩几 GB;INT4 的 14B 约 8 GB 权重很宽裕;32B INT4 约 18 GB 可跑但并发很低;70B 必须 INT4 + 两卡或 llama.cpp 把部分层 offload 到 CPU。
- GPTQ 和 AWQ 怎么选? → 两者精度相近,AWQ 无需反向传播、对指令模型更稳、vLLM/SGLang 内核支持好;GPTQ 配 Marlin 内核吞吐也很高。都需要校准数据(几百条即可),校准集应接近业务分布。工具上 AutoAWQ/AutoGPTQ 已停止维护,现在用 llm-compressor 或 GPTQModel。如果 GPU 支持 FP8,先试 FP8,精度风险更小。
- 量化后为什么有时反而变慢? → weight-only INT4 在大 batch / prefill 阶段要先反量化再做 FP16 矩阵乘,计算瓶颈下多了反量化开销;解决是上 W8A8/FP8 用整数或 FP8 内核,或确认自己的负载是 decode 主导。
- 激活量化为什么比权重量化难? → 激活存在少数幅度大几十倍的 outlier 通道,per-tensor scale 被撑大导致其余值精度塌缩;SmoothQuant 用 per-channel 缩放把难度迁移到权重上,LLM.int8() 则把 outlier 列单独用 FP16 算。
- Ollama 和 vLLM 的本质区别? → Ollama 早期是 llama.cpp 的封装,2025 年起换成基于 GGML 库的自有引擎,定位不变:面向单机单用户、GGUF 格式、CPU/GPU 混合,开箱即用但并发吞吐弱;vLLM 面向 GPU 多并发服务,连续批处理 + PagedAttention,高并发下吞吐远高于 Ollama。
易错点:
- ❌ “INT4 就是显存减半再减半、速度也翻倍” → 显存大致如此(还有 scale 开销和 KV Cache 不变),速度只在 decode 访存瓶颈下改善,prefill 和大 batch 不一定快。
- ❌ “量化只是把数值四舍五入” → 朴素 RTN 在 INT4 掉点明显,GPTQ/AWQ 的价值在误差补偿与显著权重保护;校准数据的分布也会影响效果。
- ❌ “显存只要放得下权重就行” → KV Cache 随并发 × 上下文线性增长,长上下文多并发时 KV 往往比权重更吃显存。
- ❌ “私有化部署一定比 API 便宜” → 取决于 GPU 利用率与运维人力,低频长尾负载自建通常更贵。