大数跨境

华为开源 MACaQ:122B千问模型量化只用64分钟

华为开源 MACaQ:122B千问模型量化只用64分钟 AINLP
2026-11-15
6
导读:千亿模型也能拆开来量化

华为瑞士计算系统实验室开源了 MACaQ,一套面向模型权重和激活的训练后量化工具。论文里,研究者用一张96GB显卡,花64分钟完成了 Qwen3.5-122B-A10B 的量化,过程峰值显存为32.5GB。


这个122B总参数模型,原始 FP16 权重约244GB。MACaQ 按层加载、校准和量化,不必先把整个原模型塞进显卡。这组 MoE 实验量化的是专家层,得到的 MXFP4 模型运行时需要约74GB显存,WikiText-2 困惑度则从5.06变为5.14。

让量化过程比最终模型还省显存,是这项工作很有意思的地方。它把每个线性层独立处理,既降低大模型的量化门槛,也减少了针对不同架构改造整套算法的工作。

现在项目已经接入 llama.cpp、vLLM、Diffusers 和 PyTorch,还提供了能继续精修已有 GGUF 的 MACaQ-R。

把大模型拆开来量化

量化要处理两件事:模型存着的权重,以及推理时流经各层的激活。论文主要研究 W4A4,也就是权重和激活都使用4-bit表示,矩阵乘法也在 MXFP4 下执行。

MXFP4 会让每32个数共享一个8-bit缩放因子,各自的数值用 FP4 E2M1 表示。32个数占16字节,再加1字节共享尺度,平均约为 4.25 bit一个元素。FP4 的可表示值很稀疏,正数部分只有0、0.5、1、1.5、2、3、4、6这些档位,再乘上共享尺度。

模型里的数值分布却并不整齐。一个块里有几个特别大的值,就可能把整个块的尺度拉大,让大量小值挤进几个粗糙档位。

已有方法常先缩放或旋转这些数,再进行量化。为了不增加推理工作,输入侧的变换往往要向前传播,吸收到邻近的归一化层、投影层,甚至残差分支里。换一个网络结构,就得重新找可以吸收它的位置。

MACaQ 把输入变换留在当前线性层。 权重预先变换好,输入在推理时做轻量缩放和小块旋转,再进入低精度矩阵乘法。层的输入输出仍保持原有接口,邻居不用跟着改。

论文图1 输入变换保留在线性层内部

离线量化与在线推理分工如下:

阶段
主要工作
校准
用代表性输入收集各线性层的输入统计
离线处理权重
平衡通道、旋转、选择块尺度、精修编码并打包
推理
对当前输入缩放、旋转和量化,再与已打包权重相乘

论文的流式流程只需将当前处理层及必要缓冲放进 GPU,其余权重留在主机内存。显存主要承担当前层、输入统计与校准数据,122B 实验采用了512K个校准 token、每行最多32次翻转优化。

项目里的实现还把这个流程展开到了 Transformer block:先跑校准输入,用 forward hook 为内部线性层积累统计;量化这些层后,再把输入经过量化后的 block,所得输出继续交给后面的 block。层内优化独立,校准输入仍沿网络向后传递。

针对 Qwen3 与 Qwen3.5 系列,仓库还提供按 safetensors 分片加载 block 的 Streamer,缓存分块输入,不先构造一份全模型实权重。不同模型仍需要相应加载适配;通用的是线性层里的量化方法。

先调整数值分布

MACaQ 在每层依次做通道平衡、小块旋转、缩放尺度选择和权重精修。

通道平衡先调整激活与权重之间的负担。某个激活通道太大,可以把它压小,同时把相应权重放大;权重一侧太大时则反过来调整。

假设一个通道的输入缩小一半,对应权重扩大两倍,高精度下乘积不变,但两边进入量化器时的数值范围变了。MACaQ 根据权重列的标准差、校准激活的均方根幅度决定缩放,用参数 α 控制两边的平衡,论文默认 α 为0.75。

接着是 32元素一组的 Hadamard 旋转。它把集中在少数通道上的尖峰分散开。分组大小与 MXFP4 的共享缩放组对齐,避免把一个异常值的影响扩散到多个独立量化块。

输入和权重使用配套的变换。把通道缩放记为 D、小块正交变换记为 B,则输入变成 XDB,权重变成 WD⁻¹B;相乘时,D 与 D⁻¹抵消,B 与它的转置抵消。未量化时,这一层仍计算原来的 XWᵀ。

处理好分布,还要决定每个块共用多大的尺度。尺度小,零附近分得细,但大值容易被截掉;尺度大,能容纳大值,小值的刻度却变粗。

