LUT Tensor Core: A Software-Hardware Co-Design for LUT-Based Low-Bit LLM Inference

作者/机构: Zhiwen Mo (帝国理工学院 & 微软研究院), Lei Wang (北京大学 & 微软研究院), Jianyu Wei (中国科学技术大学 & 微软研究院), Zhichen Zeng (华盛顿大学 & 微软研究院), Shijie Cao (微软研究院), Lingxiao Ma (微软研究院), Naifeng Jing (上海交通大学), Ting Cao (微软研究院), Jilong Xue (微软研究院), Fan Yang (微软研究院), Mao Yang (微软研究院)

A1 主要贡献

本文针对大规模语言模型(LLM)推理中资源密集的问题,提出了一种名为LUT Tensor Core的软硬件协同设计,旨在高效执行基于查找表(LUT)的混合精度矩阵乘法(mpGEMM),以加速低比特LLM的推理。

核心问题与研究目标
- 问题:低比特量化(如INT4/2/1权重)是降低LLM推理成本的有效方法,但这引入了mpGEMM(低精度权重与高精度激活值相乘)计算。现有硬件(如GPU)不原生支持mpGEMM,通常采用基于反量化的间接方法,这会引入额外开销并成为性能瓶瓶颈。
- 目标:释放基于LUT的mpGEMM的全部潜力,解决现有软件和硬件LUT实现中的性能差距与挑战,包括高昂的表预计算和存储开销、对比特宽度组合支持有限、次优的分块形状以及缺乏专用指令集和编译支持。

核心创新点(LUT Tensor Core设计)
1. 软件优化
* 最小化表预计算开销:将预计算过程拆分为一个独立的算子,避免了在多个计算单元中的冗余计算。通过算子融合技术,将其与前一个算子合并,进一步减少内存访问开销。
* 减少表存储开销:通过将权重的{0, 1}重新解释为{−1, 1},利用了查找表的内在对称性,从而将表的大小减少了一半。
* 支持多样的激活精度:应用表量化技术,将预计算表中的元素量化为统一的低精度(如INT8),以支持不同的激活位宽(如FP16/8, INT8)并减小表宽度。

  1. 硬件定制

    • 简化的LUT单元:软件优化分担了硬件任务,使得LUT单元的设计更简洁,广播和多路复用器(MUX)的需求减半。
    • 灵活的位串行设计:采用类位串行电路,以适应mpGEMM中各种混合精度组合。
    • 优化的分块形状:通过设计空间探索,确定了一种“细长型”的分块形状,最大限度地提高了表的复用效率。
  2. 新的指令集和编译支持

    • LMMA指令集:扩展了传统的矩阵乘法累加(MMA)指令集,创建了基于LUT的矩阵乘法累加(LMMA)指令集,包含了操作数类型和形状等关键元数据。
    • 编译优化:利用LMMA指令中的形状信息,通过基于分块的深度学习编译器(如TVM, Roller)重新编译LLM工作负载,为新硬件生成高效的内核。

主要成果
- 与传统的Tensor Core相比,本文提出的LUT Tensor Core在功耗和面积上减少了4到6倍。
- 在mpGEMM性能上,LUT Tensor Core仅用16%的面积就实现了比传统Tensor Core更高的性能。
- 与最先进的纯软件LUT实现相比,LUT Tensor Core在通用矩阵向量乘(GEMV)中实现了高达1.42倍的加速,在GEMM中实现了72.2倍的加速。
- 与最先进的基于LUT的加速器相比,其计算密度和能效提高了1.44倍。
- 在端到端LLM推理(如BitNet和量化LLAMA模型)中,实现了2.06倍至5.51倍的推理加速,且面积和精度相当。

A3 背景知识与动机

2.1 LLM推理与低比特量化

LLM架构与计算核心。近年来,LLM主要依赖于仅解码器(decoder-only)的Transformer架构【66】,如图1所示。LLM由顺序的Transformer层构建,每层包含一个多头注意力块和一个前馈网络块。在这两个块中,主要的计算都是通用矩阵乘法(GEMM),或者在权重被量化的情况下是混合精度GEMM(mpGEMM)。LLM规模的扩大需要大量的硬件资源【21, 28】。例如,LLAMA-2-70B【65】仅模型权重(FP16格式)就需要140GB内存,远超现代GPU(如NVIDIA A100或H100)的容量,这对LLM的部署构成了巨大挑战。

