文章标题:QFactory: Accelerating Quantized Large Language Model Serving with Qtile Graphs
作者/机构:Qihao Zhang, Mingshu Zhai, Rui Sun, and Jidong Zhai, Tsinghua University
核心问题:现有的量化大语言模型(QLLM)推理系统通常依赖于一种静态的“即时执行”(eager execution)范式来处理反量化操作。这种方法在遇到量化值时会立即将其转换,从而限制了更广泛的优化可能性,导致性能次优。特别是对于非对称和分组的细粒度量化算法(如GPTQ),额外的反量化计算和内存开销成为新的性能瓶颈。现有深度学习编译器(如BitBLAS)在编译这些复杂的量化核时性能会显著下降。
研究目标:本文旨在解决现有系统在处理量化核中额外反量化操作时效率低下的问题。目标是设计一个高效的编译框架,能够生成高性能的量化核,充分利用潜在的优化空间,提升QLLM的推理服务速度。
创新点/主要贡献:
本文提出了QFactory,一个专为生成高性能量化核而设计的编译框架。其核心贡献如下:
1. 提出Qtile抽象:设计了一种名为Qtile的新颖抽象,它是一个带有量化属性标注的张量表达式。Qtile通过“映射函数”和“组模式”两种标注,统一表示了各种量化算法和参数共享范围,为后续优化奠定了基础。
2. 图级Qtile计算转换:基于Qtile抽象,QFactory将传统的张量计算图转换为Qtile图(QGraph)。通过在QGraph上传播Qtile,推导出数学上等价的多个QGraph,从而探索更广泛的图转换机会,实现反量化操作的延迟执行和灵活布局。
3. 算子级Qtile调度:针对QGraph中的每个Qtile,QFactory采用差异化的Qtile调度策略,为不同的张量块(权重、激活、量化参数)在GPU内存层级中选择最优的数据加载路径,最大化数据复用和内存带宽利用率。
4. 高效的代码生成与自动调优:QFactory采用基于模板的核生成方法以利用指令级并行,并开发了一个基于机器学习的超参数选择器,以高效地自动调优和选择最佳核配置。
实验结果表明,QFactory在单个核性能上比现有系统平均提升1.66倍,并且在集成到最先进的LLM服务系统中时,能够带来1.23倍的端到端生成速度提升。
大模型推理的内存瓶颈。尽管大语言模型取得了显著进展,但其巨大的资源消耗为模型服务带来了巨大挑战。当前LLM以自回归方式生成token,导致批量大小(batch size)较低,从而形成内存密集型(memory-bound)的计算场景【【30, OmniQuant: Omnidirectionally calibrated quantization for large language models, 2024, ICLR】, 【42, Quantllm: Accelerating the serving of large language models via fp6-centric algorithm-system co-design on modern gpus, 2024, USENIX ATC】】。
量化作为解决方案。研究发现,量化是一种有前途的解决方案,可以减少LLM的大量内存占用并加速解码,尤其是在边缘设备等资源受限的环境中。为了在较低位宽下保持良好的准确性,研究人员开发了多种量化算法【【10, GPTQ: accurate post-training quantization for generative pre-trained transformers, 2022, CoRR】, 【11, OPTQ: accurate quantization for generative pre-trained transformers, 2023, ICLR】, 【30, OmniQuant: Omnidirectionally calibrated quantization for large language models, 2024, ICLR】】。这些算法提出使用各种自定义数据类型来存储压缩后的权重,例如x位整数【【17, Quantization and training of neural networks for efficient integer-arithmetic-only inference, 2018, CVPR】】、NormalFloat【【7, Qlora: Efficient finetuning of quantized llms, 2023, NeurIPS】】,甚至是由查找表定义的任意定点位宽类型【【29, LUT-GEMM: quantized matrix multiplication based on luts for efficient inference in large-scale generative language models, 2024, ICLR】】。它们还引入了额外的数据存储,如缩放因子和零点,作为量化参数以帮助恢复原始权重的大小。
非对称W4A16量化示例。以GPTQ【【10, GPTQ: accurate post-training quantization for generative pre-trained transformers, 2022, CoRR】】中采用的非对称W4A16量化为例。为了量化模型中的一个半精度权重张量w,min(w)和max(w)被映射到目标数据范围的下界和上界,即INT4数据类型中的-8和+7。张量w中的其余值则进行线性映射。具体来说,量化过程可以表示为:
其中,scale是一个半精度的缩放因子,zero是一个INT4的零点。它们是与张量w关联的辅助参数。CF2I函数表示从半精度实数值到整数的类型转换,通常采用四舍五入的方法实现。
反量化过程。在量化LLM上进行推理时,量化的模型权重需要被反量化回原始数据类型进行计算。上述量化方法的反量化过程可以表示为:w = (w_quant - zero) * scale。可以很直接地验证,除了在实数和整数数据类型之间转换时发生的精度损失外,上述方程能够恢复原始的权重值。
量化方法的多样性。为了在模型准确性、压缩率和算法复杂性之间取得平衡,研究人员提出了一系列具有可变配置的量化方法,包括对称/非对称量化(带或不带零点)、量化数据类型和量化粒度(共享相同量化参数的数据范围)。这种广泛的多样性给高效的量化核生成带来了巨大挑战。
深度学习编译器的优化层次。深度学习编译器通过在不同层级进行优化来加速模型执行。现有工作可归纳为以下两类:
* 图级转换:深度学习模型可以表示为张量计算图,其中顶点对应于算子,边表示张量数据在这些算子之间的流动。先前的工作【【16, Optimal kernel orchestration for tensor programs with korch, 2024, ASPLOS】, 【18, TASO: optimizing deep learning computation with automatic generation of graph substitutions, 2019, SOSP】, 【25, Dnnfusion: accelerating deep neural networks execution with advanced operator fusion, 2021, PLDI】, 【37, PET: optimizing tensor programs with partially equivalent transformations and automated corrections, 2021, OSDI】, 【45, EINNET: optimizing tensor programs with derivationbased transformations, 2023, OSDI】】探索了计算图上的转换空间以寻找最优的核映射。这些系统主要关注图级的代数变换,并通过核融合或选择利用率更高的核来获得更好的性能。它们利用像TVM【【4, TVM: an automated endto-end optimizing compiler for deep learning, 2018, OSDI】】这样的底层张量程序编译器进行代码生成。
* 算子级内存调度:其他编译器【【31, Welder: Scheduling deep learning memory access via tile-graph, 2023, OSDI】, 【46, ROLLER: fast and efficient tensor compilation for deep learning, 2022, OSDI】】通过张量分块(tensor tile)抽象来关注高效的算子融合和核生成,并应用内存调度来提高内存效率。BitBLAS【【39, Ladder: Enabling efficient low-precision deep learning computing through hardware-aware tensor transformation, 2024, OSDI】】将这种分块抽象扩展到支持低精度数据格式,从而能够编译量化的深度学习模型。然而,这些方法仅对模型权重张量应用调度优化,并急切地执行反量化。因此,它们难以有效处理带辅助参数的量化模型的特殊需求,这些模型需要更灵活的反量化策略和更细粒度的内存优化才能达到最佳性能。
QFactory的整体工作流程。图2展示了QFactory框架的概览。在入口处,QFactory接受用户提供的量化程序作为输入,随后通过将计算图中的某些张量替换为新设计的Qtile抽象(§3.2),将其转换为Qtile图(Q-graph)。对于常见的量化算法,QFactory提供了Q-graph的骨架模板,用户只需定义关键设置,如位宽、数据类型和量化算法。或者,用户也可以直接提供由Qtiles和标准张量块组合构建的Q-graph,以获得更大的灵活性。
核心优化步骤。此后,QFactory执行Qtile计算转换(Qtile Computation Transformation,§4),通过在Q-graph中的算子上传播Qtiles来探索Q-graph的转换空间,生成保证数学等价性的Q-graph候选。然后,QFactory分析这些候选图,并根据需要插入反量化操作。接着,为每个Q-graph生成底层代码。为了优化整体内存带宽利用率,QFactory采用差异化Qtile调度(Differentiated Qtile Scheduling,§5)来确定Qtiles的最佳数据放置和加载策略,以最大化数据复用。最后,QFactory应用基于模板的核生成(§6.1)以实现指令级并行,并开发了一个基于机器学习的核选择器(§6.2),以加速最优核配置的选择。
Qtile作为核心抽象。QFactory为量化程序提出了一种新颖的抽象,称为Qtile,它在量化程序和高效核实现之间起着关键的桥梁作用。本质上,Qtile是一个扩展了量化属性标注的张量。使用“Qtile”而非“Qtensor”是因为在GPU等并行设备上,张量是以更小的切片或数据块(data tiles)进行计算的。这个术语与Welder【【31, Welder: Scheduling deep learning memory access via tile-graph, 2023, OSDI】】中引入的tile-graph抽象保持一致。
Qtile的两种标注。Qtile通过两种类型的标注扩展了张量:映射函数(mapping function)和组模式(group pattern),分别代表量化算法和量化参数共享的范围。
映射函数与量化参数。映射函数编码了反量化所需的所有详细信息,包括量化算法及其辅助参数。它指定了压缩权重的存储格式(例如,W4A16量化中的4位整数)、压缩方法(例如,简单的类型转换或非对称量化),以及任何额外量化参数的存储格式。Qtile没有将这些量化参数视为独立的数据块,而是将它们直接整合到其扩展标注中。这使得QFactory能够利用权重张量与其关联量化参数之间的关系,从而创造数据复用的机会。理论上,通过将映射函数定义为查找表,Qtile可以表示任意的量化格式。这种灵活性使得Qtile能够处理非传统的量化方法,确保与多样化的应用方案兼容。
量化组模式。量化通常以特定的粒度进行。张量元素被分成组,在组内独立应用缩放或其他操作。这种细粒度的方法能够实现更好的近似并保留张量的值。在每个量化组内,量化参数是共享的,这使得组模式对于实现数据复用至关重要。Qtile在其标注中包含了组模式信息,并提供了四种常用的组模式属性,从粗粒度到细粒度依次为:张量(tensor, t)、通道(channel, c)、块(block, b)和单个元素(individual, i)。
Qtile示例说明。我们通过图3中的一个非对称4位量化(采用块组模式)的Qtile来说明。在这个例子中,量化权重张量被划分为3×2的块,每个块都关联一对量化参数:一个4位整数零点和一个16位半精度缩放因子。为了反量化权重张量中的一个值,需要执行计算 (W - zero) × scale。例如,权重矩阵第二行第三列的元素反量化为 (6 - 2) × (-0.4) = -1.6。
Qtile的接口作用。通过Qtile,QFactory为用户提供了一个统一的接口,用于定义现有的量化算法或设计新的算法。通过将量化信息直接嵌入到张量中,Qtile平衡了通用性和效率,有助于更广泛的编译优化以提高核性能。
将计算图转换为Qtile图(QGraph)。借助Qtile抽象,QFactory将计算图中的某些张量替换为量化张量,从而形成一个Qtile图(QGraph)。因此,图中的算子现在可能接收Qtiles和普通张量块作为输入。在现有方法中,这类算子是即时执行(eagerly executed)的,只要遇到量化张量就立即执行反量化操作。这种策略导致了对QGraph的僵化、静态的翻译,限制了进一步优化的潜力。
延迟反量化操作。相比之下,QFactory为QGraph引入了一个编译过程,通过执行Qtile计算转换将反量化操作推迟到后续阶段。通过这些转换规则,Qtiles可以主动参与算子计算,并生成新的Qtiles作为输出。这样一来,Qtiles在整个图中传播,创建出等价的QGraph。
输入: GQ: 量化程序的初始Qtile图。
输出: S: 发现的等价QGraph集合。
1 Function QtilePropagate(GQ):
2 S ← ∅ ;
3 Q ← List() ;
4 Q.Push_Back(GQ) ;
5 while Q.Size() > 0 do
6 gQ ← Q.Pop_Front() ;
7 S.Insert(gQ) ;
8 for Op ∈ gQ do
9 ITiles ← Op.GetInputTiles() ;
10 OTile ← Op.GetOutputTile() ;
11 if ! OTile.IsQtile() and ITiles.hasQtile()
and CanCompute (Op, ITiles) then
12 NTile ← ComputeQtile(Op, ITiles) ;
13 g′Q ← Replace(gQ, OTile, NTile) ;
14 if g′Q ∉ S and g′Q ∉ Q then
15 Q.Push_Back(g′Q) ;
16 return S ;
搜索所有可能的QGraph候选。QFactory提出了Qtile传播搜索(Qtile Propagation Search)用于图级优化,生成所有可能的QGraph候选,如算法1所述。给定一个Qtile图,QFactory枚举图中的所有算子(第8行),并确定是否可以对每个算子应用Qtile计算转换。如果算子的输入块(可能包括Qtiles和普通块)满足转换规则,它们将被 ComputeQTile 函数处理以产生一个输出Qtile(第12行)。这个输出Qtile随后替换图中的原始输出块,从而产生一个新的QGraph。传播过程在新生成的QGraph上重复进行。QFactory采用广度优先搜索(breadth-first search)方法来迭代地探索所有可能的QGraph。最终,返回一个包含所有备选QGraph的集合,该集合将传递给后续的优化阶段。
核心函数ComputeQtile。该算法的关键组成部分是ComputeQtile函数,它以算子及其输入块为参数,并产生一个与原始输出块相等的Qtile表达式。由于Qtiles是带有额外标注的量化张量,这些标注必须在计算中予以考虑。Qtile计算涉及两种类型的转换:组模式转换(group pattern transformation)和映射函数转换(mapping function transformation),分别对应Qtile设计中的两种标注。
组模式在计算中的演变。对Qtiles的计算会导致组模式的转换。例如,当一个元素级二元算子(如add、mul)应用于一个普通块和一个量化Qtile时,来自Qtile操作数的组模式会被广播到另一个操作数,导致输出Qtile采用与输入Qtile相同的组模式。
处理多个Qtile输入。在某些情况下,算子会应用于两个Qtile输入。在这种情况下,QFactory必须检查输入Qtiles的组模式是否可以转换为一个共同的模式。例如,当两个具有不同块步长(W1, H1)和(W2, H2)的块分组Qtiles相加时,QFactory计算块步长的最大公约数(gcd),以确定一个两个Qtiles都可以转换到的共同组模式。在这种情况下,会确定一个更细粒度的组模式 (gcd(W1, W2), gcd(H1, H2))。然后,QFactory将这些Qtiles的组模式修改为共同模式,并相应地广播关联的量化参数。这确保了不同的Qtiles能够以相同的组模式进行计算。
映射函数的传播与演变。由于映射函数与Qtile张量的反量化值密切相关,因此随着Qtiles通过各种算子的传播,Qtiles的映射函数也会演变。
线性映射函数示例。以线性映射函数为例,其中Qtile中的每个元素都通过缩放因子和零点偏置进行量化。一个线性量化的Qtile中的反量化值可以表示为 (X_sz)_i,j = s * X_i,j + z,其中 X_i,j 是低精度格式的压缩张量值,s和z分别代表缩放因子和偏置,它们在整个量化组内共享。
加法算子的映射函数转换。表1展示了将元素级加法算子应用于不同类型Qtiles时产生的输出Qtile表达式。操作数可能包括非量化的普通块(X)、带缩放因子的Qtiles(X_s)、带偏置偏移的Qtiles(X_z),或两者兼有(X_sz)。Qtile计算转换将传统的张量计算扩展到了更广泛的量化张量运算领域。从表1可以看出,量化参数可以在不同操作数之间重新分配。例如,将A_z与非量化块B相加可以转换为A + B_z,偏置偏移z1从块A的量化参数转移到了块B的量化参数。此外,在A_z1与B_s2z2相加的情况下,结果可以转换为一个Qtile (B_s2z1+z2) 和一个普通张量块 (A) 的和。这种转换在生成代码时最小化了所需的反量化操作数量,从而提供了潜在的性能改进。
矩阵乘法算子的映射函数转换。接下来,我们在表2中展示了矩阵乘法算子的Qtile转换表。由于包含了沿K维度的归约操作,Matmul算子的转换规则产生了更复杂的结果表达式。结果中引入了矩阵JX,它表示一个与X形状相同且所有元素均为1的矩阵。
转换带来的性能优势。为了说明这些转换带来的潜在好处,以Qtiles A_z1和B_z2的乘法为例。如表中所示,输出是四个Qtiles的总和。第一个分量AB是一个普通块,不需要反量化。第二和第三个分量涉及与J矩阵的矩阵乘法。虽然这些分量是需要反量化的Qtiles,但J矩阵的全一特性减小了Qtile的形状。由于JA矩阵中的所有行都是相同的,乘积JAB继承了这一特性。因此,反量化可以仅对(JAB)_z1的第一行执行,然后将结果值广播到其余行。因此,由于J矩阵的归约特性,反量化开销得以降低。最后一个分量(JAJB)_z1z2 = (JAB)_z1z2K是一个所有值都相同的矩阵,可以高效地表示和计算为单个标量。总而言之,计算成本高昂的反量化操作数量显著减少,从而提高了性能。
量化格式的转换。此外,Qtile计算转换允许在不同量化格式之间进行切换。在A和B_s2z2的矩阵乘法中,得到的Qtile表达式仅由对称量化的Qtiles(无零点)组成。由于不同的映射函数可能产生不同的反量化开销,Qtile转换通过用更轻量级的替代方案替换繁重的反量化操作,从而扩展了优化空间。
量化参数的内存访问开销。在图级Qtile转换之后,生成的QGraph通过插入反量化操作来执行。执行反量化时,Qtiles需要从最低的GPU内存加载到最高的寄存器。以前的DNN编译器只关注模型权重张量的内存访问,忽略了量化模型中引入的关联量化参数带来的开销。对于Qtiles,调度需要进一步考虑,以确保量化参数的充分复用。
GPU内存层级结构。现代GPU在内存系统中配备了分层和多路径的数据加载机制。如图4所示,GPU通常至少有四个不同的内存层级,从最低的DRAM内存到最高的寄存器文件。内存资源分配在不同范围的处理单元上,每一层提供不同的可见性。GPU内存和L2缓存是全局可见的,并在整个GPU上共享,而上面两层则特定于每个流式多处理器(SM)。用户可配置的L1缓存,称为共享内存(shared memory),对线程块内的所有线程可见,而寄存器则对单个线程私有。
数据传输路径。要在GPU上执行计算,数据必须从DRAM传输到寄存器,途经中间内存层。线程块级的共享内存允许在L1级别上显式控制数据,从而创建了两类数据路径,即全局-共享路径(global-shared path)和共享-寄存器路径(shared-register path),如图4所示。其他中间缓存层对程序员是透明的。然而,CUDA提供了一种机制,通过称为缓存操作符(cache operators)【【27, Parallel Thread Execution ISA Version 8.5, 2024, NVIDIA】】的PTX级属性来控制某些数据的缓存驱逐策略。具体来说,.cg缓存操作符允许加载指令绕过L1缓存,而.cs操作符为L1和L2缓存中的数据设置“优先驱逐”(evict-first)策略。这种策略优先从缓存中驱逐数据,最大限度地减少缓存中的内存污染,从而形成一条绕过透明缓存层的数据路径。因此,我们探索了从全局内存到寄存器的更广泛的独特数据加载路径,如图4中的蓝线所示。
新硬件特性。NVIDIA最近几代GPU(自Ampere起)引入了新的异步数据移动指令,实现了更深层次的软件流水线。Hopper系列GPU进一步引入了一个专门用于数据传输和地址计算的独立硬件组件,称为张量内存加速器(Tensor Memory Accelerator, TMA)。这些高级功能与QFactory兼容,并可以由用户作为设备规范传入,从而能够充分利用这些新的硬件能力。
差异化调度策略。利用这些多样化的数据加载路径,QFactory对张量块到不同数据路径的映射进行区分,以最大化整体内存利用率,生成针对特定场景的定制策略。
调度示例说明。为了说明这一点,我们演示了一个非量化激活块和一个量化权重Qtile的数据加载,后者由低精度权重参数及其关联的辅助量化参数组成。图5展示了QFactory发现的可能的Qtile加载调度方案。
代码模板实现数据加载路径。受CUTLASS【【33, CUTLASS, 2023, NVIDIA】】的启发,QFactory构建CUDA代码模板来实现GPU上在内存层级之间移动数据的各种数据加载路径。这种方法不仅有助于高效的代码生成,还促进了性能优化的自动调优。
高效类型转换。鉴于类型转换指令的计算吞吐量通常低于标准浮点指令【【26, CUDA C++ Programming Guide, 2024, NVIDIA】】,QFactory借鉴了先前工作【【12, Marlin: Mixed-precision auto regressive parallel inference on large language models, 2024, arXiv preprint arXiv:2408.11743】, 【39, Ladder: Enabling efficient low-precision deep learning computing through hardware-aware tensor transformation, 2024, OSDI】】中的高效类型转换方法。具体来说,QFactory以统一的方式实现了用于快速将不同格式的低位整数转换为半精度实数值的模板函数。
处理未对齐矩阵。为了解决由未对齐矩阵尺寸引起的效率低下问题(这在量化核中很常见,因为低位宽数据类型增加了对齐要求),QFactory通过模板消除了不必要的条件跳转指令。这是通过将矩阵形状和其他调优参数作为编译时常量传递来实现的,从而允许大多数程序常量在编译时被推导出来。
利用指令级并行。最后,在CUDA编译器的帮助下,QFactory启用了循环展开和指令重排序,以利用指令级并行(ILP)来重叠内存开销。虽然我们的方法与双缓冲和软件流水线等技术是正交的,但我们观察到,在大多数LLM解码场景中,ILP已经足够高效,可以提供接近最佳的性能。
应对扩大的搜索空间。由于QFactory扩展了核优化的搜索空间,如何高效地确定最佳核候选和其他核分块(tiling)中的超参数成为一个关键挑战。
ML模型预测核效率。为了解决这个问题,QFactory采用了一种基于机器学习的方法来快速识别可调参数的最佳配置。QFactory没有直接训练一个模型来输出最佳配置,而是训练一个轻量级的多层感知器(MLP)模型来预测给定核配置的效率。我们选择已实现的内存带宽利用率作为回归目标,而不是延迟,因为它提供了一个有限的值范围。具有不同量化设置的核不共享预测模型,但具有相同量化配置但不同矩阵形状的核共享同一个预测模型。我们将输入矩阵形状和核超参数(例如,分块大小、线程块大小)连接成一个向量作为输入数据,并使用核实现的带宽与设备最大带宽的比率作为标签。训练数据通过离线分析收集,其中测量了一小部分随机生成配置的核的实际执行延迟。
在线编译过程。在对新量化程序进行在线编译期间,QFactory使用训练好的模型来估计所有可能核配置的延迟。然后,QFactory选择估计延迟最低的几个核配置进行代码生成和基准测试。因此,大部分低效的核实现被排除,从而显著加快了调优过程。
LLM的量化。LLM的量化方法大致可分为量化感知训练(QAT)和训练后量化(PTQ),两者都旨在降低模型权重的位宽同时保持性能。QAT将量化集成到训练过程中,虽然计算开销大,但能实现极低的位宽,例如LLM-QAT【【24, LLMQAT: data-free quantization aware training for large language models, 2024, ACL】】、QLoRA【【7, Qlora: Efficient finetuning of quantized llms, 2023, NeurIPS】】、BitNet【【38, Bitnet: Scaling 1-bit transformers for large language models, 2023, CoRR】】等。PTQ则避免了重训,直接对预训练权重进行量化,因其高效性而得到广泛采用,特别是4位PTQ方法如GPTQ【【10, GPTQ: accurate post-training quantization for generative pre-trained transformers, 2022, CoRR】】、AWQ【【23, AWQ: activationaware weight quantization for on-device LLM compression and acceleration, 2024, MLSys】】和SpQR【【8, Spqr: A sparse-quantized representation for nearlossless LLM weight compression, 2024, ICLR】】。近期的工作如QuIP【【3, Quip: 2-bit quantization of large language models with guarantees, 2023, NeurIPS】】、SqueezeLLM【【19, Squeezellm: Dense-and-sparse quantization, 2024, ICML】】和OmniQuant【【30, OmniQuant: Omnidirectionally calibrated quantization for large language models, 2024, ICLR】】已将PTQ扩展到更低的位宽。
部署量化LLM的系统。诸如bitsandbytes【【5, bitsandbytes: 8-bit optimizers and quantization routines, 2022】】、TensorRT【【28, NVIDIA TensorRT: High Performance Deep Learning Inference Platform, 2023, NVIDIA Corporation】】、llama.cpp【【13, llama.cpp: Llm inference in c/c++, 2023, https://github.com/ggerganov/llama.cpp】】、vLLM【【21, Efficient memory management for large language model serving with pagedattention, 2023, SOSP】】和Marlin【【12, Marlin: Mixed-precision auto regressive parallel inference on large language models, 2024, arXiv preprint arXiv:2408.11743】】等系统为流行的量化格式提供了快速的核函数。然而,这些系统的应用范围有限,仅支持少数特定情况,并且在不同硬件设备上的性能可移植性较差。因此,研究人员常常需要为高级量化格式手动实现自定义核,例如AWQ【【23, AWQ: activationaware weight quantization for on-device LLM compression and acceleration, 2024, MLSys】】、FP6-LLM【【42, Quantllm: Accelerating the serving of large language models via fp6-centric algorithm-system co-design on modern gpus, 2024, USENIX ATC】】和SqueezeLLM【【19, Squeezellm: Dense-and-sparse quantization, 2024, ICML】】。LUT-GEMM【【29, LUT-GEMM: quantized matrix multiplication based on luts for efficient inference in large-scale generative language models, 2024, ICLR】】、FLUTE【【15, Fast matrix multiplications for lookup table-quantized llms, 2024, EMNLP】】和T-MAC【【40, T-MAC: CPU renaissance via table lookup for low-bit LLM deployment on edge, 2024, CoRR】】专注于优化基于查找表的量化,这在低位宽场景中特别有用。BitBLAS【【39, Ladder: Enabling efficient low-precision deep learning computing through hardware-aware tensor transformation, 2024, OSDI】】在TVM【【4, TVM: an automated endto-end optimizing compiler for deep learning, 2018, OSDI】】、Roller【【46, ROLLER: fast and efficient tensor compilation for deep learning, 2022, OSDI】】和Welder【【31, Welder: Scheduling deep learning memory access via tile-graph, 2023, OSDI】】等常规精度深度学习编译器的基础上,提供了对低精度量化的支持。然而,它未能充分解决高级量化格式或分组量化的复杂性,限制了其在更复杂的量化工作流中的有效性。
仅支持权重量化。随着批量大小(batch size)的增加,仅权重量化无法持续提供理论上的加速,因为核函数从内存密集型转变为计算密集型,从而削弱了内存占用减少带来的好处。为了解决这一局限性,激活-权重量化(activation-weight quantization)联合对激活值进行额外压缩,并采用低精度计算,即使在大批量下也能实现持续的加速。
未来工作方向。虽然QFactory目前仅支持仅权重量化,但其核心方法可以扩展到激活-权重量化,以进一步加速核函数。我们将这个方向作为未来的工作。
本文提出了QFactory,一个用于加速量化LLM服务的高效编译框架。QFactory通过引入新颖的Qtile抽象,解决了现有系统效率低下的问题,并通过Qtile计算转换和差异化内存调度探索了更广阔的优化空间。在多种GPU上的广泛评估表明,QFactory的性能优于最先进的编译器和手动优化的库。作为一个部署量化LLM的可扩展解决方案,QFactory不仅提高了模型效率,还通过减轻实现自定义核所需的大量人力,促进了新量化算法的探索。