翻译来源 https://blog.squeezebits.com/vllm-vs-tensorrtllm-6-weightonly-quantization-33728
前言
量化(Quantization) 是一种广泛应用于深度学习模型的压缩技术,可用于减少模型的存储需求并加速推理。对于 LLM(Large Language Models) 来说,量化尤为重要,因为这些模型包含大量参数,计算需求极高。vLLM 和 TensorRT-LLM 都支持多种量化方法,为用户提供了更快部署 LLM 的可行方案。
在接下来的三篇文章中,我们将探讨 vLLM 和 TensorRT-LLM 支持的量化技术。本篇文章将重点介绍:
- Weight-Only Quantization 方法。
下一篇文章将讨论 Weight-Activation Quantization,而最后一篇文章将介绍 KV Cache Quantization 在长上下文场景中的应用。
量化的效果会受到多种因素的影响,例如模型架构、模型大小、硬件条件以及模型并行性等。在本篇文章中,我们将使用 Llama-3.1 的一个相对较小的变体,并在单个 GPU 上进行实验,以便于分析。
Weight-Only Quantization
仅权重量化 通过将模型的权重从高精度浮点格式(如 FP32 或 FP16)转换为更低精度(如 INT8 或 INT4),从而减少存储占用。近年来,4-bit(INT4)量化 逐渐流行起来,因为它能够有效减少内存使用,同时保持模型的准确性。
在 Weight-Only Quantization 方案中,仅模型权重会被量化,而 激活(Activation) 仍保持高精度格式。
由于 GPU 不具备混合精度张量(Mixed-Precision Tensor)乘法的专用计算单元,因此推理时必须将量化后的权重反量化(dequantize)为高精度格式,从而引入额外的计算开销(下图)。因此,权重量化的效果取决于工作负载是受限于内存(Memory-Bound)还是受限于计算(Compute-Bound)——在计算受限的情况下,反量化的开销会更显著。
LLM 推理一般分为两个阶段:
- 预填充阶段(Prefill Phase):一次性处理较长的输入提示(Prompt),通常是 计算受限(Compute-Bound)。
- 解码阶段(Decode Phase):逐个生成 Token,在小批量(Small Batch Size)情况下通常 受限于内存(Memory-Bound),但随着批量大小增加,会逐渐向计算受限转变。
由于在同一个推理过程中,工作负载特征会有所不同,因此需要进行充分测试,以准确评估仅权重量化对 LLM 性能的真实影响。
vLLM 和 TensorRT-LLM 的量化方法
目前,有多种 Weight-Only Quantization 方法可用于 LLM,其中最知名的包括:
由于 权重量化通常会将权重比特宽度降低到 INT4 或更低,因此需要专用的计算内核(Kernel)来加速计算。vLLM 和 TensorRT-LLM 都提供了多个计算内核,以支持和加速这些量化方案。
vLLM 量化支持:
- AWQ 方案:
- 官方 AWQ 内核(Official AWQ Kernel)
- Marlin 内核(适用于batch大的情况)
- GPTQ 方案:
- ExLlamaV2 内核
- Marlin 内核
- Machete 内核(适用于 NVIDIA Hopper 架构)
TensorRT-LLM 量化支持:
- AWQ 方案(NVIDIA 自研内核)
- GPTQ 方案(NVIDIA 自研内核)
此外,在加载 Weight-Only Quantization LLM 时,由于 Sub-Byte权重需要专用格式进行存储和加载,不同框架的处理方式也有所不同:
vLLM:
- 直接支持 AutoAWQ 和 AutoGPTQ 量化的模型,并允许用户选择不同的内核加速推理。
- 还支持使用 LLM-Compressor Suite 进行 LLM 量化(采用 GPTQ 方案)。
TensorRT-LLM:
- AutoGPTQ 量化的模型需转换为 TensorRT-LLM 兼容格式。
- AWQ 量化 需使用 NVIDIA 的 Model Optimizer 进行量化,并在 TensorRT-LLM 中加速推理。
由于不同的量化方案和内核选项较多,选择最优配置往往需要大量的实验和经验。为了提供更直观的参考,我们接下来将对 vLLM 和 TensorRT-LLM 进行性能对比分析。
实验设置
量化方案与kernel
所有涉及AWQ和GPTQ的实验中,权重均被量化为4位(INT4)格式,分组大小为128用于缩放因子。对于vLLM,支持多种量化方案和内核组合。在AWQ设置下,我们使用了AutoAWQ库量化模型,并测试了两种内核:官方AWQ内核和Marlin。GPTQ方案则使用AutoGPTQ库配合ExLlamaV2内核。另一方面,Marlin和Machete内核的模型通过LLM-Compressor套件准备以获得更好的性能。
对于TensorRT-LLM,仅提供两种选项:AWQ和GPTQ,均使用NVIDIA的内核。
- vLLM: AWQ(官方/Marlin)、GPTQ(ExLlamaV2/Marlin/Machete)
- TensorRT-LLM: AWQ、GPTQ
基准数据集
所有实验均使用固定输入和输出长度的数据集以保持跨框架处理的token数量一致。
使用了两种不同的数据集:填充量大的数据(prefill-heavy)和解码量大的数据(decode-heavy)。填充量大的数据集输入和输出长度分别为2,048和128 token。解码量大的数据集输入和输出长度分别为128和2,048 token。
我们在不同最大批量大小下进行了测试。测试请求的数量为256,但针对批量大小为256的情况,我们使用了1,024个样本以获得更稳定的测量结果。
版本
我们选择了能够成功完成基准测试的版本:
- vLLM: v0.6.2
- TensorRT-LLM: 0.13.0正式版,带C++ API
模型和硬件
- 模型:Llama-3.1–8B-Instruct(FP16,AWQ-INT4,GPTQ-INT4)
- 硬件:NVIDIA H100-PCIe 80G GPU,Intel Xeon(R) Platinum 8352Y CPU(32核)@ 2.20GHz
实验结果
本文重点比较了 vLLM 和 TensorRT-LLM 在不同配置下的吞吐量表现。我们通过调整最大批量大小(max batch size)来测量吞吐量,以评估 weight-only quantization(权重量化)在内存受限(memory-bound)和计算受限(compute-bound)场景下的影响。我们将请求速率设置为无限,以确定每种内核配置下可达到的最大吞吐量。
FP16 与 WOQ Best 的对比
图 2 展示了在较小批量大小下,weight-only quantization 对吞吐量的提升效果。无论输入和输出长度如何,权重量化都能将 vLLM 和 TensorRT-LLM 的吞吐量提升约 2 倍。在小批量场景下,工作负载主要受内存带宽限制,权重量化通过减少内存读取量显著提升了性能。
随着批量大小的增加,LLM 推理过程变得更加依赖计算资源(compute-bound),weight-only quantization 带来的吞吐量增益开始减少。然而,即使在测试的最大批量大小下,权重量化的吞吐量仍然与 FP16 基准相当。在输出长度较长的 decode-heavy 场景下,尽管任务偏向计算密集型,权重量化仍然带来了意外的吞吐量提升。这主要得益于权重量化减少了模型权重所需的内存空间,从而允许更大的有效批量大小(见 图 4)。
图 4 展示了在使用 TensorRT-LLM 框架进行推理时的实际有效批量大小。在 FP16 推理模式下,有效批量大小始终低于设定的最大批量大小 256。而在使用权重量化时,由于模型大小减少,有效批量大小得以提升。这个更高的批量利用率弥补了计算受限场景下反量化(dequantization)带来的开销,从而实现了整体吞吐量的净增益。
vLLM 与 TensorRT-LLM 的对比
接下来,我们比较了 TensorRT-LLM 和 vLLM 在最优权重量化配置下的吞吐量表现。
图 5 展示了在应用权重量化的情况下,vLLM 和 TensorRT-LLM 的整体吞吐量对比。总体来看,TensorRT-LLM 在大多数最大批量大小下的吞吐量都高于 vLLM。当最大批量大小为 256 时,TensorRT-LLM 在 prefill-heavy 和 decode-heavy 场景下分别比 vLLM 高出 1.18 倍 和 1.15 倍。
然而,在 decode-heavy 数据集上,当最大批量大小为 4 和 16 时,vLLM 的表现优于 TensorRT-LLM。
此外,图 5 中的表格还展示了不同场景下最优的内核选择。值得注意的是,最优内核会随着批量大小的不同而变化。对于 TensorRT-LLM,在仅有两种内核选项的情况下,AWQ 在批量大小为 1 时表现最佳,而 GPTQ 在其他所有情况下表现更优。
相比之下,对于 vLLM,最优内核选项会随批量大小的不同而改变。在 decode-heavy 场景下,ExLlamaV2 在小批量(1)时表现最佳,Marlin 在中等批量(4–16)时表现突出,而 Machete 则在大批量(64–256)时取得了最高吞吐量。
ExLlamaV2、Marlin 和 Machete 的对比
鉴于 vLLM 中不同内核在不同批量大小下的表现存在差异,我们进一步比较了这些内核的性能。由于 Marlin 和 Machete 声称针对大批量设置进行了优化,因此我们对比了 ExLlamaV2、Marlin 和 Machete 内核在不同批量大小下的表现。由于 Machete 不支持 AWQ,因此我们在 GPTQ 下对比了 vLLM 的不同内核实现。
图 6 展示了在最大批量大小较小时的吞吐量对比。当批量大小为 1 时,ExLlamaV2 默认内核的吞吐量高于 Marlin 和 Machete 内核。
随着最大批量大小增加到 4 或 16,Marlin 和 Machete 内核开始超过 ExLlamaV2 内核的表现。特别是当批量大小为 16 时,Marlin 和 Machete 的吞吐量几乎是 ExLlamaV2 的 2 倍。在这个范围内,Marlin 内核甚至超越了 Machete 内核和 TensorRT-LLM 的最优配置。
当批量大小进一步增大时,Machete 开始展现出领先优势。这与 Machete 的开发者所声称的观点一致,即 Machete 是 Marlin 在大批量场景下的更优继任者。尽管如此,在大批量任务中,TensorRT-LLM 仍然是最佳选择。
总结
本文对 vLLM 和 TensorRT-LLM 提供的权重量化方案和内核选项进行了性能比较。总体而言,TensorRT-LLM 在大多数情况下表现更优,但值得注意的是,vLLM 在某些特定场景下也能超越 TensorRT-LLM。
此外,即使在相同的量化方案下,选择最优内核也能在 vLLM 中带来显著的性能提升。虽然随着最大批量大小的增加,权重量化带来的性能提升逐渐减弱,但通过更有效的批量利用,即使在大批量场景下,吞吐量仍可得到改善。
需要注意的是,本次评测存在一定局限性。首先,实验主要基于 LLaMA-3.1–8B-Instruct 模型在单个 H100 PCIe GPU 上进行,这些结果可能无法直接推广到其他模型或环境。在使用不同模型(尤其是更大的模型)或在多 GPU 卡上进行模型并行化时,可能会出现不同的性能趋势。其次,这两个框架还提供了许多可以与量化技术结合使用的其他优化手段,例如 chunked prefill。因此,针对自身模型、服务场景和硬件环境进行多样化实验至关重要。
在接下来的文章中,我们将探讨 weight-activation quantization(权重-激活量化)。通过利用 GPU 中低精度 Tensor Cores 进行矩阵乘法运算,权重-激活量化有望在大批量设置下实现更高吞吐量。请持续关注 vLLM vs TensorRT-LLM 系列的更多深入分析!