图1:LLM中的仅解码器Transformer块。主要计算是GEMM操作(或带有权重 量化的mpGEMM操作)。
图1:LLM中的仅解码器Transformer块。主要计算是GEMM操作(或带有权重 量化的mpGEMM操作)。

低比特量化作为解决方案。为了降低LLM部署的推理成本,低比特量化已成为一种流行的方法【10, 12, 64, 76】。它通过降低模型数值表示的精度来减少内存占用和计算时间。在LLM量化中,权重 量化优于激活值量化【37, 39】,因为模型权重的值是静态的,可以离线量化。权重可以被量化到4位、2位,甚至1位。对于4位权重,训练后量化(PTQ)只会带来微小的精度损失【12, 64, 76】。近期的研究和实践表明,在相同的内存预算下,使用量化感知训练(QAT)的2位权重 量化在模型精度上优于4位【14, 42, 49】。BitNet进一步表明,从头开始训练具有1.58位(三元)甚至1位(二元)权重的模型,可以达到与16位模型相当的精度【44, 68】。ParetoQ【42】也报告称,考虑到硬件限制,2位量化在内存减少和加速方面展现出巨大潜力。

图2:(a) GEMM,(b) 带反量化的间接mpGEMM,(c) 用于低比特LLM推理的直接mpGEMM。
图2:(a) GEMM,(b) 带反量化的间接mpGEMM,(c) 用于低比特LLM推理的直接mpGEMM。

激活值的量化挑战。与权重不同,激活值是动态生成的,具有高方差,表现为动态离群值【10, 18, 73】。由于离群值的存在,将激活值量化到8位以下具有挑战性。不同的权重和激活位宽组合已在各种模型和场景中进行了探索【10, 14, 15, 19, 68】,这表明没有一种通用的解决方案适用于所有情况。

2.2 用于低比特LLM的基于LUT的mpGEMM

mpGEMM的需求与现有方法的局限性。权重和激活值的不同位宽导致了对混合精度GEMM(mpGEMM)的独特需求,例如INT4/2/1与FP16相乘,如图2所示。当前的商用LLM推理硬件,如GPU和TPU,缺乏对mpGEMM的原生支持,而是专注于具有统一输入格式的传统GEMM。基于反量化的mpGEMM通过将低精度权重提升到与高精度激活值匹配的精度来弥合这一差距【50, 69】。然而,这种方法引入了额外的反量化操作,并放弃了低精度计算带来的效率增益。

基于LUT的mpGEMM方法。基于LUT的mpGEMM是低比特LLM推理中一个越来越有吸引力的方法【26, 38, 45, 53, 71】。它预先计算高精度激活值和低精度权重之间的点积,然后将结果存储在查找表(LUT)中以便快速检索。它不是为所有可能的高精度和低精度值组合预计算一个巨大的表(例如,FP16 × INT4需要一个大小为(2^16 × 2^4)的表),而是以分块的方式组织计算。对于mpGEMM操作的每个小块(即每小组激活值),会专门为这些激活值预计算一个LUT,并在权重矩阵的各列之间复用。这种方法最小化了表的大小,并通过在计算过程中为每个块动态构建LUT来保持效率。图3展示了一个基础示例,其中一个小块由1×4的FP16激活值和4×N的INT1权重组成。激活向量长度为4,因此查找表大小为16。在这种情况下,每个长度为4的点积结果都可以通过简单的查表获得。该表可以复用N次,考虑到权重矩阵的大小,这是非常可观的。更大的激活向量或更高比特的权重需要相应更大的查找表。

图3:一个FP16激活值和INT1权重的朴素基于LUT的mpGEMM分块示例。通过预计算的表,一次查表可以替代一个4元素向量的点积。
图3:一个FP16激活值和INT1权重的朴素基于LUT的mpGEMM分块示例。通过预计算的表,一次查表可以替代一个4元素向量的点积。

