ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

为什么 down_proj 不量化?Qwen3-8B-W4A8 张量级量化策略逐层解读(附完整张量清单)

为什么 down_proj 不量化?Qwen3-8B-W4A8 张量级量化策略逐层解读(附完整张量清单)

【免费下载链接】Qwen3-8B-W4A8

项目地址:https://ai.gitcode.com/hf_mirrors/vllm-ascend/Qwen3-8B-W4A8
点击查看免费下载

Qwen3-8B-W4A8 是对 Qwen3-8B 大语言模型做W4A8_DYNAMIC(权重 4-bit + 激活 8-bit 动态)量化后的推理权重包,专为 vLLM-Ascend 的 NPU 高效部署设计。相比 BF16 原版约 16GB 的体积,量化后权重总大小约10.7GB(11,498,317,824 字节,见 quant_model_weight_w4a8_dynamic.safetensors.index.json 的total_size字段),显存占用直接决定推理成本。

但很多人拿到模型后都有一个疑问:为什么 MLP 里的down_proj是 FLOAT 而gate_proj、up_proj却量化了?本文逐层拆解 quant_model_description.json 中的完整张量清单,把每个张量的量化决策讲清楚 📌

一、先搞懂:Qwen3-8B-W4A8 到底是什么量化方案

量化类型记录在 quant_model_description.json 开头两行:

{ "model_quant_type": "W4A8_DYNAMIC", "group_size": 256, ... }

三个关键信息:

配置项值含义
model_quant_typeW4A8_DYNAMIC权重 4-bit 存储,激活按 token 动态 8-bit 量化
group_size256权重每 256 个元素为一组,共享一组校准参数
quantizew4a8_dynamic与 config.json 中的声明一致,供加载框架自动识别

W4 部分:权重本体只占 BF16 的 1/4 空间。每 256 个权重配一组weight_scale和weight_offset(缩放因子 + 零点偏移),这是典型的分组仿射量化。

A8 部分:DYNAMIC表示激活不做离线校准,推理时按 token 实时计算量化参数,避免离线数据集偏差带来的精度损失。

为什么 scale 还有_second后缀?这是二级量化的痕迹:weight_scale/weight_offset本身也按组被量化存储(weight_scale_second、weight_offset_second就是它们各自的校准参数),进一步压缩校准开销。所以一个被量化的矩阵在磁盘上实际有5 个张量:

<name>.weight # 4-bit 权重本体 <name>.weight_scale # 一级缩放因子 <name>.weight_offset # 一级零点偏移 <name>.weight_scale_second # 缩放因子的二级校准 <name>.weight_offset_second # 偏移量的二级校准

二、单层结构透视:36 层 × 6 个量化矩阵

Qwen3-8B 为 36 层 Transformer(config.json 中num_hidden_layers: 36),每层的线性矩阵及其量化决策如下:

张量(以第 0 层为例)维度角色格式
self_attn.q_proj4096 → 4096✅ W4A8_DYNAMIC
self_attn.k_proj4096 → 1024✅ W4A8_DYNAMIC
self_attn.v_proj4096 → 1024✅ W4A8_DYNAMIC
self_attn.o_proj4096 → 4096✅ W4A8_DYNAMIC
mlp.gate_proj4096 → 12288✅ W4A8_DYNAMIC
mlp.up_proj4096 → 12288✅ W4A8_DYNAMIC
mlp.down_proj12288 → 4096⛔FLOAT
q_norm/k_norm/ 两个 layernorm1D 向量⛔ FLOAT

可以看到规律:注意力和 FFN 的 6 个"主干"矩阵全部量化,唯独down_proj例外。这正是本文的核心问题。

三、为什么 down_proj 不量化?

3.1 位置敏感:它是 FFN 的"出口"

在 SwiGLU 结构中,gate_proj和up_proj把 4096 维升到 12288 维,经过 SiLU 门控相乘后,再由down_proj压回 4096 维,叠加进残差流:

hidden → [gate_proj × SiLU(up_proj)] → down_proj → 残差流 → 下一层

gate_proj、up_proj的中间结果会被门控运算"过滤"和"稀释",而down_proj的输出处处可见——它直接决定了这一层 FFN 对残差流的贡献。对输出误差最敏感的位置,恰恰最不该压缩。

3.2 输出分布更"尖",4-bit 装不下

FFN 中间激活经 SiLU 门控后动态范围大,但down_proj的输出要参与后续 RMSNorm 与注意力归一化,数值分布集中且对极值敏感。4-bit 只有 16 个量化档位,留给这类"低容忍"矩阵的粒度明显不足——业界主流 4-bit 方案(包括各种 MoE/FFN 量化实践)也普遍将down_proj、lm_head列入排除清单,本质是同一权衡。

3.3 收益账依然划算

