目前针对大模型进行量化的方法有哪些?
2022年冬天,我盯着手里那张RTX 3090,心里一万只蚂蚁在爬。
同事扔过来一句话:“部署LLaMA-13B,跑个评测。” 我看了看卡,24G显存,勉强能跑LLaMA-7B的FP16。你让我拿这个跑13B?不如你把卡先换了行不行?
可当时穷啊,没卡怎么办?硬上量化。
那时候全社区都在吹一个方案——bitsandbytes库的load_in_8bit=True。说白了就是LLM.int8()那套骚操作:激活里有些异常大的通道(outlier),单独用FP16伺候,其他全砸成INT8。我一试,显存直接从26GB(含激活)砍到13GB!模型还真跑起来了!
但,你猜怎么着?
推理速度慢得想摔键盘。 小batch还行,并发一上来,GPU利用率死活上不去。翻源码才看明白,那些FP16的outlier根本没法用tensor core加速,只能靠CUDA core磨洋工。而且当时bitsandbytes对4-bit支持烂得一塌糊涂,我只能用8-bit,压缩率砍半,根本不解渴。
但这个坑没白踩,它让我想明白一件事:大模型量化不能只盯着权重,激活里的异常值才是真搅屎棍。 你想想,权重好歹是静态的,量化完就固定了;激活呢?每轮推理都不一样,动态范围夸张到吓人。谁能在运行时把激活也压下去,谁才是真有本事。
说到这儿,转折点来了——2023年,量化开始分叉了。
先是GPTQ。第一次看论文差点被那个Cholesky分解劝退,但上手一试,真香!我在AutoGPTQ上拿LLaMA-7B做实验,校准集就用Pile的128条数据(每条2048 tokens),量化成4-bit——W4A16。整个过程15分钟,快得感人。精度呢?我测了Wikitext困惑度,从FP16的5.68涨到5.74,几乎无损。直接部署到Flask服务里,batch size=1时显存暴降,3090上跑13B都稳得一批。
不过GPTQ有个老毛病:量化慢得像乌龟。 7B还能忍,到13B就得个把小时。70B模型你试试?网上的教程还让你慢慢等,简直浪费生命。还有个坑:校准数据集选多了过拟合,选少了重建效果差。我就翻过一次车——用全量数据跑量化,结果生成的文本居然复现了校准集里的句子,这不就露馅了么。后来死磕到128条,问题才解决。
跟GPTQ前后脚出来的,是SmoothQuant。
当时我正被激活量化整得头秃——你想做W8A8全量化,但激活里的异常值能高到几十倍,普通INT8根本扛不住。SmoothQuant的想法简单粗暴:既然激活难量化,就把量化难度往权重那边匀。具体就是给每个通道算个缩放因子:激活大的通道,对应权重也乘这个数。 这样激活压下去了,权重数值变大,量化后相对误差反而小了。整个过程是数学恒等变换,量化本身不会引入额外损失。
我在TensorRT-LLM(那时还是内部版)里试了SmoothQuant,配W8A8,Llama-2-7B。单A100上,FP16吞吐是1000 tokens/s,SmoothQuant W8A8直接飙到1800,几乎翻倍!而且精度只掉了0.3个点的困惑度。说实话,这个收益让我对INT8推理彻底改观。但前提是你得有支持INT8 tensor core的卡——Ampere架构以上,否则白搭。
时间走到2023年底,AWQ直接扔了个王炸。
当时工业界已经被GPTQ的精度和速度折磨够了——要压缩吧,GPTQ好用但等太久;要选RTN(round-to-nearest)吧,精度掉成渣。AWQ一出场,直接把W4A16的量化速度压到分钟级,精度还跟GPTQ打平。最关键的是,它不需要calibration data里的标签,纯前向就能搞定。
核心洞察特别朴素:权重通道的重要性不由它自己决定,而是由对应激活的大小决定。 换句话说,如果某个通道的激活值炸裂大,那跟它相乘的权重稍微有点误差,输出就会崩。传统的“绝对值大的权重要保护”完全是错觉。AWQ直接给这些高激活通道对应的权重乘一个缩放因子(比如2.0),把数值撑大,量化相对误差就小了。然后再在激活侧除以同一个因子,结果一模一样。不需要混合精度,不需要重训,一个matmul/scatter就搞定。
我在vLLM 0.4.0上试了AWQ,量化一个Mistral-7B-v0.1只用了几分钟(拿校准数据集跑一次前向收集activation)。部署时--quantization awq直接走起,显存从14GB降到4GB(4-bit权重)。对比FP16,小batch推理快了大约1.5倍,因为显存带宽瓶颈彻底缓解了。
我有个朋友做端侧部署,在iPhone上用MLX跑TinyLlama,也是AWQ量化到4-bit。他跟我说模型从2GB砍到500MB,手机上流畅生成,算力消耗降一半。AWQ能做到社区工业界通吃,拿MLSys 2024最佳论文,真·名正言顺。
那AWQ和GPTQ怎么选?我给你一句话的决策树:如果量化一次再也不动,或者模型参数量特别大(70B+),选GPTQ,它的补偿机制让精度更有保障;如果要频繁换模型、做实验,或者部署到生产环境需要快速迭代,选AWQ,省时间就是省钱。
但别高兴太早,W4A4的坑还在前面等着呢。
2024年中,MIT HAN Lab推出了QoQ,主打W4A8KV4——权重4-bit,激活8-bit,KV cache 4-bit。想法很丰满:都压到低比特,计算和显存都省。实际我拿Atom(一个典型的W4A4方案)在A100上跑,居然比TensorRT-LLM里的W4A16(GPTQ)还慢20%! 原因很简单:INT4 tensor core利用率不高,计算收益打不过显存节省。QoQ在上吹得天花乱坠,但我到现在也没看到它有大规模落地的案例。
RPTQ和OliVe这种处理异常值的方案,学术上挺好看,实践里却寸步难行。通道重排、outlier-victim配对,社区支持根本跟不上。我在ONNX Runtime里试过RPTQ的示例,跑是能跑,但得自己写Calibration流程,层归一化还得重新排权重,烦得要死。OliVe的outlier-victim配对思路很巧——异常值旁边通常跟着正常值,量化异常值时把旁边正常值稍微调一下就能补偿误差——但现成框架里基本没实现。感觉这些方案更适合硬件定制,比如设计一个支持非对齐量化计算的新NPU。
FP8呢?我只能说“未来可期”。DeepSeek-V3在训练切到FP8,推理也配合FP8,确实省了显存。但我手头没有H100,只能在模拟环境用NVIDIA的TransformerEngine试了试W8A8 FP8,精度比INT8高一个档次,几乎无损。不过,等大规模普及到A100以下?可能还得两年。
好,现在让我给你推荐一套真正可行的量化方案,全是血泪换来的经验:
1. 如果你只关心部署,不想折腾算法: 直接从HuggingFace下载AWQ量化好的模型,用vLLM或TGI一跑就行。W4A16在大多数场景足够,显存省75%,真·省心省力。
2. 如果想省更多显存且显卡支持INT8 tensor core(A100/Ampere以上): 硬上W8A8,选SmoothQuant或直接用FP8(H100)。但要盯着模型精度,一般掉1-2个点,你需要自己评测对业务的影响。
3. 如果非要极端压缩(边缘设备、iPhone): 只能上混合精度+更低bit,比如AWQ的4-bit + KV cache量化。KV cache量化现在有KIVI、IntactKV这些专门方案。我自己测过KIVI对长上下文生成(16K tokens)的帮助:KV cache从20GB砍到5GB,而且因为缓存IO减少,速度反而有提升。不过需要自己动手实现,有点麻烦。
4. 如果模型做多模态(LLaVA等): 老实说,眼下Image encoder那块还是FP16居多,大部分量化
读者评论 3