如何用8位字节高效打包三进制数

How to pack ternary numbers in 8-bit bytes

如何用8位字节高效打包三进制数

最近我被BitNet b1.58的三进制权重打包问题彻底吸引了。目标是让每个三进制位(trit)尽可能接近理论极限的1.58位存储空间。经过一番计算,我发现5个trit刚好能紧凑地塞进8位字节,效率高达99.06%。更妙的是,我找到了一种利用定点数乘法来替代传统取模运算的技巧,这让SIMD并行解包变得异常高效。这套方案不仅逻辑严密,而且已经成功应用在llama.cpp中,支持AVX2和ARM NEON指令集,为LLM权重的存储与加载提供了全新的优化思路。

将8位字节乘以3,就能轻松从结果的高两位提取出数字,这比在SIMD环境下使用取模运算方便得多。
  1. JoshTriplett

    这种方案能达到如此接近最优的效率,令人印象深刻。

    你确实可以用更少的位数超越 8 位存 5 个三进制位(1.6)的效率,比如 27 位存 17 个三进制位(约 1.588)。但一旦考虑到实际应用中需要向上取整为整字节,要想超越这个效率,至少得用到 176 位存 111 个三进制位(约 1.586),或者为了更快的解包速度,更实用的方案是 256 位存 161 个三进制位(约 1.59)。

    到了这个级别,即使你只有 27 字节的三进制位数据,更高效的编码方案也能节省大约 38-45MB(理论极限约 48MB),但这很可能以一定的速度损失为代价。

  2. lioeters

    Triplett 先生发了一篇关于三进制数的文章链接,这挺有意思的。(:

    这篇文章写得很好,图文并茂。文中描述的技术被 llama.cpp 用于运行像 BitNet b1.58 这样的语言模型,其权重是以三进制类型存储的。

    > ..其中 LLM 的每一个参数(或权重)都是三进制的 {-1, 0, 1}

    > 在延迟、内存、吞吐量和能耗方面显著更具成本效益

    这项技术的原始论文发表于 2024 年 2 月。(文章中也提供了链接)

    The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits - https://arxiv.org/abs/2402.17764

    然而,自那以后,只有少数其他模型使用了三进制权重。我的印象是,论文中未考虑的一些因素使得这项技术在实际应用中不如看起来那么可行。

  3. JKCalhoun

    尽管我对具体实现细节一无所知,但我喜欢幻想像 Apple 这样拥有自家芯片设计和硬件的公司,可以将这些三进制打包/解包操作放入硬件中,为每种操作提供一条指令(同时也提供使用三进制数执行各种矩阵卷积的指令),这样我们就能在设备上运行 LLM 了。

    我想随着最近出现的量化 Bonsai 模型,我们已经在手机等设备上看到了本地运行的 LLM……但我(再次,原谅我的无知)假设,如果我们能获得定制硬件指令,性能上还会有一个数量级甚至更多的提升空间。

  4. Diggsey

    这种打包/解包方案与直接使用查找表相比如何?

  5. jjgreen

    可能的应用场景:https://thedailywtf.com/articles/What_Is_Truth_0x3f_

同日更多故事

2026-07-21