Skip to content

模型量化——将 32-bit 浮点权重压缩到 2~8 bit,用精度换内存和速度,是本地推理的核心技术。

为什么需要量化 ​

DeepSeek V4 Flash 有 284B 参数。如果用 F32 存储:

284B × 4 bytes = 1.136 TB — 消费级硬件完全无法容纳

量化将每个权重从 32 bit 压缩到 2~8 bit:

Q2_K:  284B × ~0.33 bytes ≈ 94GB → 实际文件约 81GB(含元数据)
Q4_K:  284B × ~0.56 bytes ≈ 159GB
Q8_0:  284B × 1 byte ≈ 284GB

量化是本地推理的前提——没有量化,消费级硬件无法运行这个模型。

核心原理 ​

块量化(Block Quantization): 每 256 个权重为一组

Q2_K 块(84 字节 / 256 权重 = 2.625 bit/权重):
  scales[16]  — 16 组缩放因子(每组 16 个权重共享)
  qs[64]      — 256 个 2-bit 值(64 × 4 = 256 bits)
  d           — 全局缩放(float16)
  dmin        — 全局最小值偏移(float16)

反量化: weight_float = (qs_value - dmin) × scales[group] × d

非对称量化:缩放因子和偏移允许权重分布不对称(不像对称量化强制零中心),对 2-bit 这种极端量化特别重要。

在 ds4.c 中的实现 ​

量化类型用途每权重 bit
Q2_K / IQ2_XXSMoE 路由专家~2-2.6
Q4_K注意力投影、MoE 门控~4.5
Q8_0 / Q8_K共享专家、高精度路径8
F16嵌入层、输出层16
MXFP4Flash 0731 路由专家(原生浮点)~4.25

dequantize_row_*() 函数族将量化块还原为 float32 进行计算。GPU kernel 内联反量化。

Q4_K 路由专家(PRO 模型) ​

DeepSeek V4 PRO 模型的路由专家全部使用 Q4_K 量化。ds4 新增了 CPU 端的 Q4_K 路由专家推理支持:

  • block_q4_K:144 字节/block,256 元素/block,含 super-block scales 和 min values
  • ds4_vec_dot_q4_K_q8_K():Q4_K × Q8_K 点积,ARM NEON dot-product 指令加速
  • matvec_q4_k_experts_mid_prequant():使用预量化 Q8_K 激活执行 gate+up 矩阵-向量乘
  • matvec_q4_k_experts_accum_prequant():down 投影累积

MXFP4 —— 微缩浮点(Flash 0731 原生格式) ​

MXFP4 是 OCP Microscaling FP4——真正的 4-bit 浮点,不是 Q4_K 那种"4-bit 定点 + 缩放"。每 32 个权重共享一个 E8M0 指数(幂次缩放 2^(e−127)),每个权重是一个 4-bit 码表索引:

c
#define QK_MXFP4 32
typedef struct {
    uint8_t e;              // E8M0 共享指数:2^(e-127),e=0 视为零
    uint8_t qs[QK_MXFP4/2]; // 16 字节 = 32 个 4-bit 码表索引
} block_mxfp4;              // sizeof == 17 → 4.25 bit/权重

// E2M1 码表:4-bit 直接编码浮点值(含符号)
static const float ds4_mxfp4_values[16] = {
     0.0f,  0.5f, 1.0f, 1.5f, 2.0f, 3.0f, 4.0f, 6.0f,
    -0.0f, -0.5f,-1.0f,-1.5f,-2.0f,-3.0f,-4.0f,-6.0f,
};

// 反量化(标量参考实现):weight = 共享指数 × 码表值
float d = e8m0_to_f32(block.e);   // e<<23 的位型重解释;e==0 → 0x00400000
                                   // 即次正规数 2^-127(数值上视作零)
sum += d * ds4_mxfp4_values[nibble] * activation;

GGUF 张量类型 39。两个关键差异让它和 Q4_K 分工明确:

Q4_KMXFP4
编码4-bit 定点 + min/scale4-bit 浮点(E2M1 码表)
缩放每 16 权重一对 f16 scale/min每 32 权重一个 E8M0 共享指数
GPU 计算先反量化再 matmul直接喂张量核的 block-scaled MXFP4 指令(CUDA SM121 / Blackwell sm_120a)

DeepSeek 原生就把 Flash 的路由专家存成 MXFP4,所以 ds4 的 GGUF 转换是无损的——按字节搬,没有 dequant→requant 损耗。Flash 0731(DS4F)检查点以 MXFP4 为原生格式,L40S server 默认就用它。CUDA(67d97ab)与 Metal(7bec128)都有原生 MXFP4 推理路径;标量参考点积 ds4_vec_dot_mxfp4_f32() 用于正确性验证。

Metal 的 MXFP4 → half 查找表 ​

