先讲个我最近的真实经历:在某社区看到一位朋友发帖,说手上就一张消费级显卡,想跑一个开源7B模型,结果模型文件还没下载完,显存就报警了。下面一堆人回复“换云服务器”“上多卡”,我却觉得,这个问题其实有更轻巧的解法,那就是量化。
量化(Quantization)这几年在大模型圈里几乎是“显存救星”的代名词。同样的模型,FP16权重直接加载可能要占14GB显存,量化到8bit大概只需要7GB,量化到4bit甚至能压到3.5GB左右。换句话说,一张中端显卡,本来连加载都费劲的模型,量化之后不仅能加载,还能留下余量跑推理。所以这篇就围绕“大模型量化”这件事,把背后的原理、主流方案、实操步骤和常见坑一次性讲透。
如果你手里已经有了一个开源模型,正头疼显存不足、推理速度慢,或者想在自己设备上跑更快的本地服务,这篇文章很适合你。哪怕你是刚接触深度学习没多久的新手,只要会基本的Python和命令行,就能按照下面的内容一步步把模型量化跑起来,也能理解每一步背后的原因。
1. 一个扎心事实:模型为什么这么吃显存
1.1 显存开销的账,得先算明白
很多人对模型的显存占用只有一个模糊的感觉,就是“很大”,但具体大到什么程度,只有自己部署过一次才有体感。我们以主流的开源7B模型举例,也就是说模型总共有70亿个参数。FP16,也就是每参数占2字节,权重部分就是 70 × 10^8 × 2 = 14 GB,这还没算运行时的KV Cache、激活值、框架自身的临时缓冲区和CUDA环境占用。
如果你跑的是13B模型,FP16权重大约26GB。哪怕是现在比较吃香的34B级别开源模型,FP16权重直接破60GB,消费级硬件基本无缘。这时候量化就是唯一性价比最高的路径:把每个参数从16bit降到8bit,显存直接减半;降到4bit,理论上只需要FP16的1/4。这就是为什么量化在大模型时代这么流行的直接原因——它把“能不能跑”这个问题,从硬件层面转移到了算法层面。
1.2 传统压缩思路为什么不能直接套用
有人可能会想:既然模型这么大,用传统的文件压缩工具比如ZIP、GZIP不就行了吗?不行。传统的无损压缩,比如LZ77、Huffman编码,依赖的是数据中的冗余模式,解压时必须还原成原始格式才能参与运算。而神经网络推理是连续矩阵运算,每一步都需要权重数据马上可用,不可能把权重先放到硬盘压缩包里再算。
量化本质是“有损压缩”,但它直接改变了数值的存储精度和运算格式,推理时不需要解压回FP16,而是用整数运算直接完成计算,或者在做矩阵运算的节点临时反量化到原位。这样既省了显存,在某些硬件上还能提升速度,因为整数运算单元在某些架构上吞吐更高,也更省带宽。
1.3 先区分一个概念:位宽和精度的关系
我们常说的“4bit”“8bit”,指的是每个权重数值可以用多少位二进制来表示。8bit能表示256个不同的取值,4bit只能表示16个取值。FP16虽然也是16bit,但里面包含了符号位、阶码和尾数的结构化分配,能表达很大范围的数值;而整数4bit、8bit适合表达范围有限的均匀数值。
量化要解决的问题就是:把神经网络权重里那些连续分布、范围较大的浮点数值,映射到有限个离散整数上,并且让这种映射造成的精度损失尽可能小。这里的关键不是单个数的误差多大,而是所有权重引入的整体误差,对最终预测结果的影响有多大。理解这一点,后面看到各家量化方法的差异时会清晰很多。
2. 量化在做什么:从浮点到整数的一次压缩
2.1 核心公式其实很简单
量化的数学表达并不复杂。假设原始浮点权重是 r,量化后的整数是 q,需要的缩放因子是 s,那么最基本的对称量化公式是:
q = round(r / s)
反量化的时候,用 r ≈ s × q 恢复一个近似值。这个 s 怎么取?最常用的是取权重绝对值的最大值,也就是 s = max|r| / (2^(b-1) - 1),其中 b 是量化位宽。因为 4bit 能表示的正数范围通常是 0~7,同时还要留一位表示符号的话,最大值就是 7,所以分母就是 7。
但实际应用中,很多权重分布并不对称,正负范围相差很大。这时候就要用到非对称量化,公式变成:
q = round(r / s) + z
其中 z 是零点偏移,用于将浮点的最小值精确映射到整数的零点附近,避免截断误差。反量化则是 r ≈ s × (q - z)。s 的计算方式为:
s = (rmax - rmin) / (qmax - qmin)
用生活化的类比来说,这就像把一张连续的海拔地形图,从等高线精度改成只需要用16个等级的高度色块来表示。色块之间的间隔越大,地形细节丢失越多,但只要间隔选得聪明,山峰、山谷的位置依然能保留下来。量化的难点就在于“选间隔”这件事。
2.2 最大陷阱不在公式,在离群点
理论公式写出来很简单,实际做的时候第一个坑就来了:权重的值并不是均匀分布的。一个大模型训练完成后,权重往往拉成一个类似正态分布的形态,大部分值分布在零附近,少数离群点极大或极小。
如果用 minmax 范围来做缩放,也就是拿最大值最小值决定 s,那么几个离群点会把整个缩放范围拉得很大,导致大部分集中在零附近的值,因为量化步长太大而被压成一团,损失惨重。这就是为什么后来出现了 percentile、clipping 等方法:只看分布中间的那部分数据,把极端值截断掉,用截断后的范围来决定缩放因子。很多实验表明,适度截断离群点,量化后的模型精度反而更好,因为主导信息的是绝大多数普通权重,而不是那几个极端点。
2.3 按通道量化,比整模型量化精细得多
如果对整个模型所有权重用一个统一的 s,那就叫 per-tensor quantization,误差会非常大。因为不同层的权重分布差异很大,有的层权重范围可能是 [-0.5, 0.5],有的层却是 [-2.0, 2.0],统一缩放到一组参数里,必然顾此失彼。
稍微精细一点的做法是 per-channel quantization,也就是每个输出通道单独计算自己的 s 和 z。在卷积层里,每个卷积核对应一个通道;在Transformer里的线性层中,每一列或每一行可以看作一个通道。这样做的好处是,大部分通道的分布相对集中,各自的量化范围贴合实际,整体误差大幅下降。现在的 LLM 量化库,几乎清一色采用 per-channel 或 per-group 方式,group 通常取 32、64、128 个数值一组,换来更好的精度适配。
这里补充一点:实操中特别容易忽视的是,量化公式虽然简单,但不同框架的实现细节差异很大,同样的“4bit”在不同库里产生的模型大小和精度可能完全不同。所以后面看模型评测结果时,不能只看位数,还要看用了什么量化方法、什么分组大小。
3. 主流量化方法有点多,我先替你分个类
3.1 RTN:最简单的舍入量化,别小看它
RTN,Round-To-Nearest,就是直接把浮点权重四舍五入到最近的量化整数上。它不做额外的优化,只是按前面说的对称或非对称公式计算 s 和 z,再把权重转成整数。听起来很简单,但它是很多进阶方法的基础,也是评估其他方法“到底费了多少劲”的对照组。
在某些模型上,RTN 的 8bit 量化效果就已经非常好了,和 FP16 的差距可以小到忽略不计。这是量化最友好的情况,也是很多模型能直接部署的原因。但到 4bit 时,RTN 通常就不太够用了,因为每4bit只有16个取值,四舍五入带来的相对误差变得明显,尤其是那些对精度敏感的小权重。
3.2 GPTQ:透过误差补偿来“骗”过模型
GPTQ 是第一梯队里非常知名的方法,One-Shot 权重量化,核心思路是把量化问题当作一个逐层重建问题。它先对某一层的权重做量化,然后计算出这个量化误差会怎样影响该层的输出,再用一个基于二阶Hessian信息的最小二乘解法,调整这一层里尚未量化的其他权重,用来补偿已经量化部分的误差。
这里面的关键词是“重建”:我们不是单纯地追求每个权重的误差最小,而是想办法让这一层的输出和原始浮点输出尽可能接近。GPTQ 用了类似最优脑损伤(Optimal Brain Surgeon)的思想,迭代地选择影响最小的权重进行量化,然后更新剩余权重。实际使用中,GPTQ 在4bit权重、同group量化下,可以让模型精度非常接近FP16,成为自建本地推理服务最常见的权重量化选项之一。
我用一个比喻来解释它的效果:比如你负责把一幅画的油漆改成16种固定颜料,如果只是单独把每种颜色改成最近的颜料,整体画面会走样。但如果你先把几个迫不得已的颜色改了,再调其他颜色来中和色差,整幅画看起来就自然得多。GPTQ 做的就是这种“全局弥合误差”的工作。
3.3 AWQ:不调整权重,调整缩放
AWQ(Activation-aware Weight Quantization)走的是另一条路。它的名字就说了关键:意识到激活值的存在。AWQ 发现,虽然权重本身整体分布看起来规整,但同一层里,对应激活值幅度较大的那些通道,往往承担了更重要的信息。如果把权重和激活联合起来看,那些通道值得被特殊对待。
AWQ 的做法是,基于少量校准数据观察激活值的分布,找出所谓的“显著通道”,然后给这些通道的权重乘上一个很小的缩放系数,这个缩放系数本身是浮点数,不参与量化。这样做可以在不改变网络结构的前提下,把敏感通道从量化误差大的区域“搬运”到误差相对小的区域去。因为显著通道本身数值范围大,放大后量化步长相对变小,误差自然就降低了。AWQ 的亮点是不需要回归迭代,速度比 GPTQ 快,而且量化后的表现很有竞争力。它尤其适合大模型导出时追求速度的场景。
3.4 QAT:重新训练,精度上限最高
前面几种都是典型的后训练量化(PTQ,Post-Training Quantization),它们只动权重,不重新训练模型。PTQ 的优势是快,通常只需要少量校准数据,跑一轮前向推理就能完成;缺点是4bit以下时精度损失明显,尤其对中文、代码这类非英语分布的数据,有时候会掉点比较严重。
QAT(Quantization-Aware Training)则完全不同:在微调训练阶段就把量化的影响模拟进前向过程,让模型自己学会适应量化误差。通常做法是先用 FP16 权重做前向,再模拟量化和反量化,计算损失后更新浮点权重,让权重在训练过程中逐渐分布到适合量化的状态。
QAT 的代价是训练成本高,并且需要训练数据。在大模型时代,很多人会把它和 LoRA 结合,只微调一小部分关键参数,同时让主要权重量化,这样既能控制成本,又能获得比纯 PTQ 更好的精度。如果你手里的模型是为了某个特定业务长期部署,QAT 是个值得考虑的最终方案;如果只是快速验证,先走 PTQ 就够了。
3.5 量化粒度上的其他变量:W4A16、W8A8、KV Cache
很多资料里会见到“W4A16”这类写法,W 指权重 Weight,A 指激活 Activation,后面的数字是各自的量化位数。W4A16 表示权重4bit、激活保持16bit,是GPTQ、AWQ 这类权重量化方法的标准形式;W8A8 则指权重和激活都是8bit,通常需要配合特定的硬件算子才能发挥速度优势。因为激活量化需要额外处理激活值分布的动态变化,难度比纯权重量化高不少,这也是很多框架默认只量化权重的原因。
另外还有一个容易忽略的存储大头:KV Cache。长上下文推理时,KV Cache 占用的显存会快速增长。很多支持量化的推理框架已经开始支持把 KV Cache 也做 8bit 或 4bit 量化,这能在长文本场景下省出大量显存,但也会带来一点精度损失。我个人建议,在显存不是特别紧张的情况下,先不要把 KV Cache 压得太狠,尤其做代码、长文档任务时。
4. 实操:从拿到模型到量化部署的完整链路
4.1 准备环境,先检查这几件事
动手之前,先把环境确认清楚。你需要:
- 一张支持 CUDA 的 NVIDIA 显卡,或者一块支持较新 AVX 指令的 CPU(用 CPU 推理也行,只是慢);
- Python 3.10 或更高版本;
- 一个已经下载好的开源模型,比如常见的 7B 规模模型;
- 磁盘空间至少要留模型原始大小的一倍,因为导出过程通常需要临时文件。
安装依赖方面,常用的两个路径分别是模型加载库和量化推理框架。如果走模型加载路线,需要安装模型加载库和量化库,比如通过 pip 安装“模型加载”与“量化”两个扩展包。如果走 GGUF 路线,则需要编译 llama.cpp 或直接使用官方预编译二进制,配合 Python 端的绑定工具。
这里有个容易踩的坑:很多人直接装最新版的模型加载库,结果发现和新版模型加载依赖冲突,或者显卡驱动版本不匹配。我的建议是建一个干净的 Python 虚拟环境来装这些依赖,再逐个导入测试,能从源头上避开一堆兼容性问题。
4.2 方式一:模型库直载方案的 4bit 量化
最省事的 4bit 加载方式是用模型加载库配合 bitsandbytes 扩展包。用法大致是这样:
from model_loader import AutoModelForCausalLM, AutoTokenizer from quantization import BitsAndBytesConfig bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype="float16", bnb_4bit_use_double_quant=True, ) tokenizer = AutoTokenizer.from_pretrained("your-model-path") model = AutoModelForCausalLM.from_pretrained( "your-model-path", quantization_config=bnb_config, device_map="auto", )这个方案的核心是 NF4 格式,一种专门为4bit定制的高效数据格式,配合双重量化进一步压缩缩放因子。用双重量化可以再省一点显存,而且基本不损失精度。
这里有三个参数需要理解:compute_dtype表示量化权重参与矩阵运算时临时反量化成的精度,一般保持 FP16;quant_type选 nf4 是精度优先,选 fp4 则是更偏计算速度;use_double_quant会把缩放系数本身也压缩一次。如果你是在消费级显卡上跑,这几个参数按默认走基本没问题。加载成功后,你可以直接调用模型做推理,不用改原有代码结构,这也是它这么流行的原因。
4.3 方式二:GGUF 文件与本地推理框架
如果你追求的是更快的加载速度、更小的文件体积,或者甚至要在 CPU 上跑,那 GGUF 格式一般是更稳的选择。GGUF 是 llama.cpp 生态的标准格式,它把模型权重、量化参数和 Tokenizer 信息打包成单一文件,部署起来特别干净。
转换的基本流程是:
- 用官方脚本把原始模型转换成 FP16 的 GGUF 文件;
- 用量化工具将这个文件压缩成你想要的位宽,常见有 Q4_0、Q4_K_M、Q5_K_M、Q8_0 等;
- 加载这个 GGUF 文件到推理框架中开始推理。
从我的实测经验看,Q4_K_M 是质量和体积比较均衡的选择。Q4_K_M 中的 K 表示采用 K-quants 方法,会把权重的某些部分用更高精度的量化方式单独处理,M 表示混合多种量化精度。你可以简单理解为,它在4bit总体上给关键部分开了“小灶”,换来更好的精度表现。
这种方式比模型库直载要早很多,尤其适合部署为本地服务。缺点是 GGUF 的转换和量化过程在命令行下操作,新手会觉得不那么顺手,但一旦跑通,后面管理模型文件会非常轻松。
4.4 校准集怎么选,是量化质量的胜负手
很多人第一次做权重量化时,满脑子只有代码,忽略了校准数据集的选择。校准数据的作用,是让量化算法观察到模型在正常输入时各层的激活分布,从而决定缩放因子或误差补偿策略。
校准数据不是训练数据,也不需要带标签。但它的分布必须尽量接近你的真实使用场景。如果你准备用模型处理中文法律文本,结果校准集清一色是英语日常对话,那么量化后的模型在处理法律文本时,精度下降可能比预期大不少。这背后的原因很直接:量化方法根据校准集看到的数据来优化误差,遇到没见过的分布,误差补偿就不准了。
实践中一个靠谱的做法是:从你真实任务里挑出几百条不重复的样本,作为校准集。数量方面,128到1024条都有人用,我自己常用256条,性价比最高。不要盲目上几千条甚至上万条,校准集太大,量化时间会失控,而收益往往并不明显。
4.5 实际跑量化:以 GPTQ 为例的命令式操作
这里以常见的 GPTQ 量化脚本为例,展示一下核心流程。假设你已经把模型放在本地目录,量化脚本会先读取校准数据,逐层处理权重,最后输出量化后的模型目录。
python quantize_gptq.py \ --model_dir ./base_model \ --output_dir ./quantized_model \ --calib_data ./calib_samples.jsonl \ --bits 4 \ --group_size 128 \ --desc_act falsegroup_size决定权重按多少个一组共用缩放参数。128 是当前的主流默认值,量化效果和体积比较平衡。如果显存足够,用 32 或 64 会更好但体积更大。desc_act如果打开,会使量化结果更精准,但对推理速度有影响,而且部分显卡驱动和框架实现不兼容,建议先按默认关掉再测。
量化完成后,输出目录里会有专门保存量化权重、分组索引的整套文件。用模型加载代码指向这个目录就能直接加载,不需要你再做额外操作。整个过程如果遇到显存不够,可以把量化时使用的批次调小,或者用量化库的 CPU 模式跑,只是时间会拉长。
4.6 七步自查清单:部署前过一遍
- 模型加载后,先跑一条简单输入,确认能输出正常文本;
- 打印模型配置,确认量化位宽确实生效;
- 监控显存占用,确认峰值没超显卡上限;
- 测一个真实任务样本,和 FP16 的结果对比看差距;
- 对比速度,记录单次推理耗时和生成 token 数;
- 检查是否存在输出乱码或重复循环,这是格式不兼容常见的表现;
- 如果服务会被多端调用,再加一层并发测试,防止显存碎片导致崩溃。
这一步看起来繁琐,但省掉任何一项,都可能在你上线后带来半夜报警的惊喜。尤其是“对比 FP16 结果”这一步,很多人在千辛万苦量化完就急着部署,结果精度掉到哪里了都没概念,等出了问题才回来排查,那时已经晚了很多。
5. 量化之后怎么验收:别让指标骗你
5.1 什么叫“量化后掉点”
“掉点”是量化圈的黑话,指量化模型在评测指标上相比原始模型的下降幅度。常见评测包括困惑度(Perplexity)、常识推理准确率、代码生成通过率等。困惑度越低,表示模型对文本的预测越自信。一般7B模型从FP16量化到4bit,困惑度会上升一点点,但幅度通常在1以内;如果上升了几个点,那就要警惕量化设置出问题了。
实际操作中,我不会只盯着困惑度。因为困惑度反映的是模型整体分布的拟合情况,和具体任务的最终表现不一定完全对应。一个更直接的做法是:拿20条真实业务任务样本,分别用 FP16 模型和量化模型跑,逐条对比输出质量。只要关键任务没翻车,指标有点波动是可以接受的。
5.2 速度收益到底在哪
很多人的直觉是“量化后模型更小,就一定更快”,这个说法一半对一半不对。模型的推理速度瓶颈通常来自两方面:内存带宽和计算吞吐。量化后权重变小,读取权重所需的内存带宽下降,这对没有大显存、受带宽限制的设备有明显加速效果。如果你用的是高端显卡,计算吞吐本身已经很高,这时候量化带来的提升更多是“能塞下更大模型”,而不是纯粹地“变快”。
一个典型的测量数据来自本地推理工具对不同量化档位的速度记录。同样的7B模型,FP16读权重需要14GB数据,Q4_K_M只需约4GB数据,同样的加载通道下,理论带宽占用减少了一半以上,生成速度常常提升30%~80%。各位做性能对比时,一定要记录显存峰值和单token延迟两个数据,只看一个都容易得出误导性结论。
5.3 自己做一张简单的对比表
如果你部署完量化模型,建议把下面这张表的字段填一遍,长期积累下来会形成非常宝贵的经验:
| 项目 | FP16 基线 | 8bit 量化 | 4bit 量化 |
|---|---|---|---|
| 模型文件体积 | 约 14GB | 约 7GB | 约 3.5GB |
| 加载后显存占用 | 约 16GB | 约 8GB | 约 5GB |
| 困惑度变化 | 基准 | 几乎不变 | 略有上升 |
| 单条推理耗时 | 基准 | 相近 | 更快 |
| 常见任务表现 | 基准 | 稳定 | 可接受 |
实际数字会因模型、上下文长度、量化方法而不同,但整体规律是一致的。8bit 是接近无损的安全牌,4bit 是性价比牌,2bit 我基本不碰,除非你的任务极其简单。对绝大多数聊天、写作、代码生成场景,4bit 完全够用;如果是严谨的数学推理或长文档分析,我会优先保证 8bit 或混合精度。
5.4 量化精度的边界在哪里
还要记住一点:量化不是万能的。如果原模型本身质量一般,量化只会让它“一般中略差”,不会神奇地恢复能力。另外,有些模型在量化后特定能力衰减特别明显,比如表格理解、多步推理、特定语言翻译。这可能是因为这些任务对精细数值或长程依赖更敏感,一点点权重误差被放大成了结果错误。
所以验收的目的不只是“看看能不能跑”,而是要做一次准业务的回归测试。你准备好一套常年不变的测试集,每次升级模型或调整量化参数时都跑一遍,比临时抱佛脚可靠得多。
6. 常见坑与经验:我踩过之后才懂的事
6.1 校准数据和业务数据分布差异太大
这是我翻车最惨的一次。当时急着上线一个代码补全模型,随手用了模型仓库自带的英语文本做校准集。结果量化后的模型在代码补全场景下频繁出现格式混乱、括号不匹配的情况,后来换成长尾分布匹配的代码样本做校准后,问题立刻减轻了。
对比校准数据前后的差异,我发现问题的根源并不复杂:代码中符号、函数名、缩进的分布和自然语言差异极大,通用校准集无法引导量化算法保护那些对语法敏感的权重。所以任何项目的量化,校准数据一定优先级最高,不要图方便偷懒。
6.2 同一份模型,不同显示加载结果差一大截
模型加载库直载的4bit实现和 GGUF 的4bit格式,虽然同样叫4bit,但底层数值格式、分组策略和算子不同,实测精度和速度都有差异。如果你在某个方案下测得结果不好,先别急着下结论“这模型不能量化”,换个方案再测一次。
我在某个开源模型上做过对比:同一份模型,GPTQ 4bit版本在某些任务上表现不如 Q4_K_M,但推理速度又略快一点。这说明选择量化方案本质上是做一次微型评测,要根据自己的应用场景拍板。
6.3 别忽略层敏感度差异
量化误差其实并非均匀分布在所有层。研究和大规模实验都表明,Transformer 中某些中间层,特别是前几层和最后几层,对量化特别敏感。如果全模型统一4bit,这部分层的误差会被放大。
主流的混合精度策略,比如 Q4_K_M、Q5_K_M,本质上就是根据层的敏感程度使用不同位宽。如果你用自己的量化流程,可以保留某些关键层为8bit,其他层压到4bit,效果往往更稳。这也是进阶玩家和普通玩家的分水岭。
6.4 上线前一定要做长上下文压力测试
量化后模型在短输入下看着没问题,不代表长上下文也稳。长上下文推理时,KV Cache 累积误差,量化误差也可能逐层累积。很多人在短测试通过后就匆匆上线,结果用户一贴长文本,输出就开始重复、跑偏甚至崩溃。
我建议无论如何都要准备一段超过 2K token 的测试文本,跑一遍完整生成,盯住显存和输出质量。如果这一步有问题,优先尝试把 KV Cache 量化关掉,或者把上下文窗口调小一点。
6.5 记录“量化配方”,防止自己忘掉当时怎么调出来的
量化参数组合太多,今天调出一个能用的,下个月想复现,结果参数忘了,又得重试。我现在会在每个量化模型目录里放一份配置记录文件,里面写清楚:基础模型来源、量化方法、位宽、分组大小、校准集来源与条数、测试时的显存、速度、精度数据。下次遇到类似需求时,直接翻历史记录就能少走很多弯路。
这个方法不仅适用量化,也适用所有模型部署场景。时间越久越会发现,真正值钱的不是“跑通一次”,而是“能稳定复现一个好的结果”。
7. 结合我的经验给你几个实用建议
7.1 新手先别玩高阶操作,直接用现成方案
如果你是第一次做量化,不要一上来就自己写量化代码。直接用现成的模型加载库直载4bit,或者下载别人已经量化好的 GGUF 文件,先把“量化后能跑”的感觉找到。先跑通,再优化,这是最稳妥的学习路径。等你熟悉了模型加载、推理、显存监控这些基本操作,再回头研究 GPTQ 的细节,就不容易局部迷茫。
7.2 显存够用是底线,速度是加分项
在选定量化位宽前,先明确你的预算和场景。如果一张显卡显存是24GB,要跑34B模型,4bit几乎是唯一出路;如果跑7B模型,8bit甚至FP16都行,很多人却习惯性压到4bit,白丢精度。显存够用就上高精度,这是最简单有效的原则。
7.3 量化后的模型也要“回炉”微调
量化之后模型能力有损耗,如果业务场景对精度要求很高,可以考虑用极小量的业务数据做一次 LoRA 微调,让模型在量化状态下重新适应任务。这也是目前把量化模型的潜能榨干比较常见的做法。注意要在量化模型上做训练感知,不要直接拿 FP16 模型微调完再量化,顺序反了收益会打折扣。
最后再分享一个小技巧:量化跑完后,不要急着删原始模型文件。无论是校准集选择还是量化参数调整,都有可能重来,原始文件留着就是后悔药。还有,模型量化完一定要在真实硬件上重新测速,别轻信别人贴出的 benchmark,因为不少速度数字是在不同的上下文长度、批次设置下测出来的,和我们自己的场景没有绝对可比性。量化是个“看起来简单、做起来有细节”的工程,把这些细节处理好,你会发现原来的硬件瓶颈,其实没有那么难突破。