压缩您的模型
LLM Compressor 提供了一种通过各种优化技术压缩模型的直接方法。本指南将引导你完成使用不同量化方法压缩模型的流程。
先决条件
在开始之前,请确保你的环境满足以下先决条件:- 操作系统: Linux (推荐用于 GPU 支持) - Python 版本: 3.10 或更高版本 - 可用 GPU: 为获得最佳性能,建议使用 GPU。LLM Compressor 支持最新的 PyTorch 和 CUDA 版本,以兼容 NVIDIA GPU。
选择模型和数据集
在开始压缩之前,请选择要压缩的模型以及代表你使用场景的校准数据集。LLM Compressor 支持多种模型,并与 Hugging Face Transformers 和 Model Hub 原生集成,因此一个好的起点是使用 Hugging Face Model Hub 中的模型。LLM Compressor 还支持 Hugging Face Datasets 库中的许多数据集,可以轻松找到适合校准的数据集。
在本指南中,我们将使用 TinyLlama 模型和 open_platypus 数据集进行校准。你可以根据需要替换为你自己的模型和数据集。
选择量化方法和方案
LLM Compressor 支持多种量化方法和方案,每种都有其优点和缺点。方法的选择将取决于你的具体使用场景、硬件能力以及在模型大小、速度和准确性之间所做的权衡。
支持的压缩方案包括将模型量化为 W4A16、W8A8‑INT8 和 W8A8‑FP8 格式,以及稀疏化。有关可用量化方案的更详细概述,请参阅 压缩方案。
压缩方案使用包括以下内容的量化方法
| 方法 | 描述 | 准确度恢复与时间 |
|---|---|---|
| GPTQ | 利用二阶层级优化来优先处理重要权重/激活,并允许更新剩余权重 | 高准确度恢复,但运行成本更高/速度更慢 |
| AWQ | 使用通道缩放来更好地保留权重和激活中的重要异常值 | 比 GPTQ 具有更好的准确度恢复和更快的运行时 |
| SmoothQuant | 通过将激活中的异常值折叠到权重中来平滑它们,确保权重和激活量化模型的更好准确度 | 具有最小校准时间的良好准确度恢复;可与其他方法组合 |
| Round-To-Nearest (RTN) | 一种简单的量化技术,将每个值四舍五入到目标精度中可表示的最近级别。 | 在大多数情况下提供适度的准确度恢复。计算成本低且实现速度快,适合实时或资源受限的环境。 |
| AutoRound | AutoRound 通过符号梯度下降优化舍入和裁剪范围。 | 与 GPTQ/AWQ 相比,在 4 位和低于 4 位精度方面提供领先的准确度,运行时速度快于 GPTQ,与 AWQ 相当。 |
在本指南中,我们将使用 GPTQ 并与 SmoothQuant 结合创建 INT W8A8 量化模型。此组合在性能、准确性和广泛硬件的兼容性方面提供了良好的平衡。
应用配置
LLM Compressor 提供了 oneshot API,用于简单直接的模型压缩。此 API 允许你将预定义的配置应用于模型和数据集,从而轻松开始压缩。为了应用我们上面讨论的内容,我们将导入必要的修饰符并创建一个配置来应用于我们的模型和数据集
from llmcompressor.modifiers.smoothquant import SmoothQuantModifier
from llmcompressor.modifiers.quantization import GPTQModifier
from llmcompressor import oneshot
recipe = [
SmoothQuantModifier(smoothing_strength=0.8),
GPTQModifier(scheme="W8A8", targets="Linear", ignore=["lm_head"]),
]
oneshot(
model="TinyLlama/TinyLlama-1.1B-Chat-v1.0",
dataset="open_platypus",
recipe=recipe,
output_dir="TinyLlama-1.1B-Chat-v1.0-INT8",
max_seq_length=2048,
num_calibration_samples=512,
)
当你运行上述代码时,压缩后的模型将保存到指定的输出目录:TinyLlama-1.1B-Chat-v1.0-INT8。然后,你可以使用 Hugging Face Transformers 库或 vLLM 加载此模型进行推理和测试。
LLM Compressor 的内存需求
压缩模型时,应注意内存需求取决于模型大小和所使用的算法,例如 GPTQ/SparseGPT。
本节将通过几个流行的模型(8B、684B 和具有视觉功能的模型)作为示例,介绍如何计算每种算法的 CPU 和 GPU 内存需求。
GPTQ/SparseGPT 需要大量的辅助内存。GPTQ/SparseGPT 会为任何加载到 GPU 的层分配一个辅助海森矩阵。这是因为海森矩阵的大小几乎与它们试图表示的权重一样大。
此外,像 DeepSeek R1 这样的大型模型会占用大量 CPU 内存,而像 Command A 这样具有大型视觉塔的模型可能会占用大量 GPU 内存。
计算 LLM Compressor 内存需求时需要注意的事项
-
1B 模型加载需要 2GB 内存
-
文本解码器层和视觉塔层在 GPU 上的加载方式差异很大。
在文本解码器层的情况下,LLM Compressor 会一次将一层动态加载到 GPU 进行计算。模型的其余部分保留在 CPU 内存中。
然而,视觉塔层会一次性全部加载到 GPU。与文本模型不同,视觉塔在加载到 GPU 之前不会被拆分成单独的层。这可能会为视觉塔比文本层大的模型造成 GPU 内存瓶颈。
目前,LLM Compressor 不会对视觉塔进行量化,因为量化通常不值得在延迟/吞吐量和准确性损失之间进行权衡。
-
LLM Compressor 目前不支持张量并行进行压缩。支持此功能将允许层在 GPU 之间分片,从而降低每个 GPU 的内存使用量并加快压缩速度。
QuantizationModifier 或 Round-To-Nearest (RTN)
量化修饰符 RTN 不需要除其量化参数(scales/zeros)存储之外的任何额外内存。
如果我们从计算中忽略这些 scales 和 zero points,我们可以估算以下内存需求
| 模型 | CPU 需求 | GPU 需求 |
|---|---|---|
| Meta-Llama-3-8B-Instruct | 内存(8B 参数) ~= 16Gb | 内存(1 层) ~= 0.5Gb |
| DeepSeek-R1-0528-BF16 | 内存(684B 参数) ~= 1368Gb | 内存(1 层) ~= 22.4Gb |
| Qwen2.5-VL-7B-Instruct | 内存(7B 参数) ~= 14Gb | max(内存(1 文本层) ~= 0.4B, 内存(视觉塔) ~= 1.3B) ~= 1.3Gb |
GPT 量化 (GPTQ) / 稀疏 GPT
GPTQ/ SparseGPT 算法与 RTN 的不同之处在于,它们还必须为任何加载到 GPU 的层分配辅助海森矩阵。
此海森矩阵用于提高算法的准确度恢复,其大小约等于原始权重。
| 模型 | CPU 需求 | GPU 需求 |
|---|---|---|
| Meta-Llama-3-8B-Instruct | 内存(8B 参数) ~= 16Gb | 内存(1 层) * 2 ~= 1Gb |
| DeepSeek-R1-0528-BF16 | 内存(684B 参数) ~= 1368Gb | 内存(1 层) * 2 ~= 44.8Gb |
| Qwen2.5-VL-7B-Instruct | 内存(7B 参数) ~= 14Gb | max(内存(1 文本层) ~= 0.4B, 内存(视觉塔) ~= 1.3B)*2 ~= 2.6Gb |
LLM Compressor 的运行时需求
以下是每种 LLM Compressor 算法的典型运行时间,基于在 NVIDIA A100 Tensor Core GPU 上使用 Meta-Llama-3-8B-Instruct 进行的运行。
| 算法 | 估计时间 |
|---|---|
| RTN (QuantizationModifier) 仅权重 (无激活量化) | ~ 1 分钟 |
| RTN (QuantizationModifier) 权重和激活 | ~ 20 分钟 |
| GPTQ (仅权重) | ~ 30 分钟 |
| AWQ (仅权重) | ~ 30 分钟 |