MACaQ 围绕常规指数考察 +1、0、−1 三个候选,用校准输入的重要性对误差加权,选出表现最好的一档。选定以后,这个块的尺度在后续 FP4 翻转精修中保持不变。

精修看的是整层输出

直接量化通常会把权重舍入到最近的可表示值。但离原权重最近,不一定让整层输出最接近原来。

先只看权重量化,取两个有效输入作简化示例:输入为10和1,原权重都为0.9,原输出是9.9。如果两个权重都舍入到1,输出变成11;把第二个权重从1改到相邻的0.5,输出变成10.5,反而更接近9.9。

第二个权重本身偏得更远,整层输出却偏得更少。 输入通道的重要性,以及不同权重误差之间的叠加关系,决定了哪次修改值得做。

MACaQ 的目标,是让校准输入上的 XWᵀ 与量化后 XŴᵀ 之间的平方误差尽可能小。展开以后,一行权重的目标可以写成:

L = rHrᵀ,其中 r = w − ŵ,H = XᵀX。

H 的对角线反映各输入通道的能量,非对角元素则记录通道怎样共同变化。选择块尺度时只用对角项,计算简单;到 Flip-Refinement 阶段,再用完整的矩阵关系判断修改收益。

论文还给变换后的 H 加了对角正则,得到 Hf,默认系数 λ 为1。对某一行,先算出 g = Hf rᵀ。如果把第 j 个量化权重增加 Δ,那么目标误差的下降量就是:

gain = 2Δgⱼ − Δ²(Hf)ⱼⱼ。

FP4 档位并不均匀,Δ 要由当前档位、移动方向和块尺度共同决定。算法每轮考察相邻档位,选出收益最大的改动,只有 gain 大于0才接受。

论文算法1 每个输出行独立选择误差下降最大的改动

修改后,只需用 Hf 对应的一列增量更新 g,不必重新计算整个矩阵与残差的乘积。各输出行相互独立,可以并行处理;一行没有可改善的相邻改动,就从活跃集合中退出。

项目把这段反复执行的步骤交给 torch.compile 做融合,形状相同的层可以复用编译结果。这里省下的不只是搜索范围,还有每轮重复计算和已经收敛的行。

消融实验显示,在 Llama3-8B 上,直接舍入的 WikiText-2 困惑度为8.28;逐步加入尺度选择、旋转、通道平衡和翻转精修后,降到了6.87。原 FP16 模型是6.14,越低越好。

论文表5 各组件对Llama3-8B困惑度的改善

这张表使用512次翻转和200K个校准 token,与64分钟的122B实验属于不同配置。

校准投入决定质量上限

MACaQ 最直接的两个调节项,是校准 token 数量和最大翻转次数 K。前者决定输入统计看过多少数据,后者决定每行权重最多接受多少次修改。

论文图2把 Llama3-8B 的量化耗时放在横轴,WikiText-2 困惑度放在纵轴。红线是 MACaQ 的不同配置,越靠左下越好。

论文图2 Llama3-8B量化耗时与困惑度 越靠左下越好

红线在较短时间内就进入了 MR-GPTQ、DuQuant++ 的最佳质量区间。论文据此报告,达到强基线的最佳困惑度,MACaQ 所需量化时间约为其1/11。

附录给出了曲线上各档的实际配置,下面取其中三组:

校准 token
每行最大翻转次数
量化时间
困惑度 ↓
约2K
0
14.8秒
7.11
约8K
32
31.3秒
6.97
约200万
512
636.9秒
6.85

更低的困惑度,需要继续投入校准和精修时间。论文统一对照采用 K=128、200K校准 token,并没有给每个模型都使用最耗时的配置。

通道平衡参数 α 和正则系数 λ,也做了敏感性实验。图5使用 Llama3-8B、4K校准 token和16次翻转:α 从0调高后,困惑度明显下降,0.5至1之间变化较小;λ 在测试区间内则相当平稳。

论文图5 上图为通道平衡参数 下图为Hessian正则参数

推理收益随负载变化

在统一的 MXFP4 W4A4 对照中,MACaQ 拿到了论文表1各模型、各数据集的最低量化困惑度。例如 Qwen3-32B:

方法
WikiText-2 ↓
C4 ↓
原 FP16
7.62
12.45
MR-GPTQ
8.15
13.27
DuQuant++ 加 GPTQ
8.07
13.15
MACaQ
7.94
12.93

