FP8 W8A8¶
vLLM 支援使用 FP8(8 位浮點數)的權重和啟用量化,並在 Nvidia H100 和 AMD MI300x 等 GPU 上進行硬體加速。目前,W8A8 僅官方支援 Hopper 和 Ada Lovelace GPU。Ampere GPU 透過利用 Marlin 核心支援 W8A16(僅權重 FP8)。FP8 量化模型可將模型記憶體需求減少 2 倍,並將吞吐量提高高達 1.6 倍,同時對準確性的影響最小。
請訪問 Hugging Face 上精選的 vLLM 可用的量化 FP8 流行 LLM 檢查點集合。
硬體通常支援的 FP8 型別有兩種不同的表示形式,它們各自適用於不同的場景:
- E4M3:包含 1 個符號位、4 個指數位和 3 個尾數位。它可以儲存 +/-448 和
nan的值。 - E5M2:包含 1 個符號位、5 個指數位和 2 個尾數位。它可以儲存 +/-57344、+/-
inf和nan的值。增加的動態範圍是以降低儲存值的精度為代價的。
注意
FP8 計算在計算能力 > 8.9(Ada Lovelace、Hopper)的 NVIDIA GPU 上受支援。FP8 模型將在計算能力 > 8.0(Ampere)的 GPU 上以僅權重 W8A16 的形式執行,利用 FP8 Marlin。
安裝¶
要使用 vLLM 生成高效能的 FP8 量化模型,您需要安裝 llm-compressor 庫。
量化過程¶
量化過程包括三個主要步驟:
- 載入模型
- 應用量化
- 在 vLLM 中評估精度
1. 載入模型¶
使用標準的 transformers AutoModel 類載入您的模型和分詞器
from transformers import AutoTokenizer, AutoModelForCausalLM
MODEL_ID = "meta-llama/Meta-Llama-3-8B-Instruct"
model = AutoModelForCausalLM.from_pretrained(
MODEL_ID,
device_map="auto",
dtype="auto",
)
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
2. 應用量化¶
對於 FP8 量化,我們可以透過簡單的 RTN 量化來恢復準確性。我們建議使用 FP8_DYNAMIC 方案,該方案針對所有 Linear 層,它使用:
- 對權重的靜態、每通道量化
- 對啟用的動態、每令牌量化
由於簡單的 RTN 不需要權重量化資料,並且啟用是動態量化的,因此我們不需要任何校準資料來進行此量化流程。
程式碼
from llmcompressor 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: Meta-Llama-3-8B-Instruct-FP8-Dynamic
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 git+https://github.com/EleutherAI/lm-evaluation-harness.git@206b7722158f58c35b7ffcd53b035fdbdda5126d#egg=lm-eval[api]
在 vllm 中載入並執行模型。
from vllm import LLM
llm = LLM("./Meta-Llama-3-8B-Instruct-FP8-Dynamic")
result = llm.generate("Hello my name is")
print(result[0].outputs[0].text)
使用 lm_eval 評估準確性(例如,在 gsm8k 的 250 個樣本上)。
注意
量化模型可能對 bos token 的存在敏感。lm_eval 預設不新增 bos token,因此在執行評估時請務必包含 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 儲存庫上提交 issue。
線上動態量化¶
透過 vLLM 可以將原始精度 BF16/FP16 模型動態量化到 FP8,而無需任何校準資料。您可以透過在命令列中指定 --quantization="fp8" 或在 LLM 建構函式中設定 quantization="fp8" 來啟用此功能。
在此模式下,所有 Linear 模組(lm_head 除外)的權重將被量化到 FP8_E4M3 精度,並使用每張量(per-tensor)縮放因子。啟用值在每次前向傳遞期間計算其最小值和最大值,以提供動態的每張量縮放因子以獲得高精度。因此,在此模式下,延遲提升有限。
from vllm import LLM
llm = LLM("facebook/opt-125m", quantization="fp8")
# INFO 06-10 17:55:42 model_runner.py:157] Loading model weights took 0.1550 GB
result = llm.generate("Hello, my name is")
print(result[0].outputs[0].text)
警告
目前,我們在量化到 8 位之前以原始精度載入模型,因此您需要足夠的記憶體來載入整個模型。