图4:从LLAMA2-70B中提取的M0-M3形状的mpGEMM内核性能。W4A16表示INT4权重和FP16激活值。在A100 GPU上,基于LUT的软件内核(LUT-GEMM)性能不如基于反量化的内核(CUTLASS)。
图4:从LLAMA2-70B中提取的M0-M3形状的mpGEMM内核性能。W4A16表示INT4权重和FP16激活值。在A100 GPU上,基于LUT的软件内核(LUT-GEMM)性能不如基于反量化的内核(CUTLASS)。

2.3 当前基于LUT的解决方案中的差距

基于LUT的mpGEMM的潜力与挑战。基于LUT的mpGEMM因其在消除反量化和乘法、并通过简单的查表减少加法等方面的优势而前景广阔。然而,现有的软件和硬件实现面临着挑战和差距:

软件LUT内核的挑战。基于LUT的mpGEMM软件内核通常面临指令支持有限和内存访问效率低下的挑战。这些限制体现在两个方面:首先,GPU对查表操作的指令支持有限。最有效的可用指令prmt(permute)的宽度有限,无法在单条指令中完成整个查表操作,从而降低了吞吐量。其次,表的位置对性能有显著影响。将查找表存储在寄存器文件中,由于LUT方法的广播特性,会导致线程间大量数据重复,处理大表时会导致寄存器溢出。相反,将表放在共享内存中,可能会因warp内线程的随机访问而导致bank冲突,严重影响内存带宽。这些问题导致它们在现有LLM推理硬件(如GPU)上,与基于反量化的内核相比效果不佳。图4比较了文献【53】中基于LUT的mpGEMM内核与CUTLASS【50】中基于反量化的mpGEMM内核在A100 GPU上的性能。结果表明,基于反量化的内核始终优于基于LUT的内核。值得注意的是,当批量较大时,基于LUT的内核由于表访问开销而性能严重下降,表现差几个数量级。“Seg. Error”标注表示在LUT-GEMM【53】中观察到的段错误。

图5:传统LUT硬件的三个步骤。表的预计算和存储带来了沉重的开销。
图5:传统LUT硬件的三个步骤。表的预计算和存储带来了沉重的开销。

硬件LUT加速器的挑战。乍一看,定制的LUT硬件因其简单性(仅需寄存器存储表和多路复用器进行查找)而有望带来效率提升。然而,我们的研究表明,传统的LUT硬件设计未能实现这些增益。图5描绘了一个传统的三步式基于LUT的mpGEMM硬件解决方案:表预计算、查表和部分和累加。许多挑战和未被探索的设计方面显著影响了整体性能:(1)表的预计算和存储。预计算的表可能占用过多存储空间,产生面积和延迟开销,从而削弱效率增益。(2)位宽灵活性。支持各种位宽组合(例如,INT4/2/1 × FP16/FP8/INT8)可能会消耗过多的芯片面积。(3)LUT分块形状。次优的分块会增加存储成本并限制表的复用机会,从而影响性能。(4)指令和编译。基于LUT的mpGEMM需要新的指令集。然而,为标准GEMM硬件优化的传统编译栈可能无法高效地映射和调度新指令集,使得与现有软件栈的集成变得复杂。

A2 方法细节

LUT Tensor Core 设计

设计概览。我们引入了LUT Tensor Core,这是一种软硬件协同设计,旨在解决前述的效率、灵活性和集成挑战(§2.3)。图6概述了LUT Tensor Core的工作流程。与传统的基于硬件的LUT解决方案中表的预计算和存储引入显著硬件开销不同,LUT Tensor Core引入了基于软件的优化(§3.1)来优化表的预计算和存储:对输入激活张量的LUT表预计算通过算子融合执行,而输入权重张量则被重新解释以实现表存储优化。在硬件方面,基于LUT的Tensor Core微架构(§3.2)为mpGEMM处理提供了效率,并为不同位宽的数据类型提供了灵活性。为了将LUT Tensor Core集成到现有的深度学习生态系统中,LUT Tensor Core设计了LMMA指令集以暴露基于LUT的Tensor Core用于编程mpGEMM,并实现了一个编译栈来调度端到端的LLM执行(§3.3)。

