Rust in Everything
基于 candle-core 0.11.0

动手

前面各部分读的是 candle 的源码。这一部分反过来:只用标准库和 half,把推理主线里「读 GGUF、取出量化权重、反量化、量化点积」这一段自己写一遍。写完之后让 candle 处理同样的数据,两边逐字节、逐位对一对。

  1. 写一个迷你 Q8_0 量化:库 325 行代码。Q8_0 每 32 个值一块,一个 f16 scale 加 32 个 i8;量化结果和 candle 的 BlockQ8_0 逐字节相同,SmolLM2 的 211 个 Q8_0 张量反量化和 QTensor::dequantize 逐位相同,标量点积和 vec_dot_unopt 逐位相同、和 neon 版差在累加顺序。同一次矩阵乘向量,CPU 的 QMatMul 先量化输入,Metal 不量化,误差差四个数量级。读头部时测出 candle 在 BufReader<File> 上调了 98384 次 lseek,general.alignment = 0 会让它 panic。最后一张表列出 candle 多出来的东西(SIMD、K-quants、Metal 内核、QMatMul 的三种形态、分配上限)和讲它们的页。
flowchart TB
  gguf["GGUF 头部"] --> raw["张量原始字节"]
  raw --> blk["BlockQ8_0"]
  blk --> deq["反量化"]
  blk --> dot["量化点积"]
  deq --> cmp["和 candle 逐位比"]
  dot --> cmp

💬 关联讨论

发起讨论
加载中...