down_proj是 12288×4096,与单个gate_proj参数量相同。保留它不量化,FFN 权重仍省了2/3的空间;加上 4 个注意力投影矩阵,全模型 216 个主干矩阵完成 4-bit 化,总权重从 BF16 的约 16GB 压到约 10.7GB,省下的显存足以让更长的上下文和更大的 batch 跑起来📉

四、完整张量清单(1263 个张量全解)

清单以"每层模板 + 全局张量"的方式给出,与 quant_model_description.json 的 1265 条记录(含 2 条元数据)一一对应。

4.1 每层模板(第 0~35 层,共 36 层 × 35 个张量 = 1260)

✅ W4A8_DYNAMIC(30 个)——6 个矩阵 × 5 个张量:

张量前缀(model.layers.N.下)说明
self_attn.q_proj/k_proj/v_proj/o_proj各含.weight、.weight_scale、.weight_offset、.weight_scale_second、.weight_offset_second
mlp.gate_proj、mlp.up_proj同上 5 件套

⛔ FLOAT(5 个):

张量原因
self_attn.q_norm.weight/self_attn.k_norm.weightQK-Norm 逐通道缩放,仅 128 个参数,量化无收益
input_layernorm.weight/post_attention_layernorm.weightRMSNorm 归一化参数,精度敏感
mlp.down_proj.weight上文第三节所述

4.2 全局张量(3 个,全部 FLOAT)

张量说明
model.embed_tokens.weight词嵌入 151936×4096,参与逐 token 查表,量化会直接污染输入表征
model.norm.weight最终层 RMSNorm
lm_head.weight输出投影 4096×151936,直接映射 logits,是精度保底线

汇总一下:1263 个张量中1080 个为 W4A8_DYNAMIC(216 组 5 件套),183 个为 FLOAT——量化集中在"体量最大、误差容忍度高"的矩阵上,这就是完整的张量级策略 🎯

五、权重分片与校验:文件怎么对得上

权重切分为 3 个 safetensors 分片,张量到分片的映射见 quant_model_weight_w4a8_dynamic.safetensors.index.json:

分片文件张量数典型内容
quant_model_weight_w4a8_dynamic-00001-of-00003.safetensors443embed_tokens、第 0~14 层左右
quant_model_weight_w4a8_dynamic-00002-of-00003.safetensors595中间层
quant_model_weight_w4a8_dynamic-00003-of-00003.safetensors225末尾层、model.norm、lm_head

校验小技巧:在索引 JSON 中搜索layers.35.mlp.down_proj.weight,其值应为FLOAT对应分片路径;再对照layers.35.mlp.up_proj.weight_scale等 5 件套是否齐全,即可确认量化描述与权重文件一致。模型下载方式(SDK / Git)见 README.md,如需克隆可使用:

git clone https://gitcode.com/hf_mirrors/vllm-ascend/Qwen3-8B-W4A8

六、FAQ:新手最常问的 3 个问题

Q1:layernorm、q_norm 为什么不量化?它们是逐通道缩放向量(每层仅几百到几千个参数),参数量小到量化省不了什么空间,反而是归一化精度的命门,全行业惯例保留全精度。

Q2:A8 的"8-bit 激活"存在权重文件里吗?不存在。DYNAMIC意味着激活量化参数在推理时按 token 实时计算,磁盘上只有权重侧的 4 件套 + 二级校准,这也是为什么每个量化矩阵只有 5 个张量。

Q3:能否把 down_proj 也量化到 W4?技术上可以,但按本仓库给出的张量级策略,它被明确标记为FLOAT(见 quant_model_description.json)。若要自行修改排除清单,建议先做回归评测,确认生成质量再部署。

七、总结:一张表看懂量化决策逻辑

决策依据
量化 6 个主干矩阵(q/k/v/o/gate/up)参数量占绝对大头,4-bit 后体积减半以上,且误差被门控/注意力机制稀释
保留down_proj为 FLOATFFN 出口直接写入残差流,误差放大风险最高
保留 embed / lm_head / 各类 norm 为 FLOAT查表与 logits 映射对精度零容忍,参数占比低
二级 scale/offset 量化校准参数自身再压缩,进一步省空间

一句话总结:Qwen3-8B-W4A8 的量化策略是"把刀挥在最厚的肉上,把刀尖让给最嫩的肉"——1080 个张量完成 4-bit 化换取约 5GB 显存节省,而down_proj、lm_head等敏感出口以 FLOAT 形式守住输出质量。读懂 quant_model_description.json 这份 1265 行的清单,你就掌握了这类 W4A8 量化模型的完整解剖图 🧩

【免费下载链接】Qwen3-8B-W4A8

项目地址:https://ai.gitcode.com/hf_mirrors/vllm-ascend/Qwen3-8B-W4A8
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进