图6:LUT Tensor Core 工作流程。
图6:LUT Tensor Core 工作流程。

3.1 基于软件的表优化

查找表大小问题。如§2所述,基于LUT的mpGEMM需要额外的表预计算过程和存储空间来存放预计算结果。朴素地看,对于一个长度为K的激活向量和W_BITS位的权重,预计算的点积表需要$(2^{W\_BITS})^K$个条目。对于每个激活元素,将其与W_BITS位权重相乘有$2^{W\_BITS}$种可能的结果,构成了该激活元素的预计算表。因此,对于一个长度为K的激活向量,预计算表有$(2^{W\_BITS})^K$个条目。图3展示了当 K=4, W_BITS=1时,查找表有$2^4$个条目。

位串行优化及其局限性。一种常用的优化是位串行(bit-serial)【27】,它将一个W_BITS位的整数表示为W个1位整数,并通过位移对1位整数进行乘法。这种范式可以复用1位上的预计算表,因此将表大小减小到$2^K$。然而,即使是这个减小后的表大小也带来了显著的硬件开销。LUT Tensor Core提出了数据流图(DFG)转换和算子融合来消除表预计算开销,以及权重重解释和表量化来减小表的大小。

3.1.1 通过DFG转换和算子融合预计算查找表

预计算的冗余问题。基于LUT的mpGEMM需要在后续的查找操作之前,将高精度激活值与一组低精度权重之间的点积预计算成一个表。传统实现将预计算单元放置在LUT单元旁边,为每个LUT单元即时执行表预计算。这种方法由于冗余而引入了显著的硬件成本,因为多个预计算单元经常执行相同的操作。以OPT-175B中的[4096,12288]×[12288,12288] GEMM为例,一个朴素的直接预计算单元在一个大小为N=4的LUT Tensor Core阵列内共享一个表。在这种设置下,每个表在整个过程中被不同的LUT单元重复计算(12288/4 = 3072次),带来了巨大的计算负担。

解决方案:DFG转换与算子融合。为了解决这种低效率问题,我们首先转换DFG,将预计算拆分为一个独立的内核,从而实现一次性预计算并广播到所有LUT单元。这一修改将预计算开销减少了数百倍,使其可以由现有的向量单元(如CUDA Cores)处理。为了分摊广播引入的额外内存流量,LUT Tensor Core将预计算算子与其前一个算子融合,利用其逐元素计算的模式,如图6所示,详见§3.3.2。这种融合减少了内存访问,并将预计算开销降至几乎为零,如§4.6.1中的评估所示。

图7:将0,1重新解释为-1,1以实现对称性,从而将表大小减半。
图7:将0,1重新解释为-1,1以实现对称性,从而将表大小减半。

3.1.2 通过权重重解释实现表的对称化

表大小的存储和访问成本。预计算一个长度为K的激活向量所需的$2^K$大小的表,在表存储和表访问方面都带来了显著的成本。为了解决这个问题,我们观察并利用了整数表示的对称性。

权重重解释方法。假设原始量化的权重表示为:

公式1
公式1

其中,$x_i$是实值权重,$s_x$是缩放因子,$z_x$是偏置,而$q_i$是n位整数表示。我们的目标是映射$q_i$,使其围绕零对称,同时保持数学等价性。为此,需要同时调整$s_x$和$z_x$。当将一个无符号整数$q_i$映射为关于零对称时,需要进行以下调整:
公式2
公式2

这个过程如图7所示,展示了一个转换4位无符号整数的例子。通过计算$s'_x$和$z'_x$,$q'_i$从{0, 1, . . . , 14, 15}被映射到{−15, −13, . . . , 13, 15},实现了关于零的对称。

点积的等价性。接下来,点积可以表示为:

公式3
公式3

其中,$DP$是点积,$a_i$是激活值。因此,量化过程与之前保持相同,只是增加了一个离线映射步骤,将权重的$s_x(q_i − z_x)$映射到$s'_x(q'_i − z'_x)$。考虑一个二元表示$b_3b_2b_1b_0 = 0100$与变量a, b, c, d之间的点积。最初,二元值{‘0’,‘1’}被解释为{0,1}。假设$z_x = 2$且$s_x = 1/2$。计算过程如下:
公式4.1
公式4.1