实际生成任务也做了评测。Qwen3-32B 的 IFEval 从原精度的83.60%变为83.20%,MATH-500 从97.78%变为97.26%。这些结果给出了压缩后的能力损失范围;不同任务上,其他量化方法仍有各自较好的结果。

推理速度方面,项目当前 README 的 Qwen3.8-27B 示例报告:相对 BF16,prefill 为2.33倍,decode 为2.58倍。官方页面对应单卡、batch 1、4096 token输入及512 token输出,预热后重复测量,加载与编译不计入时间。

论文对 Qwen3-32B 和 Llama3-8B 另做了完整吞吐测试,使用 vLLM graph mode、512 token输入,并逐步增加 batch。表中的 decode 是整个 batch 的聚合吞吐。

论文表6 不同batch的端到端吞吐 单位token每秒

以 Qwen3-32B 为例,batch 1时,MACaQ 解码为69.8 token/s,BF16为22.8 token/s,Marlin W4A16为71.8 token/s。到 batch 256,三者分别为5252.8、3061.5和3573.3 token/s。

小 batch 解码需要反复搬运权重,W4A16 的 Marlin 已经能获得很好的收益;并发变大、计算压力上升后,MACaQ 的 W4A4 路径在这组实验里取得了更高吞吐。

为保持每层独立而留下的缩放和旋转,确实要花时间。论文将它们关掉做对照:在 Qwen3-32B 上,这部分使解码增加约2.3%开销;模型更小时,占比会更高。

论文图3 缩放和旋转相对纯MXFP4的额外解码开销

原因在于,输入侧操作的工作量大致随输入维度增长,后面的矩阵乘法还随输出维度增长。对32元素分组,缩放和旋转的理论算术工作量约为矩阵乘法的3/m,m是输出维度;实际耗时还取决于内存访问、内核启动和硬件吞吐。

项目的 Triton 实现把输入缩放、32元素 Hadamard 旋转和激活量化合进一个预处理 kernel,再交给 MXFP4 矩阵乘法。这样少启动几次 kernel,也少写回两份中间张量。2.3%的比较基线,是关掉缩放和旋转的 MXFP4 路径。

图片模型也用同一套方法

线性层并不只存在于语言模型。MACaQ 将同样的量化方法用到了 FLUX.2-klein-4B 的 DiT 线性层,保留其他组件的高精度表示。

下面是论文的原图。三列依次为 BF16、MACaQ MXFP4 和官方 NVFP4,使用相同提示词和随机种子。可以留意第一行的阴影方向,以及第二行杯子是否为空。

论文图4 左为BF16 中为MACaQ 右为官方NVFP4

研究者用 GenEval2 的800条提示词做成对比较。在1024×1024、6步生成设置下,MACaQ 的 LPIPS 为0.218,官方 NVFP4 为0.235,前者与 BF16 输出更接近;SSIM 等指标也有相同方向的结果。

显存峰值从 BF16 的18.5GB降至13.1GB,官方 NVFP4 为13.3GB。MACaQ 的 MXFP4 平均每元素4.25 bit,NVFP4 为4.50 bit。

项目里的接入范围比论文实验更广:

用途
已有接入与处理范围
文本推理
vLLM支持Qwen稠密模型与MoE 专家投影可走W4A4
本地推理
llama.cpp支持GGUF权重量化与配套输入变换 另有MACaQ-R
生成模型
Diffusers接入图像 视频和音频模型的相关线性层
语音合成
PyTorch接入Qwen3-TTS Chatterbox等模型

不同模态仍按各自模型选择精度。官方 Wan 视频演示采用 W4A8,FLUX论文实验则是 DiT 线性层 W4A4。MoE的路由器、共享专家、注意力等,也不必和路由专家使用同一量化配置。

精修也可以按码本搜索

论文附录还把 Flip-Refinement 扩展到了 llama.cpp 的 IQ3_S 和 IQ3_XXS 两种纯权重量化格式。

这些格式用一个码本条目表示连续四个权重的幅值。如果只改其中一个数,新的四元组可能根本不在合法码本中。相邻档位里几乎无处可走,就要把搜索单位从一个权重改成一个完整码字。

MACaQ 对每组四个坐标取出4×4的 Hessian 子块,计算候选码字的收益。与其余权重的关系已包含在梯度里,因此无需为每个候选重算整行输出。候选评分可以组织为矩阵乘法,再选择其中收益最大的合法码字。

在未使用重要性矩阵初始化的 Qwen3-4B IQ3_S 上,WikiText-2 困惑度从13.06降到11.81;只做标量翻转时为12.31。

论文表8的Qwen3-4B部分 IQ3码本精修结果