Metal MoE 内核做 MXFP4 matmul 时要先把 E8M0 指数 × E2M1 码值 反量化成 half。这个乘积空间只有 256 × 16 = 4096 种——metal/generate_mxfp4_half_lut.py(Ivan Fioravanti 的 exact 加速系列,fd2d5e0 合入)用精确整数运算 + 就近偶数舍入离线算出每个乘积的 binary16 位型,生成 metal/moe.metal 里的 ds4_metal_mxfp4_half_lut[256][16] 常量表:

metal
// 每个权重一次索引加载取代一次浮点乘法 + f32→f16 舍入
static inline half ds4_metal_mxfp4_half_lut_value(uchar e, uint q) {
    return as_type<half>(ds4_metal_mxfp4_half_lut[(uint)e][q]);
}

因为 E8M0 是 2 的幂、E2M1 的码值都能被 half 精确表示,这张表就是一次舍入后的精确反量化值——用查表替换"f32 码表乘法再收窄到 half",decode 步实测约 +4%。E8M0 = 0xff(∞ × 零 → NaN)那一行保留算术兜底路径,不改变 NaN 载荷行为。

LUT 漂移检查:生成器带 --check 模式并钉住规范 SHA-256;make check-mxfp4-half-lut(make test-mxfp4-metal 的前置步骤)会校验 moe.metal 里那 4096 个字面量与生成器当前输出一致——手工改动或生成器舍入逻辑变化都会让构建失败。这是"生成产物必须可再生产"的典型守卫。

MXFP4 的 ROCm 原生内核(2026-09,PR #656) ​

ROCm 侧的 MXFP4 路由专家内核(rocm/ds4_rocm_moe.cuh)不走张量核 block-scaled 指令,而是GPU 上解码 + dp4a 整数点积:激活先在 GPU 上量化成 Q8_K,dev_mxfp4_unpack4() 用 V_PERM_B32 一条指令展开 4 个 nibble 码字(码表两半驻 SGPR 立即数),dot 辅助函数族支持 lane 对分块合并访存、lo/hi 整数累加器分离(重结合但逐位一致)、gate+up 融合装载。设计细节(寄存器/LDS 预算、L2 友好网格序、占用率变体)见 Part 6 §4c。UE8M0 在 ROCm 侧的幂转换同样是 __uint_as_float(e << 23) 家族(e==0 映射次正规编码)。

GLM 5.3 的量化策略(2026-09) ​

gguf-tools/glm53_quantize.py 的 regular_qtype() 延续"非对称量化"哲学并加了一条新原则——递归路径不给量化噪声留累积的机会:

  • embedding / output 与所有 KDA dense 张量在 Q2/Q4 工件里都升 Q8_0(Q2 工件单独保 kda_q/kda_k 在 Q4_K)——KDA 的递归状态每步读写,量化误差会随递归滚雪球
  • Q4 工件路由专家 gate/up/down = Q4_K;Q2 用 IQ2_XXS gate/up + Q2_K down
  • 共享专家与前 3 层 dense FFN = Q8_0;DSA 注意力投影 = Q8_0(含 kv_b_k/kv_b_v 拆分变换);索引器保持 BF16
  • KDA 的 kda_q/k/v 在 Q4 工件里保持 BF16(也是 M3 Ultra BF16 融合 QKV 内核的前提,见 Part 6 §4l)

配套工具:glm53_manifest.py(张量清单)、glm53_full_quantize.py(305 GB FP8 "packaged weights" 路径——引擎暂不能执行,仅发布打包)、glm53_validate_gguf.py。

V4.1 Flash 的量化与盘上 Engram 编码(2026-09) ​

V4.1 的源检查点是原生 FP8 32×32 块格式(比 MXFP4 的 32 块更早一步:路由专家 2-per-byte I8 nibble、E8M0 块缩放)。deepseek41_quantize.py 的配方延续非对称哲学:Q2 = 路由 gate/up IQ2_XXS + down Q2_K、注意力/共享/头 Q8_0;Q4 只把路由专家换成 Q4_K;imatrix 从原始 safetensors 重新生成(8192 token 校准命中 97.15% 专家),记录进 deepseek41.calibration、从不二次量化 GGUF。

189 GiB 的 engram 表用另一种块缩放编码无损直拷进 GGUF:每行 264 B = 256 个 E4M3 字节 + 8 个 E8M0 缩放(32 维共享一个缩放)——和 MXFP4 同族(把 FP4 换成 FP8),运行时 CPU 解包成 F32 再手动做 BF16 舍入对齐参考数值。NaN 是硬错误:E4M3 码 0x7F、缩放 0xFF 都会在加载/读取时被拒绝。

相关概念 ​

  • gguf — 量化权重以块为单位存储在 GGUF 文件中
  • moe — 不同专家使用不同量化级别(共享专家用高精度,路由专家用低精度)
  • mmap — 量化后的模型文件通过 mmap 按需加载

详见 Part 3 — 量化与矩阵运算。