本文档详细介绍了 BitNet.cpp 中实现的基于查找表的专门优化,旨在实现 1 位三元大语言模型的高效推理。TL1 (ARM) 和 TL2 (x86) 是平台特定的优化,可显著提高三元权重矩阵乘法的性能。有关整体内核生成系统的信息,请参阅内核生成系统。
TL1 和 TL2 是专门的矩阵乘法技术,它们通过基于查找表的计算,利用三元权重(-1, 0, 1)的特性。这些优化会根据目标平台自动选择。
这两种优化通过降低计算复杂性并利用平台特定的 SIMD(单指令多数据)能力,显著提高了推理性能。
平台特定的优化提供了显著的性能和效率提升。
| 优化 | 平台 | 性能提升 | 能耗降低 |
|---|---|---|---|
| TL1 | ARM64 | 1.37 倍-5.07 倍的加速 | 55.4%-70.0% |
| TL2 | x86_64 | 2.37 倍-6.17 倍的加速 | 71.9%-82.2% |
这些提升是通过精心的矩阵分区、基于查找表的计算以及平台特定的 SIMD 指令利用实现的。
TL1 和 TL2 都采用查找表(LUT)方法,通过预先计算可能的结果并通过查找索引访问它们,从而避免昂贵的乘法操作。优化过程包括:
实际实现因平台而异,以充分利用可用的硬件能力。
来源:utils/codegen_tl2.py76-189 docs/codegen.md29-49
TL1 通过系统性的分区方法优化 ARM 架构的矩阵乘法:
这种方法最大限度地提高了缓存局部性,并能有效利用 ARM SIMD 指令。
TL1 实现需要特定的参数约束:
来源:docs/codegen.md29-38 assets/tl1.png
TL2 优化是为支持 AVX2 的 x86 架构设计的,具有更复杂的分区策略:
TL2 实现需要特定的参数约束:
来源:docs/codegen.md40-49 assets/tl2.png utils/codegen_tl2.py190-267
TL1 和 TL2 的优化内核由 codegen_tl1.py(用于 ARM)和 codegen_tl2.py(用于 x86)动态生成。这种代码生成方法使得系统能够:
代码生成过程包括:
kernel_config.ini 以供后续参考来源:utils/codegen_tl2.py682-757 docs/codegen.md17-27
生成代码包括几种关键函数类型:
查找表构造函数:
three_lut_ctor<act_k>:为 3 值权重创建查找表two_lut_ctor<act_k>:为 2 值权重创建查找表基于表的实现函数:
three_tbl_impl_{pre}<batch_size, K3>:使用 3 值表处理矩阵two_tbl_impl{pre}<batch_size, K2>:使用 2 值表处理矩阵QGEMM 封装函数:
three_qgemm_lut_{pre}<BATCH_SIZE>:3 值计算的高级封装函数two_qgemm_lut_{pre}<BATCH_SIZE>:2 值计算的高级封装函数顶层 API 函数:
ggml_preprocessor:为计算准备查找表ggml_qgemm_lut:使用查找表的主矩阵乘法函数ggml_bitnet_transform_tensor:转换张量以与优化内核配合使用来源:utils/codegen_tl2.py107-189 utils/codegen_tl2.py279-528 utils/codegen_tl2.py532-624 utils/codegen_tl2.py626-672
查找表构建是 TL1 和 TL2 优化的关键组成部分。这些表根据权重模式预先计算所有可能的输出值。
特别是对于 TL2,查找表构建包括:
来源:utils/codegen_tl2.py76-96 utils/codegen_tl2.py106-267
TL2 计算路径利用 AVX2 SIMD 指令进行高效并行处理。
主要的 AVX2 操作包括:
_mm256_loadu_si256:加载 256 位向量_mm256_shuffle_epi8:执行表查找_mm256_add_epi16:并行添加 16 位整数_mm256_cvtepi16_epi32:将 16 位整数转换为 32 位整数_mm256_storeu_si256:存储 256 位向量来源:utils/codegen_tl2.py286-422 utils/codegen_tl2.py432-486
TL1 和 TL2 优化会根据目标架构由 BitNet.cpp 框架自动利用。典型的工作流程是:
setup_env.py 检测平台并生成相应的内核codegen_tl1.py 或 codegen_tl2.py 使用适当的参数创建优化内核kernel_config.ini不同模型的参数示例:
BitNet-b1.58-large (0.7B):
--BM 256,128,256 --BK 128,64,128 --bm 32,64,32--BM 256,128,256 --BK 96,192,96 --bm 32,32,32BitNet-b1.58-3B (3.3B):
Llama3-8B-1.58 (8B):
来源:docs/codegen.md18-27 utils/codegen_tl2.py683-694
TL1 和 TL2 优化是 BitNet.cpp 的核心组件,分别在 ARM 和 x86 平台上实现了三元权重模型的高效推理。通过使用基于查找表的计算和平台特定的 SIMD 指令,这些优化与传统方法相比,实现了显著的性能提升(高达 6.17 倍加速)和能效提升(高达 82.2% 的降低)。
动态代码生成系统使这些优化能够适应不同的模型架构,同时保持最佳性能。矩阵分区策略、查找表技术和 SIMD 加速的这种结合,使得 BitNet.cpp 成为在消费级硬件上运行 1 位三元语言模型的高效框架。