重解释后,二元值{‘0’,‘1’}被重新映射以表示{-1,1},并调整缩放因子$s'_x = 1$和偏置$z'_x = 0$。更新后的计算为:
公式4.2
公式4.2

很明显,这两个表达式在数学上是等价的。

利用对称性减少表大小。由于表条目关于零对称,查找表表现出类似于奇函数的性质。假设索引是一个4位值$b_3b_2b_1b_0$,朴素的查找表(LUT)实现需要$2^4 = 16$个条目。然而,可以观察到以下类似于奇函数的性质成立:

公式5
公式5

因此,LUT中的条目数量可以减少到原来的一半,即$2^{4−1} = 8$,方程变为:
公式5.1
公式5.1

这里,∼表示按位非(NOT)操作。因此,给定一个长度为K的激活向量,表对称化可以将表长度减少到$2^{K−1}$。表的大小不仅影响预计算阶段所需的计算操作,还影响多路复用器的大小。此外,表中的每个条目还需要广播到N个PE(通常为64或128)进行点积计算。这样的优化显著减少了广播开销和MUX选择开销。注意,公式5中的$b_3b_2b_1b_0$是静态权重。位级取反可以离线完成,以简化设计,如下所示:
公式6
公式6

这种简化可以消除电路设计中的取反操作,具体将在§3.2中介绍。

3.1.3 表量化

高精度激活值带来的问题。对于像FP32或FP16这样的高精度激活值,我们采用表量化技术,将预计算的表元素转换为更低、统一的精度,如INT8。这种方法通过支持多种激活精度提供了灵活性,并通过减小表大小提高了效率。

表量化的优势。与传统的激活值量化相比,表量化允许在表预计算阶段进行更动态、更细粒度的量化。例如,对于一个包含4个激活元素的分组,我们为每个包含8个预计算点积的表执行量化。我们的经验性实验(在§4.6.2中讨论)表明,INT8表量化在保持高精度的同时简化了硬件设计,从而验证了我们方法的有效性。

图8:带位串行的优化LUT单元。
图8:带位串行的优化LUT单元。

图9:LUT-based Tensor Core的细长型MNK分块。LUT-based Tensor Core需要一个较大的N(例如64/128)以最大化表的复用,同时需要一个适当大小的K(例如4)以实现成本效益高的表大小。
图9:LUT-based Tensor Core的细长型MNK分块。LUT-based Tensor Core需要一个较大的N(例如64/128)以最大化表的复用,同时需要一个适当大小的K(例如4)以实现成本效益高的表大小。

3.2 基于LUT的Tensor Core微架构

3.2.1 采用位串行的简化LUT单元设计

软硬件协同的优势。通过利用基于软件的预计算融合和权重重解释,定制每个独立LUT单元的硬件成本得以降低。图8展示了我们的LUT单元设计。与直接设计相比,存储LUT所需的寄存器以及与表广播和多路复用器相关的成本减少了一半。如公式6所示,可以从每个LUT单元中消除位级取反电路,以进一步提高效率。为了支持权重的灵活位宽,我们采用了位串行电路架构【27, 74】。这种设计将权重的位宽映射到W_BIT个周期,从而能够以串行方式处理各种位宽。

3.2.2 细长的LUT分块

分块维度M, N, K的重要性。维度M、N和K的选择对于基于LUT的Tensor Core的性能至关重要,因为基于MAC的Tensor Core的传统选择可能导致性能次优。如图9所示,一个MNK分块的LUT阵列由M个表、K组权重和M*N个基于MUX的单元组成。每个表包含M × $2^{K−1}$个条目,每个条目广播到N个MUX单元。每组分组的二元权重包含K位,必须广播到M个MUX单元,作为MUX的选择信号。总表大小由以下公式给出:
总表大小 = $M \times 2^{K-1} \times LUT\_BIT$
分组二元权重的大小由以下公式给出:
总权重大小 = $M \times K \times W\_BIT$
其中LUT_BIT是LUT条目的位宽,W_BIT是权重的位宽。

