CHAPTER 11 / 推理与系统
量化与推测解码
一种减少表示成本,一种减少串行等待,分别验证收益。
- 解释权重、激活和 KV 量化的区别及误差来源
- 理解推测解码的草稿、验证与拒绝修正
- 选择质量和性能对照实验,避免把理论容量当成真实加速
量化是在改变数值表示
模型中的权重和中间状态通常以浮点数表示。量化使用更少位数或不同数值格式表示它们,以降低存储和数据搬运成本。一个简单的对称整数例子是 q = round(x / scale),读取时近似恢复为 x̂ = scale × q。有限整数范围意味着舍入误差,也可能发生截断;缩放因子的粒度影响不同数值之间如何共享动态范围。
要问清量化对象。权重量化压缩模型参数,激活量化影响运行中的中间数值,KV 量化压缩随上下文增长的缓存。W4A16 通常描述四位权重、十六位激活,并不自动说明 KV 也只有四位。缩放元数据、部分保留高精度的层以及内核临时空间都会增加实际占用。
理论内存收益不等于加速比例
假设模型有七十亿个参数,每个参数十六位,纯权重数据约为 14 GB;改为四位后理论数据量约为 3.5 GB,这里 GB 使用十进制。实际文件和显存还包括缩放因子、零点、元数据及未量化部分。即使权重变成四分之一,总显存也不一定变成四分之一,因为 KV 与运行时空间可能保持不变。
低位表示有机会减轻带宽或容量瓶颈,但是否更快取决于硬件指令、内核实现、反量化开销、批大小和模型结构。不能假定所有设备都高效支持同一种格式。部署时按实际 vLLM 版本的兼容列表选择,再测真实任务。质量评估需要包含数字、代码、长上下文等你的关键场景;只看一句聊天是否通顺很容易漏掉退化。
本机实验:把舍入误差算出来
下面用 Python 标准库演示四位与八位对称量化。这只是用一组权重数值演示量化重建误差,不是端到端推理;它没有运行语言模型或 GPU 内核,也不代表 AWQ、GPTQ 等实际算法。保存为 quant_lab.py 后运行,只比较重建误差和理论权重大小。
from math import sqrt
values = [-1.0, -0.37, 0.04, 0.29, 0.83]
def quantize(xs, bits):
if not xs:
raise ValueError("xs must contain at least one weight")
if not isinstance(bits, int) or bits < 2:
raise ValueError("bits must be an integer >= 2")
peak = max(abs(x) for x in xs)
if peak == 0:
return [0.0] * len(xs), 0.0
limit = 2 ** (bits - 1) - 1
scale = peak / limit
quant = [max(-limit, min(limit, round(x / scale))) for x in xs]
restored = [q * scale for q in quant]
rmse = sqrt(sum((x-y)**2 for x, y in zip(xs, restored)) / len(xs))
return restored, rmse
for bits in (4, 8):
restored, error = quantize(values, bits)
print(bits, [round(x, 4) for x in restored], "RMSE", round(error, 6))
print("7B raw weight GB", 7_000_000_000 * bits / 8 / 1e9)
assert quantize(values, 8)[1] < quantize(values, 4)[1]
assert quantize([0.0, 0.0], 4) == ([0.0, 0.0], 0.0)
try:
quantize([], 4)
except ValueError:
pass
else:
raise AssertionError("empty weights should be rejected")把某个数改成 100,观察其他小数如何受到统一 scale 的影响,这体现了异常大值与动态范围问题。再尝试把数列分成两组分别量化,比较误差与新增缩放元数据。这个实验解释表示误差,不能用于预测语言任务成功率。
空数组没有可定义的误差统计,因此函数明确抛出 ValueError;全零权重直接返回零数组和零误差,避免缩放因子为零导致除零。
推测解码先写草稿,再由目标模型验证
普通自回归 decode 每一步通常只确认下一个 token。推测解码先让便宜的草稿机制连续提出几个候选,再让目标模型并行检查这些位置。有些候选被接受,于是一次目标模型执行可以推进多个 token;一旦拒绝,就按算法修正当前位置并重新开始。草稿可以来自小模型或其他候选生成机制,不要求只有一种实现。
经典精确采样算法中,目标分布记为 p,草稿分布记为 q,候选 x 的接受概率是 min(1, p(x)/q(x))。拒绝时从归一化后的 max(p−q, 0) 分布重采样,才能保持目标采样分布。这里省略了多 token 迭代的边界处理,不能把它当作完整实现。直接“接受看起来合理的草稿”不具备同样保证。
什么时候草稿值得写
假设目标模型普通一步耗时 10 毫秒。某个推测方案草稿花 3 毫秒、一次批量验证花 12 毫秒,平均确认三个新 token,则示意时间为每 token 5 毫秒;如果平均只确认一个,则变成每 token 15 毫秒。所有数字都是假设值,作用是说明接受率、草稿开销和验证成本必须一起看。
精确推测采样在数学条件与实现正确时保持目标分布,并不承诺每次随机种子下得到逐 token 完全相同的文本;硬件数值也会造成差异。它与量化不同,量化通常改变目标模型的数值与分布,而推测解码改变生成执行方式。两者可以组合,但质量对照基准应说清是原始目标模型,还是已量化的目标模型。
把两个实验分开,才能解释结果
先固定模型与服务配置,只切换量化方案,比较任务成功率、峰值内存、TTFT、TPOT 与吞吐。再固定目标模型,只切换推测方案,记录草稿开销、接受率、平均每次验证确认的 token 数和端到端延迟。最后才测试组合效果,防止一个方案的收益掩盖另一个的退化。
推测解码在低并发、decode 占主导且候选吻合度高时可能有吸引力;高负载时额外草稿工作也会争用资源。常见误区是只看接受率,忽略为了高接受率使用了过于昂贵的草稿;或只比较输出 tokens/s,忽略输出长度和质量已经改变。真正需要优化的是满足质量要求的任务完成速度与成本。
LEARN BY DOING
选择一种优化,并写明它可能失效的条件
- 运行量化实验,比较四位、八位及添加大值后的重建误差。
- 用手算或表格列出平均确认 token 数为 1、2、3 时的推测方案耗时。
- 为真实任务定义质量底线与延迟指标,设计一次只切换一个配置的对照。
- 写出量化与推测解码的适用条件、额外开销和失败回退方式。
验收标准
- 能够区分权重、激活和 KV 三种量化对象。
- 理论七十亿参数四位纯权重容量为 3.5 GB,没有把它标为实际显存。
- 解释了为什么平均只确认一个 token 时,示例推测方案反而慢于基线。
合上书,检查一下
先作答,再看解释。答错的地方,正好是值得再读一遍的地方。
配合本章看视频
下面按本站章节主题选配。为什么没有采用原课录播 →
MIT 6.5940 · Lecture 13: LLM Deployment Techniques (Fall 2024) ↗
用高校公开课补充大模型部署与压缩优化的背景,配合本站量化章节理解资源约束。
带着问题看 · 对比 SmoothQuant、AWQ 等量化方法;区分低比特量化与推测解码的机制;结合官方讲义中的 speculative decoding 和 batching,检查加速的硬件、负载和质量前提。
查看来源与观看说明 →