AI 模型与平台
微软的推理框架将 1 位大型语言模型带到本地设备

2024 年 10 月 17 日,微软宣布了 BitNet.cpp,这是一种推理框架,旨在运行 1 位量化的大型语言模型(LLM)。BitNet.cpp 是通用人工智能领域的一个重大进步,它使得 1 位 LLM 可以在标准 CPU 上高效部署,而无需昂贵的 GPU。这一发展使得 LLM 更加普及,使其可以在广泛的设备上使用,并为设备上的人工智能应用带来了新的可能性。
了解 1 位大型语言模型
大型语言模型(LLM)传统上需要大量的计算资源,因为它们使用高精度浮点数(通常为 FP16 或 BF16)来表示模型权重。这一必要性使得部署 LLM变得昂贵和耗能。
在其核心,1 位 LLM 使用极端量化技术来表示模型权重,仅使用三个可能的值:-1、0 和 1,因此得名“1.58 位”(因为它需要稍多于一位来编码三个状态)。
三元权重系统
概念
BitNet.cpp 中的 1 位量化是一种三元权重系统。BitNet 操作仅使用三个可能的值来表示每个参数:
- -1(负数)
- 0(中性)
- 1(正数)
这导致每个参数的存储需求约为 1.58 位,从而得名 BitNet b1.58。参数位宽的这种大幅减少导致内存使用和计算复杂度大大降低,因为大多数浮点乘法被简单的加法和减法所取代。
数学基础
1 位量化涉及通过以下步骤将权重和激活转换为其三元表示:
1. 权重二值化
二值化权重涉及将其集中在均值(α)周围,得到三元表示。转换的数学表示为:
Wf=Sign(W−α)
其中:
- W 是原始权重矩阵。
- α 是权重的均值。
- Sign(x) 如果 x > 0 返回 +1,否则返回 -1。
2. 激活量化
量化激活确保输入被限制在指定的位宽内:
其中:
- Qb = 2(b−1)2^{(b-1)} 是 b 位宽的最大量化级别。
- γ 是 x 的最大绝对值(表示为 ∣∣x∣∣∞)。
- ε 是一个小数,用于防止计算过程中的溢出。
3. BitLinear 操作
BitLinear 层用简化的操作替换了传统的矩阵乘法:
y=Wf×x^e×(Qbβγ)
其中:
- β 是一个用于最小化近似误差的缩放因子。
- γ 缩放激活。
- Q_b 是量化因子。
这种转换使得计算高效,同时保持模型性能。
性能影响
内存效率
三元权重系统大大降低了内存需求:
- 传统 LLM:每个权重 16 位
- BitNet.cpp:每个权重 1.58 位
这种降低转化为与传统 16 位模型相比约 90% 的内存节省,使得更大的模型可以在相同的硬件约束下运行。
1. 推理速度:在两个 CPU 上都更快
推理速度 表示为每秒处理的令牌数量。以下是观察结果的总结:
- 在 Apple M2 Ultra 上: BitNet.cpp 在较大的模型(30B)中实现了最高 5.07 倍 的加速,相比 Llama.cpp,其峰值速度为 593.43 个令牌每秒,这是一个 1.37 倍 的加速。对于更大的模型,如 3.8B 和 7B,BitNet.cpp 在所有规模上保持了超过 84.77 个令牌每秒 的速度,展示了其在不同规模上的效率。
- 在 Intel i7-13700H 上: BitNet.cpp 实现了更显著的速度改进。在 7B 模型大小上,BitNet.cpp 相比 Llama.cpp 提供了 惊人的 5.68 倍加速。对于较小的模型,如 125M,它处理了 389.08 个令牌每秒,这是 Llama.cpp 的 2.37 倍。
2. 能效:边缘设备的游戏规则改变者
提供的图表还包括 能耗比较,显示了每个令牌处理的能耗显著降低:
- 在 Apple M2 Ultra 上: BitNet.cpp 的能耗节省显著。对于 700M 模型,它每个令牌的能耗比 Llama.cpp 少 55.4%,从 0.314 降低到 0.140。这种趋势在更大的模型中继续,70B 模型显示了 70.0% 的能耗降低。
- 在 Intel i7-13700H 上: BitNet.cpp 为 700M 模型提供了 71.9% 的能耗节省,能耗从 1.367 降低到 0.384。虽然 Llama.cpp 中 70B 模型的能耗数据不可用,但 BitNet.cpp 仍然保持高效,其能耗为 17.33。
3. 超越人类阅读速度基准
这些图表中最有趣的见解之一是对 人类阅读速度 的引用,标记为 5-7 个令牌每秒。这条红线表明两种实现,特别是 BitNet.cpp,可以轻松超越人类阅读速度,甚至对于最大的模型:
- 在 Apple M2 Ultra 上,BitNet.cpp 超越了人类阅读速度的所有模型大小,70B 模型的最低速度为 8.67 个令牌每秒。
- 在 Intel i7-13700H 上,100B 模型仍然实现了 1.70 个令牌每秒,几乎达到人类阅读速度的下限,而所有较小的模型都超越了这一基准。
训练考虑
直通估计器(STE)
由于 1 位量化引入了非可微函数,训练涉及一种称为 直通估计器(STE) 的专用技术。在这种方法中,梯度通过非可微点保持不变。以下是 Python 中的一个简化实现:
class StraightThroughEstimator(Function): @staticmethod def forward(ctx, input): return input.sign() <p>@staticmethod def backward(ctx, grad_output): return grad_output
混合精度训练
为了在训练期间保持稳定性,采用了 混合精度:
- 权重和激活: 量化为 1 位精度。
- 梯度和优化器状态: 以更高精度存储。
- 潜在权重: 以高精度维护,以便在训练期间进行准确更新。
大学习率策略
1 位模型的一个独特挑战是,小更新可能不会影响二值化权重。为了缓解这一问题,学习率被增加,以确保与传统方法相比更快的收敛和更好的优化。
组量化和归一化
BitNet.cpp 引入了 组量化和归一化 以增强模型并行性。与其计算整个权重矩阵的参数,BitNet 将权重和激活分为多个组(G)。
这种分组允许在不需要额外的组间通信的情况下进行高效的并行处理,从而实现大规模模型训练和推理。
实现注意事项和优化
CPU 优化
BitNet.cpp 利用了多个低级优化来实现峰值 CPU 性能:
- 向量化操作: 利用 SIMD 指令高效地执行位操作。
- 缓存友好内存访问: 结构化数据以最小化缓存失误。
- 并行处理: 在多个 CPU 核心上有效地分配工作负载。
以下是 BitNet 中一个关键函数的示例,该函数实现量化和推理:














