LLM Quantization Deployment
LLM Quantization Deployment
一句话解释
量化通过降低权重(或激活/KV)的数值表示精度来换取显存和带宽,但”几 bit”只是入口——真正决定质量的是编码 recipe、bit 分配策略和硬件 kernel 支持的合力。
四层分类框架
| 层次 | 回答的问题 | 代表 |
|---|---|---|
| 数值格式 | 一个数怎么表示 | BF16、FP8、NVFP4、INT8、INT4 |
| 权重编码 recipe | 一组权重怎么分 block/scale/codebook | K-quant(Q4_K_M)、I-quant(IQ4_XS)、AWQ、GPTQ |
| 动态分配策略 | 哪些 tensor 用哪种编码 | Unsloth Dynamic(UD-Q4_K_XL) |
| 文件容器 | 编码结果怎么打包分发 | GGUF、Safetensors |
关键区分:K/I-quant 决定单个 tensor 的编码方式;UD 决定 tensor 之间的格式分配。UD-Q4_K_XL 不是新的数据类型,而是以 Q4_K 为主体、按敏感度混合更高精度的 recipe。
各层核心机制
数值格式
| 格式 | 结构 | 特点 |
|---|---|---|
| BF16 | 1s + 8exp + 7mant | 训练/推理基准;动态范围大 |
| FP8 (E4M3) | 1s + 4exp + 3mant | 真浮点,GPU Tensor Core 原生支持 |
| NVFP4 | E2M1 + per-block FP8 scale + tensor FP32 scale | NVIDIA Blackwell 4-bit 浮点路线 |
FP8 ≠ Q8_0:前者是浮点格式,后者是整数 block quant。
GGUF Q/K/I 编码
| 家族 | 核心思想 | 典型 bpw |
|---|---|---|
| Q4_0/Q4_1(Legacy) | 简单 block scale(Q4_1 加 offset/min) | ~4.0 |
| K-quant | block + super-block 层级;scale/min 本身也量化 | Q4_K_S 4.67 / Q4_K_M 4.89 / Q6_K 6.56 |
| I-quant | 非线性 codebook + imatrix,专攻 ≤4 bit 极限压缩 | IQ4_XS ~4.46 |
名字里的 S/M/XL/XS 是 recipe 档位(保护多少敏感 tensor),不是模型大小。实际 bpw 高于名义值,因为 embedding/output/sensitive layer 可能用更高精度。
Importance Matrix
用 calibration data 观察哪些权重/tensor 对输出影响大,形成 importance matrix 后在量化时优先保护这些区域。I-quant 和 UD 都可能使用此信息。
Unsloth Dynamic
按 tensor/layer 敏感度动态选择格式:不敏感层给低 bit、极敏感层保 BF16。Dynamic NVFP4 在 Blackwell 上同理。这解释了为什么 UD-Q8_K_XL 比 Q8_0 更大——它不是统一 8 bit。
评估维度
| 维度 | 问题 |
|---|---|
| 精度 | 任务回归?长上下文退化?多样本盲评还是单图噪声? |
| 显存 | 权重 + KV + runtime 峰值是多少? |
| 吞吐/延迟 | 目标硬件有优化 kernel 吗?反量化开销如何? |
| 兼容性 | 引擎版本、模型架构、多卡策略支持吗? |
| 运维 | 文件格式、加载时间、可复现性? |
单张生成图不能证明量化优劣。现代优秀 4-bit 已非常接近 BF16,但 3-bit 以下开始明显分化。
选型心智模型
| 场景 | 优先考虑 |
|---|---|
| 质量/内存充足 | BF16 或 Q8_0 |
| 明显省空间少损质量 | Q6_K |
| 主流本地甜点 | Q4_K_M 或 UD-Q4_K_XL |
| 内存紧张 | Q3_K_M 或 UD-Q3_K_XL |
| 只求能跑 | IQ2/UD-Q2 系列(必须重新验证任务) |
与引擎的关系
| 容器 | 主生态引擎 |
|---|---|
| GGUF | llama.cpp / Ollama |
| Safetensors | vLLM / SGLang / TensorRT-LLM |
GGUF 是文件容器而非算法;不应与 AWQ/GPTQ 混为同类。”INT8 一定比 FP16 快”不成立——收益依硬件、batch、序列长度和 kernel 决定。
量化真正改变的是哪条资源链
权重量化、激活量化和 KV 量化解决的不是同一个问题:
| 对象 | 主要节省 | 新的风险 |
|---|---|---|
| 权重 | 常驻显存、decode 权重带宽、加载时间 | 反量化开销、敏感层误差、kernel fallback |
| 激活 | prefill 中间张量和算力/带宽 | scale 估计、异常值、训练/推理稳定性 |
| KV Cache | 长上下文并发容量与 decode 读带宽 | attention 误差、缓存格式和分页 kernel 支持 |
所以一个 Q4 权重模型可能明显降低加载显存,却几乎不改变长上下文服务的 P99:瓶颈可能已经转移到 KV、队列或跨卡通信。反过来,KV quant 若提高可驻留并发,吞吐可能上升,但单请求 TPOT 未必下降。评估前先指出要优化的资源账本,再选量化对象。
校准与敏感度决定质量,而不只是 bit 数
量化通常要用代表性 calibration data 估计 scale、异常值或 importance matrix。只在短英文样本上校准,未必能保护代码、中文、多语言或长上下文中真正敏感的层;统一给每个 tensor 相同 bit,也会把少量高敏感层的误差放大到最终 logits。应至少比较任务集合、长度分桶和生成稳定性,而不是只看一组 perplexity。
1 | BF16 reference |
“更低 bit 更快”的反例
如果 GPU 没有该量化格式的 fused GEMM,运行时可能先读取低 bit 权重,再在 kernel 内反量化成 BF16;额外解码和内存访问会抵消权重搬运收益。小 batch、短序列时 launch/反量化占比更高,反而比 FP16 慢;多卡时每卡权重变小也不代表 collective 变少。生产 benchmark 应分别测 warmup、prefill、decode、1/4/16 并发、长短 prompt 和冷加载时间。
选型记录中还要写清“模型文件可加载”和“目标任务质量通过”是两个门槛;GGUF 只回答容器/分发问题,llama.cpp 或 vLLM 才回答具体 backend 是否真的高效。