图10:LUT-mpGEMM的编译流程。整体数据流类似cutlass [50]。采用细长分块以实现更好的数据复用。
图10:LUT-mpGEMM的编译流程。整体数据流类似cutlass [50]。采用细长分块以实现更好的数据复用。

细长分块的优势。基于LUT的Tensor Core受益于细长的分块形状。当K很大时,表条目的数量呈指数增长,而N决定了每个表条目可以被多少个MUX单元复用。最优配置需要一个平衡的M、一个较大的N和一个较小的K,这与传统的GPU Tensor Core不同。此外,分块形状影响I/O流量,更接近方形的分块配置可以减少数据移动开销。在§4.2.2中,我们探索了MNK分块的设计空间,证实了细长的分块形状能产生更高的效率。

3.3 指令和编译

集成策略。为了将LUT Tensor Core集成到现有的GPU架构和生态系统中,我们引入了一个新的指令集,并基于分块式DNN编译器【5, 62, 84】开发了一个编译栈。

3.3.1 基于LUT的MMA指令

LMMA指令定义。为了能够使用LUT-based Tensor Core进行编程,我们定义了一组LMMA指令,作为GPU中MMA指令集的扩展。
lmma.{M}{N}{K}.{A_dtype}{B_dtype}{ACC_dtype}{D_dtype}
上述公式显示了LMMA指令的格式,它与MMA类似。具体来说,M、N和K表示LUT-based Tensor Core的形状。A_dtype, B_dtype, ACC_dtype, 和 D_dtype 分别表示输入、累加器和输出的数据类型。与MMA指令类似,每个LMMA指令被调度到一个warp的线程上执行。每个warp计算公式 D[m, n] = A[m, k] × B[k, n] + C[m, n]

3.3.2 编译支持和优化

实现框架。我们在TVM【5】、Roller【84】和Welder【62】的基础上实现了LUT-mpGEMM内核生成和端到端LLM编译。具体来说,编译栈包含以下关键方面。图10展示了一个在LLAMA模型上的编译示例:

图11:沿K轴对基于LUT的点积单元进行设计空间探索。通常K=4是最佳选择。
图11:沿K轴对基于LUT的点积单元进行设计空间探索。通常K=4是最佳选择。

A4 实验环境

A5 实验结果

4.2 硬件PPA基准测试

4.3 mpGEMM内核级评估

4.4 模型端到端评估

4.5 与先前工作的比较

4.6 软件优化分析

Roofline分析

A6 结论

本文提出了LUT Tensor Core,这是一种基于LUT计算范式的软硬件协同设计,旨在为低比特LLM加速实现高效的混合精度GEMM操作。LUT Tensor Core不仅提升了性能,还为各种精度组合提供了广泛的灵活性,并且能够无缝集成到现有的加速器架构和软件生态系统中。

未来工作展望
- 低比特训练与微调:将LUT Tensor Core的应用从推理扩展到训练的整个流程,需要应对反向传播中更高精度的计算需求,并可能需要新的训练算法和硬件创新。
- 长上下文注意力与KV缓存量化:探索在长上下文场景中,将LUT Tensor Core应用于注意力计算和KV缓存量化,以解决注意力机制成为瓶颈的问题。
- 更灵活的数据格式支持:将LUT-based方法扩展到支持浮点(FP)权重和非整数权重(如三元权重),以进一步增强其通用性。

方法细节中的引用汇总

在论文的“方法细节”章节(第3节),作者引用了以下关键的编译器和框架来支持其编译栈的实现:
- [5] TVM: end-to-end optimization stack for deep learning (Chen et al., 2018): 被用作代码生成的基础。LMMA指令作为内联函数(intrinsics)在TVM中注册,以便生成最终的内核代码。
- [62] Welder: Scheduling Deep Learning Memory Access via Tile-graph (Shi et al., OSDI 2023): 被用于DFG转换和算子融合。作者将预计算操作实现为一个图优化过程,并利用Welder将该算子与前序算子融合,以减少内存开销。
- [84] ROLLER: Fast and efficient tensor compilation for deep learning (Zhu et al., OSDI 2022): 被用于LUT-mpGEMM的调度。作者在Roller的rTile接口中注册了LMMA指令的形状和分块计算逻辑,以生成最优的调度配置。