已有重要性矩阵初始化时,继续精修的收益就没有这么整齐。例如 IQ3_S 原本为11.83,码本精修后为11.88;IQ3_XXS 则从13.09改善到12.64。继续调整共享尺度,也没有在这些4B对照中进一步降低困惑度。

局部重建误差更低,未必让整个模型的困惑度同步下降。 校准样本、初始化方式、格式和局部最优都会影响最终结果。

这组附录实验先做了 MACaQ 缩放与旋转,使用配套 llama.cpp 执行在线变换。它与下面保留原生激活表示的 MACaQ-R,是不同的运行路径。

GGUF有两条路线

完整 MACaQ 会把量化权重和所需变换保存下来,推理时仍要执行输入缩放与旋转。项目提供了配套的 llama.cpp 版本,以及 vLLM 插件等接入方式。

以 Qwen3-4B 为例,项目比较了几种完整 GGUF 文件的大小和相对 FP16 的 KL 偏差。图越靠左下,表示文件更小、输出分布更接近原模型。MACaQ 的 IQ4_XS 文件为2.260GB、KL为0.02804;图中另一个 IQ4_XS 对照为2.271GB、KL为0.03443。

项目原图 Qwen3-4B的GGUF大小与KL偏差

MACaQ-R 则专门精修已有的原生 K-quant MoE GGUF。它保持原来的块尺度、张量格式和激活表示,只调整受支持的 Q4_K、Q5_K、Q6_K 权重编码,输出可以由标准 llama.cpp 加载。

项目公布的 Qwen3.6-35B-A3B 例子中,原 Unsloth UD-Q4_K_XL 与 MACaQ-R 文件同为22.36GB,KL偏差从0.015731降到了0.013367。体积不变,权重编码重新选了一遍。

选择
制作时需要
运行时使用
完整路径
原模型 校准文本及配套量化环境
项目配套的llama.cpp与变换配置
原生精修
已量化MoE GGUF 匹配的原始HF模型 全精度teacher及校准文本
标准llama.cpp
服务部署
原模型 校准文本及插件环境
带MACaQ插件的vLLM

准备自己试,可以先从较小的 Qwen3-4B 开始。vLLM路径使用 Linux、Python 3.12,并按仓库安装依赖和插件;准备好有代表性的校准文本后,量化和启动接口分别为:

.venv-vllm/bin/python vllm/cli.py quantize \
  --model Qwen/Qwen3-4B \
  --calibration data/text-calibration.txt \
  --output models/qwen3-macaq --gpu 0

.venv-vllm/bin/python vllm/cli.py serve \
  --model models/qwen3-macaq --gpu 0

保存的检查点包括打包权重、尺度、变换、tokenizer和来源信息。再次加载或启动服务,不需要重新校准。Qwen3.8 等混合架构使用对应依赖,MoE也有专门支持范围。

已有 K-quant MoE GGUF,想保留标准 llama.cpp 工作流,则使用精修入口:

.venv-llamacpp/bin/python llamacpp/macaq.py refine \
  --model models/model-q4.gguf \
  --hf models/original \
  --teacher models/original-f16.gguf \
  --calibration data/calibration.txt \
  --output models/model-macaq-r.gguf \
  --work-dir work/refinement

原始模型、全精度中间文件、校准缓存与最终输出,都要预留存储空间。只想先试成品,可以直接进入华为 CSL 的 Hugging Face 集合,选择已有的 MACaQ 或 MACaQ-R 模型,再按对应后端运行。

参考链接

  • 论文:https://arxiv.org/abs/2611.10649v2
  • 项目:https://github.com/huawei-csl/MACaQ
  • 官方交互介绍:https://huawei-csl.com/blog/macaq/
  • 模型集合:https://huggingface.co/collections/huawei-csl/macaq

【声明】内容源于网络
0
0
AINLP
一个有趣有AI的自然语言处理公众号:关注AI、NLP、大模型LLM、机器学习、推荐系统、计算广告等相关技术。公众号可直接对话双语聊天机器人,尝试对对联、作诗机、藏头诗生成器、自动写作等,查询相似词,测试NLP相关工具包。
内容 6123
粉丝 0
AINLP 一个有趣有AI的自然语言处理公众号:关注AI、NLP、大模型LLM、机器学习、推荐系统、计算广告等相关技术。公众号可直接对话双语聊天机器人,尝试对对联、作诗机、藏头诗生成器、自动写作等,查询相似词,测试NLP相关工具包。
总阅读40.6k
粉丝0
内容6.1k