FP8 W8A8#
vLLM 支持在 Nvidia H100 和 AMD MI300x 等 GPU 上使用硬件加速进行 FP8(8 位浮点)权重和激活量化。目前,仅 Hopper 和 Ada Lovelace GPU 正式支持 W8A8。利用 Marlin 内核,Ampere GPU 支持 W8A16(仅权重 FP8)。使用 FP8 对模型进行量化可以减少 2 倍的模型内存需求,并在对准确性影响最小的情况下将吞吐量提高至多 1.6 倍。
请访问 HF 集合中的 适用于 vLLM 的流行 LLM 的量化 FP8 检查点。
硬件中通常支持的FP8类型有两种不同的表示形式,每种在不同场景下都有其用途:
E4M3: 由1个符号位、4个指数位和3个尾数位组成。它可以存储高达 +/-448 和
nan
的值。E5M2: 由1个符号位、5个指数位和2个尾数位组成。它可以存储高达 +/-57344、+/-
inf
和nan
的值。增加动态范围的代价是存储值的精度降低。
备注
FP8 计算在计算能力 > 8.9 的 NVIDIA GPU(Ada Lovelace、Hopper)上受支持。FP8 模型将在计算能力 > 8.0(Ampere)上作为仅权重 W8A16 运行,利用 FP8 Marlin。
在线动态量化快速入门#
将原始精度为 BF16/FP16 的模型动态量化为 FP8 可以通过 vLLM 实现,无需任何校准数据。您可以通过在命令行中指定 --quantization="fp8"
或在 LLM 构造函数中设置 quantization="fp8"
来启用该功能。
在这种模式下,所有 Linear 模块(除了最后的 lm_head
)的权重都被量化为 FP8_E4M3 精度,并使用每个张量的比例。激活值在每次前向传递期间计算其最小值和最大值,以提供高精度的动态每个张量比例。因此,这种模式下的延迟改进有限。
from vllm import LLM
model = LLM("facebook/opt-125m", quantization="fp8")
# INFO 06-10 17:55:42 model_runner.py:157] Loading model weights took 0.1550 GB
result = model.generate("Hello, my name is")
警告
目前,我们在量化到8位之前以原始精度加载模型,因此您需要足够的内存来加载整个模型。
安装#
要使用 vLLM 生成高性能的 FP8 量化模型,您需要安装 llm-compressor 库:
$ pip install llmcompressor==0.1.0
量化过程#
量化过程涉及三个主要步骤:
加载模型
应用量化
在 vLLM 中评估准确性
1. 加载模型#
使用 SparseAutoModelForCausalLM
,它封装了 AutoModelForCausalLM
,用于保存和加载量化模型:
from llmcompressor.transformers import SparseAutoModelForCausalLM
from transformers import AutoTokenizer
MODEL_ID = "meta-llama/Meta-Llama-3-8B-Instruct"
model = SparseAutoModelForCausalLM.from_pretrained(
MODEL_ID, device_map="auto", torch_dtype="auto")
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
2. 应用量化#
对于FP8量化,我们可以通过简单的RTN量化恢复精度。我们建议使用 FP8_DYNAMIC
方案来针对所有 Linear
层,该方案使用:
静态,按通道的权重量化
动态的、按token的激活量化
由于简单的 RTN 不需要数据来进行权重量化,并且激活值是动态量化的,因此我们不需要为此量化流程准备任何校准数据。
from llmcompressor.transformers import oneshot
from llmcompressor.modifiers.quantization import QuantizationModifier
# Configure the simple PTQ quantization
recipe = QuantizationModifier(
targets="Linear", scheme="FP8_DYNAMIC", ignore=["lm_head"])
# Apply the quantization algorithm.
oneshot(model=model, recipe=recipe)
# Save the model.
SAVE_DIR = MODEL_ID.split("/")[1] + "-FP8-Dynamic"
model.save_pretrained(SAVE_DIR)
tokenizer.save_pretrained(SAVE_DIR)
3. 评估准确性#
安装 vllm
和 lm-evaluation-harness
:
$ pip install vllm lm-eval==0.4.4
在 vllm
中加载并运行模型:
from vllm import LLM
model = LLM("./Meta-Llama-3-8B-Instruct-FP8-Dynamic")
model.generate("Hello my name is")
使用 lm_eval
评估准确性(例如在 gsm8k
的 250 个样本上):
备注
量化模型可能对 bos
标记的存在敏感。 lm_eval
默认不添加 bos
标记,因此在运行评估时请确保包含 add_bos_token=True
参数。
$ MODEL=$PWD/Meta-Llama-3-8B-Instruct-FP8-Dynamic
$ lm_eval \
--model vllm \
--model_args pretrained=$MODEL,add_bos_token=True \
--tasks gsm8k --num_fewshot 5 --batch_size auto --limit 250
以下是结果分数的一个示例:
|Tasks|Version| Filter |n-shot| Metric | |Value| |Stderr|
|-----|------:|----------------|-----:|-----------|---|----:|---|-----:|
|gsm8k| 3|flexible-extract| 5|exact_match|↑ |0.768|± |0.0268|
| | |strict-match | 5|exact_match|↑ |0.768|± |0.0268|
故障排除和支持#
如果你遇到任何问题或有功能请求,请在 vllm-project/llm-compressor
GitHub 仓库中提交问题。
弃用流程#
备注
以下信息保留供参考和搜索使用。下面描述的量化方法已被弃用,取而代之的是上述描述的 llmcompressor
方法。
对于静态的每张量离线量化到FP8,请安装 AutoFP8库。
git clone https://github.com/neuralmagic/AutoFP8.git
pip install -e AutoFP8
此包引入了 AutoFP8ForCausalLM
和 BaseQuantizeConfig
对象,用于管理模型的压缩方式。
使用静态激活缩放因子的离线量化#
你可以使用带有校准数据的AutoFP8,通过启用``activation_scheme=”static”``参数,为权重和激活生成每个张量的静态比例。
from datasets import load_dataset
from transformers import AutoTokenizer
from auto_fp8 import AutoFP8ForCausalLM, BaseQuantizeConfig
pretrained_model_dir = "meta-llama/Meta-Llama-3-8B-Instruct"
quantized_model_dir = "Meta-Llama-3-8B-Instruct-FP8"
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_dir, use_fast=True)
tokenizer.pad_token = tokenizer.eos_token
# Load and tokenize 512 dataset samples for calibration of activation scales
ds = load_dataset("mgoin/ultrachat_2k", split="train_sft").select(range(512))
examples = [tokenizer.apply_chat_template(batch["messages"], tokenize=False) for batch in ds]
examples = tokenizer(examples, padding=True, truncation=True, return_tensors="pt").to("cuda")
# Define quantization config with static activation scales
quantize_config = BaseQuantizeConfig(quant_method="fp8", activation_scheme="static")
# Load the model, quantize, and save checkpoint
model = AutoFP8ForCausalLM.from_pretrained(pretrained_model_dir, quantize_config)
model.quantize(examples)
model.save_quantized(quantized_model_dir)
你的模型检查点,包含量化后的权重和激活值,应该可以在 Meta-Llama-3-8B-Instruct-FP8/
找到。最后,你可以直接在 vLLM 中加载量化的模型检查点。
from vllm import LLM
model = LLM(model="Meta-Llama-3-8B-Instruct-FP8/")
# INFO 06-10 21:15:41 model_runner.py:159] Loading model weights took 8.4596 GB
result = model.generate("Hello, my name is")