直接回答
大模型量化不是一个通用的压缩开关,而是一份完整的部署契约:它必须说明量化对象是权重、激活还是 KV Cache,数值表示是 W4A16 还是 W8A8,量化算法与校准数据如何生成制品,以及哪个运行时内核负责执行。更低的名义位宽可能减少存储或内存流量,却不保证延迟更低、总显存更少或模型行为合格。只有在目标硬件和真实负载上同时通过业务质量、安全、延迟、显存与 Goodput 门禁,候选制品才具备生产价值。
核心要点
- 必须把 GPTQ、AWQ、SmoothQuant 等算法,与 INT4/INT8 数值表示、GGUF 容器和推理运行时分层讨论。
- 名义位宽只能估算权重负载下界;KV Cache、缩放参数、工作区、内存分配器与并发共同决定服务容量。
- 基础 Checkpoint、Tokenizer、Chat Template、量化器版本、校准数据、打包布局和制品校验和都属于模型契约。
- 基准应拆成同引擎受控赛道与最佳生态赛道,不能拼接不同引擎的 tokens/s 后宣布算法排名。
- 灰度只接纳同时满足业务质量、安全、延迟、显存和 Goodput 门槛的量化制品。
大模型量化究竟改变了什么
量化使用有限的离散值近似原始实数张量。常见的仿射量化可以写成:
q = clip(round(x / scale) + zero_point, q_min, q_max)
x_hat = scale * (q - zero_point)
缩放因子与可选零点可以按整个张量共享,也可以按通道、分组或数据块计算。粒度越细,通常越能跟随局部分布,但会引入更多元数据,并依赖不同的打包方式与内核。
W4A16 表示 4 位权重和 16 位激活,W8A8 表示 8 位权重和 8 位激活。但这些标签仍未说明分组大小、对称或非对称映射、累加精度、未量化模块、张量布局,以及 KV Cache 是否仍使用 FP16 或 BF16。
权重、激活与 KV Cache 是三个独立对象
三类量化解决的瓶颈不同,不能用“模型已经 INT4”一笔带过。
| 量化对象 | 主要目标 | 典型风险 | 必测指标 |
|---|---|---|---|
| 权重 | 减少制品体积和权重内存流量 | 层级质量退化、打包布局无内核支持 | 业务质量、加载时间、Decode 表现 |
| 激活 | 使用低精度矩阵计算 | 异常值和累加误差 | 任务切片质量、Prefill 延迟 |
| KV Cache | 降低上下文长度和并发带来的内存增长 | 长上下文质量退化 | 长上下文验收率、容量、ITL |
仅权重量化不会自动减少 KV Cache。长 Prompt 和高并发场景中,KV Cache 可能反而成为显存主导项。分页、隔离与容量规划可参考独立的 KV Cache 工程指南。
算法、格式、容器与运行时不能混排
GPTQ、AWQ、GGUF、bitsandbytes 和 llama.cpp 经常出现在同一张“量化方法对比表”中,但它们解决的是不同层级的问题。
| 层级 | 代表对象 | 回答的问题 |
|---|---|---|
| 数值表示 | INT8、INT4、FP8、NF4 | 张量使用哪些值与位布局? |
| 量化算法 | GPTQ、AWQ、SmoothQuant | 如何选择缩放参数或舍入后的权重? |
| 加载或转换路径 | bitsandbytes、LLM Compressor、TorchAO | 在哪个阶段完成转换或低精度加载? |
| 模型容器 | GGUF | 张量与元数据如何打包? |
| 推理运行时 | vLLM、llama.cpp、Ollama、TensorRT-LLM | 哪些内核负责调度并执行请求? |
GGUF 官方规范 定义的是带可扩展元数据、张量信息、对齐规则和内存映射能力的二进制文件格式。GGUF 可以承载不同编码的量化张量,但它本身不是与 GPTQ 或 AWQ 同层的算法。
运行时支持也会持续变化。vLLM 当前量化文档 维护方法与硬件兼容矩阵,并没有承诺每种量化制品都能在所有设备上高效运行。生成制品前应固定运行时版本,并根据当前官方矩阵验证目标路径。
GPTQ、AWQ 与 SmoothQuant 的机制差异
三种方法优化的是不同近似问题。论文能够证明机制及其报告实验,不能证明一个方法在所有模型、硬件和运行时上永久胜出。
GPTQ 使用近似二阶信息选择舍入
GPTQ 原始论文 描述了一种训练后、仅权重的一次性量化方法。它利用近似二阶信息,在逐层量化过程中更新舍入决策。生产落地时真正需要回答的是:目标模型是否受支持,校准样本能否代表业务输入,以及部署运行时是否拥有匹配制品布局的高效内核。
论文中的量化耗时、质量和加速结果只属于其报告的模型、硬件、软件与参数,不能直接迁移成新服务的容量结论。
AWQ 通过激活感知保护关键通道
AWQ 原始论文 描述的是激活感知的仅权重量化。它观察激活分布,识别关键权重通道,并搜索等价的逐通道缩放以降低关键通道的量化误差,而不是保留一个混合精度子集。该方法不依赖反向传播或权重重建。
AWQ 不保证必然比 GPTQ 更快或质量更高。模型结构、分组大小、校准数据、运行时内核与工作负载会共同改变结果。AWQ 术语页 进一步解释其机制和适用边界。
SmoothQuant 把激活难题迁移到权重
SmoothQuant 原始论文 面向 W8A8 推理。它通过等价变换平滑激活异常值,将部分量化难度迁移到权重,使两个矩阵乘操作数更适合整数计算。迁移强度和运行时实现仍然是具体部署中的参数,而不是跨模型常量。
为什么位宽不等于服务显存
理论权重负载只能作为下界:
ideal_weight_bytes = parameter_count * bits_per_weight / 8
真实文件和常驻权重还包含缩放因子、零点、分组元数据、未量化层、Tokenizer、对齐填充和容器开销。服务运行时还会分配 KV Cache、临时激活、CUDA Graph 或编译缓冲区、通信缓冲区、队列与内存碎片。
因此,“7B INT4 只需要 4 GB”不是完整的工程结论。它没有说明 4 GB 指模型文件、加载后权重、空闲进程、单请求峰值,还是满足并发目标的安全容量。LLM 推理工程指南 解释了为什么 TTFT、Token 间延迟、批处理和调度必须联合评测。
低精度不保证推理加速
只有当内存流量或低精度计算收益大于额外开销时,量化路径才会更快。常见失败模式包括:
- 运行时在每次算子执行前把权重反量化到更宽类型;
- 制品打包布局与现有内核不匹配;
- 未支持模块回退到更慢的算子;
- 短 Prompt、小 Batch 无法摊薄启动与转换开销;
- Decode 受 KV Cache 流量或调度限制,而不是受权重读取限制;
- 启动阶段重打包增加加载耗时和发布抖动。
Prefill 与 Decode 必须分开统计。候选制品可能提高吞吐却恶化首 Token 延迟,也可能减少权重显存却不能提升有效并发。
建立可复现的量化制品契约
量化制品必须能够追溯到不可变基线和完整配方。这份契约应与制品一同保存,而不是只存在于容易丢失的部署工单中。
{
"artifact_id": "support-model-w4a16-awq-r3",
"base_checkpoint": "registry.example/model",
"base_revision": "immutable-revision",
"tokenizer_revision": "immutable-revision",
"chat_template_sha256": "sha256:...",
"quantizer": {
"name": "awq",
"version": "pinned-version",
"weight_bits": 4,
"activation_bits": 16,
"group_size": 128,
"symmetric": false,
"excluded_modules": ["output_head"]
},
"calibration": {
"dataset_id": "approved-calibration-slice",
"dataset_sha256": "sha256:...",
"sampling_policy": "language-and-task-stratified"
},
"packaging": {
"format": "runtime-specific",
"runtime": "pinned-runtime",
"kernel": "verified-kernel-family"
},
"artifact_sha256": "sha256:...",
"license": "verified"
}
校准集需要覆盖生产语言、Prompt 长度、业务领域、工具调用和安全敏感输入。“几百条通用样本就足够”不是普遍规则,样本数量只有与覆盖度和稳定性检验一起记录才有意义。
Tokenizer 与 Chat Template 也必须固定。模板变化可能比量化本身产生更明显的输出差异,从而破坏归因。
用双赛道建立可复现基准
可靠评测需要把算法效果与生态成熟度分开。
同引擎受控赛道
固定基础 Checkpoint、Revision、Tokenizer、Chat Template、校准切片、评测集、服务版本、硬件、请求调度与测量代码。在可行时只改变量化配方。它回答:在受控条件下,量化选择究竟改变了什么?
最佳生态赛道
允许每个候选使用其最成熟的运行时和内核,但保持模型身份、工作负载、质量门禁和硬件等级可比。它回答:每套可部署技术栈在生产形态下能够交付什么?
不能把不同引擎、Batch、Prompt 长度与输出长度下的 tokens/s 放在同一张表中,随后宣布算法排名。
| 维度 | 必须保留的证据 |
|---|---|
| 业务质量 | 业务验收率或任务分数,并给出置信区间 |
| 行为完整性 | 工具调用有效率、JSON/Schema 有效率、拒答和安全切片 |
| 上下文 | 短、中位与尾部 Prompt,长上下文检索或推理 |
| 延迟 | TTFT、ITL 或 TPOT、端到端延迟分位数 |
| 容量 | 峰值显存、稳定并发、排队时间、OOM 率 |
| 效率 | 相同服务目标下的吞吐和 Goodput |
| 运维 | 启动时间、制品来源、回滚耗时、错误率 |
Goodput 只统计同时满足质量和延迟目标的请求,可以避免“吞吐很高但结果不可用”的候选获胜。
可运行的量化候选门禁
下面的 Python 程序不执行量化,而是验证已经测量的候选,防止团队仅凭位宽或吞吐决定晋级。它只依赖标准库。
from __future__ import annotations
import argparse
import json
from pathlib import Path
from typing import Any
REQUIRED_METRICS = {
"business_acceptance": (0.0, 1.0),
"structured_output_validity": (0.0, 1.0),
"safety_pass_rate": (0.0, 1.0),
"ttft_p95_ms": (0.0, None),
"itl_p95_ms": (0.0, None),
"peak_memory_gib": (0.0, None),
"goodput_rps": (0.0, None),
}
def number(value: Any) -> bool:
return isinstance(value, (int, float)) and not isinstance(value, bool)
def validate(candidate: dict[str, Any]) -> list[str]:
errors: list[str] = []
for field in ("artifact_id", "base_revision", "artifact_sha256"):
if not isinstance(candidate.get(field), str) or not candidate[field]:
errors.append(f"{field} must be a non-empty string")
metrics = candidate.get("metrics")
gates = candidate.get("gates")
if not isinstance(metrics, dict) or not isinstance(gates, dict):
return errors + ["metrics and gates must be objects"]
for name, (lower, upper) in REQUIRED_METRICS.items():
value = metrics.get(name)
if not number(value) or value < lower or (
upper is not None and value > upper
):
errors.append(f"invalid metric: {name}")
for name, rule in gates.items():
if name not in REQUIRED_METRICS:
errors.append(f"unknown gate: {name}")
continue
if not isinstance(rule, dict) or set(rule) != {"op", "value"}:
errors.append(f"gate {name} needs op and value")
continue
op, limit = rule["op"], rule["value"]
if op not in {"min", "max"} or not number(limit):
errors.append(f"invalid gate: {name}")
continue
measured = metrics.get(name)
if number(measured):
passed = measured >= limit if op == "min" else measured <= limit
if not passed:
errors.append(
f"gate failed: {name} measured={measured} {op}={limit}"
)
return errors
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("candidate", type=Path)
args = parser.parse_args()
try:
value = json.loads(args.candidate.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as error:
parser.error(str(error))
if not isinstance(value, dict):
parser.error("candidate root must be an object")
errors = validate(value)
if errors:
for error in errors:
print(f"ERROR: {error}")
raise SystemExit(1)
print(f"candidate passed: {value['artifact_id']}")
if __name__ == "__main__":
main()
保存为 quantization_gate.py,再检查一份真实测量结果:
python quantization_gate.py candidate.json
输入应来自固定测试条件,而不是估算。以下数值只用于展示数据结构,不代表任何模型或算法的性能:
{
"artifact_id": "support-model-w4a16-awq-r3",
"base_revision": "immutable-revision",
"artifact_sha256": "sha256:...",
"metrics": {
"business_acceptance": 0.94,
"structured_output_validity": 0.99,
"safety_pass_rate": 0.98,
"ttft_p95_ms": 420,
"itl_p95_ms": 38,
"peak_memory_gib": 18.6,
"goodput_rps": 7.4
},
"gates": {
"business_acceptance": {"op": "min", "value": 0.92},
"structured_output_validity": {"op": "min", "value": 0.98},
"safety_pass_rate": {"op": "min", "value": 0.97},
"ttft_p95_ms": {"op": "max", "value": 500},
"itl_p95_ms": {"op": "max", "value": 45},
"peak_memory_gib": {"op": "max", "value": 20},
"goodput_rps": {"op": "min", "value": 6.5}
}
}
灰度晋级与回滚
量化模型晋级应遵循模型和服务变更的同等门禁。离线基准通过后,不能直接替换全部基线实例。
- 检查 Manifest 完整性和制品校验和。
- 使用精确基线完成离线质量与性能门禁。
- 使用代表性影子流量验证,不向用户返回候选输出。
- 按租户或工作负载灰度,避免不可追踪的随机制品切换。
- 监控质量代理指标、工具错误、Schema 失败、延迟、显存和 Goodput。
- 任一硬门禁失败时回滚到固定基线。
灰度期间必须保留与候选容量兼容的基线。需要重新构建或临时下载旧制品的流程不是真正可执行的回滚。
常见失败模式
用固定排行榜选型
“AWQ 适合速度、GPTQ 适合精度、GGUF 适合 CPU”不是长期有效的规则。它隐藏了模型支持、内核成熟度、制品来源和工作负载差异。
只测困惑度
困惑度可以暴露部分分布变化,却不能证明工具调用正确、结构化输出有效、多语言行为稳定、拒答策略一致或业务任务通过。
忽略校准数据治理
未版本化的校准数据会让制品无法复现。直接使用敏感生产 Prompt 还会引入隐私和授权风险。应记录数据血缘,并使用获批且具有代表性的切片。
比较不同模型 Revision
如果候选来自不同 Checkpoint、Tokenizer 或 Chat Template,就无法隔离量化影响。所有组件都应固定后再做质量归因。
把成功加载当成兼容
运行时能够加载制品,不代表它使用了预期内核。它可能重打包、对部分层回退,甚至走低效路径。必须检查日志和 Profile,再测量完整请求链路。
常见问题
INT8 一定比 INT4 更适合生产吗?
不一定。更宽的表示通常有更多质量余量,但生产适配是测量结果,不是位宽标签。拥有成熟内核并通过业务门禁的 INT4 制品,可能优于存在算子回退或容量不足的 INT8 路径。两者必须接受相同门禁。
量化一定能降低云端推理成本吗?
不一定。只有显存节省转化为有效并发,或低精度内核提高 Goodput 时,成本才可能下降。如果系统受队列、KV Cache 或低效内核限制,成本可能不变。应计算满足 SLO 的每个已验收请求成本,而不是原始 Token 成本。
QAT 一定比 PTQ 更准确吗?
不一定。量化感知训练允许优化器适应低精度,但结果取决于训练数据、目标函数、稳定性和最终部署格式。强 PTQ 方法可能已经足够,而控制不当的 QAT 也可能导致行为回归。必须比较最终制品。
同一个量化制品能在所有运行时中执行吗?
不能。容器、张量编码、打包布局、算子和内核都可能依赖运行时。应核对当前官方兼容文档、固定版本,并验证实际加载的内核路径。
微调前还是微调后量化?
取决于工作流。QLoRA 在训练 Adapter 时加载量化且冻结的基础模型,这与生成最终推理制品不是同一件事。Adapter 合并或组合后,仍需对实际服务制品重新评测与打包。可结合 LoRA 术语 与 本地大模型部署指南 理解完整链路。
总结
大模型量化是一项端到端推理工程决策,不是固定压缩比例。先分清量化对象、数值表示、算法、容器和运行时,再保存完整制品契约。用同引擎受控赛道与最佳生态赛道评测候选,并把业务质量、安全、延迟、显存和 Goodput 设为晋级门禁,才能把一个低位宽文件转化为可部署、可审计、可回滚的模型制品。