第 2 章 · 02 quant.h 量化容器与 FORMATS 注册表 本节摘要:本节深潜 (1569 行,header-only)——Colibrì 的"规范容器解码器"。它解决两个问题:怎么把压缩的量化字节(int4/int8/FP8-e4m3/MXFP4)高效解成浮点累加,以及怎么在多架构 CPU 上用最快的 SIMD 内核(AVX2/AVX-512/AVX-VNNI/ARM NEON/NEON-SDOT/NEON-i8mm/POWER VSX)。quant.h 是纯 compute,不依赖任何 或 结构体——这条边界让它能被所有五个引擎 共享。
本节摘要:本节深潜
c/quant.h(1569 行,header-only)——Colibrì 的"规范容器解码器"。它解决两个问题:怎么把压缩的量化字节(int4/int8/FP8-e4m3/MXFP4)高效解成浮点累加,以及怎么在多架构 CPU 上用最快的 SIMD 内核(AVX2/AVX-512/AVX-VNNI/ARM NEON/NEON-SDOT/NEON-i8mm/POWER VSX)。quant.h 是纯 compute,不依赖任何Model或QT结构体——这条边界让它能被所有五个引擎.c共享。本节还讲清docs/FORMATS.md这个格式注册表为什么存在(QT.fmt是普通 int 没有 enum,两个格式同用fmt=6的真实冲突事件 → 建立注册表 + TRUST-VERIFY-REFUSE 身份验证),以及 FSE/rANS 熵编码无损压缩(cfse_pack.c/fse_coli.h/rans.h)在int4-rans256-g0格式上的应用。读完本节,你理解了 Colibrì 怎么"解字节"。
内容来源:原项目源码
c/quant.h(1569 行)、c/fse_coli.h(173 行)、docs/FORMATS.md、c/colibri.c的qt_resolve_fmt/qt_verify_fmt_stamp。
⚠️ 注意:
QT.fmt是一个普通int,不是 enum——这是 FORMATS 注册表存在的根本原因。两个独立 PR(#465 E8/IQ3 容器与本仓 FP8 直通分支)在同一周都用fmt=6,谁也没错(此前没有任何东西告诉他们"6 被占了")。这是流程缺陷,不是代码 bug。FORMATS.md + 元数据 stamp 关闭了这个缺口。
阅读完本节,你应当能够:
dot_i4f_avx512/matmul_fp8/matmul_mxfp4 三类内核各自解什么格式。int4-rans256-g0 为什么没有 ordinal(熵编码字节依赖数据,字节算术推断结构上不可能)。quant.h:1-3 头注释把它的定位说得很清楚:
1 /* quant.h — quantized matmul kernels (header-only, all functions static). 2 * Multi-architecture SIMD: AVX2 / AVX-512 / AVX-VNNI / ARM NEON / NEON-SDOT / 3 * NEON-i8mm / POWER VSX. Pure compute — no Model or QT dependency. */
三个修饰各自有深意:
.c 各自 #include "quant.h",所有函数 static,允许每个翻译单元独立包含而不冲突。这是第 1 章 02 节"共享头文件一改全改"的载体。matmul_i4)内部用 #ifdef __AVX512F__/#elif defined(__ARM_NEON)/...分派到当前编译目标的最快路径。一份源码覆盖七条 SIMD 路径。x、权重 q4、scale、shape",不知道 Model 结构体、不知道 QT 容器结构体。这条边界让它能被 GLM、DeepSeek、Inkling、Kimi、OLMoE 五个引擎共享——它们各自定义自己的 Model,但共用同一份 matmul 内核。💡 深潜要点:"no Model or QT dependency"不是修辞,是架构红线。如果 quant.h 引用了
Model,它就只能服务一个模型族,五个引擎就得各写一份 matmul——这正是第 1 章 02 节警告的"某机制只落在一个引擎没传到兄弟"缺陷。所以 quant.h 的函数签名永远是裸指针 + 整数 shape,纯函数式。
quant.h 用编译期 #ifdef 分派 SIMD。每个 matmul 内核都长这样(以 matmul_i4 为例):
125 static void matmul_i4(float *y, const float *x, const uint8_t *q4, const float *scale, int S, int I, int O) { /* ... */ 130 #if defined(__AVX512F__) && defined(__AVX512BW__) /* AVX-512 路径:dot_i4f_avx512 一次解 32 个 int4 */ /* ... */ 142 #elif defined(__ARM_NEON) /* ARM NEON 路径 */ /* ... */ 158 #if defined(__AVX512F__) && defined(__AVX512BW__) /* 第二段 SIMD(如 remainder 处理)*/ /* ... */ /* ... */ 250 }
七条 SIMD 路径分别对应的编译宏(在 quant.h:18-44 集中引入):
18 #ifdef __AVX2__ 19 #include <immintrin.h> /* AVX2: x86_64 通用 */ 36 #ifdef __ARM_NEON /* ARM NEON: 树莓派/苹果 M1 等 */ 37 #include <arm_neon.h> 39 #ifdef __VSX__ /* POWER VSX: POWER9+ */ 40 #include <altivec.h> 47 #if defined(__AVX512F__) && defined(__AVX512BW__) /* AVX-512: 高端 x86_64 */ 31 #if defined(__AVXVNNI__) && defined(__AVX2__) /* AVX-VNNI: Ice Lake+ */
注意还有两条 ARM 子路径由 __ARM_FEATURE_DOTPROD(NEON-SDOT)和 __ARM_FEATURE_MATMUL_INT8(NEON-i8mm)区分——它们是 ARMv8.2+/v8.6+ 的指令扩展,分别加速 int8 点积和 int8 矩阵乘。quant.h:18-44 引入对应的 intrinsic,然后各 matmul 内核用 #elif 分派。
最值得精读的是 quant.h:47-61 的 dot_i4f_avx512——它一次解 32 个 int4(nibble)做 FMA 累加,是 GLM int4 路径最热的循环:
49 static inline float dot_i4f_avx512(const uint8_t *w,const float *x,int I){ 50 const __m128i m4=_mm_set1_epi8(0x0F); const __m512i b8=_mm512_set1_epi32(8); 51 __m512 acc0=_mm512_setzero_ps(),acc1=_mm512_setzero_ps(); int i=0; 52 for(;i+32<=I;i+=32){ __m128i by=_mm_loadu_si128((const __m128i*)(w+(i>>1))); 53 __m128i lo=_mm_and_si128(by,m4),hi=_mm_and_si128(_mm_srli_epi16(by,4),m4); 54 __m128i n0=_mm_unpacklo_epi8(lo,hi),n1=_mm_unpackhi_epi8(lo,hi); 55 __m512 w0=_mm512_cvtepi32_ps(_mm512_sub_epi32(_mm512_cvtepu8_epi32(n0),b8)); 56 __m512 w1=_mm512_cvtepi32_ps(_mm512_sub_epi32(_mm512_cvtepu8_epi32(n1),b8)); 57 acc0=_mm512_fmadd_ps(_mm512_loadu_ps(x+i),w0,acc0); 58 acc1=_mm512_fmadd_ps(_mm512_loadu_ps(x+i+16),w1,acc1); 59 } 60 return _mm512_reduce_add_ps(_mm512_add_ps(acc0,acc1)); 61 }
逐行解读:(1) m4=0x0F 掩码、b8=8 用于把 [0,15] 的无符号 nibble 减 8 变成 [-8,7] 的有符号权重。(2) 一次 loadu_si128 读 16 字节(= 32 个 nibble)。(3) and + srli_epi16(by,4) 拆出低 4 位和高 4 位两套 nibble。(4) unpacklo/hi 把它们重排成两条 16 字节通道。(5) cvtepu8_epi32 把字节零扩展成 32 位 int,再 sub_epi32(b8) 减 8,再 cvtepi32_ps 转 float。(6) _mm512_fmadd_ps 做 16 路 FMA 累加(x*w+acc)。两条 acc0/acc1 是为了双倍指令级并行。(7) 最后 reduce 把两条累加器加起来。
这套解包技巧是 int4 在 AVX-512 上的标准 pattern——把"1 字节 2 个 nibble"的紧凑布局,展开成"1 字节 1 个有符号权重",再零扩展到 32 位 float FMA。quant.h:80-94 还有一个 i4_acc512_selftest 自检,用随机数据验证 AVX-512 路径与标量参考一致(容差 2e-5)——这是 Colibrì "诚实研究"在 kernel 层的体现:每个 SIMD 路径自带 selftest,编译时验证数值一致。
quant.h 覆盖多种量化格式,每种一组 matmul 内核(完整清单在 FORMATS.md):
| fmt | 名字 | 内核 | 含义 |
|---|---|---|---|
| 0 | f32 |
matmul (quant.h:98) |
纯 float32,基线参考 |
| 1 | int8-row |
matmul_q (quant.h:105) |
每行一个 f32 scale |
| 2 | int4-row |
matmul_i4 (quant.h:125) |
2 nibble/字节,每行一个 scale |
| 3 | int2-row |
matmul_i2 (quant.h:251) |
4 个 2-bit/字节 |
| 4 | int4-grouped |
matmul_i4_grouped (quant.h:168) |
每 group 一个 scale |
| 5 | int3-g64 |
matmul_i3 (quant.h:354) |
固定 64 输入/group |
| 6 | e8-iq3-lattice |
(upstream) | E8 格点 + 旋转 |
| 7 | mxfp4 |
matmul_mxfp4 (quant.h:1366) |
e2m1 nibble + UE8M0 scale,Vulkan 专用 |
| 8 | fp8-e4m3-b128 |
matmul_fp8 (quant.h:491) |
原生 e4m3,128×128 block scale |
两个值得注意的:(1) fmt 7 mxfp4 是 Kimi K3 的原生路由专家格式,只走 Vulkan 后端(c/backend_vulkan.c),CPU 路径 qt_resolve_fmt 永不返回 7——这是 Colibrì "一格式可能只对一个后端有效"的例子。(2) fmt 8 fp8-e4m3 是 GLM-5.2-FP8 原生读取路径(quant.h:405 注释),权重是 raw e4m3 字节,布局与 int8 字节相同,dequant 公式 w[o,i] = e4m3_decode(byte) * scale[o/128, i/128](quant.h:421)。quant.h:480 的 e4m3_decode 用预生成 LUT(E4M3_LUT[256]),不是惰性初始化——这是为了让 matmul_fp8 内部循环零分支查表。
docs/FORMATS.md 是一份轻量级格式注册表,解决一个真实事件。FORMATS.md:8-16 开篇直白:
Two independent format proposals claimed the same internal ordinal in the same week: #465 (ZacharyZcR, E8/IQ3 container) and this repo's FP8-e4m3 passthrough branch both used
fmt=6. Neither was wrong — nothing before now told either author that "6" was spoken for. That's a process gap, not a code bug:QT.fmtis a plainintwith no enum declaration and no in-repo list of what's taken.
翻译:"两个独立的格式提案在同一周抢了同一个内部编号:#465 的 E8/IQ3 容器和本仓 FP8 直通分支都用 fmt=6。两个都没错——之前没有任何东西告诉任一作者'6 被占了'。这是流程缺陷,不是代码 bug:QT.fmt 是普通 int,没有 enum 声明,仓里也没有'已占编号'清单。"
FORMATS.md 的解决方案是两层:(1) 一份仓库内注册表(就是这份文件),每行验证当前 restack,记录 ordinal/name/weight bytes/scale layout/status/since;(2) 一个可选的自描述容器 stamp(__metadata__["colibri.fmt"]),让格式的身份不必依赖"靠社交协调把编号搞对"。FORMATS.md:59-69 的表把 fmt 0-8 全部列出,并明示"下一个空闲编号是 9",且"ID 只在合并进 dev 时才被认领,没有预订机制"。
stamp 的角色是确认" stamped 的格式身份"与"字节算术推断的格式"一致。colibri.c 的 qt_verify_fmt_stamp(colibri.c:1595 附近)走三步:
TRUST 信任 stamp:把 __metadata__["colibri.fmt"] 里 {tensor_name: format_name} 当真 VERIFY 用字节算术验证:weight-byte 数 + scale-byte 数 对 [O,I] shape 推断出格式 REFUSE 不一致就拒绝:绝不让一个 stamped 的 tensor 被静默按别的格式读
关键设计:"the container itself never carries a format ordinal"(FORMATS.md:51)——容器本身不带格式编号,格式由"权重字节数 + scale 字节数 对 shape 的字节算术"推断(qt_resolve_fmt 是权威读者)。stamp 只是额外确认或在两个已知字节冲突时解决。这意味着 ordinal 冲突(如 #465 vs FP8)在解析时不报错,要等 review 时才发现——这正是 FORMATS.md 注册表要堵的流程缺口。
stamp 的特殊角色在两个已知字节冲突(byte-collision)处:一个 stamped 的 fmt=8 tensor 在歧义 shape 下仍能被读成 fmt=8(覆盖未 stamp 情况的默认);而对每个 tensor,确认 stamped 身份与字节算术推断一致(TRUST-VERIFY-REFUSE)。这是 Colibrì "对语义有硬保证"在格式层的落地:绝不让一个 stamped tensor 被静默按别的格式读。
FORMATS.md 表里有一行特殊——int4-rans256-g0,它没有 ordinal。原因在 FORMATS.md:70:"No expected_bytes(O,I) formula exists, so byte-arithmetic inference is structurally impossible for this format"——这个格式的字节长度依赖数据(熵编码后的字节数随权重内容变),没有固定的 expected_bytes(O,I) 公式,所以字节算术推断结构上不可能。它的 stamp 是强制的(__metadata__["colibri.fmt"] 必须命名 int4-rans256-g0)。
熵编码的实现在三个文件:c/rans.h(1151 行,rANS 编解码器)、c/fse_coli.h(173 行,Colibrì 自家 FSE 变体)、c/cfse_pack.c(167 行,打包工具)。fse_coli.h:1-9 的头注释解释为什么用 order-0 模型:
COSA: rANS statico ordine-0 sui NIBBLE (16 simboli)... PERCHE' proprio questo: i pesi int4 sono statisticamente BIANCHI (misurato 2026-07-17: condizionali +0.000, MI tra tensori 0.0009-0.0018 bit), quindi l'ordine-0 e' GIA' ottimo — H=2.924 bit/peso, nessun modello di contesto puo' fare meglio, e' un teorema, non una scelta.
翻译:"int4 权重统计上接近白噪(2026-07-17 实测:条件熵增益 +0.000,张量间互信息 0.0009-0.0018 bit),所以 order-0 已经最优——H=2.924 bit/权重,没有任何上下文模型能做得更好。这是定理,不是选择。" 这就是为什么 Colibrì 用最简单的 order-0 rANS,而不是更复杂的有上下文模型——权重已经接近信息熵下界。
fse_coli.h:13-19 列出五条安全约束(这段代码碰权重,bug 会静默腐化输出):(1) 解码器绝不越界读(每次 fetch 边界检查);(2) 两个 rANS 状态最终必须回到 RANS_L(完整性封印,概率约 1-2^-46 检测截断/腐化);(3) 频率表必须精确求和到 4096,否则拒绝;(4) 不可压缩输入走 raw 模式(绝不膨胀);(5) 无 malloc(在调用者缓冲区工作)。这五条与第 1 章 03 节"对语义有硬保证"一脉相承——压缩格式碰权重,任何 bug 都会静默改模型,所以安全约束极严。
⚠️ 注意:
int4-rans256-g0当前状态是 "已合并,仅离线工具"——codecrans.h、writertools/repack_rans.py、validatortools/rans_verify.py都在,但引擎没有 decode 路径(没有任何编译进引擎的fmt常量,qt_resolve_fmt没有它的分支)。把当前引擎指向 repack 后的目录是不支持的(典型结果:字节算术不匹配的命名拒绝)。stamp 要等 PR 2(把 stamp-gated 分派接到推理之前)才有负载意义。这是 Colibrì 诚实研究的标志:新格式先落地工具链,验证完整性,再决定要不要进推理路径。
#ifdef 分派。matmul_i4 用 dot_i4f_avx512)、int8(matmul_q)、FP8(matmul_fp8 用 E4M3_LUT)、MXFP4(matmul_mxfp4 只走 Vulkan)。QT.fmt 是普通 int 无 enum,fmt=6 冲突事件催生注册表 + 自描述 stamp。下一章,我们离开"数据读取层",深潜 Colibrì 的权重 JIT 核心——
c/expert_store.h怎么用 lease 契约 + LRU + 学习型热存,把 19456 个专家按需流式加载到内存。